[FFmpeg-devel] [PATCH, RFC] lavc/vp9dec: fix the multi-thread HWAccel decode error

Linjie Fu linjie.fu at intel.com
Tue Jun 11 22:19:30 EEST 2019


Fix the multi-thread HWAccel decode error for vp9.

VP9 supports the resolution changing. In multi-thread mode, worker-threads
destroy and free the first created VAAPIDecodeContext if resolution change
happens and create new one. Other threads still request to destroy previous
and demand for new context. This leads to decode failures and memory issue.

Modify to call hwaccel_uninit/hwaccel_init by ff_thread_get_format only
when the first-come thread detected the resolution changing.

Signed-off-by: Linjie Fu <linjie.fu at intel.com>
---
Fix the same issue vaapi_vp8 decoding meets:
https://patchwork.ffmpeg.org/patch/12507/

 libavcodec/vp9.c    | 18 ++++++++++++++----
 libavcodec/vp9dec.h |  2 ++
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c
index acf3ffc..e2fad9d 100644
--- a/libavcodec/vp9.c
+++ b/libavcodec/vp9.c
@@ -179,6 +179,7 @@ static int update_size(AVCodecContext *avctx, int w, int h)
     uint8_t *p;
     int bytesperpixel = s->bytesperpixel, ret, cols, rows;
     int lflvl_len, i;
+    int dim_reset = 0;
 
     av_assert0(w > 0 && h > 0);
 
@@ -186,6 +187,10 @@ static int update_size(AVCodecContext *avctx, int w, int h)
         if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
             return ret;
 
+        if (!avctx->internal->hwaccel_priv_data ||
+            s->context == avctx->internal->hwaccel_priv_data)
+            dim_reset = 1;
+
         switch (s->pix_fmt) {
         case AV_PIX_FMT_YUV420P:
         case AV_PIX_FMT_YUV420P10:
@@ -216,16 +221,21 @@ static int update_size(AVCodecContext *avctx, int w, int h)
         *fmtp++ = s->pix_fmt;
         *fmtp = AV_PIX_FMT_NONE;
 
-        ret = ff_thread_get_format(avctx, pix_fmts);
-        if (ret < 0)
-            return ret;
+        if (dim_reset) {
+            ret = ff_thread_get_format(avctx, pix_fmts);
+            if (ret < 0)
+                return ret;
+
+            avctx->pix_fmt = ret;
+        }
 
-        avctx->pix_fmt = ret;
         s->gf_fmt  = s->pix_fmt;
         s->w = w;
         s->h = h;
     }
 
+    s->context = avctx->internal->hwaccel_priv_data;
+
     cols = (w + 7) >> 3;
     rows = (h + 7) >> 3;
 
diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h
index 66573ed..bc3f36c 100644
--- a/libavcodec/vp9dec.h
+++ b/libavcodec/vp9dec.h
@@ -152,6 +152,8 @@ typedef struct VP9Context {
     int block_alloc_using_2pass;
     uint16_t mvscale[3][2];
     uint8_t mvstep[3][2];
+
+    void *context;
 } VP9Context;
 
 struct VP9TileData {
-- 
2.7.4



More information about the ffmpeg-devel mailing list