[FFmpeg-devel] [PATCH] avcodec/pthread_frame: update the main avctx from the current, ThreadContext

Steve Lhomme robux4 at ycbcr.xyz
Sat Jul 9 09:45:31 EEST 2022


Patch attached in the email.

In some cases, the submit packet can result in configurations changes of 
the hardware decoders. The previous HW context is then freed and a new 
one created. That context is supposed to move up to the main context and 
the other threads.

It appears that when more than 2 frame threads are involved, the new 
context doesn't move in the right place (or rather at the right time). 
And it can create a crash when reusing the old HW context. This patch 
fixes the issue I could reproduce in VLC with DXVA decoding.

I have no idea if this is correct or the side effects induced by this. 
It seems the right thing to do. Keeping the previous call exhibits the 
issue. It seems odd the other existing thread context are not updated 
with the current hwaccel_priv_data. But maybe they are updated later 
from the "main" thread context, in which case this patch seems solid.
-------------- next part --------------
From e8abeeff92f5d7b3b553acdb7595d40153cbec1e Mon Sep 17 00:00:00 2001
From: Steve Lhomme <robux4 at ycbcr.xyz>
Date: Fri, 8 Jul 2022 11:49:27 +0200
Subject: [PATCH] avcodec/pthread_frame: update the main avctx from the current
 ThreadContext

After a submit_decoder() the hwaccel_priv_data may have changed in that avctx.

Doing it after the "next available frame" loop will likely point to the
hwaccel_priv_data from another PerThreadContext which had the old value which
might have been freed, if the submit_decoder() resulting in a format change.
---
 libavcodec/pthread_frame.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index 8faea75a49..eff09c3510 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -529,6 +529,8 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
     if (err)
         goto finish;
 
+    update_context_from_thread(avctx, p->avctx, 1);
+
     /*
      * If we're still receiving the initial packets, don't return a frame.
      */
@@ -578,8 +580,6 @@ int ff_thread_decode_frame(AVCodecContext *avctx,
         if (finished >= avctx->thread_count) finished = 0;
     } while (!avpkt->size && !*got_picture_ptr && err >= 0 && finished != fctx->next_finished);
 
-    update_context_from_thread(avctx, p->avctx, 1);
-
     if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;
 
     fctx->next_finished = finished;
-- 
2.27.0.windows.1



More information about the ffmpeg-devel mailing list