public unsafe IDecodedVideoFrame TryDecode(RawVideoFrame rawVideoFrame) { fixed(byte *rawBufferPtr = &rawVideoFrame.FrameSegment.Array[rawVideoFrame.FrameSegment.Offset]) { int resultCode; if (rawVideoFrame is RawH264IFrame rawH264IFrame) { if (rawH264IFrame.SpsPpsSegment.Array != null && !_extraData.SequenceEqual(rawH264IFrame.SpsPpsSegment)) { if (_extraData.Length != rawH264IFrame.SpsPpsSegment.Count) { _extraData = new byte[rawH264IFrame.SpsPpsSegment.Count]; } Buffer.BlockCopy(rawH264IFrame.SpsPpsSegment.Array, rawH264IFrame.SpsPpsSegment.Offset, _extraData, 0, rawH264IFrame.SpsPpsSegment.Count); fixed(byte *initDataPtr = &_extraData[0]) { resultCode = FFmpegVideoPInvoke.SetVideoDecoderExtraData(_decoderHandle, (IntPtr)initDataPtr, _extraData.Length); if (resultCode != 0) { throw new DecoderException( $"An error occurred while setting video extra data, {_videoCodecId} codec, code: {resultCode}"); } } } } lock (disposalLock) { if (_disposed) { Console.WriteLine("Skipped decoding video frame, as decoder was disposed. (Therefore the frame probably wasn't wanted)"); return(null); } resultCode = FFmpegVideoPInvoke.DecodeFrame(_decoderHandle, (IntPtr)rawBufferPtr, rawVideoFrame.FrameSegment.Count, out int width, out int height, out FFmpegPixelFormat pixelFormat); if (resultCode != 0) { return(null); } if (_currentFrameParameters.Width != width || _currentFrameParameters.Height != height || _currentFrameParameters.PixelFormat != pixelFormat) { _currentFrameParameters = new DecodedVideoFrameParameters(width, height, pixelFormat); DropAllVideoScalers(); } } return(new DecodedVideoFrame(TransformTo)); } }
public unsafe bool TryDecode(RawVideoFrame rawVideoFrame, out DecodedVideoFrameParameters frameParameters) { Debug.Assert(rawVideoFrame.FrameSegment.Array != null, "rawVideoFrame.FrameSegment.Array != null"); fixed(byte *rawBufferPtr = &rawVideoFrame.FrameSegment.Array[rawVideoFrame.FrameSegment.Offset]) { int resultCode; if (rawVideoFrame is RawH264IFrame rawH264IFrame) { if (rawH264IFrame.SpsPpsSegment.Array != null && !_extraData.SequenceEqual(rawH264IFrame.SpsPpsSegment)) { if (_extraData.Length != rawH264IFrame.SpsPpsSegment.Count) { _extraData = new byte[rawH264IFrame.SpsPpsSegment.Count]; } Buffer.BlockCopy(rawH264IFrame.SpsPpsSegment.Array, rawH264IFrame.SpsPpsSegment.Offset, _extraData, 0, rawH264IFrame.SpsPpsSegment.Count); fixed(byte *initDataPtr = &_extraData[0]) { resultCode = FFmpegVideoPInvoke.SetVideoDecoderExtraData(_decoderHandle, (IntPtr)initDataPtr, _extraData.Length); if (resultCode != 0) { throw new DecoderException( $"An error occurred while setting video extra data, {_videoCodecId} codec, code: {resultCode}"); } } } } resultCode = FFmpegVideoPInvoke.DecodeFrame(_decoderHandle, (IntPtr)rawBufferPtr, rawVideoFrame.FrameSegment.Count, out int width, out int height, out FFmpegPixelFormat pixelFormat); if (resultCode != 0) { frameParameters = null; return(false); } _currentDecodedFrameTimestamp = rawVideoFrame.Timestamp; if (_currentFrameParameters.Width != width || _currentFrameParameters.Height != height || _currentFrameParameters.PixelFormat != pixelFormat) { _currentFrameParameters = new DecodedVideoFrameParameters(width, height, pixelFormat); DropAllVideoScalers(); } frameParameters = _currentFrameParameters; return(true); } }