From 5633cf1b5fb1d07c2ae0cf4749bef3d08dde260a Mon Sep 17 00:00:00 2001 From: dyknon Date: Thu, 20 Feb 2025 22:31:21 +0900 Subject: simple v4l2 application now... --- v4l2-sys/src/lib.rs | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 v4l2-sys/src/lib.rs (limited to 'v4l2-sys/src') diff --git a/v4l2-sys/src/lib.rs b/v4l2-sys/src/lib.rs new file mode 100644 index 0000000..b2579d9 --- /dev/null +++ b/v4l2-sys/src/lib.rs @@ -0,0 +1,148 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +use libc::c_ulong; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +// Bindgen does not handle C preprocessor macro functions, so does not handle any of the symbols +// that depend on _IOC, _IO, _IOR, _IOW, _IOWR, etc. Use constant functions to add them. + +// C preprocessor macros originally from /usr/include/asm-generic/ioctl.h amended to be Rust +// const functions. + +const fn _IOC(dir: u32, type_: char, nr: u32, size: usize) -> c_ulong { + let n = (dir << _IOC_DIRSHIFT) | ((type_ as u32) << _IOC_TYPESHIFT) | (nr << _IOC_NRSHIFT) | ((size as u32) << _IOC_SIZESHIFT); + n as c_ulong +} + +const fn _IO(type_: char, nr: u32) -> c_ulong { _IOC(_IOC_NONE, type_, nr, 0) } +const fn _IOR(type_: char, nr: u32, size: usize) -> c_ulong { _IOC(_IOC_READ, type_, nr, size) } +const fn _IOW(type_: char, nr: u32, size: usize) -> c_ulong { _IOC(_IOC_WRITE, type_, nr, size) } +const fn _IOWR(type_: char, nr: u32, size: usize) -> c_ulong { _IOC(_IOC_READ|_IOC_WRITE, type_, nr, size) } + +// C has a sizeof function, Rust handles this with this const function. + +use std::mem::size_of; + +// The relevant symbols from /usr/include/linux/videodev2.h + +pub const VIDIOC_QUERYCAP:c_ulong = _IOR('V', 0, size_of::()); +pub const VIDIOC_ENUM_FMT:c_ulong = _IOWR('V', 2, size_of::()); +pub const VIDIOC_G_FMT:c_ulong = _IOWR('V', 4, size_of::()); +pub const VIDIOC_S_FMT:c_ulong = _IOWR('V', 5, size_of::()); +pub const VIDIOC_REQBUFS:c_ulong = _IOWR('V', 8, size_of::()); +pub const VIDIOC_QUERYBUF:c_ulong = _IOWR('V', 9, size_of::()); +pub const VIDIOC_G_FBUF:c_ulong = _IOR('V', 10, size_of::()); +pub const VIDIOC_S_FBUF:c_ulong = _IOW('V', 11, size_of::()); +pub const VIDIOC_OVERLAY:c_ulong = _IOW('V', 14, size_of::()); // TODO check C int is Rust u32. +pub const VIDIOC_QBUF:c_ulong = _IOWR('V', 15, size_of::()); +pub const VIDIOC_EXPBUF:c_ulong = _IOWR('V', 16, size_of::()); +pub const VIDIOC_DQBUF:c_ulong = _IOWR('V', 17, size_of::()); +pub const VIDIOC_STREAMON:c_ulong = _IOW('V', 18, size_of::()); // TODO check C int is Rust u32. +pub const VIDIOC_STREAMOFF:c_ulong = _IOW('V', 19, size_of::()); // TODO check C int is Rust u32. +pub const VIDIOC_G_PARM:c_ulong = _IOWR('V', 21, size_of::()); +pub const VIDIOC_S_PARM:c_ulong = _IOWR('V', 22, size_of::()); +pub const VIDIOC_G_STD:c_ulong = _IOR('V', 23, size_of::()); +pub const VIDIOC_S_STD:c_ulong = _IOW('V', 24, size_of::()); +pub const VIDIOC_ENUMSTD:c_ulong = _IOWR('V', 25, size_of::()); +pub const VIDIOC_ENUMINPUT:c_ulong = _IOWR('V', 26, size_of::()); +pub const VIDIOC_G_CTRL:c_ulong = _IOWR('V', 27, size_of::()); +pub const VIDIOC_S_CTRL:c_ulong = _IOWR('V', 28, size_of::()); +pub const VIDIOC_G_TUNER:c_ulong = _IOWR('V', 29, size_of::()); +pub const VIDIOC_S_TUNER:c_ulong = _IOW('V', 30, size_of::()); +pub const VIDIOC_G_AUDIO:c_ulong = _IOR('V', 33, size_of::()); +pub const VIDIOC_S_AUDIO:c_ulong = _IOW('V', 34, size_of::()); +pub const VIDIOC_QUERYCTRL:c_ulong = _IOWR('V', 36, size_of::()); +pub const VIDIOC_QUERYMENU:c_ulong = _IOWR('V', 37, size_of::()); +pub const VIDIOC_G_INPUT:c_ulong = _IOR('V', 38, size_of::()); // TODO check C int is Rust u32. +pub const VIDIOC_S_INPUT:c_ulong = _IOWR('V', 39, size_of::()); // TODO check C int is Rust u32. +pub const VIDIOC_G_EDID:c_ulong = _IOWR('V', 40, size_of::()); +pub const VIDIOC_S_EDID:c_ulong = _IOWR('V', 41, size_of::()); +pub const VIDIOC_G_OUTPUT:c_ulong = _IOR('V', 46, size_of::()); // TODO check C int is Rust u32. +pub const VIDIOC_S_OUTPUT:c_ulong = _IOWR('V', 47, size_of::()); // TODO check C int is Rust u32. +pub const VIDIOC_ENUMOUTPUT:c_ulong = _IOWR('V', 48, size_of::()); +pub const VIDIOC_G_AUDOUT:c_ulong = _IOR('V', 49, size_of::()); +pub const VIDIOC_S_AUDOUT:c_ulong = _IOW('V', 50, size_of::()); +pub const VIDIOC_G_MODULATOR:c_ulong = _IOWR('V', 54, size_of::()); +pub const VIDIOC_S_MODULATOR:c_ulong = _IOW('V', 55, size_of::()); +pub const VIDIOC_G_FREQUENCY:c_ulong = _IOWR('V', 56, size_of::()); +pub const VIDIOC_S_FREQUENCY:c_ulong = _IOW('V', 57, size_of::()); +pub const VIDIOC_CROPCAP:c_ulong = _IOWR('V', 58, size_of::()); +pub const VIDIOC_G_CROP:c_ulong = _IOWR('V', 59, size_of::()); +pub const VIDIOC_S_CROP:c_ulong = _IOW('V', 60, size_of::()); +pub const VIDIOC_G_JPEGCOMP:c_ulong = _IOR('V', 61, size_of::()); +pub const VIDIOC_S_JPEGCOMP:c_ulong = _IOW('V', 62, size_of::()); +pub const VIDIOC_QUERYSTD:c_ulong = _IOR('V', 63, size_of::()); +pub const VIDIOC_TRY_FMT:c_ulong = _IOWR('V', 64, size_of::()); +pub const VIDIOC_ENUMAUDIO:c_ulong = _IOWR('V', 65, size_of::()); +pub const VIDIOC_ENUMAUDOUT:c_ulong = _IOWR('V', 66, size_of::()); +pub const VIDIOC_G_PRIORITY:c_ulong = _IOR('V', 67, size_of::()); /* enum v4l2_priority */ +pub const VIDIOC_S_PRIORITY:c_ulong = _IOW('V', 68, size_of::()); /* enum v4l2_priority */ +pub const VIDIOC_G_SLICED_VBI_CAP:c_ulong = _IOWR('V', 69, size_of::()); +pub const VIDIOC_LOG_STATUS:c_ulong = _IO('V', 70); +pub const VIDIOC_G_EXT_CTRLS:c_ulong = _IOWR('V', 71, size_of::()); +pub const VIDIOC_S_EXT_CTRLS:c_ulong = _IOWR('V', 72, size_of::()); +pub const VIDIOC_TRY_EXT_CTRLS:c_ulong = _IOWR('V', 73, size_of::()); +pub const VIDIOC_ENUM_FRAMESIZES:c_ulong = _IOWR('V', 74, size_of::()); +pub const VIDIOC_ENUM_FRAMEINTERVALS:c_ulong = _IOWR('V', 75, size_of::()); +pub const VIDIOC_G_ENC_INDEX:c_ulong = _IOR('V', 76, size_of::()); +pub const VIDIOC_ENCODER_CMD:c_ulong = _IOWR('V', 77, size_of::()); +pub const VIDIOC_TRY_ENCODER_CMD:c_ulong = _IOWR('V', 78, size_of::()); + +/* + * Experimental, meant for debugging, testing and internal use. + * Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined. + * You must be root to use these ioctls. Never use these in applications! + */ +pub const VIDIOC_DBG_S_REGISTER:c_ulong = _IOW('V', 79, size_of::()); +pub const VIDIOC_DBG_G_REGISTER:c_ulong = _IOWR('V', 80, size_of::()); + +pub const VIDIOC_S_HW_FREQ_SEEK:c_ulong = _IOW('V', 82, size_of::()); +pub const VIDIOC_S_DV_TIMINGS:c_ulong = _IOWR('V', 87, size_of::()); +pub const VIDIOC_G_DV_TIMINGS:c_ulong = _IOWR('V', 88, size_of::()); +pub const VIDIOC_DQEVENT:c_ulong = _IOR('V', 89, size_of::()); +pub const VIDIOC_SUBSCRIBE_EVENT:c_ulong = _IOW('V', 90, size_of::()); +pub const VIDIOC_UNSUBSCRIBE_EVENT:c_ulong = _IOW('V', 91, size_of::()); +pub const VIDIOC_CREATE_BUFS:c_ulong = _IOWR('V', 92, size_of::()); +pub const VIDIOC_PREPARE_BUF:c_ulong = _IOWR('V', 93, size_of::()); +pub const VIDIOC_G_SELECTION:c_ulong = _IOWR('V', 94, size_of::()); +pub const VIDIOC_S_SELECTION:c_ulong = _IOWR('V', 95, size_of::()); +pub const VIDIOC_DECODER_CMD:c_ulong = _IOWR('V', 96, size_of::()); +pub const VIDIOC_TRY_DECODER_CMD:c_ulong = _IOWR('V', 97, size_of::()); +pub const VIDIOC_ENUM_DV_TIMINGS:c_ulong = _IOWR('V', 98, size_of::()); +pub const VIDIOC_QUERY_DV_TIMINGS:c_ulong = _IOR('V', 99, size_of::()); +pub const VIDIOC_DV_TIMINGS_CAP:c_ulong = _IOWR('V', 100, size_of::()); +pub const VIDIOC_ENUM_FREQ_BANDS:c_ulong = _IOWR('V', 101, size_of::()); + +/* + * Experimental, meant for debugging, testing and internal use. + * Never use this in applications! + */ +pub const VIDIOC_DBG_G_CHIP_INFO:c_ulong = _IOWR('V', 102, size_of::()); + +pub const VIDIOC_QUERY_EXT_CTRL:c_ulong = _IOWR('V', 103, size_of::()); + +#[cfg(test)] +mod tests { + + use super::*; + + use rstest::rstest; + + // TODO really need to test many more, if not all of the values. + + #[rstest( + datum, expected, + case(VIDIOC_QUERYCAP, 2154321408), + case(VIDIOC_OVERLAY, 1074025998), + case(VIDIOC_G_PRIORITY, 2147767875), + case(VIDIOC_S_PRIORITY, 1074026052), + case(VIDIOC_LOG_STATUS, 22086), + )] + fn check_vidioc_symbol_values(datum: u32, expected: u32) { + assert_eq!(datum, expected); + } + +} -- cgit v1.2.3