From e716ff323b8e3f6e383cbc77b68a57f07d0725f4 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Fri, 20 Dec 2024 08:55:00 +0100 Subject: [PATCH] frontends/va: Fix decoding VC1 interlaced video VC1 has different start code for FRAME and FIELD, so we need to use FIELD start code for second field. Also simplify start code search to only look for 00 00 01. Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/2347 Cc: mesa-stable Reviewed-by: David (Ming Qiang) Wu (cherry picked from commit 6e911cf252e16d8c76659a60ea7c60315910ce7f) Part-of: --- .pick_status.json | 2 +- src/gallium/frontends/va/picture.c | 13 +++++++------ src/gallium/frontends/va/picture_vc1.c | 1 + src/gallium/include/pipe/p_video_state.h | 1 + 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index eba08ed717a..c9d75b93813 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -2224,7 +2224,7 @@ "description": "frontends/va: Fix decoding VC1 interlaced video", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/gallium/frontends/va/picture.c b/src/gallium/frontends/va/picture.c index ec964356578..25d45c59d5a 100644 --- a/src/gallium/frontends/va/picture.c +++ b/src/gallium/frontends/va/picture.c @@ -433,7 +433,8 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) enum pipe_video_format format = u_reduce_video_profile(context->templat.profile); static const uint8_t start_code_h264[] = { 0x00, 0x00, 0x01 }; static const uint8_t start_code_h265[] = { 0x00, 0x00, 0x01 }; - static const uint8_t start_code_vc1[] = { 0x00, 0x00, 0x01, 0x0d }; + static const uint8_t start_code_vc1_frame[] = { 0x00, 0x00, 0x01, 0x0d }; + static const uint8_t start_code_vc1_field[] = { 0x00, 0x00, 0x01, 0x0c }; static const uint8_t eoi_jpeg[] = { 0xff, 0xd9 }; if (!context->decoder) @@ -467,14 +468,14 @@ handleVASliceDataBufferType(vlVaContext *context, vlVaBuffer *buf) context->bs.sizes[context->bs.num_buffers++] = sizeof(start_code_h265); break; case PIPE_VIDEO_FORMAT_VC1: - if (bufHasStartcode(buf, 0x0000010d, 32) || - bufHasStartcode(buf, 0x0000010c, 32) || - bufHasStartcode(buf, 0x0000010b, 32)) + if (bufHasStartcode(buf, 0x000001, 24)) break; if (context->decoder->profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED) { - context->bs.buffers[context->bs.num_buffers] = (void *const)&start_code_vc1; - context->bs.sizes[context->bs.num_buffers++] = sizeof(start_code_vc1); + const uint8_t *start_code = + context->desc.vc1.is_first_field ? start_code_vc1_frame : start_code_vc1_field; + context->bs.buffers[context->bs.num_buffers] = (void *const)start_code; + context->bs.sizes[context->bs.num_buffers++] = sizeof(start_code_vc1_frame); } break; case PIPE_VIDEO_FORMAT_MPEG4: diff --git a/src/gallium/frontends/va/picture_vc1.c b/src/gallium/frontends/va/picture_vc1.c index 6ad1571ca96..15d0f4b564d 100644 --- a/src/gallium/frontends/va/picture_vc1.c +++ b/src/gallium/frontends/va/picture_vc1.c @@ -37,6 +37,7 @@ void vlVaHandlePictureParameterBufferVC1(vlVaDriver *drv, vlVaContext *context, vlVaGetReferenceFrame(drv, vc1->backward_reference_picture, &context->desc.vc1.ref[1]); context->desc.vc1.picture_type = vc1->picture_fields.bits.picture_type; context->desc.vc1.frame_coding_mode = vc1->picture_fields.bits.frame_coding_mode; + context->desc.vc1.is_first_field = vc1->picture_fields.bits.is_first_field; context->desc.vc1.postprocflag = vc1->post_processing != 0; context->desc.vc1.pulldown = vc1->sequence_fields.bits.pulldown; context->desc.vc1.interlace = vc1->sequence_fields.bits.interlace; diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h index 5311f230dd8..b14edae0691 100644 --- a/src/gallium/include/pipe/p_video_state.h +++ b/src/gallium/include/pipe/p_video_state.h @@ -345,6 +345,7 @@ struct pipe_vc1_picture_desc uint32_t slice_count; uint8_t picture_type; uint8_t frame_coding_mode; + uint8_t is_first_field; uint8_t postprocflag; uint8_t pulldown; uint8_t interlace;