linux_video_core/impls/
format.rs1use crate::{calls, types::*, Internal, Result};
2use std::os::unix::io::RawFd;
3
4impl Internal<&mut Format> {
5 pub fn get(&mut self, fd: RawFd) -> Result<()> {
6 unsafe_call!(calls::g_fmt(fd, *self.as_mut() as *mut _)).map(|_| ())
7 }
8}
9
10impl Internal<&mut Format> {
11 pub fn set(&self, fd: RawFd) -> Result<()> {
12 unsafe_call!(calls::s_fmt(fd, *self.as_ref() as *const _ as *mut _)).map(|_| ())
13 }
14
15 pub fn try_(&self, fd: RawFd) -> Result<()> {
16 unsafe_call!(calls::try_fmt(fd, *self.as_ref() as *const _ as *mut _)).map(|_| ())
17 }
18}
19
20impl From<BufferType> for Format {
21 fn from(type_: BufferType) -> Self {
22 Self {
23 type_,
24 fmt: FormatUnion { raw_data: [0; 200] },
25 }
26 }
27}
28
29unsafe impl Send for Format {}
30
31impl Format {
32 pub fn new<T: IsFormatData>(type_: BufferType, data: T) -> Option<Self> {
34 if T::TYPES.contains(&type_) {
35 let mut this = Self::from(type_);
36 *this.try_mut().unwrap() = data;
37 Some(this)
38 } else {
39 None
40 }
41 }
42
43 pub fn try_ref<T: IsFormatData>(&self) -> Option<&T> {
45 if T::TYPES.contains(&self.type_()) {
46 Some(unsafe { &*(&self.fmt as *const _ as *const T) })
47 } else {
48 None
49 }
50 }
51
52 pub fn try_mut<T: IsFormatData>(&mut self) -> Option<&mut T> {
54 if T::TYPES.contains(&self.type_()) {
55 Some(unsafe { &mut *(&mut self.fmt as *mut _ as *mut T) })
56 } else {
57 None
58 }
59 }
60}
61
62pub trait IsFormatData {
64 const TYPES: &'static [BufferType];
66}
67
68macro_rules! format_impl {
69 ($($type:ty: $($buf_type:ident)*,)*) => {
70 $(
71 impl IsFormatData for $type {
72 const TYPES: &'static [BufferType] = &[ $(BufferType::$buf_type,)* ];
73 }
74 )*
75
76 impl core::fmt::Display for Format {
77 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
78 self.type_.fmt(f)?;
79 ": ".fmt(f)?;
80 match self.type_ {
81 $(
82 $(BufferType::$buf_type)|* => self.try_ref::<$type>()
83 .ok_or_else(Default::default)?.fmt(f),
84 )*
85 }
86 }
87 }
88 };
89}
90
91format_impl! {
92 PixFormat: VideoCapture VideoOutput,
93 VbiFormat: VbiCapture VbiOutput,
94 SlicedVbiFormat: SlicedVbiCapture SlicedVbiOutput,
95 Window: VideoOverlay VideoOutputOverlay,
96 PixFormatMplane: VideoCaptureMplane VideoOutputMplane,
97 SdrFormat: SdrCapture SdrOutput,
98 MetaFormat: MetaCapture MetaOutput,
99}
100
101impl core::fmt::Display for PixFormat {
102 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
103 self.width.fmt(f)?;
104 'x'.fmt(f)?;
105 self.height.fmt(f)?;
106 ' '.fmt(f)?;
107 self.pixel_format.fmt(f)?;
108 ' '.fmt(f)?;
109 self.field.fmt(f)?;
110 " #".fmt(f)?;
111 self.bytes_per_line.fmt(f)?;
112 '/'.fmt(f)?;
113 self.size_image.fmt(f)?;
114 ' '.fmt(f)?;
115 self.color_space.fmt(f)?;
116 ' '.fmt(f)?;
117 self.quantization.fmt(f)?;
119 ' '.fmt(f)?;
120 self.xfer_func.fmt(f)
121 }
122}
123
124impl PixFormatMplane {
125 pub fn plane_fmt(&self) -> &[PlanePixFormat] {
127 &self.plane_fmt[..self.num_planes as usize]
128 }
129
130 pub fn plane_fmt_mut(&mut self) -> &mut [PlanePixFormat] {
132 &mut self.plane_fmt[..self.num_planes as usize]
133 }
134}
135
136impl core::fmt::Display for PixFormatMplane {
137 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
138 self.width().fmt(f)?;
139 'x'.fmt(f)?;
140 self.height().fmt(f)?;
141 ' '.fmt(f)?;
142 self.pixel_format().fmt(f)?;
143 ' '.fmt(f)?;
144 self.field().fmt(f)?;
145 for plane in self.plane_fmt() {
146 " #".fmt(f)?;
147 plane.bytes_per_line().fmt(f)?;
148 '/'.fmt(f)?;
149 plane.size_image().fmt(f)?;
150 }
151 ' '.fmt(f)?;
152 self.color_space().fmt(f)?;
153 ' '.fmt(f)?;
154 self.quantization().fmt(f)?;
156 ' '.fmt(f)?;
157 self.xfer_func().fmt(f)
158 }
159}
160
161impl core::fmt::Display for SdrFormat {
162 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
163 self.pixel_format().fmt(f)?;
164 " #".fmt(f)?;
165 self.buffer_size().fmt(f)
166 }
167}
168
169impl core::fmt::Display for MetaFormat {
170 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
171 self.data_format().fmt(f)?;
172 " #".fmt(f)?;
173 self.buffer_size().fmt(f)
174 }
175}
176
177impl core::fmt::Display for Window {
178 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
179 self.w.fmt(f)?;
181 ' '.fmt(f)?;
182 self.field.fmt(f)?;
183 " !".fmt(f)?;
184 self.chromakey.fmt(f)
185 }
186}
187
188impl core::fmt::Display for VbiFormat {
189 fn fmt(&self, _f: &mut core::fmt::Formatter) -> core::fmt::Result {
190 todo!()
191 }
192}
193
194impl core::fmt::Display for SlicedVbiFormat {
195 fn fmt(&self, _f: &mut core::fmt::Formatter) -> core::fmt::Result {
196 todo!()
197 }
198}