Describe the bug
The bcm2835-codec encoder driver does not expose the V4L2_CID_MIN_BUFFERS_FOR_CAPTURE control (0x00980081). GStreamer's v4l2 encoder element queries this control to determine how many frames the hardware holds before producing output, and uses it to compute the encoder latency reported to the pipeline. When the control is missing, GStreamer falls back to 0, causing the encoder to report zero latency.
The driver already tracks its minimum buffer requirement via port->minimum_buffer.num in queue_setup, but this value is not exposed as a V4L2 control.
Steps to reproduce the behaviour
- Query the control directly:
$ v4l2-ctl -d /dev/video11 --get-ctrl=0x00980081
unknown control '0x00980081'
- Run a GStreamer pipeline with debug logging:
GST_DEBUG=v4l2videoenc:6 gst-launch-1.0
libcamerasrc ! capsfilter caps=video/x-raw,width=1280,height=720,framerate=60/1,format=YUY2 \
! queue ! v4l2h264enc extra-controls="controls,repeat_sequence_header=1" \
! 'video/x-h264,level=(string)4' ! fakesink
- Observe in the output:
gst_v4l2_video_enc_decide_allocation: Setting latency: 0:00:00.000000000
Empirical measurement of the QBUF/DQBUF pattern on the capture pool confirms the encoder buffers 1 frame before producing output. Over
1486 frames at 1280x720@60fps:
Encoding latency (sink QBUF → src DQBUF):
median: 9.7 ms mean: 10.9 ms p95: 14.3 ms max: 18.5 ms
Device (s)
Raspberry Pi 4 Mod. B
System
raspinfo.txt
Logs
Codec Controls
video_b_frames 0x009909ca (int) : min=0 max=0 step=1 default=0 value=0 flags=update
video_gop_size 0x009909cb (int) : min=0 max=2147483647 step=1 default=60 value=60
video_bitrate_mode 0x009909ce (menu) : min=0 max=1 default=0 value=0 (Variable Bitrate)
video_bitrate 0x009909cf (int) : min=25000 max=25000000 step=25000 default=10000000 value=10000000
sequence_header_mode 0x009909d8 (menu) : min=0 max=1 default=1 value=1 (Joined With 1st Frame)
repeat_sequence_header 0x009909e2 (bool) : default=0 value=0
force_key_frame 0x009909e5 (button) : value=0 flags=write-only, execute-on-write
h264_minimum_qp_value 0x00990a61 (int) : min=0 max=51 step=1 default=20 value=20
h264_maximum_qp_value 0x00990a62 (int) : min=0 max=51 step=1 default=51 value=51
h264_i_frame_period 0x00990a66 (int) : min=0 max=2147483647 step=1 default=60 value=60
h264_level 0x00990a67 (menu) : min=0 max=15 default=11 value=11 (4)
h264_profile 0x00990a6b (menu) : min=0 max=4 default=4 value=4 (High)
No min_buffers_for_capture control present.
Additional context
GStreamer computes the encoder latency as min_buffers * frame_duration. The min_buffers value comes from querying
V4L2_CID_MIN_BUFFERS_FOR_CAPTURE. When missing, it falls back to 0.
A related issue has been filed on GStreamer's side: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/5030
Adding V4L2_CID_MIN_BUFFERS_FOR_CAPTURE as a volatile read-only control derived from port->minimum_buffer.num on the capture side would fix this. The same would be useful for the decoder.
Describe the bug
The bcm2835-codec encoder driver does not expose the
V4L2_CID_MIN_BUFFERS_FOR_CAPTUREcontrol (0x00980081). GStreamer's v4l2 encoder element queries this control to determine how many frames the hardware holds before producing output, and uses it to compute the encoder latency reported to the pipeline. When the control is missing, GStreamer falls back to 0, causing the encoder to report zero latency.The driver already tracks its minimum buffer requirement via
port->minimum_buffer.numin queue_setup, but this value is not exposed as a V4L2 control.Steps to reproduce the behaviour
Empirical measurement of the QBUF/DQBUF pattern on the capture pool confirms the encoder buffers 1 frame before producing output. Over
1486 frames at 1280x720@60fps:
Encoding latency (sink QBUF → src DQBUF):
median: 9.7 ms mean: 10.9 ms p95: 14.3 ms max: 18.5 ms
Device (s)
Raspberry Pi 4 Mod. B
System
raspinfo.txt
Logs
Codec Controls
No min_buffers_for_capture control present.
Additional context
GStreamer computes the encoder latency as min_buffers * frame_duration. The min_buffers value comes from querying
V4L2_CID_MIN_BUFFERS_FOR_CAPTURE. When missing, it falls back to 0.A related issue has been filed on GStreamer's side: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/work_items/5030
Adding
V4L2_CID_MIN_BUFFERS_FOR_CAPTUREas a volatile read-only control derived fromport->minimum_buffer.numon the capture side would fix this. The same would be useful for the decoder.