1 | use std::ops::Deref; |
2 | |
3 | use super::codec::Codec; |
4 | use ffi::*; |
5 | use {format, ChannelLayout}; |
6 | |
7 | #[derive (PartialEq, Eq, Copy, Clone)] |
8 | pub struct Audio { |
9 | codec: Codec, |
10 | } |
11 | |
12 | impl Audio { |
13 | pub unsafe fn new(codec: Codec) -> Audio { |
14 | Audio { codec } |
15 | } |
16 | } |
17 | |
18 | impl Audio { |
19 | pub fn rates(&self) -> Option<RateIter> { |
20 | unsafe { |
21 | if (*self.as_ptr()).supported_samplerates.is_null() { |
22 | None |
23 | } else { |
24 | Some(RateIter::new((*self.codec.as_ptr()).supported_samplerates)) |
25 | } |
26 | } |
27 | } |
28 | |
29 | pub fn formats(&self) -> Option<FormatIter> { |
30 | unsafe { |
31 | if (*self.codec.as_ptr()).sample_fmts.is_null() { |
32 | None |
33 | } else { |
34 | Some(FormatIter::new((*self.codec.as_ptr()).sample_fmts)) |
35 | } |
36 | } |
37 | } |
38 | |
39 | pub fn channel_layouts(&self) -> Option<ChannelLayoutIter> { |
40 | unsafe { |
41 | #[cfg (not(feature = "ffmpeg_7_0" ))] |
42 | let ptr = (*self.codec.as_ptr()).channel_layouts; |
43 | |
44 | #[cfg (feature = "ffmpeg_7_0" )] |
45 | let ptr = (*self.codec.as_ptr()).ch_layouts; |
46 | |
47 | if ptr.is_null() { |
48 | None |
49 | } else { |
50 | Some(ChannelLayoutIter::new(ptr)) |
51 | } |
52 | } |
53 | } |
54 | } |
55 | |
56 | impl Deref for Audio { |
57 | type Target = Codec; |
58 | |
59 | fn deref(&self) -> &Self::Target { |
60 | &self.codec |
61 | } |
62 | } |
63 | |
64 | pub struct RateIter { |
65 | ptr: *const i32, |
66 | } |
67 | |
68 | impl RateIter { |
69 | pub fn new(ptr: *const i32) -> Self { |
70 | RateIter { ptr } |
71 | } |
72 | } |
73 | |
74 | impl Iterator for RateIter { |
75 | type Item = i32; |
76 | |
77 | fn next(&mut self) -> Option<<Self as Iterator>::Item> { |
78 | unsafe { |
79 | if *self.ptr == 0 { |
80 | return None; |
81 | } |
82 | |
83 | let rate: i32 = *self.ptr; |
84 | self.ptr = self.ptr.offset(count:1); |
85 | |
86 | Some(rate) |
87 | } |
88 | } |
89 | } |
90 | |
91 | pub struct FormatIter { |
92 | ptr: *const AVSampleFormat, |
93 | } |
94 | |
95 | impl FormatIter { |
96 | pub fn new(ptr: *const AVSampleFormat) -> Self { |
97 | FormatIter { ptr } |
98 | } |
99 | } |
100 | |
101 | impl Iterator for FormatIter { |
102 | type Item = format::Sample; |
103 | |
104 | fn next(&mut self) -> Option<<Self as Iterator>::Item> { |
105 | unsafe { |
106 | if *self.ptr == AVSampleFormat::AV_SAMPLE_FMT_NONE { |
107 | return None; |
108 | } |
109 | |
110 | let format: Sample = (*self.ptr).into(); |
111 | self.ptr = self.ptr.offset(count:1); |
112 | |
113 | Some(format) |
114 | } |
115 | } |
116 | } |
117 | |
118 | #[cfg (not(feature = "ffmpeg_7_0" ))] |
119 | type ChannelLayoutType = u64; |
120 | #[cfg (feature = "ffmpeg_7_0" )] |
121 | type ChannelLayoutType = AVChannelLayout; |
122 | |
123 | pub struct ChannelLayoutIter { |
124 | ptr: *const ChannelLayoutType, |
125 | } |
126 | |
127 | impl ChannelLayoutIter { |
128 | pub fn new(ptr: *const ChannelLayoutType) -> Self { |
129 | ChannelLayoutIter { ptr } |
130 | } |
131 | |
132 | pub fn best(self, max: i32) -> ChannelLayout { |
133 | self.fold(init:ChannelLayout::MONO, |acc: ChannelLayout, cur: ChannelLayout| { |
134 | if cur.channels() > acc.channels() && cur.channels() <= max as _ { |
135 | cur |
136 | } else { |
137 | acc |
138 | } |
139 | }) |
140 | } |
141 | } |
142 | |
143 | impl Iterator for ChannelLayoutIter { |
144 | type Item = ChannelLayout; |
145 | |
146 | fn next(&mut self) -> Option<<Self as Iterator>::Item> { |
147 | unsafe { |
148 | #[cfg (not(feature = "ffmpeg_7_0" ))] |
149 | if *self.ptr == 0 { |
150 | return None; |
151 | } |
152 | |
153 | #[cfg (feature = "ffmpeg_7_0" )] |
154 | if self.ptr.is_null() || (*self.ptr).u.mask == 0 { |
155 | return None; |
156 | } |
157 | |
158 | #[cfg (not(feature = "ffmpeg_7_0" ))] |
159 | let layout = ChannelLayout::from_bits_truncate(*self.ptr); |
160 | |
161 | #[cfg (feature = "ffmpeg_7_0" )] |
162 | let layout = ChannelLayout::from(*self.ptr); |
163 | |
164 | self.ptr = self.ptr.offset(1); |
165 | |
166 | Some(layout) |
167 | } |
168 | } |
169 | } |
170 | |