1use crate::ffi::*;
2
3#[repr(transparent)]
4#[derive(Copy, Clone)]
5pub struct ChannelLayout(pub AVChannelLayout);
6
7impl PartialEq for ChannelLayout {
8 fn eq(&self, other: &Self) -> bool {
10 unsafe { av_channel_layout_compare(&self.0 as *const AVChannelLayout, &other.0 as *const AVChannelLayout) == 0 }
11 }
12}
13impl Eq for ChannelLayout {}
14
15impl std::fmt::Debug for ChannelLayout {
16 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
17 let mut s = fmt.debug_struct("ChannelLayout");
18 s.field("is_empty", &self.is_empty());
19 s.field("channels", &self.channels());
20 s.field("u.mask", &unsafe { self.0.u.mask });
21 s.finish()
22 }
23}
24
25macro_rules! define_layout {
26 ($name:ident, $nb:expr, $mask:expr) => {
27 pub const $name: ChannelLayout = ChannelLayout(AVChannelLayout { order: AVChannelOrder::AV_CHANNEL_ORDER_NATIVE, nb_channels: $nb, u: AVChannelLayout__bindgen_ty_1 { mask: $mask }, opaque: std::ptr::null_mut() });
28 };
29}
30
31impl ChannelLayout {
32 define_layout!(MONO, 1, AV_CH_LAYOUT_MONO);
33 define_layout!(STEREO, 2, AV_CH_LAYOUT_STEREO);
34 define_layout!(_2POINT1, 3, AV_CH_LAYOUT_2POINT1);
35 define_layout!(_2_1, 3, AV_CH_LAYOUT_2_1);
36 define_layout!(SURROUND, 3, AV_CH_LAYOUT_SURROUND);
37 define_layout!(_3POINT1, 4, AV_CH_LAYOUT_3POINT1);
38 define_layout!(_4POINT0, 4, AV_CH_LAYOUT_4POINT0);
39 define_layout!(_4POINT1, 5, AV_CH_LAYOUT_4POINT1);
40 define_layout!(_2_2, 4, AV_CH_LAYOUT_2_2);
41 define_layout!(QUAD, 4, AV_CH_LAYOUT_QUAD);
42 define_layout!(_5POINT0, 5, AV_CH_LAYOUT_5POINT0);
43 define_layout!(_5POINT1, 6, AV_CH_LAYOUT_5POINT1);
44 define_layout!(_5POINT0_BACK, 5, AV_CH_LAYOUT_5POINT0_BACK);
45 define_layout!(_5POINT1_BACK, 6, AV_CH_LAYOUT_5POINT1_BACK);
46 define_layout!(_6POINT0, 6, AV_CH_LAYOUT_6POINT0);
47 define_layout!(_6POINT0_FRONT, 6, AV_CH_LAYOUT_6POINT0_FRONT);
48 define_layout!(_3POINT1POINT2, 6, AV_CH_LAYOUT_3POINT1POINT2);
49 define_layout!(HEXAGONAL, 6, AV_CH_LAYOUT_HEXAGONAL);
50 define_layout!(_6POINT1, 7, AV_CH_LAYOUT_6POINT1);
51 define_layout!(_6POINT1_BACK, 7, AV_CH_LAYOUT_6POINT1_BACK);
52 define_layout!(_6POINT1_FRONT, 7, AV_CH_LAYOUT_6POINT1_FRONT);
53 define_layout!(_7POINT0, 7, AV_CH_LAYOUT_7POINT0);
54 define_layout!(_7POINT0_FRONT, 7, AV_CH_LAYOUT_7POINT0_FRONT);
55 define_layout!(_7POINT1, 8, AV_CH_LAYOUT_7POINT1);
56 define_layout!(_7POINT1_WIDE, 8, AV_CH_LAYOUT_7POINT1_WIDE);
57 define_layout!(_7POINT1_WIDE_BACK, 8, AV_CH_LAYOUT_7POINT1_WIDE_BACK);
58 define_layout!(_5POINT1POINT2_BACK, 8, AV_CH_LAYOUT_5POINT1POINT2_BACK);
59 define_layout!(OCTAGONAL, 8, AV_CH_LAYOUT_OCTAGONAL);
60 define_layout!(CUBE, 8, AV_CH_LAYOUT_CUBE);
61 define_layout!(_5POINT1POINT4_BACK, 10, AV_CH_LAYOUT_5POINT1POINT4_BACK);
62 define_layout!(_7POINT1POINT2, 10, AV_CH_LAYOUT_7POINT1POINT2);
63 define_layout!(_7POINT1POINT4_BACK, 12, AV_CH_LAYOUT_7POINT1POINT4_BACK);
64 define_layout!(_7POINT2POINT3, 12, AV_CH_LAYOUT_7POINT2POINT3);
65 define_layout!(_9POINT1POINT4_BACK, 14, AV_CH_LAYOUT_9POINT1POINT4_BACK);
66 define_layout!(HEXADECAGONAL, 16, AV_CH_LAYOUT_HEXADECAGONAL);
67 define_layout!(STEREO_DOWNMIX, 2, AV_CH_LAYOUT_STEREO_DOWNMIX);
68 define_layout!(_22POINT2, 24, AV_CH_LAYOUT_22POINT2);
69 define_layout!(_7POINT1_TOP_BACK, 8, AV_CH_LAYOUT_5POINT1POINT2_BACK);
70
71 #[inline]
72 pub fn channels(&self) -> i32 {
73 self.0.nb_channels
74 }
75
76 #[inline]
77 pub fn bits(&self) -> u64 {
78 unsafe { self.0.u.mask }
79 }
80
81 pub fn default(number: i32) -> ChannelLayout {
82 unsafe {
83 let mut channel_layout = std::mem::zeroed();
84 av_channel_layout_default(&mut channel_layout, number);
85 ChannelLayout(channel_layout)
86 }
87 }
88
89 pub fn is_empty(&self) -> bool {
92 self.0.order == AVChannelOrder::AV_CHANNEL_ORDER_UNSPEC
93 }
94}
95
96impl From<AVChannelLayout> for ChannelLayout {
97 fn from(value: AVChannelLayout) -> Self {
98 Self(value)
99 }
100}
101
102impl From<ChannelLayout> for AVChannelLayout {
103 fn from(value: ChannelLayout) -> Self {
104 value.0
105 }
106}