linux_media/
media_entity_desc.rs1use std::ffi::CStr;
2use std::os::fd::{AsRawFd, BorrowedFd};
3
4use linux_media_sys as media;
5use serde::{Deserialize, Serialize};
6
7use crate::error;
8use crate::ioctl;
9use crate::{EntityId, MediaEntity, MediaEntityFlags, MediaEntityFunctions, Version};
10
11#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Serialize, Deserialize)]
12pub struct MediaEntityDesc {
13 pub id: EntityId,
15 pub name: String,
17 pub r#type: MediaEntityFunctions,
19 pub flags: MediaEntityFlags,
21 pub pads: usize,
23 pub links: usize,
26}
27
28impl MediaEntityDesc {
29 pub fn from_fd<F>(fd: F, entity: EntityId) -> error::Result<Self>
30 where
31 F: AsRawFd,
32 {
33 unsafe {
34 let mut desc: media::media_entity_desc = std::mem::zeroed();
35 desc.id = entity.into();
36 ioctl!(fd, media::MEDIA_IOC_ENUM_ENTITIES, &mut desc)?;
37 Ok(desc.into())
38 }
39 }
40
41 pub fn id(&self) -> EntityId {
42 self.id
43 }
44
45 pub fn name(&self) -> &str {
46 &self.name
47 }
48
49 pub fn r#type(&self) -> MediaEntityFunctions {
50 self.r#type.clone()
51 }
52
53 pub fn flags(&self) -> MediaEntityFlags {
54 self.flags
55 }
56
57 pub fn pads(&self) -> usize {
58 self.pads
59 }
60
61 pub fn links(&self) -> usize {
62 self.links
63 }
64}
65
66impl From<media::media_entity_desc> for MediaEntityDesc {
67 fn from(desc: media::media_entity_desc) -> Self {
68 Self {
69 id: desc.id.into(),
70 name: unsafe {
71 CStr::from_ptr(desc.name.as_ptr())
72 .to_string_lossy()
73 .to_string()
74 },
75 r#type: desc.type_.try_into().unwrap(),
76 flags: desc.flags.try_into().unwrap(),
77 pads: desc.pads.try_into().unwrap(),
78 links: desc.links.try_into().unwrap(),
79 }
80 }
81}
82
83#[derive(Debug)]
89pub struct MediaEntityIter<'a> {
90 fd: BorrowedFd<'a>,
91 media_version: Version,
92 id: EntityId,
93 desc: Option<MediaEntityDesc>,
95}
96
97impl<'a> MediaEntityIter<'a> {
98 pub fn new(fd: BorrowedFd<'a>, media_version: Version, id: EntityId) -> Self {
99 Self {
100 fd,
101 media_version,
102 id,
103 desc: Self::desc(fd, id),
104 }
105 }
106
107 fn desc(fd: BorrowedFd<'_>, id: EntityId) -> Option<MediaEntityDesc> {
108 unsafe {
109 let mut desc: media::media_entity_desc = std::mem::zeroed();
110 desc.id = Into::<u32>::into(id);
111 if ioctl!(fd, media::MEDIA_IOC_ENUM_ENTITIES, &mut desc).is_ok() {
112 Some(desc.into())
113 } else {
114 None
115 }
116 }
117 }
118}
119
120impl<'a> Iterator for MediaEntityIter<'a> {
121 type Item = MediaEntity;
122 fn next(&mut self) -> Option<Self::Item> {
123 match self.desc.clone() {
124 Some(desc) => {
125 let entity = MediaEntity::from_desc(self.media_version, desc);
126 if let Some(desc) =
127 Self::desc(self.fd, self.id | media::MEDIA_ENT_ID_FLAG_NEXT.into())
128 {
129 self.id = desc.id.into();
130 self.desc = Some(desc);
131 } else {
132 self.desc = None;
133 }
134 Some(entity)
135 }
136 None => None,
137 }
138 }
139}