private unsafe void VideoDecoder_OnVideoFrame(ref AVFrame frame) { if ((OnVideoSourceEncodedSample != null) || (OnVideoSourceRawSampleFaster != null)) { int frameRate = (int)_videoDecoder.VideoAverageFrameRate; frameRate = (frameRate <= 0) ? Helper.DEFAULT_VIDEO_FRAME_RATE : frameRate; uint timestampDuration = (uint)(VideoFormat.DEFAULT_CLOCK_RATE / frameRate); var width = frame.width; var height = frame.height; // Manage Raw Sample if (OnVideoSourceRawSampleFaster != null) { if (_videoFrameBGR24Converter == null || _videoFrameBGR24Converter.SourceWidth != width || _videoFrameBGR24Converter.SourceHeight != height) { _videoFrameBGR24Converter = new VideoFrameConverter( width, height, (AVPixelFormat)frame.format, width, height, AVPixelFormat.AV_PIX_FMT_BGR24); logger.LogDebug($"Frame format: [{frame.format}]"); } var frameBGR24 = _videoFrameBGR24Converter.Convert(frame); if ((frameBGR24.width != 0) && (frameBGR24.height != 0)) { RawImage imageRawSample = new RawImage { Width = width, Height = height, Stride = frameBGR24.linesize[0], Sample = (IntPtr)frameBGR24.data[0], PixelFormat = VideoPixelFormatsEnum.Rgb }; OnVideoSourceRawSampleFaster?.Invoke(timestampDuration, imageRawSample); } } // Manage Encoded Sample if (OnVideoSourceEncodedSample != null) { if (_videoFrameYUV420PConverter == null || _videoFrameYUV420PConverter.SourceWidth != width || _videoFrameYUV420PConverter.SourceHeight != height) { _videoFrameYUV420PConverter = new VideoFrameConverter( width, height, (AVPixelFormat)frame.format, width, height, AVPixelFormat.AV_PIX_FMT_YUV420P); logger.LogDebug($"Frame format: [{frame.format}]"); } var frameYUV420P = _videoFrameYUV420PConverter.Convert(frame); if ((frameYUV420P.width != 0) && (frameYUV420P.height != 0)) { AVCodecID aVCodecId = FFmpegConvert.GetAVCodecID(_videoFormatManager.SelectedFormat.Codec); byte[]? encodedSample = _videoEncoder.Encode(aVCodecId, frameYUV420P, frameRate); if (encodedSample != null) { // Note the event handler can be removed while the encoding is in progress. OnVideoSourceEncodedSample?.Invoke(timestampDuration, encodedSample); } _forceKeyFrame = false; } else { _forceKeyFrame = true; } } } }
private void _FFmpegVideoSource_OnVideoSourceRawSampleFaster(uint durationMilliseconds, RawImage imageRawSample) { OnVideoSourceRawSampleFaster?.Invoke(durationMilliseconds, imageRawSample); }