1use std::fs::OpenOptions;
2use std::os::fd::{AsFd, BorrowedFd, OwnedFd};
3use std::os::unix::fs::OpenOptionsExt;
4use std::path::{Path, PathBuf};
5
6use crate::error;
7use crate::MediaDeviceInfo;
8use crate::MediaTopology;
9use crate::Request;
10use crate::Version;
11
12#[derive(Debug)]
13pub struct Media {
14 info: MediaDeviceInfo,
15 path: PathBuf,
16 fd: OwnedFd,
17}
18
19impl Media {
20 pub fn from_path<P>(path: P) -> error::Result<Self>
21 where
22 P: AsRef<Path>,
23 {
24 let path = path.as_ref().to_path_buf();
25 let fd: OwnedFd = OpenOptions::new()
26 .read(true)
27 .write(true)
28 .custom_flags(libc::O_CLOEXEC)
29 .open(&path)
30 .map_err(|err| error::trap_io_error(err, path.clone()))?
31 .into();
32 let info = MediaDeviceInfo::from_fd(fd.as_fd())?;
33 Ok(Self { info, path, fd })
34 }
35
36 pub fn info(&self) -> &MediaDeviceInfo {
37 &self.info
38 }
39
40 pub fn media_version(&self) -> Version {
41 self.info.media_version()
42 }
43
44 pub fn path(&self) -> &Path {
45 &self.path
46 }
47
48 pub fn device_fd(&self) -> BorrowedFd<'_> {
49 self.fd.as_fd()
50 }
51
52 pub fn new_request(&self) -> error::Result<Request<'_>> {
53 Request::new(self.fd.as_fd())
54 }
55
56 pub fn new_topology(&self) -> error::Result<MediaTopology> {
57 MediaTopology::from_fd(self.info(), self.device_fd())
58 }
59}