Skip to content

Commit

Permalink
control: Complete transition to VIDIOC_{G,S}_EXT_CTRLS API (raymanfx#41)
Browse files Browse the repository at this point in the history
Move away from the old VIDIOC_{G,S}_CTRL API.
The new API allows for larger data types (e.g. 64 bit integers) and
multi-dimensional controls.

Signed-off-by: Christopher N. Hesse <[email protected]>
  • Loading branch information
raymanfx authored Feb 17, 2022
1 parent c9ffeed commit 99ebd12
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
18 changes: 9 additions & 9 deletions src/control.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bitflags::bitflags;
use std::convert::{TryFrom, TryInto};
use std::{fmt, mem, str};
use std::{ffi, fmt, mem, str};

use crate::v4l_sys::*;

Expand Down Expand Up @@ -151,28 +151,28 @@ pub struct Description {
/// Name of the control, intended for the user
pub name: String,
/// Minimum value, inclusive
pub minimum: i32,
pub minimum: i64,
/// Maximum value, inclusive
pub maximum: i32,
pub maximum: i64,
/// Step size, always positive
pub step: i32,
pub step: u64,
/// Default value
pub default: i32,
pub default: i64,
/// Control flags
pub flags: Flags,

/// Items for menu controls (only valid if typ is a menu type)
pub items: Option<Vec<(u32, MenuItem)>>,
}

impl From<v4l2_queryctrl> for Description {
fn from(ctrl: v4l2_queryctrl) -> Self {
impl From<v4l2_query_ext_ctrl> for Description {
fn from(ctrl: v4l2_query_ext_ctrl) -> Self {
Description {
id: ctrl.id,
typ: Type::try_from(ctrl.type_).unwrap(),
name: str::from_utf8(&ctrl.name)
name: unsafe { ffi::CStr::from_ptr(ctrl.name.as_ptr()) }
.to_str()
.unwrap()
.trim_matches(char::from(0))
.to_string(),
minimum: ctrl.minimum,
maximum: ctrl.maximum,
Expand Down
21 changes: 13 additions & 8 deletions src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ impl Device {
pub fn query_controls(&self) -> io::Result<Vec<control::Description>> {
let mut controls = Vec::new();
unsafe {
let mut v4l2_ctrl: v4l2_queryctrl = mem::zeroed();
let mut v4l2_ctrl: v4l2_query_ext_ctrl = mem::zeroed();

loop {
v4l2_ctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
v4l2_ctrl.id |= V4L2_CTRL_FLAG_NEXT_COMPOUND;
match v4l2::ioctl(
self.handle().fd(),
v4l2::vidioc::VIDIOC_QUERYCTRL,
v4l2::vidioc::VIDIOC_QUERY_EXT_CTRL,
&mut v4l2_ctrl as *mut _ as *mut std::os::raw::c_void,
) {
Ok(_) => {
Expand Down Expand Up @@ -171,31 +171,36 @@ impl Device {
/// * `id` - Control identifier
pub fn control(&self, id: u32) -> io::Result<Control> {
unsafe {
let mut queryctrl: v4l2_queryctrl = mem::zeroed();
let mut queryctrl: v4l2_query_ext_ctrl = mem::zeroed();
queryctrl.id = id;
v4l2::ioctl(
self.handle().fd(),
v4l2::vidioc::VIDIOC_QUERYCTRL,
v4l2::vidioc::VIDIOC_QUERY_EXT_CTRL,
&mut queryctrl as *mut _ as *mut std::os::raw::c_void,
)?;

// determine the control type
let description = control::Description::from(queryctrl);

// query the actual control value
let mut v4l2_ctrl: v4l2_control = mem::zeroed();
let mut v4l2_ctrls: v4l2_ext_controls = mem::zeroed();
let mut v4l2_ctrl: v4l2_ext_control = mem::zeroed();
v4l2_ctrl.id = id;
v4l2_ctrls.count = 1;
v4l2_ctrls.controls = &mut v4l2_ctrl as *mut v4l2_ext_control;
v4l2::ioctl(
self.handle().fd(),
v4l2::vidioc::VIDIOC_G_CTRL,
v4l2::vidioc::VIDIOC_G_EXT_CTRLS,
&mut v4l2_ctrl as *mut _ as *mut std::os::raw::c_void,
)?;

let value = match description.typ {
control::Type::Integer | control::Type::Integer64 => {
control::Value::Integer(v4l2_ctrl.value as i64)
control::Value::Integer(v4l2_ctrl.__bindgen_anon_1.value64)
}
control::Type::Boolean => {
control::Value::Boolean(v4l2_ctrl.__bindgen_anon_1.value64 == 1)
}
control::Type::Boolean => control::Value::Boolean(v4l2_ctrl.value == 1),
_ => {
return Err(io::Error::new(
io::ErrorKind::Other,
Expand Down
1 change: 1 addition & 0 deletions src/v4l2/vidioc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,4 @@ pub const VIDIOC_ENUM_FRAMEINTERVALS: _IOC_TYPE = _IOWR!(b'V', 75, v4l2_frmivale
pub const VIDIOC_G_ENC_INDEX: _IOC_TYPE = _IOR!(b'V', 76, v4l2_enc_idx);
pub const VIDIOC_ENCODER_CMD: _IOC_TYPE = _IOWR!(b'V', 77, v4l2_encoder_cmd);
pub const VIDIOC_TRY_ENCODER_CMD: _IOC_TYPE = _IOWR!(b'V', 78, v4l2_encoder_cmd);
pub const VIDIOC_QUERY_EXT_CTRL: _IOC_TYPE = _IOWR!(b'V', 103, v4l2_query_ext_ctrl);

0 comments on commit 99ebd12

Please sign in to comment.