Message ID | 20220915135627.32230-1-anton@khirnov.net |
---|---|
State | Accepted |
Commit | d7f4ad88a0df3c1339e142957bf2c40cd056b8ce |
Headers | show |
Series | [FFmpeg-devel,1/2] lavc/videotoolbox: do not pass AVCodecContext to decoder output callback | expand |
Context | Check | Description |
---|---|---|
yinshiyou/make_loongarch64 | success | Make finished |
yinshiyou/make_fate_loongarch64 | success | Make fate finished |
andriy/make_x86 | success | Make finished |
andriy/make_fate_x86 | success | Make fate finished |
Am 15.09.22 um 15:56 schrieb Anton Khirnov: > The opaque parameter for the callback is set in videotoolbox_start(), > called when the hwaccel is initialized. When frame threading is used, > avctx will be the context corresponding to the frame thread currently > doing the decoding. Using this same codec context in all subsequent > invocations of the decoder callback (even those triggered by a different > frame thread) is unsafe, and broken after > cc867f2c09d2b69cee8a0eccd62aff002cbbfe11, since each frame thread now > cleans up its hwaccel state after decoding each frame. > > Fix this by passing hwaccel_priv_data as the opaque parameter, which > exists in a single instance forwarded between all frame threads. > > The only other use of AVCodecContext in the decoder output callback is > as a logging context. For this purpose, store a logging context in > hwaccel_priv_data. > --- > Initial version of this patch tested by Marvin on IRC. > Someone please test this final version, as I don't have the HW to do it > myself. > --- > libavcodec/videotoolbox.c | 10 ++++++---- > libavcodec/vt_internal.h | 2 ++ > 2 files changed, 8 insertions(+), 4 deletions(-) Confirmed, fixes the crash for me as well! Thx, Thilo
diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index ce83c2594a..d61d310600 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -690,8 +690,7 @@ static void videotoolbox_decoder_callback(void *opaque, CMTime pts, CMTime duration) { - AVCodecContext *avctx = opaque; - VTContext *vtctx = avctx->internal->hwaccel_priv_data; + VTContext *vtctx = opaque; if (vtctx->frame) { CVPixelBufferRelease(vtctx->frame); @@ -699,7 +698,8 @@ static void videotoolbox_decoder_callback(void *opaque, } if (!image_buffer) { - av_log(avctx, status ? AV_LOG_WARNING : AV_LOG_DEBUG, "vt decoder cb: output image buffer is null: %i\n", status); + av_log(vtctx->logctx, status ? AV_LOG_WARNING : AV_LOG_DEBUG, + "vt decoder cb: output image buffer is null: %i\n", status); return; } @@ -949,7 +949,7 @@ static int videotoolbox_start(AVCodecContext *avctx) videotoolbox->cv_pix_fmt_type); decoder_cb.decompressionOutputCallback = videotoolbox_decoder_callback; - decoder_cb.decompressionOutputRefCon = avctx; + decoder_cb.decompressionOutputRefCon = avctx->internal->hwaccel_priv_data; status = VTDecompressionSessionCreate(NULL, // allocator videotoolbox->cm_fmt_desc, // videoFormatDescription @@ -1179,6 +1179,8 @@ int ff_videotoolbox_common_init(AVCodecContext *avctx) AVHWFramesContext *hw_frames; int err; + vtctx->logctx = avctx; + // Old API - do nothing. if (avctx->hwaccel_context) return 0; diff --git a/libavcodec/vt_internal.h b/libavcodec/vt_internal.h index 54a11fd1b5..9502d7c7dc 100644 --- a/libavcodec/vt_internal.h +++ b/libavcodec/vt_internal.h @@ -45,6 +45,8 @@ typedef struct VTContext { // Current H264 parameters (used to trigger decoder restart on SPS changes). uint8_t sps[3]; bool reconfig_needed; + + void *logctx; } VTContext; int ff_videotoolbox_alloc_frame(AVCodecContext *avctx, AVFrame *frame);