aac: clear M/S flags
[nihav.git] / nihav-registry / src / register.rs
1 //! Global registry of codec information.
2 //!
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.
4 use std::fmt;
5
6 /// Codec types.
7 #[derive(Debug,Clone,Copy,PartialEq)]
8 #[allow(dead_code)]
9 pub enum CodecType {
10 /// Video codec.
11 Video,
12 /// Audio codec.
13 Audio,
14 /// Subtitle codec.
15 Subtitles,
16 /// Some special codec (e.g. some event stream or separate timecodes stream).
17 Data,
18 /// Dummy codec.
19 None,
20 }
21
22 impl fmt::Display for CodecType {
23 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24 match *self {
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, "-"),
30 }
31 }
32 }
33
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;
46
47 /// Codec description structure.
48 #[derive(Clone)]
49 pub struct CodecDescription {
50 /// Short codec name.
51 ///
52 /// Short codec name is used inside NihAV as the unique identifier.
53 pub name: &'static str,
54 /// Full codec name.
55 pub fname: &'static str,
56 /// Codec type.
57 pub ctype: CodecType,
58 /// Codec capabilities.
59 pub caps: u32,
60 }
61
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.
78 ///
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 }
81 }
82
83 impl fmt::Display for CodecDescription {
84 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
85 let mut out = self.fname.to_string();
86 if self.caps != 0 {
87 let mut capfmt = "".to_string();
88 if (self.caps & CODEC_CAP_INTRAONLY) != 0 {
89 capfmt = format!("{} Intra-only", capfmt);
90 }
91 if (self.caps & CODEC_CAP_LOSSLESS) != 0 {
92 capfmt = format!("{} Lossless", capfmt);
93 }
94 if (self.caps & CODEC_CAP_REORDER) != 0 {
95 capfmt = format!("{} Frame reorder", capfmt);
96 }
97 if (self.caps & CODEC_CAP_HYBRID) != 0 {
98 capfmt = format!("{} Can be lossy and lossless", capfmt);
99 }
100 if (self.caps & CODEC_CAP_SCALABLE) != 0 {
101 capfmt = format!("{} Scalable", capfmt);
102 }
103 out = format!("{} ({})", out, capfmt);
104 }
105 write!(f, "{}", out)
106 }
107 }
108
109 macro_rules! desc {
110 (video; $n:expr, $fn:expr) => ({
111 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
112 caps: 0 }
113 });
114 (video; $n:expr, $fn:expr, $c:expr) => ({
115 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
116 caps: $c }
117 });
118 (video-ll; $n:expr, $fn:expr) => ({
119 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
120 caps: CODEC_CAP_LOSSLESS | CODEC_CAP_INTRAONLY }
121 });
122 (video-llp; $n:expr, $fn:expr) => ({
123 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
124 caps: CODEC_CAP_LOSSLESS }
125 });
126 (video-im; $n:expr, $fn:expr) => ({
127 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
128 caps: CODEC_CAP_INTRAONLY }
129 });
130 (video-modern; $n:expr, $fn:expr) => ({
131 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
132 caps: CODEC_CAP_REORDER | CODEC_CAP_HYBRID }
133 });
134 (audio; $n:expr, $fn:expr) => ({
135 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Audio,
136 caps: 0 }
137 });
138 (audio-ll; $n:expr, $fn:expr) => ({
139 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Audio,
140 caps: CODEC_CAP_LOSSLESS | CODEC_CAP_INTRAONLY }
141 });
142 (audio-hyb; $n:expr, $fn:expr) => ({
143 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Audio,
144 caps: CODEC_CAP_HYBRID }
145 });
146 }
147
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| reg.name == name)
151 }
152
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"),
157
158 desc!(video-im; "indeo1", "Intel Raw IF09"),
159 desc!(video-im; "indeo2", "Intel Indeo 2"),
160 desc!(video; "indeo3", "Intel Indeo 3"),
161 desc!(video; "indeo4", "Intel Indeo 4", CODEC_CAP_REORDER | CODEC_CAP_SCALABLE),
162 desc!(video; "indeo5", "Intel Indeo 5", CODEC_CAP_REORDER | CODEC_CAP_SCALABLE),
163 desc!(video; "indeo5s", "Intel Indeo 5 Scalable", CODEC_CAP_SCALABLE),
164 desc!(video; "intel263", "Intel I263", CODEC_CAP_REORDER),
165 desc!(audio; "iac", "Intel Indeo audio"),
166 desc!(audio; "imc", "Intel Music Coder"),
167
168 desc!(video; "realvideo1", "Real Video 1"),
169 desc!(video; "realvideo2", "Real Video 2", CODEC_CAP_REORDER),
170 desc!(video; "realvideo3", "Real Video 3", CODEC_CAP_REORDER),
171 desc!(video; "realvideo4", "Real Video 4", CODEC_CAP_REORDER),
172 desc!(video; "realvideo6", "Real Video 6", CODEC_CAP_REORDER),
173 desc!(video; "clearvideo", "ClearVideo"),
174 desc!(video; "clearvideo_rm", "ClearVideo"),
175 desc!(audio; "ra14.4", "RealAudio 14.4"),
176 desc!(audio; "ra28.8", "RealAudio 28.8"),
177 desc!(audio; "cook", "RealAudio Cooker"),
178 desc!(audio; "ralf", "RealAudio Lossless"),
179 desc!(audio; "aac", "AAC"),
180 desc!(audio; "ac3", "ETSI TS 102 366"),
181 desc!(audio; "atrac3", "Sony Atrac3"),
182 desc!(audio; "sipro", "Sipro Labs ADPCM"),
183
184
185 desc!(video-ll; "rawvideo", "Raw video data"),
186 desc!(video-ll; "rawvideo-ms", "Raw video data"),
187
188 desc!(video; "cinepak", "Cinepak"),
189
190 desc!(video-llp; "zmbv", "Zip Motion Blocks Video"),
191
192 desc!(video; "msvideo1", "MS Video 1"),
193 desc!(video; "msrle", "MS RLE"),
194 desc!(audio; "ms-adpcm", "MS ADPCM"),
195 desc!(audio; "ima-adpcm-ms", "IMA ADPCM (MS variant)"),
196
197 desc!(video; "qt-smc", "Apple Graphics"),
198 desc!(video; "qt-rle", "Apple Animation"),
199 desc!(video; "apple-video", "Apple video"),
200 desc!(video; "sorenson-video", "Sorenson Video"),
201 desc!(video; "sorenson-video3", "Sorenson Video 3", CODEC_CAP_REORDER),
202 desc!(audio-ll; "alac", "Apple Lossless Audio Codec"),
203 desc!(audio; "mace-3", "MACE 3:1"),
204 desc!(audio; "mace-6", "MACE 6:1"),
205 desc!(audio; "ima-adpcm-qt", "IMA ADPCM (Apple variant)"),
206 desc!(audio; "qdesign-music", "QDesign Music"),
207 desc!(audio; "qdesign-music2", "QDesign Music v2"),
208 desc!(audio; "qualcomm-purevoice", "Qualcomm PureVoice"),
209
210 desc!(video; "movinglines", "Acorn Moving Lines"),
211 desc!(video; "movingblocks", "Acorn Moving Blocks"),
212 desc!(video; "movingblockshq", "Acorn Moving Blocks HQ"),
213 desc!(video; "supermovingblocks", "Acorn Super Moving Blocks"),
214 desc!(video; "linepack", "Henrik Pedersen's LinePack"),
215 desc!(video; "movie16_3", "Henrik Pedersen's Movie 16:3"),
216 desc!(video; "escape100", "Eidos Escape 100"),
217 desc!(video; "escape102", "Eidos Escape 102"),
218 desc!(video; "escape122", "Eidos Escape 122"),
219 desc!(video; "escape124", "Eidos Escape 124"),
220 desc!(video; "escape130", "Eidos Escape 130"),
221
222 desc!(video; "truemotion1", "TrueMotion 1"),
223 desc!(video-im; "truemotionrt", "TrueMotion RT"),
224 desc!(video; "truemotion2", "TrueMotion 2"),
225 desc!(video; "truemotion2x", "TrueMotion 2X"),
226 desc!(video; "vp3", "VP3"),
227 desc!(video; "vp4", "VP4"),
228 desc!(video; "vp5", "VP5"),
229 desc!(video; "vp6", "VP6"),
230 desc!(video; "vp6f", "VP6 (in Flash)"),
231 desc!(video; "vp6a", "VP6 with alpha"),
232 desc!(video; "vp7", "VP7"),
233 desc!(video; "vp8", "VP8"),
234 desc!(video; "vp9", "VP9"),
235 desc!(audio; "adpcm-dk3", "Duck DK3 ADPCM"),
236 desc!(audio; "adpcm-dk4", "Duck DK4 ADPCM"),
237 desc!(audio; "on2avc-500", "On2 AVC"),
238 desc!(audio; "on2avc-501", "On2 AVC"),
239
240 desc!(video; "flv263", "Sorenson H.263"),
241 desc!(video-llp; "flashsv", "Flash Screen Video"),
242 desc!(video-llp; "flashsv2", "Flash Screen Video 2"),
243 desc!(audio; "asao", "N*llym*s*r ASAO"),
244 desc!(audio; "flv-adpcm", "Flash ADPCM"),
245
246 desc!(audio; "mp1", "MPEG Audio Layer I"),
247 desc!(audio; "mp2", "MPEG Audio Layer II"),
248 desc!(audio; "mp3", "MPEG Audio Layer III"),
249 desc!(audio; "speex", "Speex"),
250
251 desc!(video; "gdv-video", "Gremlin Digital Video - video"),
252 desc!(audio; "gdv-audio", "Gremlin Digital Video - audio"),
253 desc!(video-im; "arxel-video", "Arxel Tribe Video"),
254 desc!(video; "beam-fcp", "Beam Software Animation"),
255 desc!(video; "beam-video", "Beam Software Video"),
256 desc!(video; "bmv-video", "BMV video"),
257 desc!(audio; "bmv-audio", "BMV audio"),
258 desc!(video; "bmv3-video", "DW Noir BMV video"),
259 desc!(audio; "bmv3-audio", "DW Noir BMV audio"),
260 desc!(video; "dp-sga", "Digital Pictures SGA video"),
261 desc!(video; "fable-imax", "Fable IMAX video"),
262 desc!(video; "fst-video", "FutureVision video"),
263 desc!(audio; "fst-audio", "FutureVision audio"),
264 desc!(video; "hl-fmv-video", "Highlander FMV video"),
265 desc!(video-llp; "ipma", "Imagination Pilots Matte Animation"),
266 desc!(video-llp; "ipma2", "Imagination Pilots Matte Animation v2"),
267 desc!(video; "legend-q-video", "Legend Entertainment Q video"),
268 desc!(video; "midivid", "MidiVid"),
269 desc!(video; "midivid3", "MidiVid 3"),
270 desc!(video-ll; "midivid-ll", "MidiVid Lossless"),
271 desc!(video; "smushv1", "SMUSH Video paletted"),
272 desc!(video; "smushv2", "SMUSH Video 16-bit"),
273 desc!(video; "smush-iact", "SMUSH IACT Audio"),
274 desc!(video; "smush-vima", "SMUSH VIMA Audio"),
275 desc!(video; "vmd-video", "VMD video"),
276 desc!(audio; "vmd-audio", "VMD audio"),
277 desc!(video; "vxvideo", "Actimagine Vx"),
278 desc!(audio; "vxaudio", "Actimagine Sx"),
279
280 desc!(video; "smacker-video", "Smacker video"),
281 desc!(audio; "smacker-audio", "Smacker audio"),
282 desc!(video; "bink-video", "Bink video"),
283 desc!(video; "bink2-video", "Bink2 video"),
284 desc!(audio; "bink-audio-dct", "Bink audio (DCT)"),
285 desc!(audio; "bink-audio-rdft", "Bink audio (RDFT)"),
286
287 desc!(audio; "lhst15f8", "L&H StreamTalk 15kbps at 8 kHz"),
288 desc!(audio; "lhst250f11", "L&H StreamTalk 25kbps at 11 kHz"),
289 desc!(audio; "lhst500f22", "L&H StreamTalk 50kpbs at 22 kHz"),
290 desc!(audio; "lhst48", "L&H StreamTalk CELP Codec 4.8kbps at 8 kHz"),
291
292 desc!(video; "vivo1", "VivoActive Video 1.0"),
293 desc!(video; "vivo2", "VivoActive Video 2.0", CODEC_CAP_REORDER),
294 desc!(audio; "g723.1", "ITU G.723.1"),
295 desc!(audio; "siren", "Polycom Siren"),
296
297 desc!(audio-ll; "ape", "Monkey's Audio"),
298 desc!(audio-ll; "flac", "Free Lossless Audio Codec"),
299 desc!(audio-ll; "tta", "True Audio codec"),
300 desc!(audio-hyb; "wavpack", "WavPack"),
301
302 desc!(video-ll; "gif", "GIF"),
303 desc!(video-im; "jpeg", "JPEG"),
304 desc!(video; "h264", "ITU H.264", CODEC_CAP_COMPLEX_REORDER | CODEC_CAP_HYBRID),
305
306 desc!(video-im; "mwv1", "Aware MotionWavelets"),
307 ];
308
309 static AVI_VIDEO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
310 (&[1, 0, 0, 0], "msrle"),
311 (&[2, 0, 0, 0], "msrle"),
312
313 (b"CRAM", "msvideo1"),
314 (b"MSVC", "msvideo1"),
315 (b"WHAM", "msvideo1"),
316
317 (b"MJPG", "jpeg"),
318
319 (b"IF09", "indeo1"),
320 (b"RT21", "indeo2"),
321 (b"IV31", "indeo3"),
322 (b"IV32", "indeo3"),
323 (b"IV41", "indeo4"),
324 (b"IV50", "indeo5"),
325 (b"I263", "intel263"),
326
327 (b"UCOD", "clearvideo"),
328 (b"cvid", "cinepak"),
329 (b"ZMBV", "zmbv"),
330
331 (b"Ipma", "ipma"),
332 (b"Ip20", "ipma2"),
333
334 (b"MVDV", "midivid"),
335 (b"MV30", "midivid3"),
336 (b"MVLZ", "midivid-ll"),
337
338 (b"DUCK", "truemotion1"),
339 (b"TR20", "truemotionrt"),
340 (b"TM20", "truemotion2"),
341 (b"TM2A", "truemotion2x"),
342 (b"TM2X", "truemotion2x"),
343 (b"VP30", "vp3"),
344 (b"VP31", "vp3"),
345 (b"VP40", "vp4"),
346 (b"VP50", "vp5"),
347 (b"VP60", "vp6"),
348 (b"VP61", "vp6"),
349 (b"VP62", "vp6"),
350 (b"VP6A", "vp6a"),
351 (b"VP70", "vp7"),
352
353 (b"MWV1", "mwv1"),
354 ];
355
356 static WAV_CODEC_REGISTER: &[(u16, &str)] = &[
357 (0x0000, "unknown"),
358 (0x0001, "pcm"),
359 (0x0002, "ms-adpcm"),
360 (0x0003, "pcm"),
361 (0x0011, "ima-adpcm-ms"),
362 (0x0061, "adpcm-dk4"),
363 (0x0062, "adpcm-dk3"),
364 (0x0401, "imc"),
365 (0x0402, "iac"),
366 (0x0500, "on2avc-500"),
367 (0x0501, "on2avc-501"),
368 ];
369
370 static MOV_VIDEO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
371 (b"cvid", "cinepak"),
372 (b"jpeg", "jpeg"),
373 //(b"raw ", "raw"),
374 //(b"Yuv2", "raw"),
375 (b"smc ", "qt-smc"),
376 (b"rle ", "qt-rle"),
377 (b"rpza", "apple-video"),
378 (b"kpcd", "kodak-photocd"),
379 //(b"mpeg", "mpeg-video"),
380 (b"mjpa", "mjpeg-a"),
381 (b"mjpb", "mjpeg-b"),
382 (b"svqi", "sorenson-video"),
383 (b"SVQ1", "sorenson-video"),
384 (b"svq3", "sorenson-video3"),
385 (b"SVQ3", "sorenson-video3"),
386
387 (b"IV31", "indeo3"),
388 (b"IV32", "indeo3"),
389
390 (b"UCOD", "clearvideo"),
391
392 (b"VP30", "vp3"),
393 (b"VP31", "vp3"),
394
395 (b"avc1", "h264"),
396 ];
397
398 static MOV_AUDIO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
399 (b"NONE", "pcm"),
400 (b"raw ", "pcm"),
401 (b"twos", "pcm"),
402 (b"sowt", "pcm"),
403 (b"fl32", "pcm"),
404 (b"fl64", "pcm"),
405 (b"in24", "pcm"),
406 (b"in32", "pcm"),
407 (b"MAC3", "mace-3"),
408 (b"MAC6", "mace-6"),
409 (b"ima4", "ima-adpcm-qt"),
410 (b"ulaw", "ulaw"),
411 (b"alaw", "alaw"),
412 (b"dvca", "dv-audio"),
413 (b"QDMC", "qdesign-music"),
414 (b"QDM2", "qdesign-music2"),
415 (b"Qclp", "qualcomm-purevoice"),
416 //(b".mp3", "mpeg-layer3"),
417
418 (b"mp4a", "aac"),
419
420 (b"alac", "alac"),
421 ];
422
423 /// Returns video codec short name for provided FOURCC (used in AVI format).
424 pub fn find_codec_from_avi_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
425 for (fourcc, name) in AVI_VIDEO_CODEC_REGISTER.iter() {
426 if *fourcc == fcc { return Some(name); }
427 }
428 None
429 }
430
431 /// Returns FOURCC (used in AVI format) for provided codec name.
432 pub fn find_avi_fourcc(codecname: &str) -> Option<[u8; 4]> {
433 for (fourcc, name) in AVI_VIDEO_CODEC_REGISTER.iter() {
434 if *name == codecname { return Some(**fourcc); }
435 }
436 None
437 }
438
439 /// Returns known audio codec short name for provided TWOCC (used in WAV and AVI format).
440 pub fn find_codec_from_wav_twocc(tcc: u16) -> Option<&'static str> {
441 for (twocc, name) in WAV_CODEC_REGISTER.iter() {
442 if *twocc == tcc { return Some(name); }
443 }
444 None
445 }
446
447 /// Returns TWOCC (used in WAV and AVI format for provided codec name.
448 pub fn find_wav_twocc(codecname: &str) -> Option<u16> {
449 for (twocc, name) in WAV_CODEC_REGISTER.iter() {
450 if *name == codecname { return Some(*twocc); }
451 }
452 None
453 }
454
455 /// Returns video codec short name for provided FOURCC (used in MOV format).
456 pub fn find_codec_from_mov_video_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
457 for (fourcc, name) in MOV_VIDEO_CODEC_REGISTER.iter() {
458 if *fourcc == fcc { return Some(name); }
459 }
460 None
461 }
462
463 /// Returns known audio codec short name for provided FOURCC (used in MOV format).
464 pub fn find_codec_from_mov_audio_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
465 for (fourcc, name) in MOV_AUDIO_CODEC_REGISTER.iter() {
466 if *fourcc == fcc { return Some(name); }
467 }
468 None
469 }
470
471 #[cfg(test)]
472 mod test {
473 use super::*;
474
475 #[test]
476 fn test_register() {
477 let c1 = find_codec_from_avi_fourcc(b"IV41").unwrap();
478 let c2 = find_codec_from_wav_twocc(0x401).unwrap();
479 println!("found {} and {}", c1, c2);
480 let cd1 = get_codec_description(c1).unwrap();
481 let cd2 = get_codec_description(c2).unwrap();
482 println!("got {} and {}", cd1, cd2);
483 }
484 }