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