Skip to content

bcm2835-codec encoder does not expose V4L2_CID_MIN_BUFFERS_FOR_CAPTURE #7313

@FabienDanieau

Description

@FabienDanieau

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

  1. Query the control directly:

$ v4l2-ctl -d /dev/video11 --get-ctrl=0x00980081
unknown control '0x00980081'

  1. 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

  1. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions