diff --git a/src/h264.c b/src/h264.c index 7d20a98..6efacb2 100644 --- a/src/h264.c +++ b/src/h264.c @@ -632,6 +632,38 @@ int h264_set_controls(struct request_data *driver_data, &surface->params.h264.slice, &surface->params.h264.picture, &slice, &weights); + /* + * Derive PFRAME / BFRAME flags in v4l2_ctrl_h264_decode_params.flags + * from VASliceParameterBufferH264.slice_type. VAAPI's slice_type + * matches the H.264 spec slice_type semantic: 0=P, 1=B, 2=I, 3=SP, + * 4=SI; values 5..9 mean "all slices in the picture have this + * slice_type" (mod 5 yields the underlying type). VAAPI consumers + * (ffmpeg, mpv) populate this for every slice; in FRAME_BASED mode + * we only see the most-recent slice's params, but slice_type is + * uniform across a single coded picture for our purposes. + * + * Kernel consumers that read these flags: tegra-vde + * (drivers/media/platform/nvidia/tegra-vde/h264.c lines 783-799 of + * 6.19.x) selects the inter-frame decode kernel. Hantro / rkvdec / + * cedrus / mediatek / qcom-iris-stateless do not consume them. + * Setting them keeps the libva-v4l2-request fork upstreamable + * across drivers without affecting hantro behaviour. + * + * Cross-reference: ext-ctrls-codec-stateless.rst Decode Parameters + * Flags — V4L2_H264_DECODE_PARAM_FLAG_PFRAME / _BFRAME. + */ + switch (surface->params.h264.slice.slice_type % 5) { + case H264_SLICE_P: + decode.flags |= V4L2_H264_DECODE_PARAM_FLAG_PFRAME; + break; + case H264_SLICE_B: + decode.flags |= V4L2_H264_DECODE_PARAM_FLAG_BFRAME; + break; + default: + /* I / SP / SI: no extra flag. */ + break; + } + sps.profile_idc = h264_profile_to_idc(profile); /*