eye_hal/platform/v4l2/
mod.rs

1//! Video for Linux (2) backend
2//!
3//! V4L2 is the standard API for video input and output on Linux.
4//!
5//! # Related Links
6//! * <https://linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/v4l/v4l2.html> - Video for Linux API
7
8pub mod context;
9pub mod device;
10pub mod stream;
11
12pub use context::Context;
13
14use std::{convert::TryInto, str};
15
16use crate::format::PixelFormat;
17
18impl From<&[u8; 4]> for PixelFormat {
19    fn from(fourcc: &[u8; 4]) -> Self {
20        // We use the Linux fourccs as defined here:
21        // https://www.kernel.org/doc/html/v5.5/media/uapi/v4l/videodev.html.
22
23        // Mono (single-component) formats
24        if fourcc == b"GREY" {
25            PixelFormat::Gray(8)
26        } else if fourcc == b"Y16 " {
27            PixelFormat::Gray(16)
28        } else if fourcc == b"Z16 " {
29            PixelFormat::Depth(16)
30        }
31        // RGB formats
32        else if fourcc == b"BGR3" {
33            PixelFormat::Bgr(24)
34        } else if fourcc == b"RGB3" {
35            PixelFormat::Rgb(24)
36        }
37        // Compressed formats
38        else if fourcc == b"MJPG" {
39            PixelFormat::Jpeg
40        }
41        // Misc
42        else {
43            PixelFormat::Custom(String::from(str::from_utf8(fourcc).unwrap()))
44        }
45    }
46}
47
48impl TryInto<[u8; 4]> for PixelFormat {
49    type Error = ();
50
51    fn try_into(self) -> Result<[u8; 4], Self::Error> {
52        // We use the Linux fourccs as defined here:
53        // https://www.kernel.org/doc/html/v5.5/media/uapi/v4l/videodev.html.
54
55        match self {
56            PixelFormat::Custom(repr) => {
57                // If the representation does not take up more than 4 four bytes, we can safely
58                // convert it into a four character code.
59                let repr_bytes = repr.as_bytes();
60                if repr_bytes.len() <= 4 {
61                    let mut bytes = [0u8; 4];
62                    bytes.clone_from_slice(&repr_bytes[..repr_bytes.len()]);
63                    Ok(bytes)
64                } else {
65                    Err(())
66                }
67            }
68            PixelFormat::Gray(8) => Ok(*b"GREY"),
69            PixelFormat::Gray(16) => Ok(*b"Y16 "),
70            PixelFormat::Depth(16) => Ok(*b"Z16 "),
71            PixelFormat::Bgr(24) => Ok(*b"BGR3"),
72            PixelFormat::Rgb(24) => Ok(*b"RGB3"),
73            PixelFormat::Rgb(32) => Ok(*b"AB24"),
74            PixelFormat::Jpeg => Ok(*b"MJPG"),
75            _ => Err(()),
76        }
77    }
78}