Module: Mesa
Branch: main
Commit: 4bf116d440e341f807367d118e7f320886485c45
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=4bf116d440e341f807367d118e7f320886485c45

Author: Ruijing Dong <[email protected]>
Date:   Tue Oct 25 15:14:21 2022 -0400

frontends/va: fixed an av1 dec image corruption.

[problem]
When decoding an av1 bitstream, it shows image corruption
in the middle of the bitstream around key frames.

[analysis]
in av1_spec.pdf page 38/669, there is a sentence below:

if ( frame_type == KEY_FRAME && show_frame ) {
   for ( i = 0; i < NUM_REF_FRAMES; i++) {
      RefValid[ i ] = 0
      ......
   }
   ......
}

This shows that the condition of invalidating current
DPB frames should be the coming frame_type is KEY_FRAME plus
show_frame is equal to 1. Otherwise, some of the frames
in sequence after KEY_FRAME still refer to the reference frames
before KEY_FRAME, and if these before KEY_FRAME reference
frames were invalidated, these frames could not find their
reference frames, and it could cause image corruption.

[solution]
Add condition of show_frame, with the corresponding fix
in ffmpeg, we cannot see this issue any longer.

Reviewed-by: Leo Liu <[email protected]>
Signed-off-by: Ruijing Dong <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19386>

---

 src/gallium/frontends/va/picture_av1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/gallium/frontends/va/picture_av1.c 
b/src/gallium/frontends/va/picture_av1.c
index 42784866664..899afe8ce9a 100644
--- a/src/gallium/frontends/va/picture_av1.c
+++ b/src/gallium/frontends/va/picture_av1.c
@@ -373,7 +373,7 @@ void vlVaHandlePictureParameterBufferAV1(vlVaDriver *drv, 
vlVaContext *context,
    context->desc.av1.picture_parameter.film_grain_info.cr_offset = 
av1->film_grain_info.cr_offset;
 
    for (i = 0 ; i < AV1_NUM_REF_FRAMES; ++i) {
-      if (av1->pic_info_fields.bits.frame_type == 0)
+      if (av1->pic_info_fields.bits.frame_type == 0 && 
av1->pic_info_fields.bits.show_frame)
          context->desc.av1.ref[i] = NULL;
       else
          vlVaGetReferenceFrame(drv, av1->ref_frame_map[i], 
&context->desc.av1.ref[i]);

Reply via email to