Skip to content

Commit

Permalink
controls: add support for h264 stateless codec controls
Browse files Browse the repository at this point in the history
The H264 stateless codec controls are required by stateless decoders
to maintain decoding state while using H264 parsed pixel format.
  • Loading branch information
semigle authored and Gnurou committed Jun 7, 2024
1 parent 8c7a023 commit b39d86b
Show file tree
Hide file tree
Showing 2 changed files with 312 additions and 0 deletions.
258 changes: 258 additions & 0 deletions lib/src/controls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -210,6 +216,258 @@ where
}
}

impl<T> From<v4l2_ctrl_h264_sps> for SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_sps>,
{
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::<T::PAYLOAD>() as u32,
__bindgen_anon_1: v4l2_ext_control__bindgen_ty_1 {
p_h264_sps: Box::into_raw(payload),
},
..unsafe { std::mem::zeroed() }
},
PhantomData,
)
}
}

impl<T> SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_sps>,
{
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<T> From<v4l2_ctrl_h264_pps> for SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_pps>,
{
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::<T::PAYLOAD>() as u32,
__bindgen_anon_1: v4l2_ext_control__bindgen_ty_1 {
p_h264_pps: Box::into_raw(payload),
},
..unsafe { std::mem::zeroed() }
},
PhantomData,
)
}
}

impl<T> SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_pps>,
{
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<T> From<v4l2_ctrl_h264_scaling_matrix> for SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_scaling_matrix>,
{
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::<T::PAYLOAD>() 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<T> SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_scaling_matrix>,
{
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<T> From<v4l2_ctrl_h264_pred_weights> for SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_pred_weights>,
{
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::<T::PAYLOAD>() 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<T> SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_pred_weights>,
{
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<T> From<v4l2_ctrl_h264_slice_params> for SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_slice_params>,
{
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::<T::PAYLOAD>() 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<T> SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_slice_params>,
{
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<T> From<v4l2_ctrl_h264_decode_params> for SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_decode_params>,
{
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::<T::PAYLOAD>() 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<T> SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_h264_decode_params>,
{
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<T> From<v4l2_ctrl_vp8_frame> for SafeExtControl<T>
where
T: ExtControlTrait<PAYLOAD = v4l2_ctrl_vp8_frame>,
Expand Down
54 changes: 54 additions & 0 deletions lib/src/controls/codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand Down

0 comments on commit b39d86b

Please sign in to comment.