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