1pub mod frame;
4pub mod resampler;
5pub mod transcoder;
6
7use std::{ffi::CString, os::raw::c_void, ptr};
8
9use crate::{
10 codec::{AudioCodecParameters, CodecError, CodecParameters, CodecTag, Decoder, Encoder},
11 format::stream::Stream,
12 packet::Packet,
13 time::TimeBase,
14 Error,
15};
16
17pub use self::{
18 frame::{AudioFrame, AudioFrameMut, ChannelLayout, ChannelLayoutRef, SampleFormat},
19 resampler::AudioResampler,
20 transcoder::AudioTranscoder,
21};
22
23pub struct AudioDecoderBuilder {
25 ptr: *mut c_void,
26 time_base: TimeBase,
27}
28
29impl AudioDecoderBuilder {
30 unsafe fn from_raw_ptr(ptr: *mut c_void) -> Self {
32 let time_base = TimeBase::MICROSECONDS;
33
34 super::ffw_decoder_set_pkt_timebase(ptr, time_base.num() as _, time_base.den() as _);
35
36 Self { ptr, time_base }
37 }
38
39 fn new(codec: &str) -> Result<Self, Error> {
41 let codec = CString::new(codec).expect("invalid codec name");
42
43 let ptr = unsafe { super::ffw_decoder_new(codec.as_ptr() as _) };
44
45 if ptr.is_null() {
46 return Err(Error::new("unknown codec"));
47 }
48
49 unsafe { Ok(Self::from_raw_ptr(ptr)) }
50 }
51
52 fn from_codec_parameters(codec_parameters: &AudioCodecParameters) -> Result<Self, Error> {
54 let ptr = unsafe { super::ffw_decoder_from_codec_parameters(codec_parameters.as_ptr()) };
55
56 if ptr.is_null() {
57 return Err(Error::new("unable to create a decoder"));
58 }
59
60 unsafe { Ok(Self::from_raw_ptr(ptr)) }
61 }
62
63 pub fn set_option<V>(self, name: &str, value: V) -> Self
65 where
66 V: ToString,
67 {
68 let name = CString::new(name).expect("invalid option name");
69 let value = CString::new(value.to_string()).expect("invalid option value");
70
71 let ret = unsafe {
72 super::ffw_decoder_set_initial_option(self.ptr, name.as_ptr() as _, value.as_ptr() as _)
73 };
74
75 if ret < 0 {
76 panic!("unable to allocate an option");
77 }
78
79 self
80 }
81
82 pub fn time_base(mut self, time_base: TimeBase) -> Self {
85 self.time_base = time_base;
86
87 unsafe {
88 super::ffw_decoder_set_pkt_timebase(
89 self.ptr,
90 time_base.num() as _,
91 time_base.den() as _,
92 );
93 }
94
95 self
96 }
97
98 pub fn extradata<T>(self, data: Option<T>) -> Self
100 where
101 T: AsRef<[u8]>,
102 {
103 let data = data.as_ref().map(|d| d.as_ref());
104
105 let ptr;
106 let size;
107
108 if let Some(data) = data {
109 ptr = data.as_ptr();
110 size = data.len();
111 } else {
112 ptr = ptr::null();
113 size = 0;
114 }
115
116 let res = unsafe { super::ffw_decoder_set_extradata(self.ptr, ptr, size as _) };
117
118 if res < 0 {
119 panic!("unable to allocate extradata");
120 }
121
122 self
123 }
124
125 pub fn build(mut self) -> Result<AudioDecoder, Error> {
127 unsafe {
128 if super::ffw_decoder_open(self.ptr) != 0 {
129 return Err(Error::new("unable to build the decoder"));
130 }
131 }
132
133 let ptr = self.ptr;
134
135 self.ptr = ptr::null_mut();
136
137 let res = AudioDecoder {
138 ptr,
139 time_base: self.time_base,
140 };
141
142 Ok(res)
143 }
144}
145
146impl Drop for AudioDecoderBuilder {
147 fn drop(&mut self) {
148 unsafe { super::ffw_decoder_free(self.ptr) }
149 }
150}
151
152unsafe impl Send for AudioDecoderBuilder {}
153unsafe impl Sync for AudioDecoderBuilder {}
154
155pub struct AudioDecoder {
157 ptr: *mut c_void,
158 time_base: TimeBase,
159}
160
161impl AudioDecoder {
162 pub fn new(codec: &str) -> Result<Self, Error> {
164 AudioDecoderBuilder::new(codec).and_then(|builder| builder.build())
165 }
166
167 pub fn from_codec_parameters(
169 codec_parameters: &AudioCodecParameters,
170 ) -> Result<AudioDecoderBuilder, Error> {
171 AudioDecoderBuilder::from_codec_parameters(codec_parameters)
172 }
173
174 pub fn from_stream(stream: &Stream) -> Result<AudioDecoderBuilder, Error> {
179 let codec_parameters = stream
180 .codec_parameters()
181 .into_audio_codec_parameters()
182 .unwrap();
183
184 let builder = AudioDecoderBuilder::from_codec_parameters(&codec_parameters)?
185 .time_base(stream.time_base());
186
187 Ok(builder)
188 }
189
190 pub fn builder(codec: &str) -> Result<AudioDecoderBuilder, Error> {
192 AudioDecoderBuilder::new(codec)
193 }
194}
195
196impl Decoder for AudioDecoder {
197 type CodecParameters = AudioCodecParameters;
198 type Frame = AudioFrame;
199
200 fn codec_parameters(&self) -> Self::CodecParameters {
201 let ptr = unsafe { super::ffw_decoder_get_codec_parameters(self.ptr) };
202
203 if ptr.is_null() {
204 panic!("unable to allocate codec parameters");
205 }
206
207 let params = unsafe { CodecParameters::from_raw_ptr(ptr) };
208
209 params.into_audio_codec_parameters().unwrap()
210 }
211
212 fn try_push(&mut self, packet: Packet) -> Result<(), CodecError> {
213 let packet = packet.with_time_base(self.time_base);
214
215 unsafe {
216 match super::ffw_decoder_push_packet(self.ptr, packet.as_ptr()) {
217 1 => Ok(()),
218 0 => Err(CodecError::again(
219 "all frames must be consumed before pushing a new packet",
220 )),
221 e => Err(CodecError::from_raw_error_code(e)),
222 }
223 }
224 }
225
226 fn try_flush(&mut self) -> Result<(), CodecError> {
227 unsafe {
228 match super::ffw_decoder_push_packet(self.ptr, ptr::null()) {
229 1 => Ok(()),
230 0 => Err(CodecError::again(
231 "all frames must be consumed before flushing",
232 )),
233 e => Err(CodecError::from_raw_error_code(e)),
234 }
235 }
236 }
237
238 fn take(&mut self) -> Result<Option<AudioFrame>, Error> {
239 let mut fptr = ptr::null_mut();
240
241 unsafe {
242 match super::ffw_decoder_take_frame(self.ptr, &mut fptr) {
243 1 => {
244 if fptr.is_null() {
245 panic!("no frame received")
246 } else {
247 Ok(Some(AudioFrame::from_raw_ptr(fptr, self.time_base)))
248 }
249 }
250 0 => Ok(None),
251 e => Err(Error::from_raw_error_code(e)),
252 }
253 }
254 }
255}
256
257impl Drop for AudioDecoder {
258 fn drop(&mut self) {
259 unsafe { super::ffw_decoder_free(self.ptr) }
260 }
261}
262
263unsafe impl Send for AudioDecoder {}
264unsafe impl Sync for AudioDecoder {}
265
266struct RawAudioEncoder {
268 ptr: *mut c_void,
269}
270
271impl RawAudioEncoder {
272 fn from_raw_ptr(ptr: *mut c_void) -> Self {
274 Self { ptr }
275 }
276}
277
278impl Drop for RawAudioEncoder {
279 fn drop(&mut self) {
280 unsafe { super::ffw_encoder_free(self.ptr) }
281 }
282}
283
284unsafe impl Send for RawAudioEncoder {}
285unsafe impl Sync for RawAudioEncoder {}
286
287pub struct AudioEncoderBuilder {
289 raw: RawAudioEncoder,
290
291 time_base: TimeBase,
292
293 sample_format: Option<SampleFormat>,
294 sample_rate: Option<u32>,
295 channel_layout: Option<ChannelLayout>,
296}
297
298impl AudioEncoderBuilder {
299 fn new(codec: &str) -> Result<Self, Error> {
301 let codec = CString::new(codec).expect("invalid codec name");
302
303 let ptr = unsafe { super::ffw_encoder_new(codec.as_ptr() as _) };
304
305 if ptr.is_null() {
306 return Err(Error::new("unknown codec"));
307 }
308
309 unsafe {
310 super::ffw_encoder_set_bit_rate(ptr, 0);
311 }
312
313 let res = Self {
314 raw: RawAudioEncoder::from_raw_ptr(ptr),
315
316 time_base: TimeBase::MICROSECONDS,
317
318 sample_format: None,
319 sample_rate: None,
320 channel_layout: None,
321 };
322
323 Ok(res)
324 }
325
326 fn from_codec_parameters(codec_parameters: &AudioCodecParameters) -> Result<Self, Error> {
328 let ptr = unsafe { super::ffw_encoder_from_codec_parameters(codec_parameters.as_ptr()) };
329
330 if ptr.is_null() {
331 return Err(Error::new("unable to create an encoder"));
332 }
333
334 let sample_format;
335 let sample_rate;
336 let channel_layout;
337
338 unsafe {
339 sample_format = SampleFormat::from_raw(super::ffw_encoder_get_sample_format(ptr));
340 sample_rate = super::ffw_encoder_get_sample_rate(ptr) as _;
341 channel_layout =
342 ChannelLayoutRef::from_raw_ptr(super::ffw_encoder_get_channel_layout(ptr));
343 }
344
345 let channel_layout = channel_layout.to_owned();
346
347 let res = Self {
348 raw: RawAudioEncoder::from_raw_ptr(ptr),
349
350 time_base: TimeBase::MICROSECONDS,
351
352 sample_format: Some(sample_format),
353 sample_rate: Some(sample_rate),
354 channel_layout: Some(channel_layout),
355 };
356
357 Ok(res)
358 }
359
360 pub fn set_option<V>(self, name: &str, value: V) -> Self
362 where
363 V: ToString,
364 {
365 let name = CString::new(name).expect("invalid option name");
366 let value = CString::new(value.to_string()).expect("invalid option value");
367
368 let ret = unsafe {
369 super::ffw_encoder_set_initial_option(
370 self.raw.ptr,
371 name.as_ptr() as _,
372 value.as_ptr() as _,
373 )
374 };
375
376 if ret < 0 {
377 panic!("unable to allocate an option");
378 }
379
380 self
381 }
382
383 pub fn bit_rate(self, bit_rate: u64) -> Self {
385 unsafe {
386 super::ffw_encoder_set_bit_rate(self.raw.ptr, bit_rate as _);
387 }
388
389 self
390 }
391
392 #[inline]
394 pub fn time_base(mut self, time_base: TimeBase) -> Self {
395 self.time_base = time_base;
396 self
397 }
398
399 #[inline]
401 pub fn sample_format(mut self, format: SampleFormat) -> Self {
402 self.sample_format = Some(format);
403 self
404 }
405
406 #[inline]
408 pub fn sample_rate(mut self, rate: u32) -> Self {
409 self.sample_rate = Some(rate);
410 self
411 }
412
413 #[inline]
415 pub fn channel_layout(mut self, layout: ChannelLayout) -> Self {
416 self.channel_layout = Some(layout);
417 self
418 }
419
420 pub fn codec_tag(self, codec_tag: impl Into<CodecTag>) -> Self {
422 unsafe {
423 super::ffw_encoder_set_codec_tag(self.raw.ptr, codec_tag.into().into());
424 }
425
426 self
427 }
428
429 pub fn build(self) -> Result<AudioEncoder, Error> {
431 let sample_format = self
432 .sample_format
433 .ok_or_else(|| Error::new("sample format not set"))?;
434
435 let sample_rate = self
436 .sample_rate
437 .ok_or_else(|| Error::new("sample rate not set"))?;
438
439 let channel_layout = self
440 .channel_layout
441 .ok_or_else(|| Error::new("channel layout not set"))?;
442
443 let tb = self.time_base;
444
445 unsafe {
446 super::ffw_encoder_set_time_base(self.raw.ptr, tb.num() as _, tb.den() as _);
447 super::ffw_encoder_set_sample_format(self.raw.ptr, sample_format.into_raw());
448 super::ffw_encoder_set_sample_rate(self.raw.ptr, sample_rate as _);
449
450 if super::ffw_encoder_set_channel_layout(self.raw.ptr, channel_layout.as_ptr()) != 0 {
451 panic!("unable to copy channel layout");
452 }
453
454 if super::ffw_encoder_open(self.raw.ptr) != 0 {
455 return Err(Error::new("unable to build the encoder"));
456 }
457 }
458
459 let res = AudioEncoder {
460 raw: self.raw,
461 time_base: tb,
462 };
463
464 Ok(res)
465 }
466}
467
468pub struct AudioEncoder {
470 raw: RawAudioEncoder,
471 time_base: TimeBase,
472}
473
474impl AudioEncoder {
475 pub fn from_codec_parameters(
477 codec_parameters: &AudioCodecParameters,
478 ) -> Result<AudioEncoderBuilder, Error> {
479 AudioEncoderBuilder::from_codec_parameters(codec_parameters)
480 }
481
482 pub fn builder(codec: &str) -> Result<AudioEncoderBuilder, Error> {
484 AudioEncoderBuilder::new(codec)
485 }
486
487 pub fn samples_per_frame(&self) -> Option<usize> {
492 let res = unsafe { super::ffw_encoder_get_frame_size(self.raw.ptr) as _ };
493
494 if res == 0 {
495 None
496 } else {
497 Some(res)
498 }
499 }
500}
501
502impl Encoder for AudioEncoder {
503 type CodecParameters = AudioCodecParameters;
504 type Frame = AudioFrame;
505
506 fn codec_parameters(&self) -> Self::CodecParameters {
507 let ptr = unsafe { super::ffw_encoder_get_codec_parameters(self.raw.ptr) };
508
509 if ptr.is_null() {
510 panic!("unable to allocate codec parameters");
511 }
512
513 let params = unsafe { CodecParameters::from_raw_ptr(ptr) };
514
515 params.into_audio_codec_parameters().unwrap()
516 }
517
518 fn try_push(&mut self, frame: AudioFrame) -> Result<(), CodecError> {
519 let frame = frame.with_time_base(self.time_base);
520
521 unsafe {
522 match super::ffw_encoder_push_frame(self.raw.ptr, frame.as_ptr()) {
523 1 => Ok(()),
524 0 => Err(CodecError::again(
525 "all packets must be consumed before pushing a new frame",
526 )),
527 e => Err(CodecError::from_raw_error_code(e)),
528 }
529 }
530 }
531
532 fn try_flush(&mut self) -> Result<(), CodecError> {
533 unsafe {
534 match super::ffw_encoder_push_frame(self.raw.ptr, ptr::null()) {
535 1 => Ok(()),
536 0 => Err(CodecError::again(
537 "all packets must be consumed before flushing",
538 )),
539 e => Err(CodecError::from_raw_error_code(e)),
540 }
541 }
542 }
543
544 fn take(&mut self) -> Result<Option<Packet>, Error> {
545 let mut pptr = ptr::null_mut();
546
547 unsafe {
548 match super::ffw_encoder_take_packet(self.raw.ptr, &mut pptr) {
549 1 => {
550 if pptr.is_null() {
551 panic!("no packet received")
552 } else {
553 Ok(Some(Packet::from_raw_ptr(pptr, self.time_base)))
554 }
555 }
556 0 => Ok(None),
557 e => Err(Error::from_raw_error_code(e)),
558 }
559 }
560 }
561}