linux_video_core/impls/
format.rs

1use 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    /// Create from value
33    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    /// Get reference to value
44    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    /// Get mutable reference to value
53    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
62/// Format data types
63pub trait IsFormatData {
64    /// Buffer types which corresponds to format type
65    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        // TODO: union
118        self.quantization.fmt(f)?;
119        ' '.fmt(f)?;
120        self.xfer_func.fmt(f)
121    }
122}
123
124impl PixFormatMplane {
125    /// Plane formats
126    pub fn plane_fmt(&self) -> &[PlanePixFormat] {
127        &self.plane_fmt[..self.num_planes as usize]
128    }
129
130    /// Plane formats
131    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        // TODO: union
155        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        // TODO:
180        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}