[FFmpeg-devel,V2] libavcodec/vp8dec: fix the multi-thread HWAccel decode error

Submitted by Jun Zhao on Oct. 17, 2018, 12:01 p.m.

Details

Message ID 1539777678-24518-1-git-send-email-mypopydev@gmail.com
State New
Headers show

Commit Message

Jun Zhao Oct. 17, 2018, 12:01 p.m.
Fix the issue: https://github.com/intel/media-driver/issues/317

the root cause is update_dimensions call get_pixel_format will
trigger the hwaccel_uninit/hwaccel_init , in current context,
there are 3 situations in the update_dimensions():
1. First time calling. No matter single thread or multithread,
   get_pixel_format() should be called after dimensions were
   set;
2. Dimention changed at the runtime. Dimention need to be
   updated when macroblocks_base is already allocated,
   get_pixel_format() should be called to recreate new frames
   according to updated dimention;
3. Multithread first time calling. After decoder init, the
   other threads will call update_dimensions() at first time
   to allocate macroblocks_base and set dimensions.
   But get_pixel_format() is shouldn't be called due to low
   level frames and context are already created.

In this fix, we only call update_dimensions as need.

Signed-off-by: Wang, Shaofei <shaofei.wang@intel.com>
Reviewed-by: Jun, Zhao <jun.zhao@intel.com>
Reviewed-by: Haihao Xiang <haihao.xiang@intel.com>
---
 libavcodec/vp8.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

Comments

mypopy@gmail.com Nov. 13, 2018, 2:40 a.m.
Ping?
On Wed, Oct 17, 2018 at 8:01 PM Jun Zhao <mypopydev@gmail.com> wrote:
>
> Fix the issue: https://github.com/intel/media-driver/issues/317
>
> the root cause is update_dimensions call get_pixel_format will
> trigger the hwaccel_uninit/hwaccel_init , in current context,
> there are 3 situations in the update_dimensions():
> 1. First time calling. No matter single thread or multithread,
>    get_pixel_format() should be called after dimensions were
>    set;
> 2. Dimention changed at the runtime. Dimention need to be
>    updated when macroblocks_base is already allocated,
>    get_pixel_format() should be called to recreate new frames
>    according to updated dimention;
> 3. Multithread first time calling. After decoder init, the
>    other threads will call update_dimensions() at first time
>    to allocate macroblocks_base and set dimensions.
>    But get_pixel_format() is shouldn't be called due to low
>    level frames and context are already created.
>
> In this fix, we only call update_dimensions as need.
>
> Signed-off-by: Wang, Shaofei <shaofei.wang@intel.com>
> Reviewed-by: Jun, Zhao <jun.zhao@intel.com>
> Reviewed-by: Haihao Xiang <haihao.xiang@intel.com>
> ---
>  libavcodec/vp8.c |    7 +++++--
>  1 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
> index a06692c..c205868 100644
> --- a/libavcodec/vp8.c
> +++ b/libavcodec/vp8.c
> @@ -187,7 +187,7 @@ static av_always_inline
>  int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
>  {
>      AVCodecContext *avctx = s->avctx;
> -    int i, ret;
> +    int i, ret, dim_reset = 0;
>
>      if (width  != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base ||
>          height != s->avctx->height) {
> @@ -196,9 +196,12 @@ int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
>          ret = ff_set_dimensions(s->avctx, width, height);
>          if (ret < 0)
>              return ret;
> +
> +        dim_reset = (s->macroblocks_base != NULL);
>      }
>
> -    if (!s->actually_webp && !is_vp7) {
> +    if ((s->pix_fmt == AV_PIX_FMT_NONE || dim_reset) &&
> +         !s->actually_webp && !is_vp7) {
>          s->pix_fmt = get_pixel_format(s);
>          if (s->pix_fmt < 0)
>              return AVERROR(EINVAL);
> --
> 1.7.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Patch hide | download patch | download mbox

diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index a06692c..c205868 100644
--- a/libavcodec/vp8.c
+++ b/libavcodec/vp8.c
@@ -187,7 +187,7 @@  static av_always_inline
 int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
 {
     AVCodecContext *avctx = s->avctx;
-    int i, ret;
+    int i, ret, dim_reset = 0;
 
     if (width  != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base ||
         height != s->avctx->height) {
@@ -196,9 +196,12 @@  int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
         ret = ff_set_dimensions(s->avctx, width, height);
         if (ret < 0)
             return ret;
+
+        dim_reset = (s->macroblocks_base != NULL);
     }
 
-    if (!s->actually_webp && !is_vp7) {
+    if ((s->pix_fmt == AV_PIX_FMT_NONE || dim_reset) &&
+         !s->actually_webp && !is_vp7) {
         s->pix_fmt = get_pixel_format(s);
         if (s->pix_fmt < 0)
             return AVERROR(EINVAL);