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