libav_ng/avcodec/
codec_parameters.rs1use 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