예제 #1
0
        /// <summary>
        /// Writes an Image frame.
        /// </summary>
        public void WriteFrame(IBitmapFrame Frame)
        {
            if (!(Frame is RepeatFrame))
            {
                using (Frame)
                {
                    Frame.CopyTo(_videoBuffer);
                }
            }

            lock (_syncLock)
                _videoStream.WriteFrame(true, _videoBuffer, 0, _videoBuffer.Length);
        }
예제 #2
0
        public void WriteFrame(IBitmapFrame image)
        {
            if (image is RepeatFrame)
            {
                return;
            }

            using (image)
            {
                // HACK: Don't know why, this fixes Preview showing multiple mouse pointers
                image.CopyTo(_dummyBuffer, _dummyBuffer.Length);
            }
        }
예제 #3
0
        public void WriteFrame(IBitmapFrame Image)
        {
            if (Image is RepeatFrame)
            {
                _writer.WriteFrame(Image);
            }
            else
            {
                var frame = new MultiDisposeFrame(Image, 2);

                _writer.WriteFrame(frame);
                _preview.Display(frame);
            }
        }
예제 #4
0
        public void WriteFrame(IBitmapFrame image)
        {
            if (image is RepeatFrame)
            {
                OriginalWriter.WriteFrame(image);
            }
            else
            {
                var frame = new MultiDisposeFrame(image, 2);

                OriginalWriter.WriteFrame(frame);
                Task.Run(() => _preview.Display(frame));
            }
        }
예제 #5
0
        public MultiDisposeFrame(IBitmapFrame Frame, int Count)
        {
            if (_frame is RepeatFrame)
            {
                throw new NotSupportedException();
            }

            if (Count < 2)
            {
                throw new ArgumentException("Count should be atleast 2", nameof(Count));
            }

            _frame = Frame ?? throw new ArgumentNullException(nameof(Frame));
            _count = Count;
        }
예제 #6
0
        bool AddFrame(IBitmapFrame Frame)
        {
            try
            {
                _videoWriter.WriteFrame(Frame);

                ++_frameCount;

                return(true);
            }
            catch (InvalidOperationException)
            {
                return(false);
            }
        }
예제 #7
0
        /// <summary>
        /// Writes an Image frame.
        /// </summary>
        public void WriteFrame(IBitmapFrame Frame)
        {
            if (!(Frame is RepeatFrame))
            {
                using (Frame)
                {
                    Frame.CopyTo(_videoBuffer);
                }
            }

            lock (_syncLock)
            {
                _connection.WriteFrame(_videoBuffer, _width, _height);
            }
        }
예제 #8
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;
                    }
                }
            });
        }
예제 #9
0
        /// <summary>
        /// Writes an Image frame.
        /// </summary>
        public void WriteFrame(IBitmapFrame Frame)
        {
            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);
                }
            }

            lock (_writer)
                _videoStream.WriteFrame(true, _videoBuffer, 0, _videoBuffer.Length);
        }
예제 #10
0
        /// <summary>
        /// Writes an Image frame.
        /// </summary>
        public void WriteFrame(IBitmapFrame Frame)
        {
            if (!(Frame is RepeatFrame))
            {
                using (Frame)
                {
                    Frame.CopyTo(_videoBuffer);
                }
            }

            lock (_syncLock)
            {
                if (IsTransparentOrTruncatedFrame(_videoBuffer))
                {
                    // To avoid dropped frames, just repeat the previous one

                    if (_hasOneGoodFrame)
                    {
                        // Use previous frame instead

                        _videoStream.WriteFrame(true, _prevVideoBuffer, 0, _prevVideoBuffer.Length);
                    }
                    else
                    {
                        // Just need to make do with what we have

                        _videoStream.WriteFrame(true, _videoBuffer, 0, _videoBuffer.Length);
                    }

                    return;
                }

                if (!_hasOneGoodFrame)
                {
                    _hasOneGoodFrame = true;
                }

                _videoStream.WriteFrame(true, _videoBuffer, 0, _videoBuffer.Length);

                // Save frame in case we need it as stand-in for next one

                Buffer.BlockCopy(_videoBuffer, 0, _prevVideoBuffer, 0, _videoBuffer.Length);
            }
        }
