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 /// Codec capability flag for intra-only codecs.
35 pub const CODEC_CAP_INTRAONLY:u32 = 0x0001;
36 /// Codec capability flag for lossless codecs.
37 pub const CODEC_CAP_LOSSLESS:u32 = 0x0002;
38 /// Codec capability flag for codecs with frame reordering.
39 pub const CODEC_CAP_REORDER:u32 = 0x0004;
40 /// Codec capability flag for codecs that can be both lossy and lossless.
41 pub const CODEC_CAP_HYBRID:u32 = 0x0008;
42 /// Codec capability flag for codecs with scalability features.
43 pub const CODEC_CAP_SCALABLE:u32 = 0x0010;
44 /// Codec capability flag for codecs with complex frame reordering.
45 pub const CODEC_CAP_COMPLEX_REORDER:u32 = 0x0020;
47 /// Codec description structure.
49 pub struct CodecDescription {
52 /// Short codec name is used inside NihAV as the unique identifier.
53 pub name: &'static str,
55 pub fname: &'static str,
58 /// Codec capabilities.
62 impl CodecDescription {
63 /// Returns short codec name.
64 pub fn get_name(&self) -> &'static str { self.name }
65 /// Returns full codec name.
66 pub fn get_full_name(&self) -> &'static str { self.fname }
67 /// Returns codec type.
68 pub fn get_codec_type(&self) -> CodecType { self.ctype }
69 /// Reports whether the codec has only intra frames or not.
70 pub fn is_intraonly(&self) -> bool { (self.caps & CODEC_CAP_INTRAONLY) != 0 }
71 /// Reports whether the codec is lossless.
72 pub fn is_lossless(&self) -> bool { (self.caps & CODEC_CAP_LOSSLESS) != 0 }
73 /// Reports whether the codec requires frame reordering.
74 pub fn has_reorder(&self) -> bool { (self.caps & CODEC_CAP_REORDER) != 0 }
75 /// Reports whether the codec can be either lossless or lossy.
76 pub fn is_hybrid(&self) -> bool { (self.caps & CODEC_CAP_HYBRID) != 0 }
77 /// Reports whether codec supports scalability.
79 /// Scalability means that codec can be decoded in reduced resolution by design.
80 pub fn is_scalable(&self) -> bool { (self.caps & CODEC_CAP_SCALABLE) != 0 }
83 impl fmt::Display for CodecDescription {
84 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85 let mut out = self.fname.to_string();
87 let mut capfmt = "".to_string();
88 if (self.caps & CODEC_CAP_INTRAONLY) != 0 {
89 capfmt = format!("{} Intra-only", capfmt);
91 if (self.caps & CODEC_CAP_LOSSLESS) != 0 {
92 capfmt = format!("{} Lossless", capfmt);
94 if (self.caps & CODEC_CAP_REORDER) != 0 {
95 capfmt = format!("{} Frame reorder", capfmt);
97 if (self.caps & CODEC_CAP_HYBRID) != 0 {
98 capfmt = format!("{} Can be lossy and lossless", capfmt);
100 if (self.caps & CODEC_CAP_SCALABLE) != 0 {
101 capfmt = format!("{} Scalable", capfmt);
103 out = format!("{} ({})", out, capfmt);
110 (video; $n:expr, $fn:expr) => ({
111 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
114 (video; $n:expr, $fn:expr, $c:expr) => ({
115 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
118 (video-ll; $n:expr, $fn:expr) => ({
119 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
120 caps: CODEC_CAP_LOSSLESS | CODEC_CAP_INTRAONLY }
122 (video-llp; $n:expr, $fn:expr) => ({
123 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
124 caps: CODEC_CAP_LOSSLESS }
126 (video-im; $n:expr, $fn:expr) => ({
127 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
128 caps: CODEC_CAP_INTRAONLY }
130 (video-modern; $n:expr, $fn:expr) => ({
131 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
132 caps: CODEC_CAP_REORDER | CODEC_CAP_HYBRID }
134 (audio; $n:expr, $fn:expr) => ({
135 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Audio,
138 (audio-ll; $n:expr, $fn:expr) => ({
139 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Audio,
140 caps: CODEC_CAP_LOSSLESS | CODEC_CAP_INTRAONLY }
142 (audio-hyb; $n:expr, $fn:expr) => ({
143 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Audio,
144 caps: CODEC_CAP_HYBRID }
148 /// Returns codec description for the provided codec short name if it is found.
149 pub fn get_codec_description(name: &str) -> Option<&'static CodecDescription> {
150 CODEC_REGISTER.iter().find(|®| reg.name == name)
153 static CODEC_REGISTER: &[CodecDescription] = &[
154 desc!(audio-ll; "pcm", "PCM"),
155 desc!(audio; "alaw", "A-law PCM"),
156 desc!(audio; "ulaw", "mu-law PCM"),
158 desc!(video-im; "indeo1", "Intel Raw IF09"),
159 desc!(video; "indeo2", "Intel Indeo 2"),
160 desc!(video; "ima-rtv2", "Intel RTV 2 (Indeo 2)"),
161 desc!(video; "indeo3", "Intel Indeo 3"),
162 desc!(video; "indeo4", "Intel Indeo 4", CODEC_CAP_REORDER | CODEC_CAP_SCALABLE),
163 desc!(video; "indeo5", "Intel Indeo 5", CODEC_CAP_REORDER | CODEC_CAP_SCALABLE),
164 desc!(video; "indeo5s", "Intel Indeo 5 Scalable", CODEC_CAP_SCALABLE),
165 desc!(video; "intel263", "Intel I263", CODEC_CAP_REORDER),
166 desc!(audio; "iac", "Intel Indeo audio"),
167 desc!(audio; "imc", "Intel Music Coder"),
169 desc!(video; "realvideo1", "Real Video 1"),
170 desc!(video; "realvideo2", "Real Video 2", CODEC_CAP_REORDER),
171 desc!(video; "realvideo3", "Real Video 3", CODEC_CAP_REORDER),
172 desc!(video; "realvideo4", "Real Video 4", CODEC_CAP_REORDER),
173 desc!(video; "realvideo6", "Real Video 6", CODEC_CAP_REORDER),
174 desc!(video; "clearvideo", "ClearVideo"),
175 desc!(video; "clearvideo_rm", "ClearVideo"),
176 desc!(audio; "ra14.4", "RealAudio 14.4"),
177 desc!(audio; "ra28.8", "RealAudio 28.8"),
178 desc!(audio; "cook", "RealAudio Cooker"),
179 desc!(audio; "ralf", "RealAudio Lossless"),
180 desc!(audio; "aac", "AAC"),
181 desc!(audio; "ac3", "ETSI TS 102 366"),
182 desc!(audio; "atrac3", "Sony Atrac3"),
183 desc!(audio; "sipro", "Sipro Labs ADPCM"),
186 desc!(video-ll; "rawvideo", "Raw video data"),
187 desc!(video-ll; "rawvideo-ms", "Raw video data"),
189 desc!(video; "cinepak", "Cinepak"),
191 desc!(video-llp; "zmbv", "Zip Motion Blocks Video"),
193 desc!(video; "msvideo1", "MS Video 1"),
194 desc!(video; "msrle", "MS RLE"),
195 desc!(audio; "ms-adpcm", "MS ADPCM"),
196 desc!(audio; "ima-adpcm-ms", "IMA ADPCM (MS variant)"),
198 desc!(video; "qt-smc", "Apple Graphics"),
199 desc!(video; "qt-rle", "Apple Animation"),
200 desc!(video; "apple-video", "Apple video"),
201 desc!(video; "sorenson-video", "Sorenson Video"),
202 desc!(video; "sorenson-video3", "Sorenson Video 3", CODEC_CAP_REORDER),
203 desc!(audio-ll; "alac", "Apple Lossless Audio Codec"),
204 desc!(audio; "mace-3", "MACE 3:1"),
205 desc!(audio; "mace-6", "MACE 6:1"),
206 desc!(audio; "ima-adpcm-qt", "IMA ADPCM (Apple variant)"),
207 desc!(audio; "qdesign-music", "QDesign Music"),
208 desc!(audio; "qdesign-music2", "QDesign Music v2"),
209 desc!(audio; "qualcomm-purevoice", "Qualcomm PureVoice"),
211 desc!(video-ll; "arm_rawvideo", "Acorn Replay Movie raw video formats"),
212 desc!(audio; "arm_rawaudio", "Acorn Replay Movie raw audio formats"),
213 desc!(video; "movinglines", "Acorn Moving Lines"),
214 desc!(video; "movingblocks", "Acorn Moving Blocks"),
215 desc!(video; "movingblockshq", "Acorn Moving Blocks HQ"),
216 desc!(video; "supermovingblocks", "Acorn Super Moving Blocks"),
217 desc!(video; "linepack", "Henrik Pedersen's LinePack"),
218 desc!(video; "movie16_3", "Henrik Pedersen's Movie 16:3"),
219 desc!(video; "escape100", "Eidos Escape 100"),
220 desc!(video; "escape102", "Eidos Escape 102"),
221 desc!(video; "escape122", "Eidos Escape 122"),
222 desc!(video; "escape124", "Eidos Escape 124"),
223 desc!(video; "escape130", "Eidos Escape 130"),
225 desc!(video; "truemotion1", "TrueMotion 1"),
226 desc!(video-im; "truemotionrt", "TrueMotion RT"),
227 desc!(video; "truemotion2", "TrueMotion 2"),
228 desc!(video; "truemotion2x", "TrueMotion 2X"),
229 desc!(video; "vp3", "VP3"),
230 desc!(video; "vp4", "VP4"),
231 desc!(video; "vp5", "VP5"),
232 desc!(video; "vp6", "VP6"),
233 desc!(video; "vp6f", "VP6 (in Flash)"),
234 desc!(video; "vp6a", "VP6 with alpha"),
235 desc!(video; "vp7", "VP7"),
236 desc!(video; "vp8", "VP8"),
237 desc!(video; "vp9", "VP9"),
238 desc!(audio; "adpcm-dk3", "Duck DK3 ADPCM"),
239 desc!(audio; "adpcm-dk4", "Duck DK4 ADPCM"),
240 desc!(audio; "on2avc-500", "On2 AVC"),
241 desc!(audio; "on2avc-501", "On2 AVC"),
243 desc!(video; "flv263", "Sorenson H.263"),
244 desc!(video-llp; "flashsv", "Flash Screen Video"),
245 desc!(video-llp; "flashsv2", "Flash Screen Video 2"),
246 desc!(audio; "asao", "N*llym*s*r ASAO"),
247 desc!(audio; "flv-adpcm", "Flash ADPCM"),
249 desc!(audio; "mp1", "MPEG Audio Layer I"),
250 desc!(audio; "mp2", "MPEG Audio Layer II"),
251 desc!(audio; "mp3", "MPEG Audio Layer III"),
252 desc!(audio; "speex", "Speex"),
254 desc!(video; "gdv-video", "Gremlin Digital Video - video"),
255 desc!(audio; "gdv-audio", "Gremlin Digital Video - audio"),
256 desc!(video-im; "arxel-video", "Arxel Tribe Video"),
257 desc!(video; "beam-fcp", "Beam Software Animation"),
258 desc!(video; "beam-video", "Beam Software Video"),
259 desc!(video; "bmv-video", "BMV video"),
260 desc!(audio; "bmv-audio", "BMV audio"),
261 desc!(video; "bmv3-video", "DW Noir BMV video"),
262 desc!(audio; "bmv3-audio", "DW Noir BMV audio"),
263 desc!(video; "dp-sga", "Digital Pictures SGA video"),
264 desc!(video; "fable-imax", "Fable IMAX video"),
265 desc!(video; "fst-video", "FutureVision video"),
266 desc!(audio; "fst-audio", "FutureVision audio"),
267 desc!(video; "hl-fmv-video", "Highlander FMV video"),
268 desc!(video-llp; "ipma", "Imagination Pilots Matte Animation"),
269 desc!(video-llp; "ipma2", "Imagination Pilots Matte Animation v2"),
270 desc!(video; "kmvc", "Karl Morton's Video Codec"),
271 desc!(video; "legend-q-video", "Legend Entertainment Q video"),
272 desc!(video; "midivid", "MidiVid"),
273 desc!(video; "midivid3", "MidiVid 3"),
274 desc!(video-ll; "midivid-ll", "MidiVid Lossless"),
275 desc!(video-ll; "rbt-video", "Sierra Robot video"),
276 desc!(audio; "rbt-audio", "Sierra Robot audio"),
277 desc!(video; "seq-video", "Sierra Sequence video"),
278 desc!(video; "smushv1", "SMUSH Video paletted"),
279 desc!(video; "smushv2", "SMUSH Video 16-bit"),
280 desc!(video; "smush-iact", "SMUSH IACT Audio"),
281 desc!(video; "smush-vima", "SMUSH VIMA Audio"),
282 desc!(video; "vmd-video", "VMD video"),
283 desc!(audio; "vmd-audio", "VMD audio"),
284 desc!(video; "vxvideo", "Actimagine Vx"),
285 desc!(audio; "vxaudio", "Actimagine Sx"),
287 desc!(video; "smacker-video", "Smacker video"),
288 desc!(audio; "smacker-audio", "Smacker audio"),
289 desc!(video; "bink-video", "Bink video"),
290 desc!(video; "bink2-video", "Bink2 video"),
291 desc!(audio; "bink-audio-dct", "Bink audio (DCT)"),
292 desc!(audio; "bink-audio-rdft", "Bink audio (RDFT)"),
294 desc!(audio; "lhst15f8", "L&H StreamTalk 15kbps at 8 kHz"),
295 desc!(audio; "lhst250f11", "L&H StreamTalk 25kbps at 11 kHz"),
296 desc!(audio; "lhst500f22", "L&H StreamTalk 50kpbs at 22 kHz"),
297 desc!(audio; "lhst48", "L&H StreamTalk CELP Codec 4.8kbps at 8 kHz"),
299 desc!(video; "vivo1", "VivoActive Video 1.0"),
300 desc!(video; "vivo2", "VivoActive Video 2.0", CODEC_CAP_REORDER),
301 desc!(audio; "g723.1", "ITU G.723.1"),
302 desc!(audio; "siren", "Polycom Siren"),
304 desc!(audio-ll; "ape", "Monkey's Audio"),
305 desc!(audio-ll; "flac", "Free Lossless Audio Codec"),
306 desc!(audio-ll; "tta", "True Audio codec"),
307 desc!(audio-hyb; "wavpack", "WavPack"),
309 desc!(video-ll; "gif", "GIF"),
310 desc!(video-im; "jpeg", "JPEG"),
311 desc!(video; "h264", "ITU H.264", CODEC_CAP_COMPLEX_REORDER | CODEC_CAP_HYBRID),
312 desc!(video-modern; "mpeg4asp", "MPEG-4 ASP"),
314 desc!(video-im; "mwv1", "Aware MotionWavelets"),
316 desc!(video-im; "pgvv", "Radius Studio Video"),
319 static AVI_VIDEO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
320 (&[1, 0, 0, 0], "msrle"),
321 (&[2, 0, 0, 0], "msrle"),
323 (b"CRAM", "msvideo1"),
324 (b"MSVC", "msvideo1"),
325 (b"WHAM", "msvideo1"),
335 (b"I263", "intel263"),
337 (b"UCOD", "clearvideo"),
338 (b"cvid", "cinepak"),
345 (b"MVDV", "midivid"),
346 (b"MV30", "midivid3"),
347 (b"MVLZ", "midivid-ll"),
349 (b"tmot", "truemotion1"),
350 (b"DUCK", "truemotion1"),
351 (b"TR20", "truemotionrt"),
352 (b"TM20", "truemotion2"),
353 (b"TM2A", "truemotion2x"),
354 (b"TM2X", "truemotion2x"),
367 (b"azpr", "apple-video"),
370 (b"VXS1", "vxvideo"),
372 (b"DX50", "mpeg4asp"),
373 (b"DIVX", "mpeg4asp"),
374 (b"XVID", "mpeg4asp"),
377 static WAV_CODEC_REGISTER: &[(u16, &str)] = &[
380 (0x0002, "ms-adpcm"),
382 (0x0011, "ima-adpcm-ms"),
384 (0x0061, "adpcm-dk4"),
385 (0x0062, "adpcm-dk3"),
388 (0x0500, "on2avc-500"),
389 (0x0501, "on2avc-501"),
392 static MOV_VIDEO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
393 (b"cvid", "cinepak"),
399 (b"rpza", "apple-video"),
400 (b"kpcd", "kodak-photocd"),
401 //(b"mpeg", "mpeg-video"),
402 (b"mjpa", "mjpeg-a"),
403 (b"mjpb", "mjpeg-b"),
404 (b"svqi", "sorenson-video"),
405 (b"SVQ1", "sorenson-video"),
406 (b"svq3", "sorenson-video3"),
407 (b"SVQ3", "sorenson-video3"),
412 (b"UCOD", "clearvideo"),
417 (b"mp4v", "mpeg4asp"),
421 static MOV_AUDIO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
432 (b"ima4", "ima-adpcm-qt"),
435 (b"dvca", "dv-audio"),
436 (b"QDMC", "qdesign-music"),
437 (b"QDM2", "qdesign-music2"),
438 (b"Qclp", "qualcomm-purevoice"),
439 //(b".mp3", "mpeg-layer3"),
446 /// Returns video codec short name for provided FOURCC (used in AVI format).
447 pub fn find_codec_from_avi_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
448 for (fourcc, name) in AVI_VIDEO_CODEC_REGISTER.iter() {
449 if *fourcc == fcc { return Some(name); }
454 /// Returns FOURCC (used in AVI format) for provided codec name.
455 pub fn find_avi_fourcc(codecname: &str) -> Option<[u8; 4]> {
456 for (fourcc, name) in AVI_VIDEO_CODEC_REGISTER.iter() {
457 if *name == codecname { return Some(**fourcc); }
462 /// Returns known audio codec short name for provided TWOCC (used in WAV and AVI format).
463 pub fn find_codec_from_wav_twocc(tcc: u16) -> Option<&'static str> {
464 for (twocc, name) in WAV_CODEC_REGISTER.iter() {
465 if *twocc == tcc { return Some(name); }
470 /// Returns TWOCC (used in WAV and AVI format for provided codec name.
471 pub fn find_wav_twocc(codecname: &str) -> Option<u16> {
472 for (twocc, name) in WAV_CODEC_REGISTER.iter() {
473 if *name == codecname { return Some(*twocc); }
478 /// Returns video codec short name for provided FOURCC (used in MOV format).
479 pub fn find_codec_from_mov_video_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
480 for (fourcc, name) in MOV_VIDEO_CODEC_REGISTER.iter() {
481 if *fourcc == fcc { return Some(name); }
486 /// Returns known audio codec short name for provided FOURCC (used in MOV format).
487 pub fn find_codec_from_mov_audio_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
488 for (fourcc, name) in MOV_AUDIO_CODEC_REGISTER.iter() {
489 if *fourcc == fcc { return Some(name); }
500 let c1 = find_codec_from_avi_fourcc(b"IV41").unwrap();
501 let c2 = find_codec_from_wav_twocc(0x401).unwrap();
502 println!("found {} and {}", c1, c2);
503 let cd1 = get_codec_description(c1).unwrap();
504 let cd2 = get_codec_description(c2).unwrap();
505 println!("got {} and {}", cd1, cd2);