diff --git a/src/h264.c b/src/h264.c index 0ae5724..b5c712d 100644 --- a/src/h264.c +++ b/src/h264.c @@ -243,13 +243,34 @@ static void h264_va_picture_to_v4l2(struct request_data *driver_data, h264_fill_dpb(driver_data, context, decode); - //decode->num_slices = surface->slices_count; + /* + * Populate every V4L2_CID_STATELESS_H264_DECODE_PARAMS field + * we can derive from VAAPI's pre-parsed VAPictureParameterBuffer + * + bitstream byte. Cross-reference: GStreamer + * gstv4l2codech264dec.c::gst_v4l2_codec_h264_dec_fill_decoder_params + * (lines 632-678). + * + * Fields not derivable from VAAPI (idr_pic_id, pic_order_cnt_lsb, + * delta_pic_order_cnt_*, dec_ref_pic_marking_bit_size, + * pic_order_cnt_bit_size, slice_group_change_cycle) require a + * full slice_header() bit-level parse, which libva-v4l2-request + * does not currently do. They are left at zero-init and the + * kernel-side hantro-vpu may compute them itself when scanning + * the OUTPUT bitstream — a hypothesis verified empirically by + * running this patch and inspecting the CAPTURE buffer. + */ decode->nal_ref_idc = nal_ref_idc; - if (nal_unit_type == 5) - decode->flags = V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC; + decode->frame_num = VAPicture->frame_num; decode->top_field_order_cnt = VAPicture->CurrPic.TopFieldOrderCnt; decode->bottom_field_order_cnt = VAPicture->CurrPic.BottomFieldOrderCnt; + if (nal_unit_type == 5) + decode->flags |= V4L2_H264_DECODE_PARAM_FLAG_IDR_PIC; + if (VAPicture->pic_fields.bits.field_pic_flag) + decode->flags |= V4L2_H264_DECODE_PARAM_FLAG_FIELD_PIC; + if (VAPicture->CurrPic.flags & VA_PICTURE_H264_BOTTOM_FIELD) + decode->flags |= V4L2_H264_DECODE_PARAM_FLAG_BOTTOM_FIELD; + pps->weighted_bipred_idc = VAPicture->pic_fields.bits.weighted_bipred_idc; pps->pic_init_qs_minus26 = VAPicture->pic_init_qs_minus26;