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);
            }
        }