diff --git a/src/h264.c b/src/h264.c index 284a2a5..a8296c2 100644 --- a/src/h264.c +++ b/src/h264.c @@ -827,10 +827,63 @@ int h264_set_controls(struct request_data *driver_data, dpb_update(context, &surface->params.h264.picture); + /* + * Dump the raw VAAPI fields at the libva boundary so issue #8 + * follow-up can disambiguate "ffmpeg-vaapi didn't populate" from + * "downstream consumer (daedalus_v4l2 wire protocol) corrupted the + * value". One-line; safe to leave in — costs a single printf per frame. + */ + request_log("h264_set_controls: VAProfile=%d seq_fields=0x%08x pic_fields=0x%08x num_ref_frames=%u bit_depth_luma_m8=%u bit_depth_chroma_m8=%u w_mbs_m1=%u h_mbs_m1=%u\n", + (int)profile, + surface->params.h264.picture.seq_fields.value, + surface->params.h264.picture.pic_fields.value, + surface->params.h264.picture.num_ref_frames, + surface->params.h264.picture.bit_depth_luma_minus8, + surface->params.h264.picture.bit_depth_chroma_minus8, + surface->params.h264.picture.picture_width_in_mbs_minus1, + surface->params.h264.picture.picture_height_in_mbs_minus1); + h264_va_picture_to_v4l2(driver_data, context, surface, &surface->params.h264.picture, &decode, &pps, &sps); + /* + * max_num_ref_frames fallback. Some VAAPI clients (older ffmpeg-vaapi + * paths, some daedalus_v4l2 consumers) leave VAPicture->num_ref_frames + * at zero. Hardware decoders tolerate; libavcodec-via-daedalus enforces + * sps.max_num_ref_frames strictly and rejects every frame. + * + * Count valid DPB entries first (the bitstream-true reference count we + * can see); fall back to a per-profile spec minimum if even that is 0. + * See marfrit/libva-v4l2-request-fourier issue #8. + */ + if (sps.max_num_ref_frames == 0) { + unsigned int valid = 0; + unsigned int i; + for (i = 0; i < 16; i++) { + const VAPictureH264 *ref = + &surface->params.h264.picture.ReferenceFrames[i]; + if (!(ref->flags & VA_PICTURE_H264_INVALID)) + valid++; + } + if (valid > 0) { + sps.max_num_ref_frames = (uint8_t)valid; + } else { + switch (profile) { + case VAProfileH264ConstrainedBaseline: + sps.max_num_ref_frames = 1; + break; + case VAProfileH264Main: + case VAProfileH264High: + case VAProfileH264MultiviewHigh: + case VAProfileH264StereoHigh: + default: + sps.max_num_ref_frames = 4; + break; + } + } + } + /* * Populate the scaling matrix unconditionally: from VAAPI's * VAIQMatrixBufferH264 when the consumer sent one this frame