1 //! Global registry of codec information.
3 //! This module contains codec information from technical level that allows user to retrieve information about codec type and features without creating and invoking a decoder for such codec.
7 #[derive(Debug,Clone,Copy,PartialEq)]
16 /// Some special codec (e.g. some event stream or separate timecodes stream).
22 impl fmt::Display for CodecType {
23 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25 CodecType::Video => write!(f, "Video"),
26 CodecType::Audio => write!(f, "Audio"),
27 CodecType::Subtitles => write!(f, "Subtitles"),
28 CodecType::Data => write!(f, "Data"),
29 CodecType::None => write!(f, "-"),
34 const CODEC_CAP_INTRAONLY:u32 = 0x0001;
35 const CODEC_CAP_LOSSLESS:u32 = 0x0002;
36 const CODEC_CAP_REORDER:u32 = 0x0004;
37 const CODEC_CAP_HYBRID:u32 = 0x0008;
38 const CODEC_CAP_SCALABLE:u32 = 0x0010;
40 /// Codec description structure.
42 pub struct CodecDescription {
45 /// Short codec name is used inside NihAV as the unique identifier.
46 pub name: &'static str,
48 pub fname: &'static str,
51 /// Codec capabilities.
55 impl CodecDescription {
56 /// Returns short codec name.
57 pub fn get_name(&self) -> &'static str { self.name }
58 /// Returns full codec name.
59 pub fn get_full_name(&self) -> &'static str { self.fname }
60 /// Returns codec type.
61 pub fn get_codec_type(&self) -> CodecType { self.ctype }
62 /// Reports whether the codec has only intra frames or not.
63 pub fn is_intraonly(&self) -> bool { (self.caps & CODEC_CAP_INTRAONLY) != 0 }
64 /// Reports whether the codec is lossless.
65 pub fn is_lossless(&self) -> bool { (self.caps & CODEC_CAP_LOSSLESS) != 0 }
66 /// Reports whether the codec requires frame reordering.
67 pub fn has_reorder(&self) -> bool { (self.caps & CODEC_CAP_REORDER) != 0 }
68 /// Reports whether the codec can be either lossless or lossy.
69 pub fn is_hybrid(&self) -> bool { (self.caps & CODEC_CAP_HYBRID) != 0 }
70 /// Reports whether codec supports scalability.
72 /// Scalability means that codec can be decoded in reduced resolution by design.
73 pub fn is_scalable(&self) -> bool { (self.caps & CODEC_CAP_SCALABLE) != 0 }
76 impl fmt::Display for CodecDescription {
77 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78 let mut out = self.fname.to_string();
80 let mut capfmt = "".to_string();
81 if (self.caps & CODEC_CAP_INTRAONLY) != 0 {
82 capfmt = format!("{} Intra-only", capfmt);
84 if (self.caps & CODEC_CAP_LOSSLESS) != 0 {
85 capfmt = format!("{} Lossless", capfmt);
87 if (self.caps & CODEC_CAP_REORDER) != 0 {
88 capfmt = format!("{} Frame reorder", capfmt);
90 if (self.caps & CODEC_CAP_HYBRID) != 0 {
91 capfmt = format!("{} Can be lossy and lossless", capfmt);
93 if (self.caps & CODEC_CAP_SCALABLE) != 0 {
94 capfmt = format!("{} Scalable", capfmt);
96 out = format!("{} ({})", out, capfmt);
103 (video; $n:expr, $fn:expr) => ({
104 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
107 (video; $n:expr, $fn:expr, $c:expr) => ({
108 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
111 (video-ll; $n:expr, $fn:expr) => ({
112 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
113 caps: CODEC_CAP_LOSSLESS | CODEC_CAP_INTRAONLY }
115 (video-llp; $n:expr, $fn:expr) => ({
116 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
117 caps: CODEC_CAP_LOSSLESS }
119 (video-im; $n:expr, $fn:expr) => ({
120 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
121 caps: CODEC_CAP_INTRAONLY }
123 (video-modern; $n:expr, $fn:expr) => ({
124 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
125 caps: CODEC_CAP_REORDER | CODEC_CAP_HYBRID }
127 (audio; $n:expr, $fn:expr) => ({
128 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Audio,
131 (audio-ll; $n:expr, $fn:expr) => ({
132 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Audio,
133 caps: CODEC_CAP_LOSSLESS | CODEC_CAP_INTRAONLY }
137 /// Returns codec description for the provided codec short name if it is found.
138 pub fn get_codec_description(name: &str) -> Option<&'static CodecDescription> {
139 for reg in CODEC_REGISTER {
140 if reg.name == name {
147 static CODEC_REGISTER: &'static [CodecDescription] = &[
148 desc!(audio-ll; "pcm", "PCM"),
150 desc!(video-im; "indeo1", "Intel Raw IF09"),
151 desc!(video-im; "indeo2", "Intel Indeo 2"),
152 desc!(video; "indeo3", "Intel Indeo 3"),
153 desc!(video; "indeo4", "Intel Indeo 4", CODEC_CAP_REORDER | CODEC_CAP_SCALABLE),
154 desc!(video; "indeo5", "Intel Indeo 5", CODEC_CAP_REORDER | CODEC_CAP_SCALABLE),
155 desc!(video; "intel263", "Intel I263", CODEC_CAP_REORDER),
156 desc!(audio; "iac", "Intel Indeo audio"),
157 desc!(audio; "imc", "Intel Music Coder"),
159 desc!(video; "realvideo1", "Real Video 1"),
160 desc!(video; "realvideo2", "Real Video 2", CODEC_CAP_REORDER),
161 desc!(video; "realvideo3", "Real Video 3", CODEC_CAP_REORDER),
162 desc!(video; "realvideo4", "Real Video 4", CODEC_CAP_REORDER),
163 desc!(video; "realvideo6", "Real Video 6", CODEC_CAP_REORDER),
164 desc!(video; "clearvideo", "ClearVideo"),
165 desc!(video; "clearvideo_rm", "ClearVideo"),
166 desc!(audio; "ra14.4", "RealAudio 14.4"),
167 desc!(audio; "ra28.8", "RealAudio 28.8"),
168 desc!(audio; "cook", "RealAudio Cooker"),
169 desc!(audio; "ralf", "RealAudio Lossless"),
170 desc!(audio; "aac", "AAC"),
171 desc!(audio; "ac3", "ETSI TS 102 366"),
172 desc!(audio; "atrac3", "Sony Atrac3"),
173 desc!(audio; "sipro", "Sipro Labs ADPCM"),
175 desc!(video; "truemotion1", "TrueMotion 1"),
176 desc!(video-im; "truemotionrt", "TrueMotion RT"),
177 desc!(video; "truemotion2", "TrueMotion 2"),
178 desc!(video; "truemotion2x", "TrueMotion 2X"),
179 desc!(video; "vp3", "VP3"),
180 desc!(video; "vp4", "VP4"),
181 desc!(video; "vp5", "VP5"),
182 desc!(video; "vp6", "VP6"),
183 desc!(video; "vp6a", "VP6"),
184 desc!(video; "vp7", "VP7"),
185 desc!(video; "vp8", "VP8"),
186 desc!(video; "vp9", "VP9"),
187 desc!(audio; "adpcm-dk3", "Duck DK3 ADPCM"),
188 desc!(audio; "adpcm-dk4", "Duck DK4 ADPCM"),
189 desc!(audio; "on2avc-500", "On2 AVC"),
190 desc!(audio; "on2avc-501", "On2 AVC"),
192 desc!(video; "gdv-video", "Gremlin Digital Video - video"),
193 desc!(audio; "gdv-audio", "Gremlin Digital Video - audio"),
194 desc!(video; "bmv-video", "BMV video"),
195 desc!(audio; "bmv-audio", "BMV audio"),
196 desc!(video; "bmv3-video", "DW Noir BMV video"),
197 desc!(audio; "bmv3-audio", "DW Noir BMV audio"),
198 desc!(video; "midivid", "MidiVid"),
199 desc!(video; "midivid3", "MidiVid 3"),
200 desc!(video-ll; "midivid-ll", "MidiVid Lossless"),
201 desc!(video; "vmd-video", "VMD video"),
202 desc!(audio; "vmd-audio", "VMD audio"),
204 desc!(video; "smacker-video", "Smacker video"),
205 desc!(audio; "smacker-audio", "Smacker audio"),
206 desc!(video; "bink-video", "Bink video"),
207 desc!(video; "bink2-video", "Bink2 video"),
208 desc!(audio; "bink-audio-dct", "Bink audio (DCT)"),
209 desc!(audio; "bink-audio-rdft", "Bink audio (RDFT)"),
211 desc!(audio; "lhst15f8", "L&H StreamTalk 15kbps at 8 kHz"),
212 desc!(audio; "lhst250f11", "L&H StreamTalk 25kbps at 11 kHz"),
213 desc!(audio; "lhst500f22", "L&H StreamTalk 50kpbs at 22 kHz"),
214 desc!(audio; "lhst48", "L&H StreamTalk CELP Codec 4.8kbps at 8 kHz"),
217 static AVI_VIDEO_CODEC_REGISTER: &'static [(&[u8;4], &str)] = &[
224 (b"I263", "intel263"),
226 (b"UCOD", "clearvideo"),
228 (b"MVDV", "midivid"),
229 (b"MV30", "midivid3"),
230 (b"MVLZ", "midivid-ll"),
232 (b"DUCK", "truemotion1"),
233 (b"TR20", "truemotionrt"),
234 (b"TM20", "truemotion2"),
235 (b"TM2A", "truemotion2x"),
236 (b"TM2X", "truemotion2x"),
248 static WAV_CODEC_REGISTER: &'static [(u16, &str)] = &[
252 (0x0061, "adpcm-dk4"),
253 (0x0062, "adpcm-dk3"),
256 (0x0500, "on2avc-500"),
257 (0x0501, "on2avc-501"),
260 /// Returns video codec short name for provided FOURCC (used in AVI format).
261 pub fn find_codec_from_avi_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
262 for (fourcc, name) in AVI_VIDEO_CODEC_REGISTER.iter() {
263 if *fourcc == fcc { return Some(name); }
268 /// Returns known audio codec short name for provided TWOCC (used in WAV and AVI format).
269 pub fn find_codec_from_wav_twocc(tcc: u16) -> Option<&'static str> {
270 for (twocc, name) in WAV_CODEC_REGISTER.iter() {
271 if *twocc == tcc { return Some(name); }
282 let c1 = find_codec_from_avi_fourcc(b"IV41").unwrap();
283 let c2 = find_codec_from_wav_twocc(0x401).unwrap();
284 println!("found {} and {}", c1, c2);
285 let cd1 = get_codec_description(c1).unwrap();
286 let cd2 = get_codec_description(c2).unwrap();
287 println!("got {} and {}", cd1, cd2);