ffmpeg_next_crossfix/util/frame/
audio.rs

1use std::mem;
2use std::ops::{Deref, DerefMut};
3use std::slice;
4
5use super::Frame;
6use ffi::*;
7use libc::{c_int, c_ulonglong};
8use util::format;
9use ChannelLayout;
10
11#[derive(PartialEq, Eq)]
12pub struct Audio(Frame);
13
14impl Audio {
15    #[inline(always)]
16    pub unsafe fn wrap(ptr: *mut AVFrame) -> Self {
17        Audio(Frame::wrap(ptr))
18    }
19
20    #[inline]
21    pub unsafe fn alloc(&mut self, format: format::Sample, samples: usize, layout: ChannelLayout) {
22        self.set_format(format);
23        self.set_samples(samples);
24        self.set_channel_layout(layout);
25
26        av_frame_get_buffer(self.as_mut_ptr(), 0);
27    }
28}
29
30impl Audio {
31    #[inline(always)]
32    pub fn empty() -> Self {
33        unsafe { Audio(Frame::empty()) }
34    }
35
36    #[inline]
37    pub fn new(format: format::Sample, samples: usize, layout: ChannelLayout) -> Self {
38        unsafe {
39            let mut frame = Audio::empty();
40            frame.alloc(format, samples, layout);
41
42            frame
43        }
44    }
45
46    #[inline]
47    pub fn format(&self) -> format::Sample {
48        unsafe {
49            if (*self.as_ptr()).format == -1 {
50                format::Sample::None
51            } else {
52                format::Sample::from(mem::transmute::<_, AVSampleFormat>((*self.as_ptr()).format))
53            }
54        }
55    }
56
57    #[inline]
58    pub fn set_format(&mut self, value: format::Sample) {
59        unsafe {
60            (*self.as_mut_ptr()).format = mem::transmute::<AVSampleFormat, c_int>(value.into());
61        }
62    }
63
64    #[inline]
65    pub fn channel_layout(&self) -> ChannelLayout {
66        unsafe {
67            ChannelLayout::from_bits_truncate(
68                av_frame_get_channel_layout(self.as_ptr()) as c_ulonglong
69            )
70        }
71    }
72
73    #[inline]
74    pub fn set_channel_layout(&mut self, value: ChannelLayout) {
75        unsafe {
76            av_frame_set_channel_layout(self.as_mut_ptr(), value.bits() as i64);
77        }
78    }
79
80    #[inline]
81    pub fn channels(&self) -> u16 {
82        unsafe { av_frame_get_channels(self.as_ptr()) as u16 }
83    }
84
85    #[inline]
86    pub fn set_channels(&mut self, value: u16) {
87        unsafe {
88            av_frame_set_channels(self.as_mut_ptr(), i32::from(value));
89        }
90    }
91
92    #[inline]
93    pub fn rate(&self) -> u32 {
94        unsafe { av_frame_get_sample_rate(self.as_ptr()) as u32 }
95    }
96
97    #[inline]
98    pub fn set_rate(&mut self, value: u32) {
99        unsafe {
100            av_frame_set_sample_rate(self.as_mut_ptr(), value as c_int);
101        }
102    }
103
104    #[inline]
105    pub fn samples(&self) -> usize {
106        unsafe { (*self.as_ptr()).nb_samples as usize }
107    }
108
109    #[inline]
110    pub fn set_samples(&mut self, value: usize) {
111        unsafe {
112            (*self.as_mut_ptr()).nb_samples = value as c_int;
113        }
114    }
115
116    #[inline]
117    pub fn is_planar(&self) -> bool {
118        self.format().is_planar()
119    }
120
121    #[inline]
122    pub fn is_packed(&self) -> bool {
123        self.format().is_packed()
124    }
125
126    #[inline]
127    pub fn planes(&self) -> usize {
128        unsafe {
129            if (*self.as_ptr()).linesize[0] == 0 {
130                return 0;
131            }
132        }
133
134        if self.is_packed() {
135            1
136        } else {
137            self.channels() as usize
138        }
139    }
140
141    #[inline]
142    pub fn plane<T: Sample>(&self, index: usize) -> &[T] {
143        if index >= self.planes() {
144            panic!("out of bounds");
145        }
146
147        if !<T as Sample>::is_valid(self.format(), self.channels()) {
148            panic!("unsupported type");
149        }
150
151        unsafe { slice::from_raw_parts((*self.as_ptr()).data[index] as *const T, self.samples()) }
152    }
153
154    #[inline]
155    pub fn plane_mut<T: Sample>(&mut self, index: usize) -> &mut [T] {
156        if index >= self.planes() {
157            panic!("out of bounds");
158        }
159
160        if !<T as Sample>::is_valid(self.format(), self.channels()) {
161            panic!("unsupported type");
162        }
163
164        unsafe {
165            slice::from_raw_parts_mut((*self.as_mut_ptr()).data[index] as *mut T, self.samples())
166        }
167    }
168
169    #[inline]
170    pub fn data(&self, index: usize) -> &[u8] {
171        if index >= self.planes() {
172            panic!("out of bounds");
173        }
174
175        unsafe {
176            slice::from_raw_parts(
177                (*self.as_ptr()).data[index],
178                (*self.as_ptr()).linesize[index] as usize,
179            )
180        }
181    }
182
183    #[inline]
184    pub fn data_mut(&mut self, index: usize) -> &mut [u8] {
185        if index >= self.planes() {
186            panic!("out of bounds");
187        }
188
189        unsafe {
190            slice::from_raw_parts_mut(
191                (*self.as_mut_ptr()).data[index],
192                (*self.as_ptr()).linesize[index] as usize,
193            )
194        }
195    }
196}
197
198impl Deref for Audio {
199    type Target = Frame;
200
201    fn deref(&self) -> &<Self as Deref>::Target {
202        &self.0
203    }
204}
205
206impl DerefMut for Audio {
207    fn deref_mut(&mut self) -> &mut <Self as Deref>::Target {
208        &mut self.0
209    }
210}
211
212impl ::std::fmt::Debug for Audio {
213    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
214        f.write_str("ffmpeg::frame::Audio { ")?;
215        f.write_str(&format!("format: {:?}, ", self.format()))?;
216        f.write_str(&format!("channels: {:?}, ", self.channels()))?;
217        f.write_str(&format!("rate: {:?}, ", self.rate()))?;
218        f.write_str(&format!("samples: {:?} ", self.samples()))?;
219        f.write_str("}")
220    }
221}
222
223impl Clone for Audio {
224    fn clone(&self) -> Self {
225        let mut cloned = Audio::new(self.format(), self.samples(), self.channel_layout());
226        cloned.clone_from(self);
227
228        cloned
229    }
230
231    fn clone_from(&mut self, source: &Self) {
232        unsafe {
233            av_frame_copy(self.as_mut_ptr(), source.as_ptr());
234            av_frame_copy_props(self.as_mut_ptr(), source.as_ptr());
235        }
236    }
237}
238
239impl From<Frame> for Audio {
240    fn from(frame: Frame) -> Self {
241        Audio(frame)
242    }
243}
244
245pub unsafe trait Sample {
246    fn is_valid(format: format::Sample, channels: u16) -> bool;
247}
248
249unsafe impl Sample for u8 {
250    #[inline(always)]
251    fn is_valid(format: format::Sample, _channels: u16) -> bool {
252        matches!(format, format::Sample::U8(..))
253    }
254}
255
256unsafe impl Sample for (u8, u8) {
257    #[inline(always)]
258    fn is_valid(format: format::Sample, channels: u16) -> bool {
259        channels == 2 && format == format::Sample::U8(format::sample::Type::Packed)
260    }
261}
262
263unsafe impl Sample for (u8, u8, u8) {
264    #[inline(always)]
265    fn is_valid(format: format::Sample, channels: u16) -> bool {
266        channels == 3 && format == format::Sample::U8(format::sample::Type::Packed)
267    }
268}
269
270unsafe impl Sample for (u8, u8, u8, u8) {
271    #[inline(always)]
272    fn is_valid(format: format::Sample, channels: u16) -> bool {
273        channels == 4 && format == format::Sample::U8(format::sample::Type::Packed)
274    }
275}
276
277unsafe impl Sample for (u8, u8, u8, u8, u8) {
278    #[inline(always)]
279    fn is_valid(format: format::Sample, channels: u16) -> bool {
280        channels == 5 && format == format::Sample::U8(format::sample::Type::Packed)
281    }
282}
283
284unsafe impl Sample for (u8, u8, u8, u8, u8, u8) {
285    #[inline(always)]
286    fn is_valid(format: format::Sample, channels: u16) -> bool {
287        channels == 6 && format == format::Sample::U8(format::sample::Type::Packed)
288    }
289}
290
291unsafe impl Sample for (u8, u8, u8, u8, u8, u8, u8) {
292    #[inline(always)]
293    fn is_valid(format: format::Sample, channels: u16) -> bool {
294        channels == 7 && format == format::Sample::U8(format::sample::Type::Packed)
295    }
296}
297
298unsafe impl Sample for i16 {
299    #[inline(always)]
300    fn is_valid(format: format::Sample, _channels: u16) -> bool {
301        matches!(format, format::Sample::I16(..))
302    }
303}
304
305unsafe impl Sample for (i16, i16) {
306    #[inline(always)]
307    fn is_valid(format: format::Sample, channels: u16) -> bool {
308        channels == 2 && format == format::Sample::I16(format::sample::Type::Packed)
309    }
310}
311
312unsafe impl Sample for (i16, i16, i16) {
313    #[inline(always)]
314    fn is_valid(format: format::Sample, channels: u16) -> bool {
315        channels == 3 && format == format::Sample::I16(format::sample::Type::Packed)
316    }
317}
318
319unsafe impl Sample for (i16, i16, i16, i16) {
320    #[inline(always)]
321    fn is_valid(format: format::Sample, channels: u16) -> bool {
322        channels == 4 && format == format::Sample::I16(format::sample::Type::Packed)
323    }
324}
325
326unsafe impl Sample for (i16, i16, i16, i16, i16) {
327    #[inline(always)]
328    fn is_valid(format: format::Sample, channels: u16) -> bool {
329        channels == 5 && format == format::Sample::I16(format::sample::Type::Packed)
330    }
331}
332
333unsafe impl Sample for (i16, i16, i16, i16, i16, i16) {
334    #[inline(always)]
335    fn is_valid(format: format::Sample, channels: u16) -> bool {
336        channels == 6 && format == format::Sample::I16(format::sample::Type::Packed)
337    }
338}
339
340unsafe impl Sample for (i16, i16, i16, i16, i16, i16, i16) {
341    #[inline(always)]
342    fn is_valid(format: format::Sample, channels: u16) -> bool {
343        channels == 7 && format == format::Sample::I16(format::sample::Type::Packed)
344    }
345}
346
347unsafe impl Sample for i32 {
348    #[inline(always)]
349    fn is_valid(format: format::Sample, _channels: u16) -> bool {
350        matches!(format, format::Sample::I32(..))
351    }
352}
353
354unsafe impl Sample for (i32, i32) {
355    #[inline(always)]
356    fn is_valid(format: format::Sample, channels: u16) -> bool {
357        channels == 2 && format == format::Sample::I32(format::sample::Type::Packed)
358    }
359}
360
361unsafe impl Sample for (i32, i32, i32) {
362    #[inline(always)]
363    fn is_valid(format: format::Sample, channels: u16) -> bool {
364        channels == 3 && format == format::Sample::I32(format::sample::Type::Packed)
365    }
366}
367
368unsafe impl Sample for (i32, i32, i32, i32) {
369    #[inline(always)]
370    fn is_valid(format: format::Sample, channels: u16) -> bool {
371        channels == 4 && format == format::Sample::I32(format::sample::Type::Packed)
372    }
373}
374
375unsafe impl Sample for (i32, i32, i32, i32, i32) {
376    #[inline(always)]
377    fn is_valid(format: format::Sample, channels: u16) -> bool {
378        channels == 5 && format == format::Sample::I32(format::sample::Type::Packed)
379    }
380}
381
382unsafe impl Sample for (i32, i32, i32, i32, i32, i32) {
383    #[inline(always)]
384    fn is_valid(format: format::Sample, channels: u16) -> bool {
385        channels == 6 && format == format::Sample::I32(format::sample::Type::Packed)
386    }
387}
388
389unsafe impl Sample for (i32, i32, i32, i32, i32, i32, i32) {
390    #[inline(always)]
391    fn is_valid(format: format::Sample, channels: u16) -> bool {
392        channels == 7 && format == format::Sample::I32(format::sample::Type::Packed)
393    }
394}
395
396unsafe impl Sample for f32 {
397    #[inline(always)]
398    fn is_valid(format: format::Sample, _channels: u16) -> bool {
399        matches!(format, format::Sample::F32(..))
400    }
401}
402
403unsafe impl Sample for (f32, f32) {
404    #[inline(always)]
405    fn is_valid(format: format::Sample, channels: u16) -> bool {
406        channels == 2 && format == format::Sample::F32(format::sample::Type::Packed)
407    }
408}
409
410unsafe impl Sample for (f32, f32, f32) {
411    #[inline(always)]
412    fn is_valid(format: format::Sample, channels: u16) -> bool {
413        channels == 3 && format == format::Sample::F32(format::sample::Type::Packed)
414    }
415}
416
417unsafe impl Sample for (f32, f32, f32, f32) {
418    #[inline(always)]
419    fn is_valid(format: format::Sample, channels: u16) -> bool {
420        channels == 4 && format == format::Sample::F32(format::sample::Type::Packed)
421    }
422}
423
424unsafe impl Sample for (f32, f32, f32, f32, f32) {
425    #[inline(always)]
426    fn is_valid(format: format::Sample, channels: u16) -> bool {
427        channels == 5 && format == format::Sample::F32(format::sample::Type::Packed)
428    }
429}
430
431unsafe impl Sample for (f32, f32, f32, f32, f32, f32) {
432    #[inline(always)]
433    fn is_valid(format: format::Sample, channels: u16) -> bool {
434        channels == 6 && format == format::Sample::F32(format::sample::Type::Packed)
435    }
436}
437
438unsafe impl Sample for (f32, f32, f32, f32, f32, f32, f32) {
439    #[inline(always)]
440    fn is_valid(format: format::Sample, channels: u16) -> bool {
441        channels == 7 && format == format::Sample::F32(format::sample::Type::Packed)
442    }
443}
444
445unsafe impl Sample for f64 {
446    #[inline(always)]
447    fn is_valid(format: format::Sample, _channels: u16) -> bool {
448        matches!(format, format::Sample::F64(..))
449    }
450}
451
452unsafe impl Sample for (f64, f64) {
453    #[inline(always)]
454    fn is_valid(format: format::Sample, channels: u16) -> bool {
455        channels == 2 && format == format::Sample::F64(format::sample::Type::Packed)
456    }
457}
458
459unsafe impl Sample for (f64, f64, f64) {
460    #[inline(always)]
461    fn is_valid(format: format::Sample, channels: u16) -> bool {
462        channels == 3 && format == format::Sample::F64(format::sample::Type::Packed)
463    }
464}
465
466unsafe impl Sample for (f64, f64, f64, f64) {
467    #[inline(always)]
468    fn is_valid(format: format::Sample, channels: u16) -> bool {
469        channels == 4 && format == format::Sample::F64(format::sample::Type::Packed)
470    }
471}
472
473unsafe impl Sample for (f64, f64, f64, f64, f64) {
474    #[inline(always)]
475    fn is_valid(format: format::Sample, channels: u16) -> bool {
476        channels == 5 && format == format::Sample::F64(format::sample::Type::Packed)
477    }
478}
479
480unsafe impl Sample for (f64, f64, f64, f64, f64, f64) {
481    #[inline(always)]
482    fn is_valid(format: format::Sample, channels: u16) -> bool {
483        channels == 6 && format == format::Sample::F64(format::sample::Type::Packed)
484    }
485}
486
487unsafe impl Sample for (f64, f64, f64, f64, f64, f64, f64) {
488    #[inline(always)]
489    fn is_valid(format: format::Sample, channels: u16) -> bool {
490        channels == 7 && format == format::Sample::F64(format::sample::Type::Packed)
491    }
492}