fix trailing whitespace
[nihav.git] / 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
25const CODEC_CAP_INTRAONLY:u32 = 0x000001;
26const CODEC_CAP_LOSSLESS:u32 = 0x000002;
27const CODEC_CAP_REORDER:u32 = 0x000004;
28const CODEC_CAP_HYBRID:u32 = 0x000008;
29const CODEC_CAP_SCALABLE:u32 = 0x000010;
30
34829caa 31#[derive(Clone)]
d48ee414
KS
32pub struct CodecDescription {
33 name: &'static str,
34 fname: &'static str,
35 ctype: CodecType,
36 caps: u32,
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 {
52 let mut out = format!("{}", self.fname);
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] = &[
45e794c4
KS
121 desc!(video-im; "indeo1", "Intel Raw IF09"),
122 desc!(video-im; "indeo2", "Intel Indeo 2"),
123 desc!(video; "indeo3", "Intel Indeo 3"),
124 desc!(video; "indeo4", "Intel Indeo 4", CODEC_CAP_REORDER | CODEC_CAP_SCALABLE),
125 desc!(video; "indeo5", "Intel Indeo 5", CODEC_CAP_REORDER | CODEC_CAP_SCALABLE),
1a36a05d 126 desc!(video; "intel263", "Intel I263", CODEC_CAP_REORDER),
45e794c4
KS
127 desc!(audio; "iac", "Intel Indeo audio"),
128 desc!(audio; "imc", "Intel Music Coder"),
ce52b3b5
KS
129
130 desc!(video; "realvideo1", "Real Video 1"),
131 desc!(video; "realvideo2", "Real Video 2"),
132 desc!(video; "realvideo3", "Real Video 3", CODEC_CAP_REORDER),
133 desc!(video; "realvideo4", "Real Video 4", CODEC_CAP_REORDER),
134 desc!(video; "clearvideo", "ClearVideo"),
750b299c 135 desc!(video; "clearvideo_rm", "ClearVideo"),
ce52b3b5
KS
136 desc!(audio; "ra14.4", "RealAudio 14.4"),
137 desc!(audio; "ra28.8", "RealAudio 28.8"),
138 desc!(audio; "cook", "RealAudio Cooker"),
139 desc!(audio; "ralf", "RealAudio Lossless"),
140 desc!(audio; "aac", "AAC"),
16dd4f44 141 desc!(audio; "ac3", "ETSI TS 102 366"),
ce52b3b5
KS
142 desc!(audio; "atrac3", "Sony Atrac3"),
143 desc!(audio; "sipro", "Sipro Labs ADPCM"),
d48ee414
KS
144];
145
146static AVI_VIDEO_CODEC_REGISTER: &'static [(&[u8;4], &str)] = &[
45e794c4
KS
147 (b"IF09", "indeo1"),
148 (b"RT21", "indeo2"),
149 (b"IV31", "indeo3"),
150 (b"IV32", "indeo3"),
151 (b"IV41", "indeo4"),
152 (b"IV50", "indeo5"),
836bf150 153 (b"I263", "intel263"),
ce52b3b5 154
750b299c 155 (b"UCOD", "clearvideo"),
d48ee414
KS
156];
157
158static WAV_CODEC_REGISTER: &'static [(u16, &str)] = &[
45e794c4
KS
159 (0x0000, "pcm"),
160 (0x0001, "pcm"),
161 (0x0003, "pcm"),
162 (0x0401, "imc"),
163 (0x0402, "iac"),
d48ee414
KS
164];
165
166pub fn find_codec_from_avi_fourcc(fcc: &[u8;4]) -> Option<&'static str> {
167 for i in 0..AVI_VIDEO_CODEC_REGISTER.len() {
168 let (fourcc, name) = AVI_VIDEO_CODEC_REGISTER[i];
169 if fourcc == fcc { return Some(name); }
170 }
171 None
172}
173
174pub fn find_codec_from_wav_twocc(tcc: u16) -> Option<&'static str> {
175 for i in 0..WAV_CODEC_REGISTER.len() {
176 let (twocc, name) = WAV_CODEC_REGISTER[i];
177 if twocc == tcc { return Some(name); }
178 }
179 None
180}
181
182#[cfg(test)]
183mod test {
184 use super::*;
185
186 #[test]
187 fn test_register() {
188 let c1 = find_codec_from_avi_fourcc(b"IV41").unwrap();
189 let c2 = find_codec_from_wav_twocc(0x401).unwrap();
190 println!("found {} and {}", c1, c2);
191 let cd1 = get_codec_description(c1).unwrap();
192 let cd2 = get_codec_description(c2).unwrap();
193 println!("got {} and {}", cd1, cd2);
194 }
b58d7656 195}