aac: clear M/S flags
[nihav.git] / nihav-registry / src / register.rs
... / ...
CommitLineData
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.
4use std::fmt;
5
6/// Codec types.
7#[derive(Debug,Clone,Copy,PartialEq)]
8#[allow(dead_code)]
9pub 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
22impl 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.
35pub const CODEC_CAP_INTRAONLY:u32 = 0x0001;
36/// Codec capability flag for lossless codecs.
37pub const CODEC_CAP_LOSSLESS:u32 = 0x0002;
38/// Codec capability flag for codecs with frame reordering.
39pub const CODEC_CAP_REORDER:u32 = 0x0004;
40/// Codec capability flag for codecs that can be both lossy and lossless.
41pub const CODEC_CAP_HYBRID:u32 = 0x0008;
42/// Codec capability flag for codecs with scalability features.
43pub const CODEC_CAP_SCALABLE:u32 = 0x0010;
44/// Codec capability flag for codecs with complex frame reordering.
45pub const CODEC_CAP_COMPLEX_REORDER:u32 = 0x0020;
46
47/// Codec description structure.
48#[derive(Clone)]
49pub 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
62impl 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
83impl 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
109macro_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.
149pub fn get_codec_description(name: &str) -> Option<&'static CodecDescription> {
150 CODEC_REGISTER.iter().find(|&reg| reg.name == name)
151}
152
153static 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-ll; "arm_rawvideo", "Acorn Replay Movie raw video formats"),
211 desc!(audio; "arm_rawaudio", "Acorn Replay Movie raw audio formats"),
212 desc!(video; "movinglines", "Acorn Moving Lines"),
213 desc!(video; "movingblocks", "Acorn Moving Blocks"),
214 desc!(video; "movingblockshq", "Acorn Moving Blocks HQ"),
215 desc!(video; "supermovingblocks", "Acorn Super Moving Blocks"),
216 desc!(video; "linepack", "Henrik Pedersen's LinePack"),
217 desc!(video; "movie16_3", "Henrik Pedersen's Movie 16:3"),
218 desc!(video; "escape100", "Eidos Escape 100"),
219 desc!(video; "escape102", "Eidos Escape 102"),
220 desc!(video; "escape122", "Eidos Escape 122"),
221 desc!(video; "escape124", "Eidos Escape 124"),
222 desc!(video; "escape130", "Eidos Escape 130"),
223
224 desc!(video; "truemotion1", "TrueMotion 1"),
225 desc!(video-im; "truemotionrt", "TrueMotion RT"),
226 desc!(video; "truemotion2", "TrueMotion 2"),
227 desc!(video; "truemotion2x", "TrueMotion 2X"),
228 desc!(video; "vp3", "VP3"),
229 desc!(video; "vp4", "VP4"),
230 desc!(video; "vp5", "VP5"),
231 desc!(video; "vp6", "VP6"),
232 desc!(video; "vp6f", "VP6 (in Flash)"),
233 desc!(video; "vp6a", "VP6 with alpha"),
234 desc!(video; "vp7", "VP7"),
235 desc!(video; "vp8", "VP8"),
236 desc!(video; "vp9", "VP9"),
237 desc!(audio; "adpcm-dk3", "Duck DK3 ADPCM"),
238 desc!(audio; "adpcm-dk4", "Duck DK4 ADPCM"),
239 desc!(audio; "on2avc-500", "On2 AVC"),
240 desc!(audio; "on2avc-501", "On2 AVC"),
241
242 desc!(video; "flv263", "Sorenson H.263"),
243 desc!(video-llp; "flashsv", "Flash Screen Video"),
244 desc!(video-llp; "flashsv2", "Flash Screen Video 2"),
245 desc!(audio; "asao", "N*llym*s*r ASAO"),
246 desc!(audio; "flv-adpcm", "Flash ADPCM"),
247
248 desc!(audio; "mp1", "MPEG Audio Layer I"),
249 desc!(audio; "mp2", "MPEG Audio Layer II"),
250 desc!(audio; "mp3", "MPEG Audio Layer III"),
251 desc!(audio; "speex", "Speex"),
252
253 desc!(video; "gdv-video", "Gremlin Digital Video - video"),
254 desc!(audio; "gdv-audio", "Gremlin Digital Video - audio"),
255 desc!(video-im; "arxel-video", "Arxel Tribe Video"),
256 desc!(video; "beam-fcp", "Beam Software Animation"),
257 desc!(video; "beam-video", "Beam Software Video"),
258 desc!(video; "bmv-video", "BMV video"),
259 desc!(audio; "bmv-audio", "BMV audio"),
260 desc!(video; "bmv3-video", "DW Noir BMV video"),
261 desc!(audio; "bmv3-audio", "DW Noir BMV audio"),
262 desc!(video; "dp-sga", "Digital Pictures SGA video"),
263 desc!(video; "fable-imax", "Fable IMAX video"),
264 desc!(video; "fst-video", "FutureVision video"),
265 desc!(audio; "fst-audio", "FutureVision audio"),
266 desc!(video; "hl-fmv-video", "Highlander FMV video"),
267 desc!(video-llp; "ipma", "Imagination Pilots Matte Animation"),
268 desc!(video-llp; "ipma2", "Imagination Pilots Matte Animation v2"),
269 desc!(video; "legend-q-video", "Legend Entertainment Q video"),
270 desc!(video; "midivid", "MidiVid"),
271 desc!(video; "midivid3", "MidiVid 3"),
272 desc!(video-ll; "midivid-ll", "MidiVid Lossless"),
273 desc!(video; "smushv1", "SMUSH Video paletted"),
274 desc!(video; "smushv2", "SMUSH Video 16-bit"),
275 desc!(video; "smush-iact", "SMUSH IACT Audio"),
276 desc!(video; "smush-vima", "SMUSH VIMA Audio"),
277 desc!(video; "vmd-video", "VMD video"),
278 desc!(audio; "vmd-audio", "VMD audio"),
279 desc!(video; "vxvideo", "Actimagine Vx"),
280 desc!(audio; "vxaudio", "Actimagine Sx"),
281
282 desc!(video; "smacker-video", "Smacker video"),
283 desc!(audio; "smacker-audio", "Smacker audio"),
284 desc!(video; "bink-video", "Bink video"),
285 desc!(video; "bink2-video", "Bink2 video"),
286 desc!(audio; "bink-audio-dct", "Bink audio (DCT)"),
287 desc!(audio; "bink-audio-rdft", "Bink audio (RDFT)"),
288
289 desc!(audio; "lhst15f8", "L&H StreamTalk 15kbps at 8 kHz"),
290 desc!(audio; "lhst250f11", "L&H StreamTalk 25kbps at 11 kHz"),
291 desc!(audio; "lhst500f22", "L&H StreamTalk 50kpbs at 22 kHz"),
292 desc!(audio; "lhst48", "L&H StreamTalk CELP Codec 4.8kbps at 8 kHz"),
293
294 desc!(video; "vivo1", "VivoActive Video 1.0"),
295 desc!(video; "vivo2", "VivoActive Video 2.0", CODEC_CAP_REORDER),
296 desc!(audio; "g723.1", "ITU G.723.1"),
297 desc!(audio; "siren", "Polycom Siren"),
298
299 desc!(audio-ll; "ape", "Monkey's Audio"),
300 desc!(audio-ll; "flac", "Free Lossless Audio Codec"),
301 desc!(audio-ll; "tta", "True Audio codec"),
302 desc!(audio-hyb; "wavpack", "WavPack"),
303
304 desc!(video-ll; "gif", "GIF"),
305 desc!(video-im; "jpeg", "JPEG"),
306 desc!(video; "h264", "ITU H.264", CODEC_CAP_COMPLEX_REORDER | CODEC_CAP_HYBRID),
307
308 desc!(video-im; "mwv1", "Aware MotionWavelets"),
309];
310
311static AVI_VIDEO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
312 (&[1, 0, 0, 0], "msrle"),
313 (&[2, 0, 0, 0], "msrle"),
314
315 (b"CRAM", "msvideo1"),
316 (b"MSVC", "msvideo1"),
317 (b"WHAM", "msvideo1"),
318
319 (b"MJPG", "jpeg"),
320
321 (b"IF09", "indeo1"),
322 (b"RT21", "indeo2"),
323 (b"IV31", "indeo3"),
324 (b"IV32", "indeo3"),
325 (b"IV41", "indeo4"),
326 (b"IV50", "indeo5"),
327 (b"I263", "intel263"),
328
329 (b"UCOD", "clearvideo"),
330 (b"cvid", "cinepak"),
331 (b"ZMBV", "zmbv"),
332
333 (b"Ipma", "ipma"),
334 (b"Ip20", "ipma2"),
335
336 (b"MVDV", "midivid"),
337 (b"MV30", "midivid3"),
338 (b"MVLZ", "midivid-ll"),
339
340 (b"DUCK", "truemotion1"),
341 (b"TR20", "truemotionrt"),
342 (b"TM20", "truemotion2"),
343 (b"TM2A", "truemotion2x"),
344 (b"TM2X", "truemotion2x"),
345 (b"VP30", "vp3"),
346 (b"VP31", "vp3"),
347 (b"VP40", "vp4"),
348 (b"VP50", "vp5"),
349 (b"VP60", "vp6"),
350 (b"VP61", "vp6"),
351 (b"VP62", "vp6"),
352 (b"VP6A", "vp6a"),
353 (b"VP70", "vp7"),
354
355 (b"MWV1", "mwv1"),
356];
357
358static WAV_CODEC_REGISTER: &[(u16, &str)] = &[
359 (0x0000, "unknown"),
360 (0x0001, "pcm"),
361 (0x0002, "ms-adpcm"),
362 (0x0003, "pcm"),
363 (0x0011, "ima-adpcm-ms"),
364 (0x0061, "adpcm-dk4"),
365 (0x0062, "adpcm-dk3"),
366 (0x0401, "imc"),
367 (0x0402, "iac"),
368 (0x0500, "on2avc-500"),
369 (0x0501, "on2avc-501"),
370];
371
372static MOV_VIDEO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
373 (b"cvid", "cinepak"),
374 (b"jpeg", "jpeg"),
375 //(b"raw ", "raw"),
376 //(b"Yuv2", "raw"),
377 (b"smc ", "qt-smc"),
378 (b"rle ", "qt-rle"),
379 (b"rpza", "apple-video"),
380 (b"kpcd", "kodak-photocd"),
381 //(b"mpeg", "mpeg-video"),
382 (b"mjpa", "mjpeg-a"),
383 (b"mjpb", "mjpeg-b"),
384 (b"svqi", "sorenson-video"),
385 (b"SVQ1", "sorenson-video"),
386 (b"svq3", "sorenson-video3"),
387 (b"SVQ3", "sorenson-video3"),
388
389 (b"IV31", "indeo3"),
390 (b"IV32", "indeo3"),
391
392 (b"UCOD", "clearvideo"),
393
394 (b"VP30", "vp3"),
395 (b"VP31", "vp3"),
396
397 (b"avc1", "h264"),
398];
399
400static MOV_AUDIO_CODEC_REGISTER: &[(&[u8;4], &str)] = &[
401 (b"NONE", "pcm"),
402 (b"raw ", "pcm"),
403 (b"twos", "pcm"),
404 (b"sowt", "pcm"),
405 (b"fl32", "pcm"),
406 (b"fl64", "pcm"),
407 (b"in24", "pcm"),
408 (b"in32", "pcm"),
409 (b"MAC3", "mace-3"),
410 (b"MAC6", "mace-6"),
411 (b"ima4", "ima-adpcm-qt"),
412 (b"ulaw", "ulaw"),
413 (b"alaw", "alaw"),
414 (b"dvca", "dv-audio"),
415 (b"QDMC", "qdesign-music"),
416 (b"QDM2", "qdesign-music2"),
417 (b"Qclp", "qualcomm-purevoice"),
418 //(b".mp3", "mpeg-layer3"),
419
420 (b"mp4a", "aac"),
421
422 (b"alac", "alac"),
423];
424
425/// Returns video codec short name for provided FOURCC (used in AVI format).
426pub fn find_codec_from_avi_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
427 for (fourcc, name) in AVI_VIDEO_CODEC_REGISTER.iter() {
428 if *fourcc == fcc { return Some(name); }
429 }
430 None
431}
432
433/// Returns FOURCC (used in AVI format) for provided codec name.
434pub fn find_avi_fourcc(codecname: &str) -> Option<[u8; 4]> {
435 for (fourcc, name) in AVI_VIDEO_CODEC_REGISTER.iter() {
436 if *name == codecname { return Some(**fourcc); }
437 }
438 None
439}
440
441/// Returns known audio codec short name for provided TWOCC (used in WAV and AVI format).
442pub fn find_codec_from_wav_twocc(tcc: u16) -> Option<&'static str> {
443 for (twocc, name) in WAV_CODEC_REGISTER.iter() {
444 if *twocc == tcc { return Some(name); }
445 }
446 None
447}
448
449/// Returns TWOCC (used in WAV and AVI format for provided codec name.
450pub fn find_wav_twocc(codecname: &str) -> Option<u16> {
451 for (twocc, name) in WAV_CODEC_REGISTER.iter() {
452 if *name == codecname { return Some(*twocc); }
453 }
454 None
455}
456
457/// Returns video codec short name for provided FOURCC (used in MOV format).
458pub fn find_codec_from_mov_video_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
459 for (fourcc, name) in MOV_VIDEO_CODEC_REGISTER.iter() {
460 if *fourcc == fcc { return Some(name); }
461 }
462 None
463}
464
465/// Returns known audio codec short name for provided FOURCC (used in MOV format).
466pub fn find_codec_from_mov_audio_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
467 for (fourcc, name) in MOV_AUDIO_CODEC_REGISTER.iter() {
468 if *fourcc == fcc { return Some(name); }
469 }
470 None
471}
472
473#[cfg(test)]
474mod test {
475 use super::*;
476
477 #[test]
478 fn test_register() {
479 let c1 = find_codec_from_avi_fourcc(b"IV41").unwrap();
480 let c2 = find_codec_from_wav_twocc(0x401).unwrap();
481 println!("found {} and {}", c1, c2);
482 let cd1 = get_codec_description(c1).unwrap();
483 let cd2 = get_codec_description(c2).unwrap();
484 println!("got {} and {}", cd1, cd2);
485 }
486}