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 <David.Wu3@amd.com>
(cherry picked from commit 6e911cf252)

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32852>
This commit is contained in:
David Rosca
2024-12-20 08:55:00 +01:00
committed by Dylan Baker
parent 33337b54b0
commit e716ff323b
4 changed files with 10 additions and 7 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -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;

View File

@@ -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;