Skip to main content

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