]> git.nihav.org Git - nihav.git/blame - nihav-realmedia/src/codecs/rv40.rs
core/soundcvt: add resampling support
[nihav.git] / nihav-realmedia / src / codecs / rv40.rs
CommitLineData
5641dccf
KS
1use nihav_core::formats;
2use nihav_core::frame::*;
3use nihav_core::io::bitreader::*;
4use nihav_core::io::codebook::*;
5use nihav_core::io::intcode::*;
6use nihav_core::codecs::*;
b4d5b851 7use nihav_codec_support::codecs::{MV, ZERO_MV};
47527732
KS
8use super::rv3040::*;
9use super::rv40dsp::*;
eb904044 10use super::rv40data::*;
47527732
KS
11
12struct AICCodeReader8 {
13 lengths: &'static [u8],
14 codes: &'static [u8],
15}
16
17impl CodebookDescReader<i8> for AICCodeReader8 {
18 fn bits(&mut self, idx: usize) -> u8 { self.lengths[idx] }
19 fn code(&mut self, idx: usize) -> u32 { self.codes[idx] as u32 }
20 fn sym (&mut self, idx: usize) -> i8 { idx as i8 }
21 fn len (&mut self) -> usize { self.lengths.len() }
22}
23
24struct AICCodeReader16 {
25 lengths: &'static [u8],
26 codes: &'static [u16],
27}
28
29impl CodebookDescReader<i8> for AICCodeReader16 {
30 fn bits(&mut self, idx: usize) -> u8 { self.lengths[idx] }
31 fn code(&mut self, idx: usize) -> u32 { self.codes[idx] as u32 }
32 fn sym (&mut self, idx: usize) -> i8 { idx as i8 }
33 fn len (&mut self) -> usize { self.lengths.len() }
34}
35
36struct TypeCodeReader {
37 lengths: &'static [u8],
38 codes: &'static [u8],
39 syms: &'static [MBType],
40}
41
42impl CodebookDescReader<MBType> for TypeCodeReader {
43 fn bits(&mut self, idx: usize) -> u8 { self.lengths[idx] }
44 fn code(&mut self, idx: usize) -> u32 { self.codes[idx] as u32 }
45 fn sym (&mut self, idx: usize) -> MBType{ self.syms[idx] }
46 fn len (&mut self) -> usize { self.lengths.len() }
47}
48
49struct RealVideo40BR {
50 width: usize,
51 height: usize,
52 aic_top_cb: Codebook<i8>,
53 aic_mode1_cb: Vec<Codebook<i8>>,
54 aic_mode2_cb: Vec<Codebook<i8>>,
55 ptype_cb: Vec<Codebook<MBType>>,
56 btype_cb: Vec<Codebook<MBType>>,
57 had_skip_run: bool,
58}
59
60impl RealVideo40BR {
61 fn new() -> Self {
62 let mut coderead = AICCodeReader8{ lengths: &RV40_AIC_TOP_BITS, codes: &RV40_AIC_TOP_CODES };
63 let aic_top_cb = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
64
65 let mut aic_mode1_cb: Vec<Codebook<i8>> = Vec::with_capacity(RV40_AIC_MODE1_BITS.len());
66 for i in 0..RV40_AIC_MODE1_BITS.len() {
67 if (i % 10) != 9 {
68 let mut coderead = AICCodeReader8{ lengths: &RV40_AIC_MODE1_BITS[i], codes: &RV40_AIC_MODE1_CODES[i] };
69 let cb = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
70 aic_mode1_cb.push(cb);
71 } else {
72 let mut coderead = AICCodeReader8{ lengths: &RV40_AIC_MODE1_BITS_DUMMY, codes: &RV40_AIC_MODE1_CODES_DUMMY };
73 let cb = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
74 aic_mode1_cb.push(cb);
75 }
76 }
77
78 let mut aic_mode2_cb: Vec<Codebook<i8>> = Vec::with_capacity(RV40_AIC_MODE2_BITS.len());
79 for i in 0..RV40_AIC_MODE2_BITS.len() {
80 let mut coderead = AICCodeReader16{ lengths: &RV40_AIC_MODE2_BITS[i], codes: &RV40_AIC_MODE2_CODES[i] };
81 let cb = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
82 aic_mode2_cb.push(cb);
83 }
84
85 let mut ptype_cb: Vec<Codebook<MBType>> = Vec::with_capacity(RV40_PTYPE_BITS.len());
86 for i in 0..RV40_PTYPE_BITS.len() {
87 let mut coderead = TypeCodeReader{ lengths: &RV40_PTYPE_BITS[i], codes: &RV40_PTYPE_CODES[i], syms: RV40_PTYPE_SYMS };
88 let cb = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
89 ptype_cb.push(cb);
90 }
91
92 let mut btype_cb: Vec<Codebook<MBType>> = Vec::with_capacity(RV40_BTYPE_BITS.len());
93 for i in 0..RV40_BTYPE_BITS.len() {
94 let mut coderead = TypeCodeReader{ lengths: &RV40_BTYPE_BITS[i], codes: &RV40_BTYPE_CODES[i], syms: RV40_BTYPE_SYMS };
95 let cb = Codebook::new(&mut coderead, CodebookMode::MSB).unwrap();
96 btype_cb.push(cb);
97 }
98
99 RealVideo40BR {
100 width: 0,
101 height: 0,
e07387c7
KS
102 aic_top_cb,
103 aic_mode1_cb,
104 aic_mode2_cb,
105 ptype_cb,
106 btype_cb,
47527732
KS
107 had_skip_run: false,
108 }
109 }
e07387c7 110 fn predict_b_mv_component(&self, sstate: &SState, mvi: &MVInfo, mbinfo: &[RV34MBInfo], mbtype: MBType, fwd: bool) -> MV {
47527732
KS
111 let mut pred_mvs: [MV; 3] = [ZERO_MV; 3];
112 let mut mv_count: usize = 0;
113 let mb_x = sstate.mb_x;
114 let mb_y = sstate.mb_y;
115 let mb_stride = sstate.mb_w;
116 let mb_idx = mb_x + mb_y * mb_stride;
117
118 if !mbtype.has_mv_dir(fwd) {
119 return ZERO_MV;
120 }
121
122 if sstate.has_left && mbinfo[mb_idx - 1].mbtype.has_mv_dir(fwd) {
123 pred_mvs[mv_count] = mvi.get_mv(mb_x - 1, mb_y, 0, 0, fwd);
124 mv_count += 1;
125 }
126 if !sstate.has_top {
127 return pred_mvs[0];
128 }
129 if mbinfo[mb_idx - mb_stride].mbtype.has_mv_dir(fwd) {
130 pred_mvs[mv_count] = mvi.get_mv(mb_x, mb_y - 1, 0, 0, fwd);
131 mv_count += 1;
132 }
133 if sstate.has_tr {
134 if mbinfo[mb_idx - mb_stride + 1].mbtype.has_mv_dir(fwd) {
135 pred_mvs[mv_count] = mvi.get_mv(mb_x + 1, mb_y - 1, 0, 0, fwd);
136 mv_count += 1;
137 }
138 } else {
139 if sstate.has_tl && mbinfo[mb_idx - mb_stride - 1].mbtype.has_mv_dir(fwd) {
140 pred_mvs[mv_count] = mvi.get_mv(mb_x - 1, mb_y - 1, 0, 0, fwd);
141 mv_count += 1;
142 }
143 }
144
145 match mv_count {
146 3 => MV::pred(pred_mvs[0], pred_mvs[1], pred_mvs[2]),
147 2 => { let sum_mv = pred_mvs[0] + pred_mvs[1]; MV { x: sum_mv.x / 2, y: sum_mv.y / 2 } },
148 1 => pred_mvs[0],
149 _ => ZERO_MV,
150 }
151 }
152}
153
154fn get_dimension(br: &mut BitReader, tab: &'static [i16]) -> DecoderResult<usize> {
155 let t = br.read(3)? as usize;
156 if tab[t] > 0 { return Ok(tab[t] as usize); }
157 if tab[t] < 0 {
158 let idx = (-tab[t] as usize) + (br.read(1)? as usize);
159 if tab[idx] != 0 { return Ok(tab[idx] as usize); }
160 }
161 let mut size: usize = 0;
162 loop {
163 let t = br.read(8)? as usize;
164 size += t << 2;
165 if t != 255 { break; }
166 }
167 Ok(size)
168}
169
170impl RV34BitstreamDecoder for RealVideo40BR {
171 fn decode_slice_header(&mut self, br: &mut BitReader, old_w: usize, old_h: usize) -> DecoderResult<RV34SliceHeader> {
172 if br.read(1)? != 0 { return Err(DecoderError::InvalidData); }
173 let ft_idx = br.read(2)?;
174 let ftype = match ft_idx {
175 0|1 => FrameType::I,
176 2 => FrameType::P,
177 _ => FrameType::B,
178 };
179 let q = br.read(5)? as u8;
180 if br.read(2)? != 0 { return Err(DecoderError::InvalidData); }
181 let set_idx = br.read(2)? as usize;
182 let deblock = !br.read_bool()?;
183 let pts = br.read(13)? as u16;
184 let w;
185 let h;
186 if (ftype == FrameType::I) || !br.read_bool()? {
187 w = get_dimension(br, &RV40_STANDARD_WIDTHS)?;
188 h = get_dimension(br, &RV40_STANDARD_HEIGHTS)?;
189 } else {
190 w = old_w;
191 h = old_h;
192 }
193 let start = br.read(get_slice_start_offset_bits(w, h))? as usize;
47527732
KS
194
195 self.had_skip_run = false;
196
e07387c7 197 Ok(RV34SliceHeader{ ftype, quant: q, deblock, pts, width: w, height: h, start, end: 0, set_idx })
47527732
KS
198 }
199 fn decode_intra_pred(&mut self, br: &mut BitReader, types: &mut [i8], mut pos: usize, tstride: usize, has_top: bool) -> DecoderResult<()> {
200 let start;
47527732
KS
201 if has_top {
202 start = 0;
203 } else {
204 let code = br.read_cb(&self.aic_top_cb)?;
205 types[pos + 0] = (code >> 2) & 2;
206 types[pos + 1] = (code >> 1) & 2;
207 types[pos + 2] = (code >> 0) & 2;
208 types[pos + 3] = (code << 1) & 2;
47527732
KS
209 pos += tstride;
210 start = 1;
211 }
212 for _ in start..4 {
213 let mut x: usize = 0;
214 while x < 4 {
215 let tr = types[pos + x - tstride + 1];
216 let t = types[pos + x - tstride];
217 let l = types[pos + x - 1];
47527732
KS
218 let ctx = if x < 3 { ((tr & 0xF) as u16) + (((t as u16) & 0xF) << 4) + (((l as u16) & 0xF) << 8) } else { 0xFFF };
219 let res = RV40_AIC_PATTERNS.iter().position(|&x| x == ctx);
220 if let Some(idx) = res {
221 let code = br.read_cb(&self.aic_mode2_cb[idx])?;
222 types[pos + x + 0] = code / 9;
223 types[pos + x + 1] = code % 9;
47527732
KS
224 x += 2;
225 } else {
226 if (t != -1) && (l != -1) {
227 let idx = (t as usize) + (l as usize) * 10;
228 types[pos + x] = br.read_cb(&self.aic_mode1_cb[idx])?;
229 } else {
230 match l {
231 -1 if t < 2 => { types[pos + x] = (br.read(1)? as i8) ^ 1; },
232 0 | 2 => { types[pos + x] = ((br.read(1)? as i8) ^ 1) << 1; },
233 _ => { types[pos + x] = 0; },
234 };
235 }
47527732
KS
236 x += 1;
237 }
238 }
239 pos += tstride;
240 }
241 Ok(())
242 }
243 fn decode_inter_mb_hdr(&mut self, br: &mut BitReader, ftype: FrameType, mbtype_ref: MBType) -> DecoderResult<MBInfo> {
244 let skip_run = if self.had_skip_run { 0 } else { br.read_code(UintCodeType::Gamma)? as usize };
245 if skip_run > 0 {
246 self.had_skip_run = true;
247 return Ok(MBInfo { mbtype: MBType::MBSkip, skip_run: skip_run - 1, dquant: false })
248 }
249 self.had_skip_run = false;
250 let mut mbtype;
251 let idx;
252 if ftype == FrameType::P {
253 idx = match mbtype_ref {
254 MBType::MBIntra => 0,
255 MBType::MBIntra16 => 1,
256 MBType::MBP16x16 => 2,
257 MBType::MBP8x8 => 3,
258 MBType::MBP16x8 => 4,
259 MBType::MBP8x16 => 5,
260 MBType::MBP16x16Mix => 6,
261 _ => unreachable!(),
262 };
263 mbtype = br.read_cb(&self.ptype_cb[idx])?;
264 } else {
265 idx = match mbtype_ref {
266 MBType::MBIntra => 0,
267 MBType::MBIntra16 => 1,
268 MBType::MBForward => 2,
269 MBType::MBBackward => 3,
270 MBType::MBBidir => 4,
271 MBType::MBDirect => 5,
272 _ => 0,
273 };
274 mbtype = br.read_cb(&self.btype_cb[idx])?;
275 }
276 let dquant = mbtype == MBType::Invalid;
277 if dquant {
278 mbtype = if ftype == FrameType::P { br.read_cb(&self.ptype_cb[idx])? }
279 else { br.read_cb(&self.btype_cb[idx])? };
280 }
e07387c7 281 Ok(MBInfo { mbtype, skip_run: 0, dquant })
47527732 282 }
e07387c7 283 fn predict_b_mv(&self, sstate: &SState, mvi: &MVInfo, mbtype: MBType, mvs: &[MV], mbinfo: &[RV34MBInfo]) -> (MV, MV) {
47527732
KS
284 let mut mv_f = self.predict_b_mv_component(sstate, mvi, mbinfo, mbtype, true);
285 let mut mv_b = self.predict_b_mv_component(sstate, mvi, mbinfo, mbtype, false);
286
287 match mbtype {
288 MBType::MBForward => { mv_f += mvs[0]; },
289 MBType::MBBackward => { mv_b += mvs[0]; },
290 MBType::MBBidir => {
291 mv_f += mvs[0];
292 mv_b += mvs[1];
293 },
294 _ => {},
295 };
296
297 (mv_f, mv_b)
298 }
299 fn quant_dc(&self, is_intra: bool, q: u8) -> u8 { RV40_QUANT_DC[if is_intra { 0 } else { 1 }][q as usize] }
300}
301
302struct RealVideo40Decoder {
303 bd: RealVideo40BR,
2422d969 304 info: NACodecInfoRef,
47527732
KS
305 dec: RV34Decoder,
306}
307
308impl RealVideo40Decoder {
309 fn new() -> Self {
310 RealVideo40Decoder{
311 bd: RealVideo40BR::new(),
2422d969 312 info: NACodecInfoRef::default(),
47527732
KS
313 dec: RV34Decoder::new(false, Box::new(RV40DSP::new())),
314 }
315 }
316}
317
318impl NADecoder for RealVideo40Decoder {
3c69ce1b 319 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
47527732
KS
320 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
321 let fmt = formats::YUV420_FORMAT;
322 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt));
2422d969 323 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
47527732
KS
324
325 let edata = info.get_extradata().unwrap();
326 let src: &[u8] = &edata;
327
47527732
KS
328 if src.len() < 2 { return Err(DecoderError::InvalidData); }
329
330 self.bd.width = vinfo.get_width();
331 self.bd.height = vinfo.get_height();
3c69ce1b
KS
332
333 supp.pool_u8.set_dec_bufs(3);
334 supp.pool_u8.prealloc_video(NAVideoInfo::new(self.bd.width, self.bd.height, false, fmt), 4)?;
335
47527732
KS
336 Ok(())
337 } else {
47527732
KS
338 Err(DecoderError::InvalidData)
339 }
340 }
3c69ce1b 341 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
47527732
KS
342 let src = pkt.get_buffer();
343
3c69ce1b 344 let (bufinfo, ftype, ts) = self.dec.parse_frame(supp, src.as_slice(), &mut self.bd)?;
47527732
KS
345
346 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
347 frm.set_keyframe(ftype == FrameType::I);
348 frm.set_frame_type(ftype);
349 frm.set_pts(Some(ts));
171860fc 350 Ok(frm.into_ref())
47527732 351 }
f9be4e75
KS
352 fn flush(&mut self) {
353 self.dec.flush();
354 }
47527732
KS
355}
356
7d57ae2f
KS
357impl NAOptionHandler for RealVideo40Decoder {
358 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
359 fn set_options(&mut self, _options: &[NAOption]) { }
360 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
361}
362
08a1fab7 363pub fn get_decoder() -> Box<dyn NADecoder + Send> {
47527732
KS
364 Box::new(RealVideo40Decoder::new())
365}
366
367#[cfg(test)]
368mod test {
3167c45c
KS
369 use nihav_core::codecs::RegisteredDecoders;
370 use nihav_core::demuxers::RegisteredDemuxers;
ce742854 371 use nihav_codec_support::test::dec_video::*;
78fb6560 372 use crate::realmedia_register_all_decoders;
e64739f8 373 use crate::realmedia_register_all_demuxers;
886cde48 374 // samples from a private collection
47527732
KS
375 #[test]
376 fn test_rv40() {
3167c45c
KS
377 let mut dmx_reg = RegisteredDemuxers::new();
378 realmedia_register_all_demuxers(&mut dmx_reg);
379 let mut dec_reg = RegisteredDecoders::new();
78fb6560 380 realmedia_register_all_decoders(&mut dec_reg);
3167c45c 381
1702ecec
KS
382 test_decoding("realmedia", "realvideo4", "assets/RV/rv40_weighted_mc.rmvb", Some(1500),
383 &dmx_reg, &dec_reg,ExpectedTestResult::MD5Frames(vec![
384 [0x27cf336a, 0xc1686c50, 0x5304783d, 0x6e77ffa2],
385 [0x91f236c7, 0x3bda2d38, 0x961a0243, 0xda803cf1],
386 [0x4075d7e8, 0xbcd7f85b, 0x1c0dd34b, 0x405d0a5d],
387 [0x642498b7, 0xb57aa202, 0x69ea0d23, 0x1cc0794f],
388 [0x1c1a4df8, 0x7e3fbd7d, 0x7fdeb57f, 0xf5d65179],
389 [0x86a5dcdd, 0xd66caabf, 0xdfe1fc99, 0xb3443375],
390 [0x86846664, 0xbee4268d, 0xc1e017e6, 0xc9d984c8],
391 [0x0ecbe176, 0x81e5aca6, 0xb7bda49c, 0x34007e7b],
392 [0x48c8a90e, 0xed003b8a, 0xc9e7e9a6, 0x54b1eca8],
393 [0x540cbc0b, 0x6d7afaa8, 0xb0951c1f, 0xed22089e],
394 [0x73190f85, 0x9cd72603, 0x1063ca54, 0xd4f82c7f],
395 [0xef6206e8, 0x6affb292, 0xe12b7c9c, 0x37416240],
396 [0x59f61c91, 0x66b2a632, 0x46556395, 0x74fbc1de],
397 [0xd75635ca, 0x60d13826, 0xfa41d914, 0x9cfded0e],
398 [0x7a8c4396, 0x6f3eda39, 0x4238dbaf, 0xa9052803]]));
399 test_decoding("realmedia", "realvideo4", "assets/RV/rv40_weighted_mc_2.rmvb", Some(2000),
400 &dmx_reg, &dec_reg,
401 ExpectedTestResult::MD5([0x4224b9d6, 0x32e3ff63, 0x02df9e60, 0xfa0548ee]));
47527732
KS
402 }
403}
404
405const RV40_STANDARD_WIDTHS: [i16; 8] = [ 160, 172, 240, 320, 352, 640, 704, 0 ];
406const RV40_STANDARD_HEIGHTS: [i16; 12] = [ 120, 132, 144, 240, 288, 480, -8, -10, 180, 360, 576, 0 ];