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}