public void Display(IBitmapFrame Frame) { if (Frame is RepeatFrame) { return; } if (!IsVisible) { Frame.Dispose(); return; } var win = MainWindow.Instance; win.Dispatcher.Invoke(() => { win.DisplayImage.Image = null; _lastFrame?.Dispose(); _lastFrame = Frame; Frame = Frame.Unwrap(); switch (Frame) { case DrawingFrame drawingFrame: try { // TODO: Preview is not shown during Webcam only recordings // This check swallows errors var h = drawingFrame.Bitmap.Height; if (h == 0) { return; } } catch { return; } win.WinFormsHost.Visibility = Visibility.Visible; win.DisplayImage.Image = drawingFrame.Bitmap; break; case Texture2DFrame texture2DFrame: win.WinFormsHost.Visibility = Visibility.Collapsed; if (_d3D9PreviewAssister == null) { _d3D9PreviewAssister = new D3D9PreviewAssister(ServiceProvider.Get <IPlatformServices>()); _texture = _d3D9PreviewAssister.GetSharedTexture(texture2DFrame.PreviewTexture); using var surface = _texture.GetSurfaceLevel(0); _backBufferPtr = surface.NativePointer; } Invalidate(_backBufferPtr, texture2DFrame.Width, texture2DFrame.Height); break; } }); }
public void Display(IBitmapFrame Frame) { if (Frame is RepeatFrame) { return; } if (!IsVisible) { Frame.Dispose(); return; } _previewWindow.Dispatcher.Invoke(() => { _previewWindow.DisplayImage.Image = null; _lastFrame?.Dispose(); _lastFrame = Frame; Frame = Frame.Unwrap(); switch (Frame) { case DrawingFrame drawingFrame: _previewWindow.WinFormsHost.Visibility = Visibility.Visible; _previewWindow.DisplayImage.Image = drawingFrame.Bitmap; break; case Texture2DFrame texture2DFrame: _previewWindow.WinFormsHost.Visibility = Visibility.Collapsed; if (_d3D9PreviewAssister == null) { _d3D9PreviewAssister = new D3D9PreviewAssister(ServiceProvider.Get <IPlatformServices>()); _texture = _d3D9PreviewAssister.GetSharedTexture(texture2DFrame.PreviewTexture); using (var surface = _texture.GetSurfaceLevel(0)) { _backBufferPtr = surface.NativePointer; } } Invalidate(_backBufferPtr, texture2DFrame.Width, texture2DFrame.Height); break; } }); }
/// <summary> /// Writes an Image frame. /// </summary> public void WriteFrame(IBitmapFrame Frame) { if (_ffmpegProcess.HasExited) { Frame.Dispose(); throw new FFmpegException(_ffmpegProcess.ExitCode); } if (_firstFrame) { if (!_ffmpegIn.WaitForConnection(5000)) { throw new Exception("Cannot connect Video pipe to FFmpeg"); } _firstFrame = false; } _lastFrameTask?.Wait(); if (!(Frame is RepeatFrame)) { using (Frame) { if (Frame.Unwrap() is INV12Frame nv12Frame) { nv12Frame.CopyNV12To(_videoBuffer); } else { Frame.CopyTo(_videoBuffer); } } } try { _lastFrameTask = _ffmpegIn.WriteAsync(_videoBuffer, 0, _videoBuffer.Length); } catch (Exception e) when(_ffmpegProcess.HasExited) { throw new FFmpegException(_ffmpegProcess.ExitCode, e); } }
/// <summary> /// Writes an Image frame. /// </summary> public void WriteFrame(IBitmapFrame Frame) { if (_ffmpegProcess.HasExited) { Frame.Dispose(); throw new FFmpegException(_ffmpegProcess.ExitCode); } if (_firstFrame) { if (!_ffmpegIn.WaitForConnection(5000)) { throw new Exception("Cannot connect Video pipe to FFmpeg"); } _firstFrame = false; } if (_lastFrameTask == null) { _lastFrameTask = Task.CompletedTask; } if (!(Frame is RepeatFrame)) { using (Frame) { if (Frame.Unwrap() is INV12Frame nv12Frame) { nv12Frame.CopyNV12To(_videoBuffer); } else { Frame.CopyTo(_videoBuffer); } } } // Drop frames if semaphore cannot be acquired soon enough. // Frames are dropped mostly in the beginning of recording till atleast one audio frame is received. if (!_spVideo.Wait(_spTimeout)) { ++_skippedFrames; _frameStreak = 0; return; } // Most of the drops happen in beginning of video, once that stops, sync can be done. if (!_initialStability) { ++_frameStreak; if (_frameStreak > FrameStreakThreshold) { _initialStability = true; } } try { // Check if last write failed. if (_lastFrameTask != null && _lastFrameTask.IsFaulted) { _lastFrameTask.Wait(); } _lastFrameTask = _lastFrameTask.ContinueWith(async M => { try { await _ffmpegIn.WriteAsync(_videoBuffer, 0, _videoBuffer.Length); } finally { _spVideo.Release(); } }); } catch (Exception e) when(_ffmpegProcess.HasExited) { throw new FFmpegException(_ffmpegProcess.ExitCode, e); } }