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