1use bitflags::bitflags;
2
3use crate::CapabilityFlags;
4
5macro_rules! buf_types {
6 (
7 $( $(#[$($attr:tt)+])* $name:ident = $value:literal, )+
8 ) => {
9 ffi_enum! {
10 pub enum BufType: u32 { $( $(#[$($attr)+])* $name = $value, )+
13 }
14 }
15
16 impl BufType {
17 const ALL: &'static [Self] = &[
18 $( Self::$name, )+
19 ];
20 }
21
22 bitflags! {
23 pub struct BufTypes: u32 {
25 $( $(#[$($attr)+])* const $name = 1 << $value; )+
26 }
27 }
28
29 impl BufTypes {
30 const CAPS: &'static [CapabilityFlags] = &[
31 $( CapabilityFlags::$name, )+
32 ];
33 }
34 };
35}
36
37buf_types! {
38 VIDEO_CAPTURE = 1,
40 VIDEO_OUTPUT = 2,
42 VIDEO_OVERLAY = 3,
43 VBI_CAPTURE = 4,
44 VBI_OUTPUT = 5,
45 SLICED_VBI_CAPTURE = 6,
46 SLICED_VBI_OUTPUT = 7,
47 VIDEO_OUTPUT_OVERLAY = 8,
48 VIDEO_CAPTURE_MPLANE = 9,
49 VIDEO_OUTPUT_MPLANE = 10,
50 SDR_CAPTURE = 11,
51 SDR_OUTPUT = 12,
52 META_CAPTURE = 13,
54 META_OUTPUT = 14,
56}
57
58impl BufTypes {
59 pub(crate) fn from_capabilities(caps: CapabilityFlags) -> Self {
60 let mut buf_types = BufTypes::empty();
61 for (i, cap) in Self::CAPS.iter().enumerate() {
62 if caps.contains(*cap) {
63 buf_types |= BufTypes::from_bits(1 << (i + 1)).unwrap();
64 }
65 }
66
67 buf_types
68 }
69}
70
71impl IntoIterator for BufTypes {
72 type Item = BufType;
73 type IntoIter = BufTypesIter;
74
75 fn into_iter(self) -> Self::IntoIter {
76 BufTypesIter {
77 buf_types: self,
78 index: 0,
79 }
80 }
81}
82
83pub struct BufTypesIter {
85 buf_types: BufTypes,
86 index: u32,
87}
88
89impl Iterator for BufTypesIter {
90 type Item = BufType;
91
92 fn next(&mut self) -> Option<Self::Item> {
93 loop {
94 self.index += 1;
95
96 if self
97 .buf_types
98 .contains(BufTypes::from_bits(1 << self.index)?)
99 {
100 return Some(BufType::ALL[self.index as usize - 1]);
101 }
102 }
103 }
104}