Skip to main content

libav_ng/avcodec/
codec_parameters.rs

1use libav_sys_ng::{
2    avcodec_get_name, avcodec_parameters_alloc, avcodec_parameters_copy, AVCodecParameters,
3    AVMediaType, AVMediaType_AVMEDIA_TYPE_ATTACHMENT, AVMediaType_AVMEDIA_TYPE_AUDIO,
4    AVMediaType_AVMEDIA_TYPE_DATA, AVMediaType_AVMEDIA_TYPE_NB, AVMediaType_AVMEDIA_TYPE_SUBTITLE,
5    AVMediaType_AVMEDIA_TYPE_UNKNOWN, AVMediaType_AVMEDIA_TYPE_VIDEO,
6};
7use libav_sys_ng::{AVCodecID, AVColorRange, AVRational};
8use std::ffi::CStr;
9use std::fmt::Debug;
10
11pub struct CodecParameters {
12    pub(crate) _p: *mut AVCodecParameters,
13}
14
15impl CodecParameters {
16    pub fn new() -> Option<CodecParameters> {
17        unsafe {
18            let raw = avcodec_parameters_alloc();
19
20            if raw.is_null() {
21                return None;
22            }
23
24            Some(CodecParameters { _p: raw })
25        }
26    }
27
28    pub fn codec_type(&self) -> AVMediaType {
29        unsafe { (*self._p).codec_type }
30    }
31
32    pub fn codec_id(&self) -> AVCodecID {
33        unsafe { (*self._p).codec_id }
34    }
35
36    pub fn codec_name(&self) -> &str {
37        unsafe {
38            let id = (*self._p).codec_id;
39            let name_raw = avcodec_get_name(id);
40
41            if name_raw.is_null() {
42                "(null)"
43            } else {
44                CStr::from_ptr(name_raw).to_str().unwrap()
45            }
46        }
47    }
48
49    pub fn bitrate(&self) -> i64 {
50        unsafe { (*self._p).bit_rate }
51    }
52
53    pub fn size(&self) -> (i32, i32) {
54        unsafe { ((*self._p).width, (*self._p).height) }
55    }
56
57    pub fn aspect_ratio(&self) -> AVRational {
58        unsafe { (*self._p).sample_aspect_ratio }
59    }
60
61    pub fn framerate(&self) -> AVRational {
62        unsafe { (*self._p).framerate }
63    }
64
65    pub fn color_range(&self) -> AVColorRange {
66        unsafe { (*self._p).color_range }
67    }
68
69    pub fn format(&self) -> i32 {
70        unsafe { (*self._p).format }
71    }
72
73    pub fn sample_rate(&self) -> Option<i32> {
74        if self.codec_type() == AVMediaType_AVMEDIA_TYPE_AUDIO {
75            Some(unsafe { (*self._p).sample_rate })
76        } else {
77            None
78        }
79    }
80
81    #[inline]
82    pub fn is_audio(&self) -> bool {
83        self.codec_type() == AVMediaType_AVMEDIA_TYPE_AUDIO
84    }
85
86    #[inline]
87    pub fn is_video(&self) -> bool {
88        self.codec_type() == AVMediaType_AVMEDIA_TYPE_VIDEO
89    }
90
91    #[inline]
92    pub fn raw(&self) -> *const AVCodecParameters {
93        self._p.cast()
94    }
95
96    #[inline]
97    pub fn raw_mut(&self) -> *mut AVCodecParameters {
98        self._p
99    }
100}
101
102impl Clone for CodecParameters {
103    fn clone(&self) -> Self {
104        let parameters = CodecParameters::new().expect("Failed to allocate AVCodecParameters");
105
106        unsafe { avcodec_parameters_copy(parameters._p, self._p) };
107
108        parameters
109    }
110}
111
112impl Debug for CodecParameters {
113    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114        let codec_type = unsafe {
115            if (*self._p).codec_type == AVMediaType_AVMEDIA_TYPE_NB {
116                "AVMEDIA_TYPE_NB"
117            } else if (*self._p).codec_type == AVMediaType_AVMEDIA_TYPE_UNKNOWN {
118                "AVMEDIA_TYPE_UNKNOWN"
119            } else if (*self._p).codec_type == AVMediaType_AVMEDIA_TYPE_AUDIO {
120                "AVMEDIA_TYPE_AUDIO"
121            } else if (*self._p).codec_type == AVMediaType_AVMEDIA_TYPE_VIDEO {
122                "AVMEDIA_TYPE_VIDEO"
123            } else if (*self._p).codec_type == AVMediaType_AVMEDIA_TYPE_DATA {
124                "AVMEDIA_TYPE_DATA"
125            } else if (*self._p).codec_type == AVMediaType_AVMEDIA_TYPE_SUBTITLE {
126                "AVMEDIA_TYPE_SUBTITLE"
127            } else if (*self._p).codec_type == AVMediaType_AVMEDIA_TYPE_ATTACHMENT {
128                "AVMEDIA_TYPE_ATTACHMENT"
129            } else {
130                "?"
131            }
132        };
133
134        let (width, height) = self.size();
135
136        f.debug_struct("CodecParameters")
137            .field("codec_type", &codec_type)
138            .field("codec_id", &self.codec_name())
139            .field("bitrate", &self.bitrate())
140            .field("width", &width)
141            .field("height", &height)
142            .field("aspect_ratio", &self.aspect_ratio())
143            .field("frame_rate", &self.framerate())
144            .finish()
145    }
146}
147
148/*
149impl Drop for CodecParameters {
150    fn drop(&mut self) {
151        unsafe { avcodec_parameters_free(&mut self._par) }
152    }
153}
154*/