STRUCT V4L2_CTRL_VP9_FRAME(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… struct v4l2_ctrl_vp9_frame(9) β€” VP9 frame decoding control

okay bestie, so this is straight out of the Kernel API Manual, and it's literally the control struct that carries everything the kernel needs to know about one VP9 frame. one frame. all the vibes. no cap. πŸŽ€

Think of it as the little index card your decoder hands over before it goes "k, decoding now ✨" β€” and if any field on that card is wrong, the whole thing is giving πŸ’€. so let's read it carefully, yeah?


✨ SYNOPSIS ✨

struct v4l2_ctrl_vp9_frame {
    struct v4l2_vp9_loop_filter lf;
    struct v4l2_vp9_quantization quant;
    struct v4l2_vp9_segmentation seg;
    __u32 flags;
    __u16 compressed_header_size;
    __u16 uncompressed_header_size;
    __u16 frame_width_minus_1;
    __u16 frame_height_minus_1;
    __u16 render_width_minus_1;
    __u16 render_height_minus_1;
    __u64 last_frame_ts;
    __u64 golden_frame_ts;
    __u64 alt_frame_ts;
    __u8 ref_frame_sign_bias;
    __u8 reset_frame_context;
    __u8 frame_context_idx;
    __u8 profile;
    __u8 bit_depth;
    __u8 interpolation_filter;
    __u8 tile_cols_log2;
    __u8 tile_rows_log2;
    __u8 reference_mode;
    __u8 reserved[7];
};

look at her. iconic. she's got nested structs, she's got __u64 timestamps, she's got exactly 7 reserved bytes at the end like a little bow πŸŽ€


🌸 Members 🌸

the three nested-struct girlies

  • lf β€” loop filter parameters. peep v4l2_vp9_loop_filter for the full tea. 🫧
  • quant β€” quantization parameters. details live in v4l2_vp9_quantization.
  • seg β€” segmentation parameters. go read v4l2_vp9_segmentation, iykyk.

the generalists

  • flags β€” a combination of the V4L2_VP9_FRAME_FLAG_{} flags. mix and match, bestie. πŸ”₯
  • compressed_header_size β€” size of the compressed header, in bytes.
  • uncompressed_header_size β€” size of the uncompressed header, in bytes. yes they're two different things. no you cannot skip either. πŸ™ˆ

the size fields (all of them are "minus 1", do NOT forget the +1)

  • frame_width_minus_1 β€” add 1 to it and you'll get the frame width, expressed in pixels. 🀏
  • frame_height_minus_1 β€” add 1 to it and you'll get the frame height, expressed in pixels.
  • render_width_minus_1 β€” add 1 to it and you'll get the expected render width, expressed in pixels. this one is not used during the decoding process, but it might be used by HW scalers to prepare a frame that's ready for scanout. so like, it's not doing the homework, it's just getting the fit ready for the runway πŸ’…
  • render_height_minus_1 β€” add 1 to it and you'll get the expected render height, expressed in pixels. same deal: not used during the decoding process, but might be used by HW scalers to prep a frame that's ready for scanout. ✨

the timestamp trio (they're all the same rule, bestie)

  • last_frame_ts β€” the "last" reference buffer timestamp. the timestamp refers to the timestamp field in struct v4l2_buffer. use v4l2_timeval_to_ns to convert the struct timeval to a __u64.
  • golden_frame_ts β€” the "golden" reference buffer timestamp. again: it refers to the timestamp field in struct v4l2_buffer, and you use v4l2_timeval_to_ns to convert the struct timeval to a __u64.
  • alt_frame_ts β€” the "alt" reference buffer timestamp. yep, same: timestamp field in struct v4l2_buffer, and v4l2_timeval_to_ns converts the struct timeval to a __u64. three for three, slay. πŸ¦‹

the little __u8 icons

  • ref_frame_sign_bias β€” a bitfield specifying whether the sign bias is set for a given reference frame. set to either of the V4L2_VP9_SIGN_BIAS_{} values.
  • reset_frame_context β€” specifies whether the frame context should be reset to default values. either of V4L2_VP9_RESET_FRAME_CTX_{}.
  • frame_context_idx β€” the frame context that should be used/updated.
  • profile β€” VP9 profile. can be 0, 1, 2 or 3.
  • bit_depth β€” bits per component. can be 8, 10 or 12. ⚠️ note that not all profiles support 10 and/or 12 bit depths β€” don't just assume, check your profile first, ok? πŸ™
  • interpolation_filter β€” specifies the filter selection used for performing inter prediction. set to one of V4L2_VP9_INTERP_FILTER_{}.
  • tile_cols_log2 β€” the base 2 logarithm of the width of each tile (width measured in units of 8x8 blocks). it shall be less than or equal to 6. like, that's the rule. respect it. πŸ‘‘
  • tile_rows_log2 β€” the base 2 logarithm of the height of each tile (height measured in units of 8x8 blocks).
  • reference_mode β€” specifies the type of inter prediction to be used. set to one of V4L2_VP9_REFERENCE_MODE_{}.

the responsible one

  • reserved β€” padding field. should be zeroed by applications. that's it, that's the whole job. zero it out, be a good citizen 🫢

πŸ’€ real talk: reserved gets zeroed by applications, tile_cols_log2 stays ≀ 6, and the minus_1 fields always get the +1. these aren't suggestions, bestie, they're the vibe check.

πŸ¦‹ SEE ALSO πŸ¦‹

the kernel file ./include/uapi/linux/v4l2-controls.h, plus this whole friend group right here:

  • enum v4l2_mpeg_video_av1_profile(9), enum v4l2_mpeg_video_av1_level(9)
  • enum v4l2_stateless_h264_decode_mode(9), enum v4l2_stateless_h264_start_code(9)
  • struct v4l2_ctrl_h264_sps(9), struct v4l2_ctrl_h264_pps(9), struct v4l2_ctrl_h264_scaling_matrix(9), struct v4l2_ctrl_h264_pred_weights(9), struct v4l2_h264_reference(9), struct v4l2_ctrl_h264_slice_params(9), struct v4l2_h264_dpb_entry(9), struct v4l2_ctrl_h264_decode_params(9)
  • struct v4l2_ctrl_fwht_params(9)
  • struct v4l2_vp8_segment(9), struct v4l2_vp8_loop_filter(9), struct v4l2_vp8_quantization(9), struct v4l2_vp8_entropy(9), struct v4l2_vp8_entropy_coder_state(9), struct v4l2_ctrl_vp8_frame(9)
  • struct v4l2_ctrl_mpeg2_sequence(9), struct v4l2_ctrl_mpeg2_picture(9), struct v4l2_ctrl_mpeg2_quantisation(9)
  • struct v4l2_ctrl_hevc_sps(9), struct v4l2_ctrl_hevc_pps(9), struct v4l2_hevc_dpb_entry(9), struct v4l2_hevc_pred_weight_table(9), struct v4l2_ctrl_hevc_slice_params(9), struct v4l2_ctrl_hevc_decode_params(9), struct v4l2_ctrl_hevc_scaling_matrix(9)
  • struct v4l2_vp9_loop_filter(9), struct v4l2_vp9_quantization(9), struct v4l2_vp9_segmentation(9), struct v4l2_vp9_mv_probs(9), struct v4l2_ctrl_vp9_compressed_hdr(9)
  • struct v4l2_ctrl_av1_sequence(9), struct v4l2_ctrl_av1_tile_group_entry(9), enum v4l2_av1_warp_model(9), enum v4l2_av1_reference_frame(9), struct v4l2_av1_global_motion(9), enum v4l2_av1_frame_restoration_type(9), struct v4l2_av1_loop_restoration(9), struct v4l2_av1_cdef(9), enum v4l2_av1_segment_feature(9), struct v4l2_av1_segmentation(9), struct v4l2_av1_loop_filter(9), struct v4l2_av1_quantization(9), struct v4l2_av1_tile_info(9), enum v4l2_av1_frame_type(9), enum v4l2_av1_interpolation_filter(9), enum v4l2_av1_tx_mode(9), struct v4l2_ctrl_av1_frame(9), struct v4l2_ctrl_av1_film_grain(9)

that's the whole page, bestie, every field accounted for, nothing skipped. πŸ’–

later gator β€” this one came from ./include/uapi/linux, dated October 2026, filed under struct v4l2_ctrl_vp9_frame(9). mwah πŸŽ€βœ¨

πŸ“¦ where this page comes from