playa_ffmpeg/util/frame/
audio.rs

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