예제 #1
0
        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;
                }
            });
        }
예제 #2
0
        public void Display(IBitmapFrame frame)
        {
            if (frame is RepeatFrame)
            {
                return;
            }

            if (!_visible)
            {
                frame.Dispose();
                return;
            }

            _previewWindow.Dispatcher.Invoke(() =>
            {
                _previewWindow.DisplayImage.Image = null;

                _lastFrame?.Dispose();
                _lastFrame = frame;

                if (frame is MultiDisposeFrame frameWrapper)
                {
                    switch (frameWrapper.Frame)
                    {
                    case DrawingFrameBase 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;
                    }
                }
            });
        }
예제 #3
0
        /// <summary>
        /// Writes an Image frame.
        /// </summary>
        public void WriteFrame(IBitmapFrame Frame)
        {
            if (_ffmpegProcess.HasExited)
            {
                Frame.Dispose();
                throw new Exception($"An Error Occured with FFMpeg, Exit Code: {_ffmpegProcess.ExitCode}");
            }

            if (_firstFrame)
            {
                _ffmpegIn.WaitForConnection();

                _firstFrame = false;
            }

            if (!(Frame is RepeatFrame))
            {
                using (Frame)
                {
                    var image = Frame.Bitmap;

                    var bits = image.LockBits(new Rectangle(Point.Empty, image.Size), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
                    Marshal.Copy(bits.Scan0, _videoBuffer, 0, _videoBuffer.Length);
                    image.UnlockBits(bits);
                }
            }

            _ffmpegIn.WriteAsync(_videoBuffer, 0, _videoBuffer.Length);
        }
예제 #4
0
        /// <summary>
        /// Writes an Image frame.
        /// </summary>
        public void WriteFrame(IBitmapFrame Frame)
        {
            if (_ffmpegProcess.HasExited)
            {
                Frame.Dispose();
                throw new Exception($"An Error Occurred with FFmpeg, Exit Code: {_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)
                {
                    Frame.CopyTo(_videoBuffer, _videoBuffer.Length);
                }
            }

            _lastFrameTask = _ffmpegIn.WriteAsync(_videoBuffer, 0, _videoBuffer.Length);
        }
예제 #5
0
        public void WriteFrame(IBitmapFrame Image)
        {
            var cancel = _previewWindow.Dispatcher.Invoke(() =>
            {
                if (Image is RepeatFrame)
                {
                    return(false);
                }

                _lastFrame?.Dispose();

                _lastFrame = Image;

                if (!_previewWindow.IsVisible)
                {
                    return(true);
                }

                _previewWindow.DisplayImage.Image = Image.Bitmap;

                return(false);
            });

            if (cancel)
            {
                throw new OperationCanceledException();
            }
        }
예제 #6
0
        public void Dispose()
        {
            _previewWindow.Dispatcher.Invoke(() =>
            {
                _lastFrame?.Dispose();
                _lastFrame = null;

                _previewWindow.DisplayImage.Image = null;
            });
        }
예제 #7
0
        public void Dispose()
        {
            lock (_syncLock)
            {
                --_count;

                if (_count == 0)
                {
                    _frame.Dispose();
                }
            }
        }
예제 #8
0
        /// <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);
            }
        }
예제 #9
0
        /// <summary>
        /// Writes an Image frame.
        /// </summary>
        public void WriteFrame(IBitmapFrame Frame)
        {
            try
            {
                if (_ffmpegProcess.HasExited)
                {
                    Frame.Dispose();
                    throw new Exception($"An Error Occurred with FFmpeg, Exit Code: {_ffmpegProcess.ExitCode}");
                }

                if (_firstFrame)
                {
                    if (!_ffmpegIn.WaitForConnection(waitTimeForPipeConnection))
                    {
                        throw new Exception("Cannot connect Video pipe to FFmpeg");
                    }

                    _firstFrame = false;
                }

                _lastFrameTask?.Wait();

                if (!(Frame is RepeatFrame))
                {
                    using (Frame)
                    {
                        Frame.CopyTo(_videoBuffer, _videoBuffer.Length);
                    }
                }

                _lastFrameTask = _ffmpegIn.WriteAsync(_videoBuffer, 0, _videoBuffer.Length);

                if (framesToBeWritten != null)
                {
                    framesToBeWritten.Enqueue(_videoBuffer);
                }
            }
            catch (Exception e)
            {
                WriteLog("WriteFrame() - " + e.Message + " - " + e.StackTrace);
                throw e;
            }
        }
예제 #10
0
        /// <summary>
        /// Writes an Image frame.
        /// </summary>
        public void WriteFrame(IBitmapFrame Frame)
        {
            if (_ffmpegProcess.HasExited)
            {
                Frame.Dispose();
                throw new Exception($"An Error Occurred with FFmpeg, Exit Code: {_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)
            {
                ++_framesSkipped;
                return;
            }
            _keyVector.WriteKeyOutputFile();
            ++frameCount;
            using (Frame)
            {
                Frame.CopyTo(_videoBuffer, _videoBuffer.Length);
            }

            //Debug.Print(frameCount.ToString());

            _lastFrameTask = _ffmpegIn.WriteAsync(_videoBuffer, 0, _videoBuffer.Length);
        }
예제 #11
0
        public void Display(IBitmapFrame Frame)
        {
            if (Frame is RepeatFrame)
            {
                return;
            }

            if (!_visible || DateTime.Now - _timestamp < _minInterval)
            {
                Frame.Dispose();

                return;
            }

            _timestamp = DateTime.Now;

            using (Frame)
                Frame.CopyTo(_buffer, _buffer.Length);

            _previewWindow.Dispatcher.Invoke(() =>
            {
                _writeableBitmap.WritePixels(new Int32Rect(0, 0, Frame.Width, Frame.Height), _buffer, Frame.Width * 4, 0);
            });
        }
예제 #12
0
        /// <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);
            }
        }
예제 #13
0
 public void Display(IBitmapFrame Frame)
 {
     Frame.Dispose();
 }
예제 #14
0
 public void WriteFrame(IBitmapFrame Image)
 {
     Image.Dispose();
 }