ac_ffmpeg/codec/
mod.rs

1//! A/V codecs.
2
3pub mod audio;
4pub mod bsf;
5pub mod video;
6
7use std::{
8    ffi::{CStr, CString},
9    fmt::{self, Display, Formatter},
10    os::raw::{c_char, c_int, c_void},
11    ptr, slice,
12};
13
14use crate::{
15    codec::{
16        audio::{ChannelLayoutRef, SampleFormat},
17        video::PixelFormat,
18    },
19    packet::Packet,
20    Error,
21};
22
23#[cfg(codec_params_side_data)]
24use crate::packet::{SideDataRef, SideDataType};
25
26extern "C" {
27    fn ffw_audio_codec_parameters_new(codec: *const c_char) -> *mut c_void;
28    fn ffw_video_codec_parameters_new(codec: *const c_char) -> *mut c_void;
29    fn ffw_subtitle_codec_parameters_new(codec: *const c_char) -> *mut c_void;
30    fn ffw_codec_parameters_clone(params: *const c_void) -> *mut c_void;
31    fn ffw_codec_parameters_is_audio_codec(params: *const c_void) -> c_int;
32    fn ffw_codec_parameters_is_video_codec(params: *const c_void) -> c_int;
33    fn ffw_codec_parameters_is_subtitle_codec(params: *const c_void) -> c_int;
34    fn ffw_codec_parameters_get_decoder_name(params: *const c_void) -> *const c_char;
35    fn ffw_codec_parameters_get_encoder_name(params: *const c_void) -> *const c_char;
36    fn ffw_codec_parameters_get_bit_rate(params: *const c_void) -> i64;
37    fn ffw_codec_parameters_get_format(params: *const c_void) -> c_int;
38    fn ffw_codec_parameters_get_width(params: *const c_void) -> c_int;
39    fn ffw_codec_parameters_get_height(params: *const c_void) -> c_int;
40    fn ffw_codec_parameters_get_sample_rate(params: *const c_void) -> c_int;
41    fn ffw_codec_parameters_get_channel_layout(params: *const c_void) -> *const c_void;
42    fn ffw_codec_parameters_get_codec_tag(params: *const c_void) -> u32;
43    fn ffw_codec_parameters_get_extradata(params: *mut c_void) -> *mut c_void;
44    fn ffw_codec_parameters_get_extradata_size(params: *const c_void) -> c_int;
45    fn ffw_codec_parameters_set_bit_rate(params: *mut c_void, bit_rate: i64);
46    fn ffw_codec_parameters_set_format(params: *mut c_void, format: c_int);
47    fn ffw_codec_parameters_set_width(params: *mut c_void, width: c_int);
48    fn ffw_codec_parameters_set_height(params: *mut c_void, height: c_int);
49    fn ffw_codec_parameters_set_sample_rate(params: *mut c_void, rate: c_int);
50    fn ffw_codec_parameters_set_channel_layout(params: *mut c_void, layout: *const c_void)
51        -> c_int;
52    fn ffw_codec_parameters_set_codec_tag(params: *mut c_void, codec_tag: u32);
53    fn ffw_codec_parameters_set_extradata(
54        params: *mut c_void,
55        extradata: *const u8,
56        size: c_int,
57    ) -> c_int;
58    fn ffw_codec_parameters_free(params: *mut c_void);
59
60    #[cfg(codec_params_side_data)]
61    fn ffw_codec_parameters_get_nb_coded_side_data(params: *const c_void) -> usize;
62
63    #[cfg(codec_params_side_data)]
64    fn ffw_codec_parameters_get_coded_side_data(
65        params: *const c_void,
66        index: usize,
67    ) -> *const c_void;
68
69    #[cfg(codec_params_side_data)]
70    fn ffw_codec_parameters_add_coded_side_data(
71        params: *mut c_void,
72        data_type: c_int,
73        data: *const u8,
74        size: usize,
75    ) -> c_int;
76
77    fn ffw_decoder_new(codec: *const c_char) -> *mut c_void;
78    fn ffw_decoder_from_codec_parameters(params: *const c_void) -> *mut c_void;
79    fn ffw_decoder_set_extradata(decoder: *mut c_void, extradata: *const u8, size: c_int) -> c_int;
80    fn ffw_decoder_set_initial_option(
81        decoder: *mut c_void,
82        key: *const c_char,
83        value: *const c_char,
84    ) -> c_int;
85    fn ffw_decoder_set_pkt_timebase(decoder: *mut c_void, num: c_int, den: c_int);
86    fn ffw_decoder_open(decoder: *mut c_void) -> c_int;
87    fn ffw_decoder_push_packet(decoder: *mut c_void, packet: *const c_void) -> c_int;
88    fn ffw_decoder_take_frame(decoder: *mut c_void, frame: *mut *mut c_void) -> c_int;
89    fn ffw_decoder_get_codec_parameters(decoder: *const c_void) -> *mut c_void;
90    fn ffw_decoder_free(decoder: *mut c_void);
91
92    fn ffw_encoder_new(codec: *const c_char) -> *mut c_void;
93    fn ffw_encoder_from_codec_parameters(params: *const c_void) -> *mut c_void;
94    fn ffw_encoder_get_codec_parameters(encoder: *const c_void) -> *mut c_void;
95    fn ffw_encoder_get_pixel_format(encoder: *const c_void) -> c_int;
96    fn ffw_encoder_get_width(encoder: *const c_void) -> c_int;
97    fn ffw_encoder_get_height(encoder: *const c_void) -> c_int;
98    fn ffw_encoder_get_sample_format(encoder: *const c_void) -> c_int;
99    fn ffw_encoder_get_sample_rate(encoder: *const c_void) -> c_int;
100    fn ffw_encoder_get_channel_layout(encoder: *const c_void) -> *const c_void;
101    fn ffw_encoder_get_frame_size(encoder: *const c_void) -> c_int;
102    fn ffw_encoder_set_time_base(encoder: *mut c_void, num: c_int, den: c_int);
103    fn ffw_encoder_set_bit_rate(encoder: *mut c_void, bit_rate: i64);
104    fn ffw_encoder_set_pixel_format(encoder: *mut c_void, format: c_int);
105    fn ffw_encoder_set_width(encoder: *mut c_void, width: c_int);
106    fn ffw_encoder_set_height(encoder: *mut c_void, height: c_int);
107    fn ffw_encoder_set_sample_format(encoder: *mut c_void, format: c_int);
108    fn ffw_encoder_set_sample_rate(encoder: *mut c_void, sample_rate: c_int);
109    fn ffw_encoder_set_channel_layout(encoder: *mut c_void, layout: *const c_void) -> c_int;
110    fn ffw_encoder_set_codec_tag(encoder: *mut c_void, codec_tag: u32);
111    fn ffw_encoder_set_initial_option(
112        encoder: *mut c_void,
113        key: *const c_char,
114        value: *const c_char,
115    ) -> c_int;
116    fn ffw_encoder_open(encoder: *mut c_void) -> c_int;
117    fn ffw_encoder_push_frame(encoder: *mut c_void, frame: *const c_void) -> c_int;
118    fn ffw_encoder_take_packet(encoder: *mut c_void, packet: *mut *mut c_void) -> c_int;
119    fn ffw_encoder_free(encoder: *mut c_void);
120}
121
122/// Error variants.
123#[derive(Debug, Clone)]
124enum CodecErrorVariant {
125    /// An error.
126    Error(Error),
127    /// An error indicating that another operation needs to be done before
128    /// continuing with the current operation.
129    Again(&'static str),
130}
131
132/// A decoding or encoding error.
133#[derive(Debug, Clone)]
134pub struct CodecError {
135    variant: CodecErrorVariant,
136}
137
138impl CodecError {
139    /// Create a new error.
140    fn error<T>(msg: T) -> Self
141    where
142        T: ToString,
143    {
144        Self {
145            variant: CodecErrorVariant::Error(Error::new(msg)),
146        }
147    }
148
149    /// Create a new FFmpeg error from a given FFmpeg error code.
150    fn from_raw_error_code(code: c_int) -> Self {
151        Self::from(Error::from_raw_error_code(code))
152    }
153
154    /// Create a new error indicating that another operation needs to be done.
155    fn again(msg: &'static str) -> Self {
156        Self {
157            variant: CodecErrorVariant::Again(msg),
158        }
159    }
160
161    /// Check if another operation needs to be done.
162    #[inline]
163    pub fn is_again(&self) -> bool {
164        matches!(&self.variant, CodecErrorVariant::Again(_))
165    }
166
167    /// Get the inner error (if any).
168    #[inline]
169    pub fn into_inner(self) -> Option<Error> {
170        if let CodecErrorVariant::Error(err) = self.variant {
171            Some(err)
172        } else {
173            None
174        }
175    }
176
177    /// Get the inner error or panic if another operation needs to be done.
178    pub fn unwrap_inner(self) -> Error {
179        match self.variant {
180            CodecErrorVariant::Error(err) => err,
181            CodecErrorVariant::Again(msg) => panic!("{}", msg),
182        }
183    }
184}
185
186impl Display for CodecError {
187    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
188        match &self.variant {
189            CodecErrorVariant::Again(msg) => write!(f, "{}", msg),
190            CodecErrorVariant::Error(err) => write!(f, "{}", err),
191        }
192    }
193}
194
195impl std::error::Error for CodecError {}
196
197impl From<Error> for CodecError {
198    #[inline]
199    fn from(err: Error) -> Self {
200        Self {
201            variant: CodecErrorVariant::Error(err),
202        }
203    }
204}
205
206/// Iterator over codec parameters side data.
207#[cfg(codec_params_side_data)]
208pub struct SideDataIter<'a> {
209    params: &'a InnerCodecParameters,
210    index: usize,
211    len: usize,
212}
213
214#[cfg(codec_params_side_data)]
215impl<'a> Iterator for SideDataIter<'a> {
216    type Item = &'a SideDataRef;
217
218    fn next(&mut self) -> Option<Self::Item> {
219        if self.index == self.len {
220            return None;
221        }
222
223        let side_data = unsafe {
224            SideDataRef::from_raw_ptr(ffw_codec_parameters_get_coded_side_data(
225                self.params.ptr,
226                self.index,
227            ))
228        };
229
230        self.index += 1;
231
232        Some(side_data)
233    }
234
235    fn size_hint(&self) -> (usize, Option<usize>) {
236        let hint = self.len - self.index;
237
238        (hint, Some(hint))
239    }
240}
241
242#[cfg(codec_params_side_data)]
243impl ExactSizeIterator for SideDataIter<'_> {}
244
245/// Inner struct holding the pointer to the codec parameters.
246struct InnerCodecParameters {
247    ptr: *mut c_void,
248}
249
250impl InnerCodecParameters {
251    /// Create codec parameters from a given raw representation.
252    unsafe fn from_raw_ptr(ptr: *mut c_void) -> Self {
253        Self { ptr }
254    }
255
256    /// Get raw pointer to the underlying object.
257    fn as_ptr(&self) -> *const c_void {
258        self.ptr
259    }
260
261    /// Check if these codec parameters are for an audio codec.
262    fn is_audio_codec(&self) -> bool {
263        unsafe { ffw_codec_parameters_is_audio_codec(self.ptr) != 0 }
264    }
265
266    /// Check if these codec parameters are for a video codec.
267    fn is_video_codec(&self) -> bool {
268        unsafe { ffw_codec_parameters_is_video_codec(self.ptr) != 0 }
269    }
270
271    /// Check if these codec parameters are for a subtitle codec.
272    fn is_subtitle_codec(&self) -> bool {
273        unsafe { ffw_codec_parameters_is_subtitle_codec(self.ptr) != 0 }
274    }
275
276    /// Get name of the decoder that is able to decode this codec or None
277    /// if the decoder is not available.
278    fn get_decoder_name(&self) -> Option<&'static str> {
279        unsafe {
280            let ptr = ffw_codec_parameters_get_decoder_name(self.ptr);
281
282            if ptr.is_null() {
283                None
284            } else {
285                let name = CStr::from_ptr(ptr as _);
286
287                Some(name.to_str().unwrap())
288            }
289        }
290    }
291
292    /// Get name of the encoder that is able to produce encoding of this codec
293    /// or None if the encoder is not available.
294    fn get_encoder_name(&self) -> Option<&'static str> {
295        unsafe {
296            let ptr = ffw_codec_parameters_get_encoder_name(self.ptr);
297
298            if ptr.is_null() {
299                None
300            } else {
301                let name = CStr::from_ptr(ptr as _);
302
303                Some(name.to_str().unwrap())
304            }
305        }
306    }
307
308    /// Get codec tag.
309    fn get_codec_tag(&self) -> CodecTag {
310        let codec_tag = unsafe { ffw_codec_parameters_get_codec_tag(self.ptr) };
311
312        codec_tag.into()
313    }
314
315    /// Set codec tag.
316    fn set_codec_tag<T>(&mut self, codec_tag: T)
317    where
318        T: Into<CodecTag>,
319    {
320        let codec_tag = codec_tag.into();
321
322        unsafe {
323            ffw_codec_parameters_set_codec_tag(self.ptr, codec_tag.into());
324        }
325    }
326
327    /// Get bit rate.
328    fn get_bit_rate(&self) -> u64 {
329        unsafe { ffw_codec_parameters_get_bit_rate(self.ptr) as _ }
330    }
331
332    /// Set bit rate.
333    fn set_bit_rate(&mut self, bit_rate: u64) {
334        unsafe {
335            ffw_codec_parameters_set_bit_rate(self.ptr, bit_rate as _);
336        }
337    }
338
339    /// Get frame sample format.
340    fn get_sample_format(&self) -> SampleFormat {
341        unsafe { SampleFormat::from_raw(ffw_codec_parameters_get_format(self.ptr)) }
342    }
343
344    /// Set frame sample format.
345    fn set_sample_format(&mut self, format: SampleFormat) {
346        unsafe {
347            ffw_codec_parameters_set_format(self.ptr, format.into_raw());
348        }
349    }
350
351    /// Get sampling rate.
352    fn get_sample_rate(&self) -> u32 {
353        unsafe { ffw_codec_parameters_get_sample_rate(self.ptr) as _ }
354    }
355
356    /// Set sampling rate.
357    fn set_sample_rate(&mut self, rate: u32) {
358        assert!(rate > 0);
359
360        unsafe {
361            ffw_codec_parameters_set_sample_rate(self.ptr, rate as _);
362        }
363    }
364
365    /// Get channel layout.
366    fn get_channel_layout(&self) -> &ChannelLayoutRef {
367        unsafe { ChannelLayoutRef::from_raw_ptr(ffw_codec_parameters_get_channel_layout(self.ptr)) }
368    }
369
370    /// Set channel layout.
371    fn set_channel_layout(&mut self, layout: &ChannelLayoutRef) {
372        let ret = unsafe { ffw_codec_parameters_set_channel_layout(self.ptr, layout.as_ptr()) };
373
374        if ret != 0 {
375            panic!("unable to copy channel layout");
376        }
377    }
378
379    /// Get frame pixel format.
380    fn get_pixel_format(&self) -> PixelFormat {
381        unsafe { PixelFormat::from_raw(ffw_codec_parameters_get_format(self.ptr)) }
382    }
383
384    /// Set frame pixel format.
385    fn set_pixel_format(&mut self, format: PixelFormat) {
386        unsafe {
387            ffw_codec_parameters_set_format(self.ptr, format.into_raw());
388        }
389    }
390
391    /// Get frame width.
392    fn get_width(&self) -> usize {
393        unsafe { ffw_codec_parameters_get_width(self.ptr) as _ }
394    }
395
396    /// Set frame width.
397    fn set_width(&mut self, width: usize) {
398        unsafe {
399            ffw_codec_parameters_set_width(self.ptr, width as _);
400        }
401    }
402
403    /// Get frame height.
404    fn get_height(&self) -> usize {
405        unsafe { ffw_codec_parameters_get_height(self.ptr) as _ }
406    }
407
408    /// Set frame height.
409    fn set_height(&mut self, height: usize) {
410        unsafe {
411            ffw_codec_parameters_set_height(self.ptr, height as _);
412        }
413    }
414
415    /// Get extradata.
416    fn get_extradata(&self) -> Option<&[u8]> {
417        unsafe {
418            let data = ffw_codec_parameters_get_extradata(self.ptr) as *const u8;
419            let size = ffw_codec_parameters_get_extradata_size(self.ptr) as usize;
420
421            if data.is_null() {
422                None
423            } else {
424                Some(slice::from_raw_parts(data, size))
425            }
426        }
427    }
428
429    /// Set extradata.
430    fn set_extradata<T>(&mut self, data: Option<T>)
431    where
432        T: AsRef<[u8]>,
433    {
434        let data = data.as_ref().map(|d| d.as_ref());
435
436        let ptr;
437        let size;
438
439        if let Some(data) = data {
440            ptr = data.as_ptr();
441            size = data.len();
442        } else {
443            ptr = ptr::null();
444            size = 0;
445        }
446
447        let res = unsafe { ffw_codec_parameters_set_extradata(self.ptr, ptr, size as _) };
448
449        if res < 0 {
450            panic!("unable to allocate extradata");
451        }
452    }
453
454    /// Get the additional data associated with the entire stream.
455    #[cfg(codec_params_side_data)]
456    fn get_coded_side_data(&self) -> SideDataIter<'_> {
457        let len = unsafe { ffw_codec_parameters_get_nb_coded_side_data(self.ptr) };
458
459        SideDataIter {
460            params: self,
461            index: 0,
462            len,
463        }
464    }
465
466    /// Add new side data.
467    #[cfg(codec_params_side_data)]
468    fn add_coded_side_data(&mut self, data_type: SideDataType, data: &[u8]) -> Result<(), Error> {
469        let ret = unsafe {
470            ffw_codec_parameters_add_coded_side_data(
471                self.ptr,
472                data_type.into_raw(),
473                data.as_ptr(),
474                data.len(),
475            )
476        };
477
478        if ret < 0 {
479            Err(Error::from_raw_error_code(ret))
480        } else {
481            Ok(())
482        }
483    }
484}
485
486impl Drop for InnerCodecParameters {
487    fn drop(&mut self) {
488        unsafe { ffw_codec_parameters_free(self.ptr) }
489    }
490}
491
492impl Clone for InnerCodecParameters {
493    fn clone(&self) -> Self {
494        let ptr = unsafe { ffw_codec_parameters_clone(self.ptr) };
495
496        if ptr.is_null() {
497            panic!("unable to clone codec parameters");
498        }
499
500        Self { ptr }
501    }
502}
503
504unsafe impl Send for InnerCodecParameters {}
505unsafe impl Sync for InnerCodecParameters {}
506
507/// Variants of codec parameters.
508#[derive(Clone)]
509enum CodecParametersVariant {
510    Audio(AudioCodecParameters),
511    Video(VideoCodecParameters),
512    Subtitle(SubtitleCodecParameters),
513    Other(OtherCodecParameters),
514}
515
516impl CodecParametersVariant {
517    /// Create codec parameters from a given raw representation.
518    unsafe fn from_raw_ptr(ptr: *mut c_void) -> Self {
519        let inner = InnerCodecParameters::from_raw_ptr(ptr);
520
521        if inner.is_audio_codec() {
522            Self::Audio(AudioCodecParameters::from(inner))
523        } else if inner.is_video_codec() {
524            Self::Video(VideoCodecParameters::from(inner))
525        } else if inner.is_subtitle_codec() {
526            Self::Subtitle(SubtitleCodecParameters::from(inner))
527        } else {
528            Self::Other(OtherCodecParameters::from(inner))
529        }
530    }
531}
532
533impl AsRef<InnerCodecParameters> for CodecParametersVariant {
534    fn as_ref(&self) -> &InnerCodecParameters {
535        match self {
536            Self::Audio(audio) => audio.as_ref(),
537            Self::Video(video) => video.as_ref(),
538            Self::Subtitle(subtitle) => subtitle.as_ref(),
539            Self::Other(other) => other.as_ref(),
540        }
541    }
542}
543
544/// Codec parameters.
545#[derive(Clone)]
546pub struct CodecParameters {
547    inner: CodecParametersVariant,
548}
549
550impl CodecParameters {
551    /// Create codec parameters from a given raw representation.
552    pub(crate) unsafe fn from_raw_ptr(ptr: *mut c_void) -> Self {
553        Self {
554            inner: CodecParametersVariant::from_raw_ptr(ptr),
555        }
556    }
557
558    /// Get raw pointer to the underlying object.
559    pub(crate) fn as_ptr(&self) -> *const c_void {
560        self.inner.as_ref().as_ptr()
561    }
562
563    /// Check if these codec parameters are for an audio codec.
564    pub fn is_audio_codec(&self) -> bool {
565        self.inner.as_ref().is_audio_codec()
566    }
567
568    /// Check if these codec parameters are for a video codec.
569    pub fn is_video_codec(&self) -> bool {
570        self.inner.as_ref().is_video_codec()
571    }
572
573    /// Check if these codec parameters are for a subtitle codec.
574    pub fn is_subtitle_codec(&self) -> bool {
575        self.inner.as_ref().is_subtitle_codec()
576    }
577
578    /// Get name of the decoder that is able to decode this codec or None
579    /// if the decoder is not available.
580    pub fn decoder_name(&self) -> Option<&'static str> {
581        self.inner.as_ref().get_decoder_name()
582    }
583
584    /// Get name of the encoder that is able to produce encoding of this codec
585    /// or None if the encoder is not available.
586    pub fn encoder_name(&self) -> Option<&'static str> {
587        self.inner.as_ref().get_encoder_name()
588    }
589
590    /// Get reference to audio codec parameters (if possible).
591    pub fn as_audio_codec_parameters(&self) -> Option<&AudioCodecParameters> {
592        if let CodecParametersVariant::Audio(params) = &self.inner {
593            Some(params)
594        } else {
595            None
596        }
597    }
598
599    /// Get reference to video codec parameters (if possible).
600    pub fn as_video_codec_parameters(&self) -> Option<&VideoCodecParameters> {
601        if let CodecParametersVariant::Video(params) = &self.inner {
602            Some(params)
603        } else {
604            None
605        }
606    }
607
608    /// Get reference to subtitle codec parameters (if possible).
609    pub fn as_subtitle_codec_parameters(&self) -> Option<&SubtitleCodecParameters> {
610        if let CodecParametersVariant::Subtitle(params) = &self.inner {
611            Some(params)
612        } else {
613            None
614        }
615    }
616
617    /// Convert this object into audio codec parameters (if possible).
618    pub fn into_audio_codec_parameters(self) -> Option<AudioCodecParameters> {
619        if let CodecParametersVariant::Audio(params) = self.inner {
620            Some(params)
621        } else {
622            None
623        }
624    }
625
626    /// Convert this object into video codec parameters (if possible).
627    pub fn into_video_codec_parameters(self) -> Option<VideoCodecParameters> {
628        if let CodecParametersVariant::Video(params) = self.inner {
629            Some(params)
630        } else {
631            None
632        }
633    }
634
635    /// Convert this object into subtitle codec parameters (if possible).
636    pub fn into_subtitle_codec_parameters(self) -> Option<SubtitleCodecParameters> {
637        if let CodecParametersVariant::Subtitle(params) = self.inner {
638            Some(params)
639        } else {
640            None
641        }
642    }
643}
644
645impl From<AudioCodecParameters> for CodecParameters {
646    #[inline]
647    fn from(params: AudioCodecParameters) -> Self {
648        Self {
649            inner: CodecParametersVariant::Audio(params),
650        }
651    }
652}
653
654impl From<VideoCodecParameters> for CodecParameters {
655    #[inline]
656    fn from(params: VideoCodecParameters) -> Self {
657        Self {
658            inner: CodecParametersVariant::Video(params),
659        }
660    }
661}
662impl From<SubtitleCodecParameters> for CodecParameters {
663    #[inline]
664    fn from(params: SubtitleCodecParameters) -> Self {
665        Self {
666            inner: CodecParametersVariant::Subtitle(params),
667        }
668    }
669}
670
671/// Builder for audio codec parameters.
672pub struct AudioCodecParametersBuilder {
673    inner: InnerCodecParameters,
674}
675
676impl AudioCodecParametersBuilder {
677    /// Create a new builder for a given audio codec.
678    fn new(codec: &str) -> Result<Self, Error> {
679        let codec = CString::new(codec).expect("invalid codec name");
680
681        let ptr = unsafe { ffw_audio_codec_parameters_new(codec.as_ptr() as *const _) };
682
683        if ptr.is_null() {
684            return Err(Error::new("unknown codec"));
685        }
686
687        let params = unsafe { InnerCodecParameters::from_raw_ptr(ptr) };
688
689        let res = AudioCodecParametersBuilder { inner: params };
690
691        Ok(res)
692    }
693
694    /// Set bit rate.
695    pub fn bit_rate(mut self, bit_rate: u64) -> Self {
696        self.inner.set_bit_rate(bit_rate);
697        self
698    }
699
700    /// Set frame sample format.
701    pub fn sample_format(mut self, format: SampleFormat) -> Self {
702        self.inner.set_sample_format(format);
703        self
704    }
705
706    /// Set sampling rate.
707    pub fn sample_rate(mut self, rate: u32) -> Self {
708        self.inner.set_sample_rate(rate);
709        self
710    }
711
712    /// Set channel layout.
713    pub fn channel_layout(mut self, layout: &ChannelLayoutRef) -> Self {
714        self.inner.set_channel_layout(layout);
715        self
716    }
717
718    /// Set codec tag.
719    pub fn codec_tag<T>(mut self, codec_tag: T) -> Self
720    where
721        T: Into<CodecTag>,
722    {
723        self.inner.set_codec_tag(codec_tag);
724        self
725    }
726
727    /// Set extradata.
728    pub fn extradata<T>(mut self, data: Option<T>) -> Self
729    where
730        T: AsRef<[u8]>,
731    {
732        self.inner.set_extradata(data);
733        self
734    }
735
736    /// Add new side data.
737    #[cfg(codec_params_side_data)]
738    pub fn add_coded_side_data(
739        &mut self,
740        data_type: SideDataType,
741        data: &[u8],
742    ) -> Result<(), Error> {
743        self.inner.add_coded_side_data(data_type, data)
744    }
745
746    /// Build the codec parameters.
747    #[inline]
748    pub fn build(self) -> AudioCodecParameters {
749        AudioCodecParameters { inner: self.inner }
750    }
751}
752
753impl From<AudioCodecParameters> for AudioCodecParametersBuilder {
754    #[inline]
755    fn from(params: AudioCodecParameters) -> Self {
756        Self {
757            inner: params.inner,
758        }
759    }
760}
761
762/// Audio codec parameters.
763#[derive(Clone)]
764pub struct AudioCodecParameters {
765    inner: InnerCodecParameters,
766}
767
768impl AudioCodecParameters {
769    /// Get builder for audio codec parameters.
770    pub fn builder(codec: &str) -> Result<AudioCodecParametersBuilder, Error> {
771        AudioCodecParametersBuilder::new(codec)
772    }
773
774    /// Get raw pointer to the underlying object.
775    pub(crate) fn as_ptr(&self) -> *const c_void {
776        self.inner.ptr
777    }
778
779    /// Get name of the decoder that is able to decode this codec or None
780    /// if the decoder is not available.
781    pub fn decoder_name(&self) -> Option<&'static str> {
782        self.inner.get_decoder_name()
783    }
784
785    /// Get name of the encoder that is able to produce encoding of this codec
786    /// or None if the encoder is not available.
787    pub fn encoder_name(&self) -> Option<&'static str> {
788        self.inner.get_encoder_name()
789    }
790
791    /// Get bit rate.
792    pub fn bit_rate(&self) -> u64 {
793        self.inner.get_bit_rate()
794    }
795
796    /// Get frame sample format.
797    pub fn sample_format(&self) -> SampleFormat {
798        self.inner.get_sample_format()
799    }
800
801    /// Get sampling rate.
802    pub fn sample_rate(&self) -> u32 {
803        self.inner.get_sample_rate()
804    }
805
806    /// Get channel layout.
807    pub fn channel_layout(&self) -> &ChannelLayoutRef {
808        self.inner.get_channel_layout()
809    }
810
811    /// Get codec tag.
812    pub fn codec_tag(&self) -> CodecTag {
813        self.inner.get_codec_tag()
814    }
815
816    /// Get extradata.
817    pub fn extradata(&self) -> Option<&[u8]> {
818        self.inner.get_extradata()
819    }
820
821    /// Get the additional data associated with the entire stream.
822    #[cfg(codec_params_side_data)]
823    pub fn coded_side_data(&self) -> SideDataIter<'_> {
824        self.inner.get_coded_side_data()
825    }
826}
827
828impl AsRef<InnerCodecParameters> for AudioCodecParameters {
829    fn as_ref(&self) -> &InnerCodecParameters {
830        &self.inner
831    }
832}
833
834impl From<InnerCodecParameters> for AudioCodecParameters {
835    fn from(params: InnerCodecParameters) -> Self {
836        Self { inner: params }
837    }
838}
839
840/// Builder for video codec parameters.
841pub struct VideoCodecParametersBuilder {
842    inner: InnerCodecParameters,
843}
844
845impl VideoCodecParametersBuilder {
846    /// Create a new builder for a given video codec.
847    fn new(codec: &str) -> Result<Self, Error> {
848        let codec = CString::new(codec).expect("invalid codec name");
849
850        let ptr = unsafe { ffw_video_codec_parameters_new(codec.as_ptr() as *const _) };
851
852        if ptr.is_null() {
853            return Err(Error::new("unknown codec"));
854        }
855
856        let params = unsafe { InnerCodecParameters::from_raw_ptr(ptr) };
857
858        let res = VideoCodecParametersBuilder { inner: params };
859
860        Ok(res)
861    }
862
863    /// Set bit rate.
864    pub fn bit_rate(mut self, bit_rate: u64) -> Self {
865        self.inner.set_bit_rate(bit_rate);
866        self
867    }
868
869    /// Set frame pixel format.
870    pub fn pixel_format(mut self, format: PixelFormat) -> Self {
871        self.inner.set_pixel_format(format);
872        self
873    }
874
875    /// Set frame width.
876    pub fn width(mut self, width: usize) -> Self {
877        self.inner.set_width(width);
878        self
879    }
880
881    /// Set frame height.
882    pub fn height(mut self, height: usize) -> Self {
883        self.inner.set_height(height);
884        self
885    }
886
887    /// Set codec tag.
888    pub fn codec_tag<T>(mut self, codec_tag: T) -> Self
889    where
890        T: Into<CodecTag>,
891    {
892        self.inner.set_codec_tag(codec_tag);
893        self
894    }
895
896    /// Set extradata.
897    pub fn extradata<T>(mut self, data: Option<T>) -> Self
898    where
899        T: AsRef<[u8]>,
900    {
901        self.inner.set_extradata(data);
902        self
903    }
904
905    /// Add new side data.
906    #[cfg(codec_params_side_data)]
907    pub fn add_coded_side_data(
908        &mut self,
909        data_type: SideDataType,
910        data: &[u8],
911    ) -> Result<(), Error> {
912        self.inner.add_coded_side_data(data_type, data)
913    }
914
915    /// Build the codec parameters.
916    #[inline]
917    pub fn build(self) -> VideoCodecParameters {
918        VideoCodecParameters { inner: self.inner }
919    }
920}
921
922impl From<VideoCodecParameters> for VideoCodecParametersBuilder {
923    #[inline]
924    fn from(params: VideoCodecParameters) -> VideoCodecParametersBuilder {
925        VideoCodecParametersBuilder {
926            inner: params.inner,
927        }
928    }
929}
930
931/// Video codec parameters.
932#[derive(Clone)]
933pub struct VideoCodecParameters {
934    inner: InnerCodecParameters,
935}
936
937impl VideoCodecParameters {
938    /// Get builder for video codec parameters.
939    pub fn builder(codec: &str) -> Result<VideoCodecParametersBuilder, Error> {
940        VideoCodecParametersBuilder::new(codec)
941    }
942
943    /// Get raw pointer to the underlying object.
944    pub(crate) fn as_ptr(&self) -> *const c_void {
945        self.inner.ptr
946    }
947
948    /// Get name of the decoder that is able to decode this codec or None
949    /// if the decoder is not available.
950    pub fn decoder_name(&self) -> Option<&'static str> {
951        self.inner.get_decoder_name()
952    }
953
954    /// Get name of the encoder that is able to produce encoding of this codec
955    /// or None if the encoder is not available.
956    pub fn encoder_name(&self) -> Option<&'static str> {
957        self.inner.get_encoder_name()
958    }
959
960    /// Get bit rate.
961    pub fn bit_rate(&self) -> u64 {
962        self.inner.get_bit_rate()
963    }
964
965    /// Get frame pixel format.
966    pub fn pixel_format(&self) -> PixelFormat {
967        self.inner.get_pixel_format()
968    }
969
970    /// Get frame width.
971    pub fn width(&self) -> usize {
972        self.inner.get_width()
973    }
974
975    /// Get frame height.
976    pub fn height(&self) -> usize {
977        self.inner.get_height()
978    }
979
980    /// Get codec tag.
981    pub fn codec_tag(&self) -> CodecTag {
982        self.inner.get_codec_tag()
983    }
984
985    /// Get extradata.
986    pub fn extradata(&self) -> Option<&[u8]> {
987        self.inner.get_extradata()
988    }
989
990    /// Get the additional data associated with the entire stream.
991    #[cfg(codec_params_side_data)]
992    pub fn coded_side_data(&self) -> SideDataIter<'_> {
993        self.inner.get_coded_side_data()
994    }
995}
996
997impl AsRef<InnerCodecParameters> for VideoCodecParameters {
998    fn as_ref(&self) -> &InnerCodecParameters {
999        &self.inner
1000    }
1001}
1002
1003impl From<InnerCodecParameters> for VideoCodecParameters {
1004    fn from(params: InnerCodecParameters) -> Self {
1005        Self { inner: params }
1006    }
1007}
1008
1009/// Subtitle codec parameters.
1010#[derive(Clone)]
1011pub struct SubtitleCodecParameters {
1012    inner: InnerCodecParameters,
1013}
1014
1015impl SubtitleCodecParameters {
1016    pub fn new(codec: &str) -> Result<Self, Error> {
1017        let codec = CString::new(codec).expect("invalid codec name");
1018
1019        let ptr = unsafe { ffw_subtitle_codec_parameters_new(codec.as_ptr() as *const _) };
1020
1021        if ptr.is_null() {
1022            return Err(Error::new("unknown codec"));
1023        }
1024
1025        let params = unsafe { InnerCodecParameters::from_raw_ptr(ptr) };
1026
1027        let res = SubtitleCodecParameters { inner: params };
1028        Ok(res)
1029    }
1030
1031    /// Get name of the decoder that is able to decode this codec or None
1032    /// if the decoder is not available.
1033    pub fn decoder_name(&self) -> Option<&'static str> {
1034        self.inner.get_decoder_name()
1035    }
1036
1037    /// Get name of the encoder that is able to produce encoding of this codec
1038    /// or None if the encoder is not available.
1039    pub fn encoder_name(&self) -> Option<&'static str> {
1040        self.inner.get_encoder_name()
1041    }
1042}
1043
1044impl AsRef<InnerCodecParameters> for SubtitleCodecParameters {
1045    fn as_ref(&self) -> &InnerCodecParameters {
1046        &self.inner
1047    }
1048}
1049
1050impl From<InnerCodecParameters> for SubtitleCodecParameters {
1051    fn from(params: InnerCodecParameters) -> Self {
1052        Self { inner: params }
1053    }
1054}
1055
1056/// Other codec parameters.
1057#[derive(Clone)]
1058struct OtherCodecParameters {
1059    inner: InnerCodecParameters,
1060}
1061
1062impl AsRef<InnerCodecParameters> for OtherCodecParameters {
1063    fn as_ref(&self) -> &InnerCodecParameters {
1064        &self.inner
1065    }
1066}
1067
1068impl From<InnerCodecParameters> for OtherCodecParameters {
1069    fn from(params: InnerCodecParameters) -> Self {
1070        Self { inner: params }
1071    }
1072}
1073
1074/// A codec tag.
1075#[derive(Copy, Clone, PartialEq)]
1076pub struct CodecTag(u32);
1077
1078impl From<u32> for CodecTag {
1079    #[inline]
1080    fn from(value: u32) -> Self {
1081        Self(value)
1082    }
1083}
1084
1085impl From<CodecTag> for u32 {
1086    #[inline]
1087    fn from(value: CodecTag) -> Self {
1088        value.0
1089    }
1090}
1091
1092impl From<&[u8; 4]> for CodecTag {
1093    #[inline]
1094    fn from(value: &[u8; 4]) -> Self {
1095        Self(u32::from_le_bytes(*value))
1096    }
1097}
1098
1099/// A media decoder.
1100///
1101/// # Common decoder operation
1102/// 1. Push a packet to the decoder.
1103/// 2. Take all frames from the decoder until you get None.
1104/// 3. If there are more packets to be decoded, continue with 1.
1105/// 4. Flush the decoder.
1106/// 5. Take all frames from the decoder until you get None.
1107pub trait Decoder {
1108    type CodecParameters;
1109    type Frame;
1110
1111    /// Get codec parameters.
1112    fn codec_parameters(&self) -> Self::CodecParameters;
1113
1114    /// Push a given packet to the decoder.
1115    ///
1116    /// # Panics
1117    /// The method panics if the operation is not expected (i.e. another
1118    /// operation needs to be done).
1119    fn push(&mut self, packet: Packet) -> Result<(), Error> {
1120        self.try_push(packet).map_err(|err| err.unwrap_inner())
1121    }
1122
1123    /// Push a given packet to the decoder.
1124    fn try_push(&mut self, packet: Packet) -> Result<(), CodecError>;
1125
1126    /// Flush the decoder.
1127    ///
1128    /// # Panics
1129    /// The method panics if the operation is not expected (i.e. another
1130    /// operation needs to be done).
1131    fn flush(&mut self) -> Result<(), Error> {
1132        self.try_flush().map_err(|err| err.unwrap_inner())
1133    }
1134
1135    /// Flush the decoder.
1136    fn try_flush(&mut self) -> Result<(), CodecError>;
1137
1138    /// Take the next frame from the decoder.
1139    fn take(&mut self) -> Result<Option<Self::Frame>, Error>;
1140}
1141
1142/// A media encoder.
1143///
1144/// # Common encoder operation
1145/// 1. Push a frame to the encoder.
1146/// 2. Take all packets from the encoder until you get None.
1147/// 3. If there are more frames to be encoded, continue with 1.
1148/// 4. Flush the encoder.
1149/// 5. Take all packets from the encoder until you get None.
1150pub trait Encoder {
1151    type CodecParameters;
1152    type Frame;
1153
1154    /// Get codec parameters.
1155    fn codec_parameters(&self) -> Self::CodecParameters;
1156
1157    /// Push a given frame to the encoder.
1158    ///
1159    /// # Panics
1160    /// The method panics if the operation is not expected (i.e. another
1161    /// operation needs to be done).
1162    fn push(&mut self, frame: Self::Frame) -> Result<(), Error> {
1163        self.try_push(frame).map_err(|err| err.unwrap_inner())
1164    }
1165
1166    /// Push a given frame to the encoder.
1167    fn try_push(&mut self, frame: Self::Frame) -> Result<(), CodecError>;
1168
1169    /// Flush the encoder.
1170    ///
1171    /// # Panics
1172    /// The method panics if the operation is not expected (i.e. another
1173    /// operation needs to be done).
1174    fn flush(&mut self) -> Result<(), Error> {
1175        self.try_flush().map_err(|err| err.unwrap_inner())
1176    }
1177
1178    /// Flush the encoder.
1179    fn try_flush(&mut self) -> Result<(), CodecError>;
1180
1181    /// Take the next packet from the encoder.
1182    fn take(&mut self) -> Result<Option<Packet>, Error>;
1183}
1184
1185/// A media filter.
1186///
1187/// # Common filter operation
1188/// 1. Push a frame to the filter.
1189/// 2. Take all frames from the filter until you get `None`.
1190/// 3. If there are more frames to be filtered, continue with 1.
1191/// 4. Flush the filter.
1192/// 5. Take all frames from the filter until you get `None`.
1193pub trait Filter {
1194    type Frame;
1195
1196    /// Push a given frame to the filter.
1197    ///
1198    /// # Panics
1199    /// The method panics if the operation is not expected (i.e. another
1200    /// operation needs to be done).
1201    fn push(&mut self, frame: Self::Frame) -> Result<(), Error> {
1202        self.try_push(frame).map_err(|err| err.unwrap_inner())
1203    }
1204
1205    /// Push a given frame to the filter.
1206    fn try_push(&mut self, frame: Self::Frame) -> Result<(), CodecError>;
1207
1208    /// Flush the filter.
1209    ///
1210    /// # Panics
1211    /// The method panics if the operation is not expected (i.e. another
1212    /// operation needs to be done).
1213    fn flush(&mut self) -> Result<(), Error> {
1214        self.try_flush().map_err(|err| err.unwrap_inner())
1215    }
1216
1217    /// Flush the filter.
1218    fn try_flush(&mut self) -> Result<(), CodecError>;
1219
1220    /// Take the next frame from the filter.
1221    fn take(&mut self) -> Result<Option<Self::Frame>, Error>;
1222}