[FFmpeg-cvslog] libavcodec/vp8dec: fix the multi-thread HWAccel decode error
Shaofei Wang
git at videolan.org
Wed Sep 23 21:12:51 EEST 2020
ffmpeg | branch: master | Shaofei Wang <shaofei.wang at intel.com> | Tue Jun 11 02:52:29 2019 -0400| [eb6bb8f32fdc9be89cce65869dce9dd950e91be2] | committer: Ronald S. Bultje
libavcodec/vp8dec: fix the multi-thread HWAccel decode error
Fix the issue: https://github.com/intel/media-driver/issues/317
the root cause is update_dimensions will be called multple times
when decoder thread number is not only 1, but update_dimensions
call get_pixel_format in each decode thread will trigger the
hwaccel_uninit/hwaccel_init more than once. But only one hwaccel
should be shared with all decode threads.
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 dimension;
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 at intel.com>
Reviewed-by: Jun, Zhao <jun.zhao at intel.com>
Reviewed-by: Haihao Xiang <haihao.xiang at intel.com>
Signed-off-by: Ronald S. Bultje <rsbultje at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=eb6bb8f32fdc9be89cce65869dce9dd950e91be2
---
libavcodec/vp8.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c
index bab4223aca..d5d133540a 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);
More information about the ffmpeg-cvslog
mailing list