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!(video-im; "yv92", "Intel Indeo YVU9 Compressed"),
167 desc!(audio; "iac", "Intel Indeo audio"),
168 desc!(audio; "imc", "Intel Music Coder"),
169 desc!(audio; "dvi-adpcm", "Intel DVI ADPCM"),
171 desc!(video; "realvideo1", "Real Video 1"),
172 desc!(video; "realvideo2", "Real Video 2", CODEC_CAP_REORDER),
173 desc!(video; "realvideo3", "Real Video 3", CODEC_CAP_REORDER),
174 desc!(video; "realvideo4", "Real Video 4", CODEC_CAP_REORDER),
175 desc!(video; "realvideo6", "Real Video 6", CODEC_CAP_REORDER),
176 desc!(video; "clearvideo", "ClearVideo"),
177 desc!(video; "clearvideo_rm", "ClearVideo"),
178 desc!(audio; "ra14.4", "RealAudio 14.4"),
179 desc!(audio; "ra28.8", "RealAudio 28.8"),
180 desc!(audio; "cook", "RealAudio Cooker"),
181 desc!(audio; "ralf", "RealAudio Lossless"),
182 desc!(audio; "aac", "AAC"),
183 desc!(audio; "ac3", "ETSI TS 102 366"),
184 desc!(audio; "ac3-multi", "ETSI TS 102 366 (multiple frames)"),
185 desc!(audio; "atrac3", "Sony Atrac3"),
186 desc!(audio; "sipro", "Sipro Labs ADPCM"),
189 desc!(video-ll; "rawvideo", "Raw video data"),
190 desc!(video-ll; "rawvideo-ms", "Raw video data"),
192 desc!(video; "cinepak", "Cinepak"),
194 desc!(video-llp; "zmbv", "Zip Motion Blocks Video"),
196 desc!(video; "msvideo1", "MS Video 1"),
197 desc!(video; "msrle", "MS RLE"),
198 desc!(audio; "ms-adpcm", "MS ADPCM"),
199 desc!(audio; "ima-adpcm-ms", "IMA ADPCM (MS variant)"),
201 desc!(video; "qt-smc", "Apple Graphics"),
202 desc!(video; "qt-rle", "Apple Animation"),
203 desc!(video; "apple-video", "Apple video"),
204 desc!(video; "qdraw", "Apple QuickDraw"),
205 desc!(video; "sorenson-video", "Sorenson Video"),
206 desc!(video; "sorenson-video3", "Sorenson Video 3", CODEC_CAP_REORDER),
207 desc!(video; "qt-cdvideo", "CD Video Codec"),
208 desc!(video-im; "qt-sivq", "SIVQ"),
209 desc!(video-ll; "qt-yuv2", "Raw YUV"),
210 desc!(video-ll; "qt-yuv4", "libquicktime YUV4"),
211 desc!(audio-ll; "alac", "Apple Lossless Audio Codec"),
212 desc!(audio; "mace-3", "MACE 3:1"),
213 desc!(audio; "mace-6", "MACE 6:1"),
214 desc!(audio; "ima-adpcm-qt", "IMA ADPCM (Apple variant)"),
215 desc!(audio; "qdesign-music", "QDesign Music"),
216 desc!(audio; "qdesign-music2", "QDesign Music v2"),
217 desc!(audio; "qualcomm-purevoice", "Qualcomm PureVoice"),
219 desc!(video-ll; "arm_rawvideo", "Acorn Replay Movie raw video formats"),
220 desc!(audio; "arm_rawaudio", "Acorn Replay Movie raw audio formats"),
221 desc!(video; "movinglines", "Acorn Moving Lines"),
222 desc!(video; "movingblocks", "Acorn Moving Blocks"),
223 desc!(video; "movingblockshq", "Acorn Moving Blocks HQ"),
224 desc!(video; "supermovingblocks", "Acorn Super Moving Blocks"),
225 desc!(video; "linepack", "Henrik Pedersen's LinePack"),
226 desc!(video; "movie16_3", "Henrik Pedersen's Movie 16:3"),
227 desc!(video; "escape-any", "wrapper for Eidos Escape codecs"),
228 desc!(video; "escape100", "Eidos Escape 100"),
229 desc!(video; "escape102", "Eidos Escape 102"),
230 desc!(video; "escape122", "Eidos Escape 122"),
231 desc!(video; "escape124", "Eidos Escape 124"),
232 desc!(video; "escape130", "Eidos Escape 130"),
233 desc!(audio; "escape-adpcm", "Eidos Escape ADPCM"),
234 desc!(video-llp; "euclid", "Iota Euclid / The Complete Animation"),
235 desc!(audio; "iota-sound", "IotaSound"),
237 desc!(video; "truemotion1", "TrueMotion 1"),
238 desc!(video-im; "truemotionrt", "TrueMotion RT"),
239 desc!(video; "truemotion2", "TrueMotion 2"),
240 desc!(video; "truemotion2x", "TrueMotion 2X"),
241 desc!(video; "vp3", "VP3"),
242 desc!(video; "vp4", "VP4"),
243 desc!(video; "vp5", "VP5"),
244 desc!(video; "vp6", "VP6"),
245 desc!(video; "vp6f", "VP6 (in Flash)"),
246 desc!(video; "vp6a", "VP6 with alpha"),
247 desc!(video; "vp7", "VP7"),
248 desc!(video; "vp8", "VP8"),
249 desc!(video; "vp9", "VP9"),
250 desc!(audio; "adpcm-dk3", "Duck DK3 ADPCM"),
251 desc!(audio; "adpcm-dk4", "Duck DK4 ADPCM"),
252 desc!(audio; "on2avc-500", "On2 AVC"),
253 desc!(audio; "on2avc-501", "On2 AVC"),
255 desc!(video; "flv263", "Sorenson H.263"),
256 desc!(video-llp; "flashsv", "Flash Screen Video"),
257 desc!(video-llp; "flashsv2", "Flash Screen Video 2"),
258 desc!(audio; "asao", "N*llym*s*r ASAO"),
259 desc!(audio; "flv-adpcm", "Flash ADPCM"),
261 desc!(audio; "mp1", "MPEG Audio Layer I"),
262 desc!(audio; "mp2", "MPEG Audio Layer II"),
263 desc!(audio; "mp3", "MPEG Audio Layer III"),
264 desc!(audio; "mp3-multi", "MPEG Audio Layer III (multiple frames)"),
265 desc!(audio; "speex", "Speex"),
267 desc!(video; "gdv-video", "Gremlin Digital Video - video"),
268 desc!(audio; "gdv-audio", "Gremlin Digital Video - audio"),
269 desc!(video-im; "arxel-video", "Arxel Tribe Video"),
270 desc!(video; "beam-fcp", "Beam Software Animation"),
271 desc!(video; "beam-video", "Beam Software Video"),
272 desc!(video; "bmv-video", "BMV video"),
273 desc!(audio; "bmv-audio", "BMV audio"),
274 desc!(video; "bmv3-video", "DW Noir BMV video"),
275 desc!(audio; "bmv3-audio", "DW Noir BMV audio"),
276 desc!(video; "dp-sga", "Digital Pictures SGA video"),
277 desc!(video; "fable-imax", "Fable IMAX video"),
278 desc!(video; "fst-video", "FutureVision video"),
279 desc!(audio; "fst-audio", "FutureVision audio"),
280 desc!(video; "hl-fmv-video", "Highlander FMV video"),
281 desc!(video-llp; "ipma", "Imagination Pilots Matte Animation"),
282 desc!(video-llp; "ipma2", "Imagination Pilots Matte Animation v2"),
283 desc!(video; "kmvc", "Karl Morton's Video Codec"),
284 desc!(video; "legend-q-video", "Legend Entertainment Q video"),
285 desc!(video; "midivid", "MidiVid"),
286 desc!(video; "midivid3", "MidiVid 3"),
287 desc!(video-ll; "midivid-ll", "MidiVid Lossless"),
288 desc!(video-llp; "pdq2", "PDQ2"),
289 desc!(video-ll; "rbt-video", "Sierra Robot video"),
290 desc!(audio; "rbt-audio", "Sierra Robot audio"),
291 desc!(video; "seq-video", "Sierra Sequence video"),
292 desc!(video; "smushv1", "SMUSH Video paletted"),
293 desc!(video; "smushv2", "SMUSH Video 16-bit"),
294 desc!(video; "smush-iact", "SMUSH IACT Audio"),
295 desc!(video; "smush-vima", "SMUSH VIMA Audio"),
296 desc!(video; "vmd-video", "VMD video"),
297 desc!(audio; "vmd-audio", "VMD audio"),
298 desc!(video; "vxvideo", "Actimagine Vx"),
299 desc!(audio; "vxaudio", "Actimagine Sx"),
301 desc!(video; "smacker-video", "Smacker video"),
302 desc!(audio; "smacker-audio", "Smacker audio"),
303 desc!(video; "bink-video", "Bink video"),
304 desc!(video; "bink2-video", "Bink2 video"),
305 desc!(audio; "bink-audio-dct", "Bink audio (DCT)"),
306 desc!(audio; "bink-audio-rdft", "Bink audio (RDFT)"),
308 desc!(audio; "lhst15f8", "L&H StreamTalk 15kbps at 8 kHz"),
309 desc!(audio; "lhst250f11", "L&H StreamTalk 25kbps at 11 kHz"),
310 desc!(audio; "lhst500f22", "L&H StreamTalk 50kpbs at 22 kHz"),
311 desc!(audio; "lhst48", "L&H StreamTalk CELP Codec 4.8kbps at 8 kHz"),
313 desc!(video; "vivo1", "VivoActive Video 1.0"),
314 desc!(video; "vivo2", "VivoActive Video 2.0", CODEC_CAP_REORDER),
315 desc!(audio; "g723.1", "ITU G.723.1"),
316 desc!(audio; "siren", "Polycom Siren"),
318 desc!(audio-ll; "ape", "Monkey's Audio"),
319 desc!(audio-ll; "flac", "Free Lossless Audio Codec"),
320 desc!(audio-ll; "tta", "True Audio codec"),
321 desc!(audio-hyb; "wavpack", "WavPack"),
323 desc!(video-ll; "gif", "GIF"),
324 desc!(video-im; "jpeg", "JPEG"),
325 desc!(video; "h264", "ITU H.264", CODEC_CAP_COMPLEX_REORDER | CODEC_CAP_HYBRID),
326 desc!(video-modern; "mpeg4asp", "MPEG-4 ASP"),
328 desc!(video; "fif", "Fractal Codec"),
330 desc!(video-im; "mvi0", "MotionPixels (MVI)"),
331 desc!(video; "mvi1", "MotionPixels 1"),
332 desc!(video; "mvi2", "MotionPixels 2"),
334 desc!(video; "gryphon-arbc-vfw", "Gryphon Software ARBC in AVI"),
335 desc!(video; "gryphon-arbc-qt", "Gryphon Software ARBC in MOV"),
337 desc!(video-im; "mwv1", "Aware MotionWavelets"),
339 desc!(video-llp; "pivideo", "PI-Video"),
341 desc!(video-im; "adorage", "proDAD Adorage"),
342 desc!(video-im; "moviepak", "RasterOps MoviePak"),
343 desc!(video-im; "pgvv", "Radius Studio Video"),
345 desc!(video-llp; "qpeg-dvc", "QPEG video in DVC"),
347 desc!(video; "teal-video", "TealMovie video"),
348 desc!(audio; "teal-audio", "TealMovie audio"),
350 desc!(video; "ultimotion", "IBM Ultimotion"),
353 static AVI_VIDEO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
354 (&[1, 0, 0, 0], "msrle"),
355 (&[2, 0, 0, 0], "msrle"),
357 (b"CRAM", "msvideo1"),
358 (b"MSVC", "msvideo1"),
359 (b"WHAM", "msvideo1"),
369 (b"I263", "intel263"),
372 (b"UCOD", "clearvideo"),
373 (b"cvid", "cinepak"),
374 (b"savi", "cinepak"),
375 (b"tony", "cinepak"),
382 (b"MVDV", "midivid"),
383 (b"MV30", "midivid3"),
384 (b"MVLZ", "midivid-ll"),
388 (b"tmot", "truemotion1"),
389 (b"DUCK", "truemotion1"),
390 (b"PVEZ", "truemotion1"),
391 (b"TR20", "truemotionrt"),
392 (b"TM20", "truemotion2"),
393 (b"TM2A", "truemotion2x"),
394 (b"TM2X", "truemotion2x"),
411 (b"pDAD", "adorage"),
413 (b"pivc", "pivideo"),
415 (b"ULTI", "ultimotion"),
417 (b"ARBC", "gryphon-arbc-vfw"),
418 (b"azpr", "apple-video"),
421 (b"ESCP", "escape-any"),
423 (b"VXS1", "vxvideo"),
425 (b"DX50", "mpeg4asp"),
426 (b"DIVX", "mpeg4asp"),
427 (b"XVID", "mpeg4asp"),
430 static WAV_CODEC_REGISTER: &[(u16, &str)] = &[
433 (0x0002, "ms-adpcm"),
437 (0x0011, "ima-adpcm-ms"),
438 (0x0055, "mp3-multi"),
439 (0x0061, "adpcm-dk4"),
440 (0x0062, "adpcm-dk3"),
443 (0x0500, "on2avc-500"),
444 (0x0501, "on2avc-501"),
445 (0x2000, "ac3-multi"),
448 static MOV_VIDEO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
449 (b"cvid", "cinepak"),
451 (b"raw ", "rawvideo"),
455 (b"rpza", "apple-video"),
457 (b"cdvc", "qt-cdvideo"),
458 (b"SIVQ", "qt-sivq"),
459 (b"kpcd", "kodak-photocd"),
460 //(b"mpeg", "mpeg-video"),
461 (b"mjpa", "mjpeg-a"),
462 (b"mjpb", "mjpeg-b"),
463 (b"SVQ1", "sorenson-video"),
464 (b"svqi", "sorenson-video"),
465 (b"SVQ3", "sorenson-video3"),
466 (b"svq3", "sorenson-video3"),
468 (b"msvc", "msvideo1"),
475 (b"arbc", "gryphon-arbc-qt"),
476 (b"MPAK", "moviepak"),
478 (b"UCOD", "clearvideo"),
480 (b"tmot", "truemotion1"),
484 (b"ESCP", "escape-any"),
486 (b"mp4v", "mpeg4asp"),
489 (b"j420", "rawvideo"),
490 (b"yuv2", "qt-yuv2"),
491 (b"yuv4", "qt-yuv4"),
494 static MOV_AUDIO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
505 (b"ima4", "ima-adpcm-qt"),
508 (b"dvca", "dv-audio"),
509 (b"QDMC", "qdesign-music"),
510 (b"QDM2", "qdesign-music2"),
511 (b"Qclp", "qualcomm-purevoice"),
512 //(b".mp3", "mpeg-layer3"),
519 /// Returns video codec short name for provided FOURCC (used in AVI format).
520 pub fn find_codec_from_avi_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
521 for (fourcc, name) in AVI_VIDEO_CODEC_REGISTER.iter() {
522 if *fourcc == fcc { return Some(name); }
527 /// Returns FOURCC (used in AVI format) for provided codec name.
528 pub fn find_avi_fourcc(codecname: &str) -> Option<[u8; 4]> {
529 for (fourcc, name) in AVI_VIDEO_CODEC_REGISTER.iter() {
530 if *name == codecname { return Some(**fourcc); }
535 /// Returns known audio codec short name for provided TWOCC (used in WAV and AVI format).
536 pub fn find_codec_from_wav_twocc(tcc: u16) -> Option<&'static str> {
537 for (twocc, name) in WAV_CODEC_REGISTER.iter() {
538 if *twocc == tcc { return Some(name); }
543 /// Returns TWOCC (used in WAV and AVI format for provided codec name.
544 pub fn find_wav_twocc(codecname: &str) -> Option<u16> {
545 for (twocc, name) in WAV_CODEC_REGISTER.iter() {
546 if *name == codecname { return Some(*twocc); }
551 /// Returns video codec short name for provided FOURCC (used in MOV format).
552 pub fn find_codec_from_mov_video_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
553 for (fourcc, name) in MOV_VIDEO_CODEC_REGISTER.iter() {
554 if *fourcc == fcc { return Some(name); }
559 /// Returns known audio codec short name for provided FOURCC (used in MOV format).
560 pub fn find_codec_from_mov_audio_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
561 for (fourcc, name) in MOV_AUDIO_CODEC_REGISTER.iter() {
562 if *fourcc == fcc { return Some(name); }
567 /// Returns FOURCC (used in MOV format) for provided video codec name.
568 pub fn find_mov_video_fourcc(codecname: &str) -> Option<[u8; 4]> {
569 for (fourcc, name) in MOV_VIDEO_CODEC_REGISTER.iter() {
570 if *name == codecname { return Some(**fourcc); }
575 /// Returns FOURCC (used in MOV format) for provided audio codec name.
576 pub fn find_mov_audio_fourcc(codecname: &str) -> Option<[u8; 4]> {
577 for (fourcc, name) in MOV_AUDIO_CODEC_REGISTER.iter() {
578 if *name == codecname { return Some(**fourcc); }
589 let c1 = find_codec_from_avi_fourcc(b"IV41").unwrap();
590 let c2 = find_codec_from_wav_twocc(0x401).unwrap();
591 println!("found {} and {}", c1, c2);
592 let cd1 = get_codec_description(c1).unwrap();
593 let cd2 = get_codec_description(c2).unwrap();
594 println!("got {} and {}", cd1, cd2);