From 9ef263f81a16d404ea59660b140b505bc4647c5a Mon Sep 17 00:00:00 2001 From: Marvin Scholz Date: Wed, 6 May 2020 02:55:52 +0200 Subject: [PATCH] obs-ffmpeg: Fix AVFrame handling in FFmpeg output Fix an issue in the way AVFrames were handled in the FFmpeg encoder plugin, which could lead to tearing in the encoded video due to data races in the AVFrame and AVBuffer. This is fixed by calling av_frame_make_writable which ensures the frame and its associated buffer are writable. If its not, it will copy the AVFrame, create a new AVBuffer for it and decrease the refcount of the old AVFrame and AVBuffer. This way OBS always ends up with a usable buffer to write into which is not still used by the encoder while avoiding a copy when unnecessary. --- plugins/obs-ffmpeg/obs-ffmpeg-output.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/obs-ffmpeg/obs-ffmpeg-output.c b/plugins/obs-ffmpeg/obs-ffmpeg-output.c index b26942079..6c711f5ec 100644 --- a/plugins/obs-ffmpeg/obs-ffmpeg-output.c +++ b/plugins/obs-ffmpeg/obs-ffmpeg-output.c @@ -699,6 +699,15 @@ static void receive_video(void *param, struct video_data *frame) if (!data->start_timestamp) data->start_timestamp = frame->timestamp; + ret = av_frame_make_writable(data->vframe); + if (ret < 0) { + blog(LOG_WARNING, + "receive_video: Error obtaining writable " + "AVFrame: %s", + av_err2str(ret)); + //FIXME: stop the encode with an error + return; + } if (!!data->swscale) sws_scale(data->swscale, (const uint8_t *const *)frame->data, (const int *)frame->linesize, 0, data->config.height,