App MediaFrameReader always returns null Bitmap

306 Views Asked by At

I am using MediaCapture to preview camera on the screen, which is working fine.

However, I need to access the current frames in my App. Therefore I added FrameReader to the MediaCapture to get the event Reader_FrameArrived.

So the event is working, however the bitmap itself is always null.

I implemented the ecent callback just like shown in the examples:

var mediaFrameReference = sender.TryAcquireLatestFrame();
var videoMediaFrame = mediaFrameReference?.VideoMediaFrame;
var softwareBitmap = videoMediaFrame?.SoftwareBitmap;

if (softwareBitmap != null)
{
    Debug.WriteLine("here");
}
else
{
    return;
}

and this is how I initialize the reader:

var frameSourceGroups = await MediaFrameSourceGroup.FindAllAsync();

var allGroups = await MediaFrameSourceGroup.FindAllAsync();
var eligibleGroups = allGroups.Select(g => new
{
    Group = g,

    // For each source kind, find the source which offers that kind of media frame,
    // or null if there is no such source.
    SourceInfos = new MediaFrameSourceInfo[]
    {
        g.SourceInfos.FirstOrDefault(info => info.SourceKind == MediaFrameSourceKind.Color),
        g.SourceInfos.FirstOrDefault(info => info.SourceKind == MediaFrameSourceKind.Depth),
        g.SourceInfos.FirstOrDefault(info => info.SourceKind == MediaFrameSourceKind.Infrared),
    }
}).Where(g => g.SourceInfos.Any(info => info != null)).ToList();

if (eligibleGroups.Count == 0)
{
    System.Diagnostics.Debug.WriteLine("No source group with color, depth or infrared found.");
    return;
}

var selectedGroupIndex = 0; // Select the first eligible group
MediaFrameSourceGroup selectedGroup = eligibleGroups[selectedGroupIndex].Group;
MediaFrameSourceInfo colorSourceInfo = eligibleGroups[selectedGroupIndex].SourceInfos[0];
MediaFrameSourceInfo infraredSourceInfo = eligibleGroups[selectedGroupIndex].SourceInfos[1];
MediaFrameSourceInfo depthSourceInfo = eligibleGroups[selectedGroupIndex].SourceInfos[2];

//_mediaCapture.FrameSources.TryGetValue(cameraDevice.Id, out _source);
var colorFrameSource = _mediaCapture.FrameSources[colorSourceInfo.Id];

if (colorFrameSource != null)
{
    _reader = await _mediaCapture.CreateFrameReaderAsync(colorFrameSource, MediaEncodingSubtypes.Argb32);
    _reader.FrameArrived += Reader_FrameArrived;
    
    MediaFrameReaderStartStatus result = await _reader.StartAsync();

    Debug.WriteLine(result.ToString());
}

Any ideas why the bitmap could be null?

1

There are 1 best solutions below

4
On BEST ANSWER

I am using MediaCapture to preview camera on the screen, which is working fine.

For the scenario, we suggest you use MediaCapture class capture bitmap, it contains GetPreviewFrameAsync method gets a preview frame from the capture device than convert it to SoftwareBitmap.

private async Task GetPreviewFrameAsSoftwareBitmapAsync()
{
    // Get information about the preview
    var previewProperties = _mediaCapture.VideoDeviceController.GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;

    // Create the video frame to request a SoftwareBitmap preview frame
    var videoFrame = new VideoFrame(BitmapPixelFormat.Bgra8, (int)previewProperties.Width, (int)previewProperties.Height);

    // Capture the preview frame
    using (var currentFrame = await _mediaCapture.GetPreviewFrameAsync(videoFrame))
    {
        // Collect the resulting frame
        SoftwareBitmap previewFrame = currentFrame.SoftwareBitmap;

        // Show the frame information
        FrameInfoTextBlock.Text = String.Format("{0}x{1} {2}", previewFrame.PixelWidth, previewFrame.PixelHeight, previewFrame.BitmapPixelFormat);

        // Add a simple green filter effect to the SoftwareBitmap
        if (GreenEffectCheckBox.IsChecked == true)
        {
            ApplyGreenFilter(previewFrame);
        }

        // Show the frame (as is, no rotation is being applied)
        if (ShowFrameCheckBox.IsChecked == true)
        {
            // Create a SoftwareBitmapSource to display the SoftwareBitmap to the user
            var sbSource = new SoftwareBitmapSource();
            await sbSource.SetBitmapAsync(previewFrame);

            // Display it in the Image control
            PreviewFrameImage.Source = sbSource;
        }

        // Save the frame (as is, no rotation is being applied)
        if (SaveFrameCheckBox.IsChecked == true)
        {
            var file = await _captureFolder.CreateFileAsync("PreviewFrame.jpg", CreationCollisionOption.GenerateUniqueName);

            Debug.WriteLine("Saving preview frame to " + file.Path);

            await SaveSoftwareBitmapAsync(previewFrame, file);
        }
    }
}

And here is official code sample that you could refer directly.