1 //! Safe wrapper for the `VIDIOC_STREAM(ON|OFF)` ioctls.
2 use crate::QueueType;
3 use nix::errno::Errno;
4 use std::os::unix::io::AsRawFd;
5 use thiserror::Error;
6
7 #[doc(hidden)]
8 mod ioctl {
9 nix::ioctl_write_ptr!(vidioc_streamon, b'V', 18, u32);
10 nix::ioctl_write_ptr!(vidioc_streamoff, b'V', 19, u32);
11 }
12
13 #[derive(Debug, Error)]
14 pub enum StreamOnError {
15 #[error("queue type ({0}) not supported, or no buffers allocated or enqueued")]
16 InvalidQueue(QueueType),
17 #[error("invalid pad configuration")]
18 InvalidPadConfig,
19 #[error("invalid pipeline link configuration")]
20 InvalidPipelineConfig,
21 #[error("ioctl error: {0}")]
22 IoctlError(Errno),
23 }
24
25 impl From<StreamOnError> for Errno {
from(err: StreamOnError) -> Self26 fn from(err: StreamOnError) -> Self {
27 match err {
28 StreamOnError::InvalidQueue(_) => Errno::EINVAL,
29 StreamOnError::InvalidPadConfig => Errno::EPIPE,
30 StreamOnError::InvalidPipelineConfig => Errno::ENOLINK,
31 StreamOnError::IoctlError(e) => e,
32 }
33 }
34 }
35
36 /// Safe wrapper around the `VIDIOC_STREAMON` ioctl.
streamon(fd: &impl AsRawFd, queue: QueueType) -> Result<(), StreamOnError>37 pub fn streamon(fd: &impl AsRawFd, queue: QueueType) -> Result<(), StreamOnError> {
38 match unsafe { ioctl::vidioc_streamon(fd.as_raw_fd(), &(queue as u32)) } {
39 Ok(_) => Ok(()),
40 Err(Errno::EINVAL) => Err(StreamOnError::InvalidQueue(queue)),
41 Err(Errno::EPIPE) => Err(StreamOnError::InvalidPadConfig),
42 Err(Errno::ENOLINK) => Err(StreamOnError::InvalidPipelineConfig),
43 Err(e) => Err(StreamOnError::IoctlError(e)),
44 }
45 }
46
47 #[derive(Debug, Error)]
48 pub enum StreamOffError {
49 #[error("queue type not supported")]
50 InvalidQueue,
51 #[error("ioctl error: {0}")]
52 IoctlError(Errno),
53 }
54
55 impl From<StreamOffError> for Errno {
from(err: StreamOffError) -> Self56 fn from(err: StreamOffError) -> Self {
57 match err {
58 StreamOffError::InvalidQueue => Errno::EINVAL,
59 StreamOffError::IoctlError(e) => e,
60 }
61 }
62 }
63
64 /// Safe wrapper around the `VIDIOC_STREAMOFF` ioctl.
streamoff(fd: &impl AsRawFd, queue: QueueType) -> Result<(), StreamOffError>65 pub fn streamoff(fd: &impl AsRawFd, queue: QueueType) -> Result<(), StreamOffError> {
66 match unsafe { ioctl::vidioc_streamoff(fd.as_raw_fd(), &(queue as u32)) } {
67 Ok(_) => Ok(()),
68 Err(Errno::EINVAL) => Err(StreamOffError::InvalidQueue),
69 Err(e) => Err(StreamOffError::IoctlError(e)),
70 }
71 }
72