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 fn deref(&self) -> &Self::Target {
229 &self.inner
230 }
231}
232
233pub struct PlanesMut<'a> {
235 inner: Vec<Plane<'a>>,
236}
237
238impl<'a> From<&'a mut AudioFrameMut> for PlanesMut<'a> {
239 fn from(frame: &'a mut AudioFrameMut) -> Self {
240 let sample_format = frame.sample_format();
241 let channel_layout = frame.channel_layout();
242
243 Self {
244 inner: get_audio_planes(frame.ptr, sample_format, channel_layout.channels() as _),
245 }
246 }
247}
248
249impl<'a> Deref for PlanesMut<'a> {
250 type Target = [Plane<'a>];
251
252 fn deref(&self) -> &Self::Target {
253 &self.inner
254 }
255}
256
257impl<'a> DerefMut for PlanesMut<'a> {
258 fn deref_mut(&mut self) -> &mut Self::Target {
259 &mut self.inner
260 }
261}
262
263pub struct AudioFrameMut {
265 ptr: *mut c_void,
266 time_base: TimeBase,
267}
268
269impl AudioFrameMut {
270 pub fn silence(
273 channel_layout: &ChannelLayoutRef,
274 sample_format: SampleFormat,
275 sample_rate: u32,
276 samples: usize,
277 ) -> Self {
278 let ptr = unsafe {
279 ffw_frame_new_silence(
280 channel_layout.as_ptr(),
281 sample_format.into_raw(),
282 sample_rate as _,
283 samples as _,
284 )
285 };
286
287 if ptr.is_null() {
288 panic!("unable to allocate an audio frame");
289 }
290
291 Self {
292 ptr,
293 time_base: TimeBase::MICROSECONDS,
294 }
295 }
296
297 pub fn sample_format(&self) -> SampleFormat {
299 unsafe { SampleFormat::from_raw(ffw_frame_get_format(self.ptr)) }
300 }
301
302 pub fn sample_rate(&self) -> u32 {
304 unsafe { ffw_frame_get_sample_rate(self.ptr) as _ }
305 }
306
307 pub fn samples(&self) -> usize {
309 unsafe { ffw_frame_get_nb_samples(self.ptr) as _ }
310 }
311
312 pub fn planes(&self) -> Planes {
314 Planes::from(self)
315 }
316
317 pub fn planes_mut(&mut self) -> PlanesMut {
319 PlanesMut::from(self)
320 }
321
322 pub fn channel_layout(&self) -> &ChannelLayoutRef {
324 unsafe { ChannelLayoutRef::from_raw_ptr(ffw_frame_get_channel_layout(self.ptr)) }
325 }
326
327 pub fn time_base(&self) -> TimeBase {
329 self.time_base
330 }
331
332 pub fn with_time_base(mut self, time_base: TimeBase) -> Self {
335 let new_pts = self.pts().with_time_base(time_base);
336
337 unsafe {
338 ffw_frame_set_pts(self.ptr, new_pts.timestamp());
339 }
340
341 self.time_base = time_base;
342
343 self
344 }
345
346 pub fn pts(&self) -> Timestamp {
348 let pts = unsafe { ffw_frame_get_pts(self.ptr) };
349
350 Timestamp::new(pts, self.time_base)
351 }
352
353 pub fn with_pts(self, pts: Timestamp) -> Self {
355 let pts = pts.with_time_base(self.time_base);
356
357 unsafe { ffw_frame_set_pts(self.ptr, pts.timestamp()) }
358
359 self
360 }
361
362 pub fn freeze(mut self) -> AudioFrame {
364 let ptr = self.ptr;
365
366 self.ptr = ptr::null_mut();
367
368 AudioFrame {
369 ptr,
370 time_base: self.time_base,
371 }
372 }
373}
374
375impl Drop for AudioFrameMut {
376 fn drop(&mut self) {
377 unsafe { ffw_frame_free(self.ptr) }
378 }
379}
380
381unsafe impl Send for AudioFrameMut {}
382unsafe impl Sync for AudioFrameMut {}
383
384pub struct AudioFrame {
386 ptr: *mut c_void,
387 time_base: TimeBase,
388}
389
390impl AudioFrame {
391 pub(crate) unsafe fn from_raw_ptr(ptr: *mut c_void, time_base: TimeBase) -> Self {
393 AudioFrame { ptr, time_base }
394 }
395
396 pub fn sample_format(&self) -> SampleFormat {
398 unsafe { SampleFormat::from_raw(ffw_frame_get_format(self.ptr)) }
399 }
400
401 pub fn sample_rate(&self) -> u32 {
403 unsafe { ffw_frame_get_sample_rate(self.ptr) as _ }
404 }
405
406 pub fn samples(&self) -> usize {
408 unsafe { ffw_frame_get_nb_samples(self.ptr) as _ }
409 }
410
411 pub fn planes(&self) -> Planes {
413 Planes::from(self)
414 }
415
416 pub fn channel_layout(&self) -> &ChannelLayoutRef {
418 unsafe { ChannelLayoutRef::from_raw_ptr(ffw_frame_get_channel_layout(self.ptr)) }
419 }
420
421 pub fn time_base(&self) -> TimeBase {
423 self.time_base
424 }
425
426 pub fn with_time_base(mut self, time_base: TimeBase) -> Self {
429 let new_pts = self.pts().with_time_base(time_base);
430
431 unsafe {
432 ffw_frame_set_pts(self.ptr, new_pts.timestamp());
433 }
434
435 self.time_base = time_base;
436
437 self
438 }
439
440 pub fn pts(&self) -> Timestamp {
442 let pts = unsafe { ffw_frame_get_pts(self.ptr) };
443
444 Timestamp::new(pts, self.time_base)
445 }
446
447 pub fn with_pts(self, pts: Timestamp) -> Self {
449 let pts = pts.with_time_base(self.time_base);
450
451 unsafe { ffw_frame_set_pts(self.ptr, pts.timestamp()) }
452
453 self
454 }
455
456 pub(crate) fn as_ptr(&self) -> *const c_void {
458 self.ptr
459 }
460
461 pub fn try_into_mut(self) -> Result<AudioFrameMut, AudioFrame> {
464 let res = unsafe { ffw_frame_is_writable(self.ptr) };
465 if res > 0 {
466 Ok(self.into_mut())
467 } else {
468 Err(self)
469 }
470 }
471
472 pub fn into_mut(mut self) -> AudioFrameMut {
475 let res = unsafe { ffw_frame_make_writable(self.ptr) };
476
477 if res < 0 {
478 panic!("unable to make the frame mutable");
479 }
480
481 let ptr = self.ptr;
482
483 self.ptr = ptr::null_mut();
484
485 AudioFrameMut {
486 ptr,
487 time_base: self.time_base,
488 }
489 }
490}
491
492impl Clone for AudioFrame {
493 fn clone(&self) -> Self {
494 let ptr = unsafe { ffw_frame_clone(self.ptr) };
495
496 if ptr.is_null() {
497 panic!("unable to clone a frame");
498 }
499
500 Self {
501 ptr,
502 time_base: self.time_base,
503 }
504 }
505}
506
507impl Drop for AudioFrame {
508 fn drop(&mut self) {
509 unsafe { ffw_frame_free(self.ptr) }
510 }
511}
512
513unsafe impl Send for AudioFrame {}
514unsafe impl Sync for AudioFrame {}