Skip to main content

ffmpeg_the_third/util/frame/
audio.rs

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