core: document refs module
[nihav.git] / nihav-core / src / register.rs
CommitLineData
d48ee414
KS
1use std::fmt;
2
34829caa 3#[derive(Debug,Clone,Copy,PartialEq)]
d48ee414
KS
4#[allow(dead_code)]
5pub enum CodecType {
6 Video,
7 Audio,
8 Subtitles,
9 Data,
10 None,
11}
12
13impl fmt::Display for CodecType {
14 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
15 match *self {
16 CodecType::Video => write!(f, "Video"),
17 CodecType::Audio => write!(f, "Audio"),
18 CodecType::Subtitles => write!(f, "Subtitles"),
19 CodecType::Data => write!(f, "Data"),
20 CodecType::None => write!(f, "-"),
21 }
22 }
23}
24
e243ceb4
KS
25const CODEC_CAP_INTRAONLY:u32 = 0x0001;
26const CODEC_CAP_LOSSLESS:u32 = 0x0002;
27const CODEC_CAP_REORDER:u32 = 0x0004;
28const CODEC_CAP_HYBRID:u32 = 0x0008;
29const CODEC_CAP_SCALABLE:u32 = 0x0010;
d48ee414 30
34829caa 31#[derive(Clone)]
d48ee414 32pub struct CodecDescription {
5641dccf
KS
33 pub name: &'static str,
34 pub fname: &'static str,
35 pub ctype: CodecType,
36 pub caps: u32,
d48ee414
KS
37}
38
39impl CodecDescription {
40 pub fn get_name(&self) -> &'static str { self.name }
41 pub fn get_full_name(&self) -> &'static str { self.fname }
42 pub fn get_codec_type(&self) -> CodecType { self.ctype }
43 pub fn is_intraonly(&self) -> bool { (self.caps & CODEC_CAP_INTRAONLY) != 0 }
44 pub fn is_lossless(&self) -> bool { (self.caps & CODEC_CAP_LOSSLESS) != 0 }
45 pub fn has_reorder(&self) -> bool { (self.caps & CODEC_CAP_REORDER) != 0 }
46 pub fn is_hybrid(&self) -> bool { (self.caps & CODEC_CAP_HYBRID) != 0 }
47 pub fn is_scalable(&self) -> bool { (self.caps & CODEC_CAP_SCALABLE) != 0 }
48}
49
50impl fmt::Display for CodecDescription {
51 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
e243ceb4 52 let mut out = self.fname.to_string();
d48ee414
KS
53 if self.caps != 0 {
54 let mut capfmt = "".to_string();
55 if (self.caps & CODEC_CAP_INTRAONLY) != 0 {
56 capfmt = format!("{} Intra-only", capfmt);
57 }
58 if (self.caps & CODEC_CAP_LOSSLESS) != 0 {
59 capfmt = format!("{} Lossless", capfmt);
60 }
61 if (self.caps & CODEC_CAP_REORDER) != 0 {
62 capfmt = format!("{} Frame reorder", capfmt);
63 }
64 if (self.caps & CODEC_CAP_HYBRID) != 0 {
65 capfmt = format!("{} Can be lossy and lossless", capfmt);
66 }
67 if (self.caps & CODEC_CAP_SCALABLE) != 0 {
68 capfmt = format!("{} Scalable", capfmt);
69 }
70 out = format!("{} ({})", out, capfmt);
71 }
72 write!(f, "{}", out)
73 }
74}
75
76macro_rules! desc {
77 (video; $n:expr, $fn:expr) => ({
78 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
79 caps: 0 }
80 });
81 (video; $n:expr, $fn:expr, $c:expr) => ({
82 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
83 caps: $c }
84 });
85 (video-ll; $n:expr, $fn:expr) => ({
86 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
87 caps: CODEC_CAP_LOSSLESS | CODEC_CAP_INTRAONLY }
88 });
89 (video-llp; $n:expr, $fn:expr) => ({
90 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
91 caps: CODEC_CAP_LOSSLESS }
92 });
93 (video-im; $n:expr, $fn:expr) => ({
94 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
95 caps: CODEC_CAP_INTRAONLY }
96 });
97 (video-modern; $n:expr, $fn:expr) => ({
98 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Video,
99 caps: CODEC_CAP_REORDER | CODEC_CAP_HYBRID }
100 });
101 (audio; $n:expr, $fn:expr) => ({
102 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Audio,
103 caps: 0 }
104 });
105 (audio-ll; $n:expr, $fn:expr) => ({
106 CodecDescription{ name: $n, fname: $fn, ctype: CodecType::Audio,
107 caps: CODEC_CAP_LOSSLESS | CODEC_CAP_INTRAONLY }
108 });
109}
110
111pub fn get_codec_description(name: &str) -> Option<&'static CodecDescription> {
34829caa
KS
112 for reg in CODEC_REGISTER {
113 if reg.name == name {
114 return Some(reg);
d48ee414
KS
115 }
116 }
117 None
118}
119
120static CODEC_REGISTER: &'static [CodecDescription] = &[
e8e022f4
KS
121 desc!(audio-ll; "pcm", "PCM"),
122
45e794c4
KS
123 desc!(video-im; "indeo1", "Intel Raw IF09"),
124 desc!(video-im; "indeo2", "Intel Indeo 2"),
125 desc!(video; "indeo3", "Intel Indeo 3"),
126 desc!(video; "indeo4", "Intel Indeo 4", CODEC_CAP_REORDER | CODEC_CAP_SCALABLE),
127 desc!(video; "indeo5", "Intel Indeo 5", CODEC_CAP_REORDER | CODEC_CAP_SCALABLE),
1a36a05d 128 desc!(video; "intel263", "Intel I263", CODEC_CAP_REORDER),
45e794c4
KS
129 desc!(audio; "iac", "Intel Indeo audio"),
130 desc!(audio; "imc", "Intel Music Coder"),
ce52b3b5
KS
131
132 desc!(video; "realvideo1", "Real Video 1"),
133 desc!(video; "realvideo2", "Real Video 2"),
134 desc!(video; "realvideo3", "Real Video 3", CODEC_CAP_REORDER),
135 desc!(video; "realvideo4", "Real Video 4", CODEC_CAP_REORDER),
0b791d5c 136 desc!(video; "realvideo6", "Real Video 6", CODEC_CAP_REORDER),
ce52b3b5 137 desc!(video; "clearvideo", "ClearVideo"),
750b299c 138 desc!(video; "clearvideo_rm", "ClearVideo"),
ce52b3b5
KS
139 desc!(audio; "ra14.4", "RealAudio 14.4"),
140 desc!(audio; "ra28.8", "RealAudio 28.8"),
141 desc!(audio; "cook", "RealAudio Cooker"),
142 desc!(audio; "ralf", "RealAudio Lossless"),
143 desc!(audio; "aac", "AAC"),
16dd4f44 144 desc!(audio; "ac3", "ETSI TS 102 366"),
ce52b3b5
KS
145 desc!(audio; "atrac3", "Sony Atrac3"),
146 desc!(audio; "sipro", "Sipro Labs ADPCM"),
e8e022f4 147
d24468d9
KS
148 desc!(video; "truemotion1", "TrueMotion 1"),
149 desc!(video-im; "truemotionrt", "TrueMotion RT"),
150 desc!(video; "truemotion2", "TrueMotion 2"),
e8e022f4
KS
151 desc!(video; "truemotion2x", "TrueMotion 2X"),
152 desc!(video; "vp3", "VP3"),
153 desc!(video; "vp4", "VP4"),
154 desc!(video; "vp5", "VP5"),
155 desc!(video; "vp6", "VP6"),
629a1025 156 desc!(video; "vp6a", "VP6"),
e8e022f4
KS
157 desc!(video; "vp7", "VP7"),
158 desc!(video; "vp8", "VP8"),
159 desc!(video; "vp9", "VP9"),
160 desc!(audio; "adpcm-dk3", "Duck DK3 ADPCM"),
161 desc!(audio; "adpcm-dk4", "Duck DK4 ADPCM"),
629a1025
KS
162 desc!(audio; "on2avc-500", "On2 AVC"),
163 desc!(audio; "on2avc-501", "On2 AVC"),
e8e022f4
KS
164
165 desc!(video; "gdv-video", "Gremlin Digital Video - video"),
166 desc!(audio; "gdv-audio", "Gremlin Digital Video - audio"),
167 desc!(video; "bmv-video", "BMV video"),
168 desc!(audio; "bmv-audio", "BMV audio"),
ecda1cc1
KS
169 desc!(video; "bmv3-video", "DW Noir BMV video"),
170 desc!(audio; "bmv3-audio", "DW Noir BMV audio"),
801bba83
KS
171 desc!(video; "midivid", "MidiVid"),
172 desc!(video; "midivid3", "MidiVid 3"),
173 desc!(video-ll; "midivid-ll", "MidiVid Lossless"),
9895bd7b
KS
174 desc!(video; "vmd-video", "VMD video"),
175 desc!(audio; "vmd-audio", "VMD audio"),
e8e022f4
KS
176
177 desc!(video; "smacker-video", "Smacker video"),
178 desc!(audio; "smacker-audio", "Smacker audio"),
179 desc!(video; "bink-video", "Bink video"),
180 desc!(video; "bink2-video", "Bink2 video"),
181 desc!(audio; "bink-audio-dct", "Bink audio (DCT)"),
182 desc!(audio; "bink-audio-rdft", "Bink audio (RDFT)"),
d48ee414
KS
183];
184
185static AVI_VIDEO_CODEC_REGISTER: &'static [(&[u8;4], &str)] = &[
45e794c4
KS
186 (b"IF09", "indeo1"),
187 (b"RT21", "indeo2"),
188 (b"IV31", "indeo3"),
189 (b"IV32", "indeo3"),
190 (b"IV41", "indeo4"),
191 (b"IV50", "indeo5"),
836bf150 192 (b"I263", "intel263"),
ce52b3b5 193
750b299c 194 (b"UCOD", "clearvideo"),
b2d656d0 195
801bba83
KS
196 (b"MVDV", "midivid"),
197 (b"MV30", "midivid3"),
198 (b"MVLZ", "midivid-ll"),
199
b2d656d0
KS
200 (b"DUCK", "truemotion1"),
201 (b"TR20", "truemotionrt"),
202 (b"TM20", "truemotion2"),
203 (b"TM2A", "truemotion2x"),
204 (b"TM2X", "truemotion2x"),
40e95291
KS
205 (b"VP30", "vp3"),
206 (b"VP31", "vp3"),
207 (b"VP40", "vp4"),
208 (b"VP50", "vp5"),
209 (b"VP60", "vp6"),
210 (b"VP61", "vp6"),
211 (b"VP62", "vp6"),
1bf8e0fc 212 (b"VP6A", "vp6a"),
40e95291 213 (b"VP70", "vp7"),
d48ee414
KS
214];
215
216static WAV_CODEC_REGISTER: &'static [(u16, &str)] = &[
45e794c4
KS
217 (0x0000, "pcm"),
218 (0x0001, "pcm"),
219 (0x0003, "pcm"),
fadee95f
KS
220 (0x0061, "adpcm-dk4"),
221 (0x0062, "adpcm-dk3"),
45e794c4
KS
222 (0x0401, "imc"),
223 (0x0402, "iac"),
a38be6e4
KS
224 (0x0500, "on2avc-500"),
225 (0x0501, "on2avc-501"),
d48ee414
KS
226];
227
228pub fn find_codec_from_avi_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
e243ceb4
KS
229 for (fourcc, name) in AVI_VIDEO_CODEC_REGISTER.iter() {
230 if *fourcc == fcc { return Some(name); }
d48ee414
KS
231 }
232 None
233}
234
235pub fn find_codec_from_wav_twocc(tcc: u16) -> Option<&'static str> {
e243ceb4
KS
236 for (twocc, name) in WAV_CODEC_REGISTER.iter() {
237 if *twocc == tcc { return Some(name); }
d48ee414
KS
238 }
239 None
240}
241
242#[cfg(test)]
243mod test {
244 use super::*;
245
246 #[test]
247 fn test_register() {
248 let c1 = find_codec_from_avi_fourcc(b"IV41").unwrap();
249 let c2 = find_codec_from_wav_twocc(0x401).unwrap();
250 println!("found {} and {}", c1, c2);
251 let cd1 = get_codec_description(c1).unwrap();
252 let cd2 = get_codec_description(c2).unwrap();
253 println!("got {} and {}", cd1, cd2);
254 }
b58d7656 255}