diff --git a/src/h264.c b/src/h264.c index b22beb4..ba29c5d 100644 --- a/src/h264.c +++ b/src/h264.c @@ -552,6 +552,35 @@ int h264_set_controls(struct request_data *driver_data, sps.profile_idc = h264_profile_to_idc(profile); + /* + * VAAPI's decode-side VAPictureParameterBufferH264 does not carry + * level_idc — see va.h, the field exists only in + * VAEncSequenceParameterBufferH264 on the encode path. The H.264 + * SPS NAL is also not included in VASliceDataBuffer (ffmpeg-vaapi + * parses it client-side and forwards only slice data), so a + * SPS-NAL byte extractor is not viable from the bitstream we + * receive. + * + * Hantro and other stateless H.264 decoders use level_idc to + * pre-allocate decoder resources (DPB, motion-vector buffers); a + * zero-init level_idc=0 is invalid (lowest legal is 10 = Level + * 1.0) and causes hantro to silently skip the decode hardware + * dispatch. + * + * Hardcode level_idc = 51 (Level 5.1, max for 1080p/4K@30) as a + * known-incomplete intermediate. This INTENTIONALLY OVER-ALLOCATES + * decoder resources and is sufficient for any stream up to 4K@30. + * It is corpus-correct, not contract-correct. + * + * TODO: derive level_idc from (VAProfile, picture_width_in_mbs, + * picture_height_in_mbs) per H.264 Annex A.3 max-MB-per-second + * thresholds. That is a small lookup table but requires also + * mapping the consumer's framerate, which VAAPI doesn't provide + * directly. For now the over-allocation is the upstreamable + * compromise. + */ + sps.level_idc = 51; + /* * Build the per-request control list incrementally: * - SPS, PPS, DECODE_PARAMS: always required (in either decode