private FFmpegFrame ensureFramePixelFormat(FFmpegFrame frame, AVPixelFormat targetPixelFormat) { if (frame.PixelFormat == targetPixelFormat) { return(frame); } int width = frame.Pointer->width; int height = frame.Pointer->height; swsContext = ffmpeg.sws_getCachedContext( swsContext, width, height, frame.PixelFormat, width, height, targetPixelFormat, 1, null, null, null); if (!scalerFrames.TryDequeue(out var scalerFrame)) { scalerFrame = new FFmpegFrame(ffmpeg, returnScalerFrame); } // (re)initialize the scaler frame if needed. if (scalerFrame.PixelFormat != targetPixelFormat || scalerFrame.Pointer->width != width || scalerFrame.Pointer->height != height) { ffmpeg.av_frame_unref(scalerFrame.Pointer); // Note: this field determines the scaler's output pix format. scalerFrame.PixelFormat = targetPixelFormat; scalerFrame.Pointer->width = width; scalerFrame.Pointer->height = height; int getBufferResult = ffmpeg.av_frame_get_buffer(scalerFrame.Pointer, 0); if (getBufferResult < 0) { Logger.Log($"Failed to allocate SWS frame buffer: {getErrorMessage(getBufferResult)}"); scalerFrame.Dispose(); frame.Return(); return(null); } } int scalerResult = ffmpeg.sws_scale( swsContext, frame.Pointer->data, frame.Pointer->linesize, 0, height, scalerFrame.Pointer->data, scalerFrame.Pointer->linesize); // return the original frame regardless of the scaler result. frame.Return(); if (scalerResult < 0) { Logger.Log($"Failed to scale frame: {getErrorMessage(scalerResult)}"); scalerFrame.Dispose(); return(null); } return(scalerFrame); }