예제 #11
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);
            }
        }
예제 #12
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;
            }
        }
예제 #13
0
        public void Display(IBitmapFrame Frame)
        {
            _previewWindow.Dispatcher.Invoke(() =>
            {
                if (Frame is RepeatFrame)
                {
                    return;
                }

                _lastFrame?.Dispose();

                _lastFrame = Frame;

                if (!_previewWindow.IsVisible)
                {
                    return;
                }

                _previewWindow.DisplayImage.Image = Frame.Bitmap;
            });
        }
예제 #14
0
        public void WriteFrame(IBitmapFrame Image)
        {
            if (Image is RepeatFrame)
            {
                return;
            }

            _lastFrame?.Dispose();

            _lastFrame = Image;

            if (!_previewWindow.IsVisible)
            {
                throw new OperationCanceledException();
            }

            _previewWindow.Dispatcher.Invoke(() =>
            {
                _previewWindow.DisplayImage.Image = Image.Bitmap;
            });
        }
예제 #15
0
        public void Dispose()
        {
            _previewWindow.Dispatcher.Invoke(() =>
            {
                _previewWindow.DisplayImage.Image = null;

                _lastFrame?.Dispose();
                _lastFrame = null;

                if (_d3D9PreviewAssister != null)
                {
                    Invalidate(IntPtr.Zero, 0, 0);

                    _texture.Dispose();

                    _d3D9PreviewAssister.Dispose();

                    _d3D9PreviewAssister = null;
                }
            });
        }
예제 #16
0
        /// <summary>
        /// Adds a frame to this animation.
        /// </summary>
        public void WriteFrame(IBitmapFrame Frame, int Delay)
        {
            gifStream.Position = 0;

            if (_firstFrame)
            {
                if (Frame is RepeatFrame)
                {
                    return;
                }

                var image = Frame.Bitmap;

                _width  = image.Width;
                _height = image.Height;
            }

            if (!(Frame is RepeatFrame))
            {
                using (Frame)
                    Frame.Bitmap.Save(gifStream, ImageFormat.Gif);
            }

            // Steal the global color table info
            if (_firstFrame)
            {
                InitHeader(gifStream, _writer, _width, _height);
            }

            WriteGraphicControlBlock(gifStream, _writer, Delay);
            WriteImageBlock(gifStream, _writer, !_firstFrame, 0, 0, _width, _height);

            if (_firstFrame)
            {
                _firstFrame = false;
            }
        }
예제 #17
0
        public void Dispose()
        {
            var win = MainWindow.Instance;

            win.Dispatcher.Invoke(() =>
            {
                win.DisplayImage.Image      = null;
                win.WinFormsHost.Visibility = Visibility.Collapsed;

                _lastFrame?.Dispose();
                _lastFrame = null;

                if (_d3D9PreviewAssister != null)
                {
                    Invalidate(IntPtr.Zero, 0, 0);

                    _texture.Dispose();

                    _d3D9PreviewAssister.Dispose();

                    _d3D9PreviewAssister = null;
                }
            });
        }
예제 #18
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);
        }
예제 #19
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);
            });
        }
예제 #20
0
 public void Display(IBitmapFrame Frame)
 {
     Frame.Dispose();
 }
예제 #21
0
 public void WriteFrame(IBitmapFrame Image)
 {
     Image.Dispose();
 }
예제 #22
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);
            }
        }
예제 #23
0
 /// <inheritdoc />
 public void WriteFrame(IBitmapFrame Frame)
 {
     _ffMpegWriter.WriteFrame(Frame);
 }
예제 #24
0
 /// <summary>
 /// Writes a Image frame.
 /// </summary>
 /// <param name="image">Image frame to write.</param>
 public void WriteFrame(IBitmapFrame image) => WriteFrame(image, _defaultFrameDelay);