ac_ffmpeg/codec/audio/frame/
mod.rs1#[cfg(not(channel_layout_v2))]
4mod channels_v1;
5
6#[cfg(channel_layout_v2)]
7mod channels_v2;
8
9use std::{
10 ffi::{CStr, CString},
11 fmt::{self, Display, Formatter},
12 marker::PhantomData,
13 ops::{Deref, DerefMut},
14 os::raw::{c_char, c_int, c_void},
15 ptr, slice,
16 str::FromStr,
17};
18
19use crate::time::{TimeBase, Timestamp};
20
21#[cfg(not(channel_layout_v2))]
22pub use channels_v1::{ChannelLayout, ChannelLayoutRef};
23
24#[cfg(channel_layout_v2)]
25pub use channels_v2::{ChannelLayout, ChannelLayoutRef};
26
27extern "C" {
28 fn ffw_get_sample_format_by_name(name: *const c_char) -> c_int;
29 fn ffw_get_sample_format_name(format: c_int) -> *const c_char;
30 fn ffw_sample_format_is_planar(format: c_int) -> c_int;
31 fn ffw_sample_format_is_none(format: c_int) -> c_int;
32
33 fn ffw_frame_new_silence(
34 channel_layout: *const c_void,
35 sample_fmt: c_int,
36 sample_rate: c_int,
37 nb_samples: c_int,
38 ) -> *mut c_void;
39 fn ffw_frame_get_format(frame: *const c_void) -> c_int;
40 fn ffw_frame_get_nb_samples(frame: *const c_void) -> c_int;
41 fn ffw_frame_get_sample_rate(frame: *const c_void) -> c_int;
42 fn ffw_frame_get_channel_layout(frame: *const c_void) -> *const c_void;
43 fn ffw_frame_get_pts(frame: *const c_void) -> i64;
44 fn ffw_frame_set_pts(frame: *mut c_void, pts: i64);
45 fn ffw_frame_get_plane_data(frame: *mut c_void, index: usize) -> *mut u8;
46 fn ffw_frame_get_line_size(frame: *const c_void, plane: usize) -> usize;
47 fn ffw_frame_clone(frame: *const c_void) -> *mut c_void;
48 fn ffw_frame_free(frame: *mut c_void);
49 fn ffw_frame_is_writable(frame: *const c_void) -> c_int;
50 fn ffw_frame_make_writable(frame: *mut c_void) -> c_int;
51}
52
53#[derive(Debug, Copy, Clone)]
55pub struct UnknownChannelLayout;
56
57impl Display for UnknownChannelLayout {
58 fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
59 f.write_str("unknown channel layout")
60 }
61}
62
63impl std::error::Error for UnknownChannelLayout {}
64
65pub fn get_channel_layout(name: &str) -> ChannelLayout {
67 ChannelLayout::from_str(name).unwrap()
68}
69
70#[derive(Debug, Copy, Clone)]
72pub struct UnknownSampleFormat;
73
74#[derive(Copy, Clone, Eq, PartialEq)]
76pub struct SampleFormat(c_int);
77
78impl SampleFormat {
79 pub(crate) fn from_raw(v: c_int) -> Self {
81 Self(v)
82 }
83
84 pub(crate) fn into_raw(self) -> c_int {
86 let Self(format) = self;
87
88 format
89 }
90
91 pub fn name(self) -> &'static str {
93 unsafe {
94 let ptr = ffw_get_sample_format_name(self.into_raw());
95
96 if ptr.is_null() {
97 panic!("invalid sample format");
98 }
99
100 let name = CStr::from_ptr(ptr as _);
101
102 name.to_str().unwrap()
103 }
104 }
105
106 pub fn is_planar(self) -> bool {
109 unsafe { ffw_sample_format_is_planar(self.into_raw()) != 0 }
110 }
111}
112
113impl FromStr for SampleFormat {
114 type Err = UnknownSampleFormat;
115
116 fn from_str(s: &str) -> Result<Self, Self::Err> {
117 let name = CString::new(s).expect("invalid sample format name");
118
119 unsafe {
120 let format = ffw_get_sample_format_by_name(name.as_ptr() as _);
121
122 if ffw_sample_format_is_none(format) == 0 {
123 Ok(Self(format))
124 } else {
125 Err(UnknownSampleFormat)
126 }
127 }
128 }
129}
130
131pub fn get_sample_format(name: &str) -> SampleFormat {
133 SampleFormat::from_str(name).unwrap()
134}
135
136pub struct Plane<'a> {
140 frame: *mut c_void,
141 index: usize,
142 line_size: usize,
143 phantom: PhantomData<&'a ()>,
144}
145
146impl Plane<'_> {
147 fn new(frame: *mut c_void, index: usize, line_size: usize) -> Self {
149 Self {
150 frame,
151 index,
152 line_size,
153 phantom: PhantomData,
154 }
155 }
156
157 pub fn data(&self) -> &[u8] {
159 unsafe {
160 let data = ffw_frame_get_plane_data(self.frame, self.index as _);
161 slice::from_raw_parts(data, self.line_size)
162 }
163 }
164
165 pub fn data_mut(&mut self) -> &mut [u8] {
167 unsafe {
168 let data = ffw_frame_get_plane_data(self.frame, self.index as _);
169 slice::from_raw_parts_mut(data, self.line_size)
170 }
171 }
172}
173
174fn get_audio_planes<'a>(
176 frame: *mut c_void,
177 sample_format: SampleFormat,
178 channels: usize,
179) -> Vec<Plane<'a>> {
180 let line_size = unsafe { ffw_frame_get_line_size(frame, 0) as _ };
181
182 let mut inner = Vec::new();
183
184 if sample_format.is_planar() {
185 for i in 0..channels {
186 inner.push(Plane::new(frame, i, line_size));
187 }
188 } else {
189 inner.push(Plane::new(frame, 0, line_size));
190 }
191
192 inner
193}
194
195pub struct Planes<'a> {
200 inner: Vec<Plane<'a>>,
201}
202
203impl<'a> From<&'a AudioFrame> for Planes<'a> {
204 fn from(frame: &'a AudioFrame) -> Self {
205 let sample_format = frame.sample_format();
206 let channel_layout = frame.channel_layout();
207
208 Self {
209 inner: get_audio_planes(frame.ptr, sample_format, channel_layout.channels() as _),
210 }
211 }
212}
213
214impl<'a> From<&'a AudioFrameMut> for Planes<'a> {
215 fn from(frame: &'a AudioFrameMut) -> Self {
216 let sample_format = frame.sample_format();
217 let channel_layout = frame.channel_layout();
218
219 Self {
220 inner: get_audio_planes(frame.ptr, sample_format, channel_layout.channels() as _),
221 }
222 }
223}
224
225impl<'a> Deref for Planes<'a> {
226 type Target = [Plane<'a>];
227
228 #[inline]
229 fn deref(&self) -> &Self::Target {
230 &self.inner
231 }
232}
233
234pub struct PlanesMut<'a> {
236 inner: Vec<Plane<'a>>,
237}
238
239impl<'a> From<&'a mut AudioFrameMut> for PlanesMut<'a> {
240 fn from(frame: &'a mut AudioFrameMut) -> Self {
241 let sample_format = frame.sample_format();
242 let channel_layout = frame.channel_layout();
243
244 Self {
245 inner: get_audio_planes(frame.ptr, sample_format, channel_layout.channels() as _),
246 }
247 }
248}
249
250impl<'a> Deref for PlanesMut<'a> {
251 type Target = [Plane<'a>];
252
253 #[inline]
254 fn deref(&self) -> &Self::Target {
255 &self.inner
256 }
257}
258
259impl DerefMut for PlanesMut<'_> {
260 #[inline]
261 fn deref_mut(&mut self) -> &mut Self::Target {
262 &mut self.inner
263 }
264}
265
266pub struct AudioFrameMut {
268 ptr: *mut c_void,
269 time_base: TimeBase,
270}
271
272impl AudioFrameMut {
273 pub fn silence(
276 channel_layout: &ChannelLayoutRef,
277 sample_format: SampleFormat,
278 sample_rate: u32,
279 samples: usize,
280 ) -> Self {
281 let ptr = unsafe {
282 ffw_frame_new_silence(
283 channel_layout.as_ptr(),
284 sample_format.into_raw(),
285 sample_rate as _,
286 samples as _,
287 )
288 };
289
290 if ptr.is_null() {
291 panic!("unable to allocate an audio frame");
292 }
293
294 Self {
295 ptr,
296 time_base: TimeBase::MICROSECONDS,
297 }
298 }
299
300 pub fn sample_format(&self) -> SampleFormat {
302 unsafe { SampleFormat::from_raw(ffw_frame_get_format(self.ptr)) }
303 }
304
305 pub fn sample_rate(&self) -> u32 {
307 unsafe { ffw_frame_get_sample_rate(self.ptr) as _ }
308 }
309
310 pub fn samples(&self) -> usize {
312 unsafe { ffw_frame_get_nb_samples(self.ptr) as _ }
313 }
314
315 #[inline]
317 pub fn planes(&self) -> Planes {
318 Planes::from(self)
319 }
320
321 #[inline]
323 pub fn planes_mut(&mut self) -> PlanesMut {
324 PlanesMut::from(self)
325 }
326
327 pub fn channel_layout(&self) -> &ChannelLayoutRef {
329 unsafe { ChannelLayoutRef::from_raw_ptr(ffw_frame_get_channel_layout(self.ptr)) }
330 }
331
332 #[inline]
334 pub fn time_base(&self) -> TimeBase {
335 self.time_base
336 }
337
338 pub fn with_time_base(mut self, time_base: TimeBase) -> Self {
341 let new_pts = self.pts().with_time_base(time_base);
342
343 unsafe {
344 ffw_frame_set_pts(self.ptr, new_pts.timestamp());
345 }
346
347 self.time_base = time_base;
348
349 self
350 }
351
352 pub fn pts(&self) -> Timestamp {
354 let pts = unsafe { ffw_frame_get_pts(self.ptr) };
355
356 Timestamp::new(pts, self.time_base)
357 }
358
359 pub fn with_pts(self, pts: Timestamp) -> Self {
361 let pts = pts.with_time_base(self.time_base);
362
363 unsafe { ffw_frame_set_pts(self.ptr, pts.timestamp()) }
364
365 self
366 }
367
368 #[inline]
370 pub fn freeze(mut self) -> AudioFrame {
371 let ptr = self.ptr;
372
373 self.ptr = ptr::null_mut();
374
375 AudioFrame {
376 ptr,
377 time_base: self.time_base,
378 }
379 }
380}
381
382impl Drop for AudioFrameMut {
383 fn drop(&mut self) {
384 unsafe { ffw_frame_free(self.ptr) }
385 }
386}
387
388unsafe impl Send for AudioFrameMut {}
389unsafe impl Sync for AudioFrameMut {}
390
391pub struct AudioFrame {
393 ptr: *mut c_void,
394 time_base: TimeBase,
395}
396
397impl AudioFrame {
398 pub(crate) unsafe fn from_raw_ptr(ptr: *mut c_void, time_base: TimeBase) -> Self {
400 AudioFrame { ptr, time_base }
401 }
402
403 pub fn sample_format(&self) -> SampleFormat {
405 unsafe { SampleFormat::from_raw(ffw_frame_get_format(self.ptr)) }
406 }
407
408 pub fn sample_rate(&self) -> u32 {
410 unsafe { ffw_frame_get_sample_rate(self.ptr) as _ }
411 }
412
413 pub fn samples(&self) -> usize {
415 unsafe { ffw_frame_get_nb_samples(self.ptr) as _ }
416 }
417
418 #[inline]
420 pub fn planes(&self) -> Planes {
421 Planes::from(self)
422 }
423
424 pub fn channel_layout(&self) -> &ChannelLayoutRef {
426 unsafe { ChannelLayoutRef::from_raw_ptr(ffw_frame_get_channel_layout(self.ptr)) }
427 }
428
429 #[inline]
431 pub fn time_base(&self) -> TimeBase {
432 self.time_base
433 }
434
435 pub fn with_time_base(mut self, time_base: TimeBase) -> Self {
438 let new_pts = self.pts().with_time_base(time_base);
439
440 unsafe {
441 ffw_frame_set_pts(self.ptr, new_pts.timestamp());
442 }
443
444 self.time_base = time_base;
445
446 self
447 }
448
449 pub fn pts(&self) -> Timestamp {
451 let pts = unsafe { ffw_frame_get_pts(self.ptr) };
452
453 Timestamp::new(pts, self.time_base)
454 }
455
456 pub fn with_pts(self, pts: Timestamp) -> Self {
458 let pts = pts.with_time_base(self.time_base);
459
460 unsafe { ffw_frame_set_pts(self.ptr, pts.timestamp()) }
461
462 self
463 }
464
465 pub(crate) fn as_ptr(&self) -> *const c_void {
467 self.ptr
468 }
469
470 pub fn try_into_mut(self) -> Result<AudioFrameMut, AudioFrame> {
473 let res = unsafe { ffw_frame_is_writable(self.ptr) };
474 if res > 0 {
475 Ok(self.into_mut())
476 } else {
477 Err(self)
478 }
479 }
480
481 pub fn into_mut(mut self) -> AudioFrameMut {
484 let res = unsafe { ffw_frame_make_writable(self.ptr) };
485
486 if res < 0 {
487 panic!("unable to make the frame mutable");
488 }
489
490 let ptr = self.ptr;
491
492 self.ptr = ptr::null_mut();
493
494 AudioFrameMut {
495 ptr,
496 time_base: self.time_base,
497 }
498 }
499}
500
501impl Clone for AudioFrame {
502 fn clone(&self) -> Self {
503 let ptr = unsafe { ffw_frame_clone(self.ptr) };
504
505 if ptr.is_null() {
506 panic!("unable to clone a frame");
507 }
508
509 Self {
510 ptr,
511 time_base: self.time_base,
512 }
513 }
514}
515
516impl Drop for AudioFrame {
517 fn drop(&mut self) {
518 unsafe { ffw_frame_free(self.ptr) }
519 }
520}
521
522unsafe impl Send for AudioFrame {}
523unsafe impl Sync for AudioFrame {}