This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch release/8.0 in repository ffmpeg.
commit 87fdf8f8fd716d95c65113b0b0bfd98ad20e2879 Author: Diego de Souza <[email protected]> AuthorDate: Thu Oct 8 15:23:51 2026 +0200 Commit: Timo Rothenpieler <[email protected]> CommitDate: Thu Oct 8 21:33:25 2026 +0200 avcodec/dxva2: fix frame->buf[] data race with frame threading ff_dxva2_common_end_frame() adds a reference to the decoder to frame->buf[], so that the decoder outlives the frames decoded with it. It is called from the hwaccel end_frame() callback, which with frame threading may run after ff_thread_finish_setup(). From that point on, other threads may copy the frame: the H.264 decoder keeps a separate AVFrame per picture in each thread and synchronizes them in update_thread_context() with av_frame_replace(), which reads frame->buf[] while the decoding thread may be writing to it. As noted in fa77cb258b ("avcodec/h264dec: Fix data race when updating decode_error_flags"), a decoding thread must not modify any field that av_frame_ref() copies after ff_thread_finish_setup(). This has been observed as an intermittent access violation in av_buffer_replace() when decoding H.264 with D3D11VA and frame threading on Windows on Arm: the copying thread read a non-NULL frame->buf[1] entry, but saw the fields of the AVBufferRef it points to as zero, and dereferenced the NULL buffer pointer when incrementing the reference count. Store the decoder reference in FrameDecodeData.hwaccel_priv instead, as nvdec does for its per-frame state. The decode data is attached to frame->private_ref when the buffer is allocated, before ff_thread_finish_setup(), and all references to the frame share it, so update_thread_context() only takes a new reference to it. The decoder reference is added to frame->buf[] by hwaccel_priv_post_process(), which runs in the caller's thread when the frame is returned, so returned frames keep the decoder alive. Since the decode data is shared, the second field of a field pair no longer adds a second decoder reference to the frame. Signed-off-by: Diego de Souza <[email protected]> (cherry picked from commit 538d10d1878fb546c3a2645efa56119848f9ccfc) --- libavcodec/dxva2.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c index 22ecd5acaf..3833dcccaa 100644 --- a/libavcodec/dxva2.c +++ b/libavcodec/dxva2.c @@ -889,6 +889,20 @@ static int frame_add_buf(AVFrame *frame, AVBufferRef *ref) return AVERROR(EINVAL); } +static void dxva2_frame_priv_free(void *priv) +{ + AVBufferRef *decoder_ref = priv; + + av_buffer_unref(&decoder_ref); +} + +static int dxva2_frame_post_process(void *logctx, AVFrame *frame) +{ + const FrameDecodeData *fdd = frame->private_ref; + + return frame_add_buf(frame, fdd->hwaccel_priv); +} + int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, const void *pp, unsigned pp_size, const void *qm, unsigned qm_size, @@ -911,9 +925,24 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx); if (sctx->decoder_ref) { - result = frame_add_buf(frame, sctx->decoder_ref); - if (result < 0) - return result; + FrameDecodeData *fdd = frame->private_ref; + + /* With frame threading, this may run after ff_thread_finish_setup(), + * when other threads may already be copying this AVFrame, so its + * buf[] array must not be modified here. Store the decoder + * reference in the per-frame decode data, which all references to + * the frame share, and add it to frame->buf[] once the frame is + * output. The second field of a field pair reuses the reference + * stored for the first. */ + if (!fdd->hwaccel_priv) { + AVBufferRef *decoder_ref = av_buffer_ref(sctx->decoder_ref); + if (!decoder_ref) + return AVERROR(ENOMEM); + + fdd->hwaccel_priv = decoder_ref; + fdd->hwaccel_priv_free = dxva2_frame_priv_free; + fdd->hwaccel_priv_post_process = dxva2_frame_post_process; + } } do { -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
