From b39d86b128e868facc4c8e573de5c037066326b4 Mon Sep 17 00:00:00 2001 From: Slawomir Rosek Date: Tue, 14 May 2024 09:27:38 +0200 Subject: [PATCH] controls: add support for h264 stateless codec controls The H264 stateless codec controls are required by stateless decoders to maintain decoding state while using H264 parsed pixel format. --- lib/src/controls.rs | 258 ++++++++++++++++++++++++++++++++++++++ lib/src/controls/codec.rs | 54 ++++++++ 2 files changed, 312 insertions(+) diff --git a/lib/src/controls.rs b/lib/src/controls.rs index 9c24a6b..9b4ec5f 100644 --- a/lib/src/controls.rs +++ b/lib/src/controls.rs @@ -65,6 +65,12 @@ use std::marker::PhantomData; use crate::bindings; use crate::bindings::v4l2_ctrl_fwht_params; +use crate::bindings::v4l2_ctrl_h264_decode_params; +use crate::bindings::v4l2_ctrl_h264_pps; +use crate::bindings::v4l2_ctrl_h264_pred_weights; +use crate::bindings::v4l2_ctrl_h264_scaling_matrix; +use crate::bindings::v4l2_ctrl_h264_slice_params; +use crate::bindings::v4l2_ctrl_h264_sps; use crate::bindings::v4l2_ctrl_vp8_frame; use crate::bindings::v4l2_ext_control; use crate::bindings::v4l2_ext_control__bindgen_ty_1; @@ -210,6 +216,258 @@ where } } +impl From for SafeExtControl +where + T: ExtControlTrait, +{ + fn from(params: v4l2_ctrl_h264_sps) -> Self { + let payload = Box::new(params); + + Self( + v4l2_ext_control { + id: T::ID, + size: std::mem::size_of::() as u32, + __bindgen_anon_1: v4l2_ext_control__bindgen_ty_1 { + p_h264_sps: Box::into_raw(payload), + }, + ..unsafe { std::mem::zeroed() } + }, + PhantomData, + ) + } +} + +impl SafeExtControl +where + T: ExtControlTrait, +{ + pub fn h264_sps(&self) -> &v4l2_ctrl_h264_sps { + unsafe { self.0.__bindgen_anon_1.p_h264_sps.as_ref().unwrap() } + } + + pub fn h264_sps_mut(&mut self) -> &mut v4l2_ctrl_h264_sps { + unsafe { self.0.__bindgen_anon_1.p_h264_sps.as_mut().unwrap() } + } +} + +impl From for SafeExtControl +where + T: ExtControlTrait, +{ + fn from(params: v4l2_ctrl_h264_pps) -> Self { + let payload = Box::new(params); + + Self( + v4l2_ext_control { + id: T::ID, + size: std::mem::size_of::() as u32, + __bindgen_anon_1: v4l2_ext_control__bindgen_ty_1 { + p_h264_pps: Box::into_raw(payload), + }, + ..unsafe { std::mem::zeroed() } + }, + PhantomData, + ) + } +} + +impl SafeExtControl +where + T: ExtControlTrait, +{ + pub fn h264_pps(&self) -> &v4l2_ctrl_h264_pps { + unsafe { self.0.__bindgen_anon_1.p_h264_pps.as_ref().unwrap() } + } + + pub fn h264_pps_mut(&mut self) -> &mut v4l2_ctrl_h264_pps { + unsafe { self.0.__bindgen_anon_1.p_h264_pps.as_mut().unwrap() } + } +} + +impl From for SafeExtControl +where + T: ExtControlTrait, +{ + fn from(params: v4l2_ctrl_h264_scaling_matrix) -> Self { + let payload = Box::new(params); + + Self( + v4l2_ext_control { + id: T::ID, + size: std::mem::size_of::() as u32, + __bindgen_anon_1: v4l2_ext_control__bindgen_ty_1 { + p_h264_scaling_matrix: Box::into_raw(payload), + }, + ..unsafe { std::mem::zeroed() } + }, + PhantomData, + ) + } +} + +impl SafeExtControl +where + T: ExtControlTrait, +{ + pub fn h264_scaling_matrix(&self) -> &v4l2_ctrl_h264_scaling_matrix { + unsafe { + self.0 + .__bindgen_anon_1 + .p_h264_scaling_matrix + .as_ref() + .unwrap() + } + } + + pub fn h264_scaling_matrix_mut(&mut self) -> &mut v4l2_ctrl_h264_scaling_matrix { + unsafe { + self.0 + .__bindgen_anon_1 + .p_h264_scaling_matrix + .as_mut() + .unwrap() + } + } +} + +impl From for SafeExtControl +where + T: ExtControlTrait, +{ + fn from(params: v4l2_ctrl_h264_pred_weights) -> Self { + let payload = Box::new(params); + + Self( + v4l2_ext_control { + id: T::ID, + size: std::mem::size_of::() as u32, + __bindgen_anon_1: v4l2_ext_control__bindgen_ty_1 { + p_h264_pred_weights: Box::into_raw(payload), + }, + ..unsafe { std::mem::zeroed() } + }, + PhantomData, + ) + } +} + +impl SafeExtControl +where + T: ExtControlTrait, +{ + pub fn h264_pred_weights(&self) -> &v4l2_ctrl_h264_pred_weights { + unsafe { + self.0 + .__bindgen_anon_1 + .p_h264_pred_weights + .as_ref() + .unwrap() + } + } + + pub fn h264_pred_weights_mut(&mut self) -> &mut v4l2_ctrl_h264_pred_weights { + unsafe { + self.0 + .__bindgen_anon_1 + .p_h264_pred_weights + .as_mut() + .unwrap() + } + } +} + +impl From for SafeExtControl +where + T: ExtControlTrait, +{ + fn from(params: v4l2_ctrl_h264_slice_params) -> Self { + let payload = Box::new(params); + + Self( + v4l2_ext_control { + id: T::ID, + size: std::mem::size_of::() as u32, + __bindgen_anon_1: v4l2_ext_control__bindgen_ty_1 { + p_h264_slice_params: Box::into_raw(payload), + }, + ..unsafe { std::mem::zeroed() } + }, + PhantomData, + ) + } +} + +impl SafeExtControl +where + T: ExtControlTrait, +{ + pub fn h264_slice_params(&self) -> &v4l2_ctrl_h264_slice_params { + unsafe { + self.0 + .__bindgen_anon_1 + .p_h264_slice_params + .as_ref() + .unwrap() + } + } + + pub fn h264_slice_params_mut(&mut self) -> &mut v4l2_ctrl_h264_slice_params { + unsafe { + self.0 + .__bindgen_anon_1 + .p_h264_slice_params + .as_mut() + .unwrap() + } + } +} + +impl From for SafeExtControl +where + T: ExtControlTrait, +{ + fn from(params: v4l2_ctrl_h264_decode_params) -> Self { + let payload = Box::new(params); + + Self( + v4l2_ext_control { + id: T::ID, + size: std::mem::size_of::() as u32, + __bindgen_anon_1: v4l2_ext_control__bindgen_ty_1 { + p_h264_decode_params: Box::into_raw(payload), + }, + ..unsafe { std::mem::zeroed() } + }, + PhantomData, + ) + } +} + +impl SafeExtControl +where + T: ExtControlTrait, +{ + pub fn h264_decode_params(&self) -> &v4l2_ctrl_h264_decode_params { + unsafe { + self.0 + .__bindgen_anon_1 + .p_h264_decode_params + .as_ref() + .unwrap() + } + } + + pub fn h264_decode_params_mut(&mut self) -> &mut v4l2_ctrl_h264_decode_params { + unsafe { + self.0 + .__bindgen_anon_1 + .p_h264_decode_params + .as_mut() + .unwrap() + } + } +} + impl From for SafeExtControl where T: ExtControlTrait, diff --git a/lib/src/controls/codec.rs b/lib/src/controls/codec.rs index eb771e7..ce88e40 100644 --- a/lib/src/controls/codec.rs +++ b/lib/src/controls/codec.rs @@ -4,6 +4,12 @@ use bitflags::bitflags; use crate::bindings; use crate::bindings::v4l2_ctrl_fwht_params; +use crate::bindings::v4l2_ctrl_h264_decode_params; +use crate::bindings::v4l2_ctrl_h264_pps; +use crate::bindings::v4l2_ctrl_h264_pred_weights; +use crate::bindings::v4l2_ctrl_h264_scaling_matrix; +use crate::bindings::v4l2_ctrl_h264_slice_params; +use crate::bindings::v4l2_ctrl_h264_sps; use crate::bindings::v4l2_ctrl_vp8_frame; use crate::controls::ExtControlTrait; @@ -25,6 +31,54 @@ bitflags! { } } +pub struct H264DecodeMode; +impl ExtControlTrait for H264DecodeMode { + const ID: u32 = bindings::V4L2_CID_STATELESS_H264_DECODE_MODE; + type PAYLOAD = i32; +} + +pub struct H264StartCode; +impl ExtControlTrait for H264StartCode { + const ID: u32 = bindings::V4L2_CID_STATELESS_H264_START_CODE; + type PAYLOAD = i32; +} + +pub struct H264Sps; +impl ExtControlTrait for H264Sps { + const ID: u32 = bindings::V4L2_CID_STATELESS_H264_SPS; + type PAYLOAD = v4l2_ctrl_h264_sps; +} + +pub struct H264Pps; +impl ExtControlTrait for H264Pps { + const ID: u32 = bindings::V4L2_CID_STATELESS_H264_PPS; + type PAYLOAD = v4l2_ctrl_h264_pps; +} + +pub struct H264ScalingMatrix; +impl ExtControlTrait for H264ScalingMatrix { + const ID: u32 = bindings::V4L2_CID_STATELESS_H264_SCALING_MATRIX; + type PAYLOAD = v4l2_ctrl_h264_scaling_matrix; +} + +pub struct H264PredWeights; +impl ExtControlTrait for H264PredWeights { + const ID: u32 = bindings::V4L2_CID_STATELESS_H264_PRED_WEIGHTS; + type PAYLOAD = v4l2_ctrl_h264_pred_weights; +} + +pub struct H264SliceParams; +impl ExtControlTrait for H264SliceParams { + const ID: u32 = bindings::V4L2_CID_STATELESS_H264_SLICE_PARAMS; + type PAYLOAD = v4l2_ctrl_h264_slice_params; +} + +pub struct H264DecodeParams; +impl ExtControlTrait for H264DecodeParams { + const ID: u32 = bindings::V4L2_CID_STATELESS_H264_DECODE_PARAMS; + type PAYLOAD = v4l2_ctrl_h264_decode_params; +} + pub struct FwhtParams; impl ExtControlTrait for FwhtParams { const ID: u32 = bindings::V4L2_CID_STATELESS_FWHT_PARAMS;