private void NewFrameArrived(MediaFrameReader sender, MediaFrameArrivedEventArgs args) { if (!StreamFaultTimer.IsRunning) { StreamFaultTimer.Start(); } StreamFaultTimer.Restart(); MediaFrameReference LatestFrame = sender.TryAcquireLatestFrame(); if (LatestFrame != null) { VideoMediaFrame LatestVideoFrame = LatestFrame.VideoMediaFrame; if (LatestVideoFrame.SoftwareBitmap == null) { HandleFrame(Convert.Direct3dToSKImage(LatestVideoFrame.Direct3DSurface)); } else { HandleFrame(Convert.SoftwareBitmapToSKImage(LatestVideoFrame.SoftwareBitmap)); } if (LatestVideoFrame.Direct3DSurface != null) { LatestVideoFrame.Direct3DSurface.Dispose(); } if (LatestVideoFrame.SoftwareBitmap != null) { LatestVideoFrame.SoftwareBitmap.Dispose(); } LatestFrame.Dispose(); } else { } }
/// <summary> /// When done with the VideoCapture class, you will need to dispose it to release unmanaged memory. /// </summary> public void Dispose() { bitmap.Dispose(); bitmap = null; frameReference.Dispose(); frameReference = null; videoFrame.Dispose(); videoFrame = null; }
public void ProcessFrame(MediaFrameReference frame) { var softwareBitmap = FrameRenderer.ConvertToDisplayableImage(frame?.VideoMediaFrame); if (softwareBitmap != null) { // Swap the processed frame to _backBuffer and trigger UI thread to render it softwareBitmap = Interlocked.Exchange(ref _backBuffer, softwareBitmap); // UI thread always reset _backBuffer before using it. Unused bitmap should be disposed. softwareBitmap?.Dispose(); // Changes to xaml ImageElement must happen in UI thread through Dispatcher var task = _imageElement.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => { // Don't let two copies of this task run at the same time. if (_taskRunning) { return; } _taskRunning = true; // Keep draining frames from the backbuffer until the backbuffer is empty. SoftwareBitmap latestBitmap; while ((latestBitmap = Interlocked.Exchange(ref _backBuffer, null)) != null) { var imageSource = (SoftwareBitmapSource)_imageElement.Source; await imageSource.SetBitmapAsync(latestBitmap); latestBitmap.Dispose(); } _taskRunning = false; }); } frame.Dispose(); }
private CameraFrameInternal GetFrameFromMediaFrameReader(MediaFrameReader frameReader) { // get the latest frame MediaFrameReference frameReference = frameReader?.TryAcquireLatestFrame(); VideoMediaFrame videoFrame = frameReference?.VideoMediaFrame; SoftwareBitmap frameBmp = videoFrame?.SoftwareBitmap; CameraFrameInternal frame = null; if (frameBmp != null) { // get a camera frame and populate with the correct data for this frame - acquire copies the bitmap to the frame frame = framePool.AcquireFrame(frameBmp, desiredPixelFormat); frame.PixelFormat = desiredPixelFormat; frame.Resolution = Resolution; frame.FrameTime = frameReference.SystemRelativeTime.HasValue ? frameReference.SystemRelativeTime.Value.TotalSeconds : 0.0; frame.Exposure = frameReference.Duration.TotalSeconds; frame.Gain = Gain; if (KeepSoftwareBitmap) { frame.SoftwareBitmap = frameBmp; } else { frameBmp.Dispose(); } // extrinsics and intrinsics frame.Extrinsics = GetExtrinsics(frameReference.CoordinateSystem); frame.Intrinsics = ConvertIntrinsics(frameReference.VideoMediaFrame.CameraIntrinsics); } frameReference?.Dispose(); return(frame); }
/// <summary> /// When done with the VideoCapture class, you will need to dispose it to release unmanaged memory. /// </summary> public void Dispose() { bitmap.Dispose(); frameReference.Dispose(); }