annotate the sources for test samples
[nihav.git] / nihav-realmedia / src / codecs / rv30.rs
CommitLineData
5641dccf
KS
1use nihav_core::formats;
2use nihav_core::io::bitreader::*;
3use nihav_core::io::intcode::*;
4use nihav_core::frame::*;
5use nihav_core::codecs::*;
b4d5b851 6use nihav_codec_support::codecs::{MV, ZERO_MV};
47527732
KS
7use super::rv3040::*;
8use super::rv30dsp::*;
9
10struct RealVideo30BR {
11 rpr_bits: u8,
12 width: usize,
13 height: usize,
14 widths: Vec<usize>,
15 heights: Vec<usize>,
16}
17
18impl RealVideo30BR {
19 fn new() -> Self {
20 RealVideo30BR {
21 rpr_bits: 0,
22 width: 0,
23 height: 0,
24 widths: Vec::new(),
25 heights: Vec::new(),
26 }
27 }
28}
29
30impl RV34BitstreamDecoder for RealVideo30BR {
31 fn decode_slice_header(&mut self, br: &mut BitReader, _old_w: usize, _old_h: usize) -> DecoderResult<RV34SliceHeader> {
32 if br.read(3)? != 0 { return Err(DecoderError::InvalidData); }
33 let ft_idx = br.read(2)?;
34 let ftype = match ft_idx {
35 0|1 => FrameType::I,
36 2 => FrameType::P,
37 _ => FrameType::B,
38 };
39 if br.read(1)? != 0 { return Err(DecoderError::InvalidData); }
40 let q = br.read(5)? as u8;
41 let deblock = !br.read_bool()?;
42 let pts = br.read(13)? as u16;
43 let rpr = br.read(self.rpr_bits)? as usize;
44 let (w, h) = if rpr != 0 {
45 validate!(rpr < self.widths.len());
46 (self.widths[rpr], self.heights[rpr])
47 } else {
48 (self.width, self.height)
49 };
50 let start = br.read(get_slice_start_offset_bits(w, h))? as usize;
51 br.skip(1)?;
52
e07387c7 53 Ok(RV34SliceHeader{ ftype, quant: q, deblock, pts, width: w, height: h, start, end: 0, set_idx: 0 })
47527732
KS
54 }
55 fn decode_intra_pred(&mut self, br: &mut BitReader, types: &mut [i8], mut pos: usize, tstride: usize, _has_top: bool) -> DecoderResult<()> {
56 for _ in 0..4 {
57 for x in 0..2 {
58 let code = br.read_code(UintCodeType::Gamma)? as usize;
59 validate!(code < 81);
60 for k in 0..2 {
61 let new = RV30_ITYPE_MAP[code * 2 + k] as usize;
62 let top = (types[pos + x * 2 + k - tstride] + 1) as usize;
63 let left = (types[pos + x * 2 + k - 1] + 1) as usize;
64 types[pos + x * 2 + k] = RV30_ITYPE[top * 90 + left * 9 + new];
65 validate!(types[pos + x * 2 + k] != 9);
66 }
67 }
68 pos += tstride;
69 }
70 Ok(())
71 }
72 fn decode_inter_mb_hdr(&mut self, br: &mut BitReader, ftype: FrameType, _mbtype: MBType) -> DecoderResult<MBInfo> {
73 let mut code = br.read_code(UintCodeType::Gamma)? as usize;
74 let mut dq = false;
75 validate!(code < 11);
76 if code > 5 {
77 code -= 6;
78 dq = true;
79 }
80 let idx = if ftype == FrameType::P { 0 } else { 1 };
81 Ok(MBInfo { mbtype: RV30_MB_TYPES[idx][code], skip_run: 0, dquant: dq })
82 }
e07387c7 83 fn predict_b_mv(&self, sstate: &SState, mvi: &MVInfo, mbtype: MBType, mvs: &[MV], _mbinfo: &[RV34MBInfo]) -> (MV, MV) {
47527732
KS
84 let mb_x = sstate.mb_x;
85 let mb_y = sstate.mb_y;
86 let mv_f;
87 let mv_b;
88 match mbtype {
89 MBType::MBForward | MBType::MBBackward => {
90 let mv_pred = mvi.pred_mb_mv(mb_x, mb_y, true, sstate.has_top, sstate.has_left, sstate.has_tr, sstate.has_tl);
91 mv_f = mv_pred + mvs[0];
92 mv_b = mv_f;
93 },
94 _ => {
95 mv_f = ZERO_MV;
96 mv_b = ZERO_MV;
97 },
98 };
99 (mv_f, mv_b)
100 }
101 fn quant_dc(&self, _is_intra: bool, q: u8) -> u8 { RV30_QUANT_DC[q as usize] }
102}
103
104struct RealVideo30Decoder {
105 bd: RealVideo30BR,
2422d969 106 info: NACodecInfoRef,
47527732
KS
107 dec: RV34Decoder,
108}
109
110impl RealVideo30Decoder {
111 fn new() -> Self {
112 RealVideo30Decoder{
113 bd: RealVideo30BR::new(),
2422d969 114 info: NACodecInfoRef::default(),
47527732
KS
115 dec: RV34Decoder::new(true, Box::new(RV30DSP::new())),
116 }
117 }
118}
119
120impl NADecoder for RealVideo30Decoder {
3c69ce1b 121 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
47527732
KS
122 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
123 let fmt = formats::YUV420_FORMAT;
124 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt));
2422d969 125 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
47527732
KS
126
127 let edata = info.get_extradata().unwrap();
128 let src: &[u8] = &edata;
129
130 if src.len() < 2 { return Err(DecoderError::InvalidData); }
131 let num_rpr = (src[1] & 7) as usize;
132 if src.len() < num_rpr * 2 + 8 { return Err(DecoderError::ShortData); }
133 self.bd.rpr_bits = ((num_rpr >> 1) + 1) as u8;
134 if self.bd.rpr_bits > 3 { self.bd.rpr_bits = 3; }
e07387c7 135 for i in 0..=num_rpr {
47527732
KS
136 self.bd.widths.push ((src[6 + i * 2] as usize) << 2);
137 self.bd.heights.push((src[7 + i * 2] as usize) << 2);
138 }
139
140 self.bd.width = vinfo.get_width();
141 self.bd.height = vinfo.get_height();
3c69ce1b
KS
142
143 supp.pool_u8.set_dec_bufs(3);
144 supp.pool_u8.prealloc_video(NAVideoInfo::new(self.bd.width, self.bd.height, false, fmt), 4)?;
145
47527732
KS
146 Ok(())
147 } else {
148println!("???");
149 Err(DecoderError::InvalidData)
150 }
151 }
3c69ce1b 152 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
47527732
KS
153 let src = pkt.get_buffer();
154
3c69ce1b 155 let (bufinfo, ftype, pts) = self.dec.parse_frame(supp, src.as_slice(), &mut self.bd)?;
47527732
KS
156
157 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
158 frm.set_keyframe(ftype == FrameType::I);
159 frm.set_pts(Some(pts));
160 frm.set_frame_type(ftype);//if ftype == FrameType::B { FrameType::Skip } else { ftype } );
171860fc 161 Ok(frm.into_ref())
47527732 162 }
f9be4e75
KS
163 fn flush(&mut self) {
164 self.dec.flush();
165 }
47527732
KS
166}
167
7d57ae2f
KS
168impl NAOptionHandler for RealVideo30Decoder {
169 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
170 fn set_options(&mut self, _options: &[NAOption]) { }
171 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
172}
173
08a1fab7 174pub fn get_decoder() -> Box<dyn NADecoder + Send> {
47527732
KS
175 Box::new(RealVideo30Decoder::new())
176}
177
178#[cfg(test)]
179mod test {
3167c45c
KS
180 use nihav_core::codecs::RegisteredDecoders;
181 use nihav_core::demuxers::RegisteredDemuxers;
ce742854 182 use nihav_codec_support::test::dec_video::*;
78fb6560 183 use crate::realmedia_register_all_decoders;
e64739f8 184 use crate::realmedia_register_all_demuxers;
47527732
KS
185 #[test]
186 fn test_rv30() {
3167c45c
KS
187 let mut dmx_reg = RegisteredDemuxers::new();
188 realmedia_register_all_demuxers(&mut dmx_reg);
189 let mut dec_reg = RegisteredDecoders::new();
78fb6560 190 realmedia_register_all_decoders(&mut dec_reg);
3167c45c 191
886cde48 192 // sample from a private collection
70860638
KS
193 test_decoding("realmedia", "realvideo3", "assets/RV/rv30_weighted_mc.rm", Some(700),
194 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
195 [0x2a4d13bf, 0x2f21f3c9, 0xcbd601be, 0x61a6405c],
196 [0x17ea48c7, 0x68334ff5, 0x6fb9729b, 0x9a93ed12],
197 [0xce42a48c, 0x0b5b7f0d, 0x3f66c4a1, 0x261f08e2],
198 [0x91ca8f5b, 0x1f578a93, 0x44e533f2, 0x83beec8a],
199 [0x8cb256a7, 0xb3889afd, 0x28806114, 0x9bbd5287],
200 [0x694570e2, 0x4b2df948, 0xc7d2e36d, 0xa5eb66b2],
201 [0xb9b68059, 0x0d420917, 0x4e0f33d4, 0x8d3a6b0b],
202 [0xb9d6bfa6, 0x04442a8e, 0x6fafc34e, 0xb418a23e],
203 [0xb94e226d, 0xbf8a5fc5, 0x6d9a03c6, 0x4a0d1a50],
204 [0xa2e76d33, 0x1b6996e4, 0xb6a26052, 0x3f5f6145],
205 [0x3b509515, 0x4aa2f4f9, 0x12a0c73b, 0x5b9b20d1],
206 [0x976e0e06, 0xf6194e6f, 0xe0fefc31, 0xf7587bd3],
207 [0x7b38660e, 0xa46f4080, 0xa493f422, 0x36eaaa3b],
208 [0x6375934a, 0xf2a23087, 0x367f9738, 0xf2251e09],
209 [0x54bcefe7, 0xbbc91dc7, 0x0acec7d7, 0x95cf6d02]]));
886cde48 210 // sample: https://samples.mplayerhq.hu/real/VC-RV30/simpsons-clip.rm
70860638
KS
211 test_decoding("realmedia", "realvideo3", "assets/RV/simpsons-clip.rm", Some(1337),
212 &dmx_reg, &dec_reg,
213 ExpectedTestResult::MD5([0x36604117, 0x415f95cc, 0xec38e776, 0x9818d3be]));
47527732
KS
214 }
215}
216
217const RV30_QUANT_DC: [u8; 32] = [
218 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
219 16, 17, 18, 19, 20, 21, 22, 22, 22, 23, 23, 23, 24, 24, 25, 25
220];
221
222const RV30_MB_TYPES: [[MBType; 6]; 2] = [
223 [ MBType::MBSkip, MBType::MBP16x16, MBType::MBP8x8, MBType::Invalid, MBType::MBIntra, MBType::MBIntra16 ],
224 [ MBType::MBSkip, MBType::MBDirect, MBType::MBForward, MBType::MBBackward, MBType::MBIntra, MBType::MBIntra16 ],
225];
226
227const RV30_ITYPE_MAP: [i8; 9*9*2] = [
228 0, 0, 0, 1, 1, 0, 1, 1, 0, 2, 2, 0, 0, 3, 3, 0, 1, 2,
229 2, 1, 0, 4, 4, 0, 3, 1, 1, 3, 0, 5, 5, 0, 2, 2, 1, 4,
230 4, 1, 0, 6, 3, 2, 1, 5, 2, 3, 5, 1, 6, 0, 0, 7, 4, 2,
231 2, 4, 3, 3, 6, 1, 1, 6, 7, 0, 0, 8, 5, 2, 4, 3, 2, 5,
232 3, 4, 1, 7, 4, 4, 7, 1, 8, 0, 6, 2, 3, 5, 5, 3, 2, 6,
233 1, 8, 2, 7, 7, 2, 8, 1, 5, 4, 4, 5, 3, 6, 6, 3, 8, 2,
234 4, 6, 5, 5, 6, 4, 2, 8, 7, 3, 3, 7, 6, 5, 5, 6, 7, 4,
235 4, 7, 8, 3, 3, 8, 7, 5, 8, 4, 5, 7, 4, 8, 6, 6, 7, 6,
236 5, 8, 8, 5, 6, 7, 8, 6, 7, 7, 6, 8, 8, 7, 7, 8, 8, 8,
237];
238
239const RV30_ITYPE: [i8; 10*10*9] = [
240 0, 9, 9, 9, 9, 9, 9, 9, 9,
241 0, 2, 9, 9, 9, 9, 9, 9, 9,
242 9, 9, 9, 9, 9, 9, 9, 9, 9,
243 2, 0, 9, 9, 9, 9, 9, 9, 9,
244 9, 9, 9, 9, 9, 9, 9, 9, 9,
245 9, 9, 9, 9, 9, 9, 9, 9, 9,
246 9, 9, 9, 9, 9, 9, 9, 9, 9,
247 9, 9, 9, 9, 9, 9, 9, 9, 9,
248 9, 9, 9, 9, 9, 9, 9, 9, 9,
249 9, 9, 9, 9, 9, 9, 9, 9, 9,
250
251 0, 1, 9, 9, 9, 9, 9, 9, 9,
252 0, 2, 1, 6, 4, 8, 5, 7, 3,
253 1, 0, 2, 6, 5, 4, 3, 8, 7,
254 2, 8, 0, 1, 7, 4, 3, 6, 5,
255 2, 0, 1, 3, 8, 5, 4, 7, 6,
256 2, 0, 1, 4, 6, 7, 8, 3, 5,
257 0, 1, 5, 2, 6, 3, 8, 4, 7,
258 0, 1, 6, 2, 4, 7, 5, 8, 3,
259 2, 7, 0, 1, 4, 8, 6, 3, 5,
260 2, 8, 0, 1, 7, 3, 4, 5, 6,
261
262 1, 0, 9, 9, 9, 9, 9, 9, 9,
263 1, 2, 5, 6, 3, 0, 4, 8, 7,
264 1, 6, 2, 5, 3, 0, 4, 8, 7,
265 2, 1, 7, 6, 8, 3, 5, 0, 4,
266 1, 2, 5, 3, 6, 8, 4, 7, 0,
267 1, 6, 2, 0, 4, 5, 8, 7, 3,
268 1, 5, 2, 6, 3, 8, 4, 0, 7,
269 1, 6, 0, 2, 4, 5, 7, 3, 8,
270 2, 1, 7, 6, 0, 8, 5, 4, 3,
271 1, 2, 7, 8, 3, 4, 5, 6, 0,
272
273 9, 9, 9, 9, 9, 9, 9, 9, 9,
274 0, 2, 1, 8, 7, 6, 5, 4, 3,
275 1, 2, 0, 6, 5, 7, 4, 8, 3,
276 2, 8, 7, 1, 0, 6, 4, 3, 5,
277 2, 0, 8, 1, 3, 7, 5, 4, 6,
278 2, 0, 4, 1, 7, 8, 6, 3, 5,
279 2, 0, 1, 5, 8, 4, 6, 7, 3,
280 2, 0, 6, 1, 4, 7, 8, 5, 3,
281 2, 7, 8, 1, 0, 5, 4, 6, 3,
282 2, 8, 7, 1, 0, 4, 3, 6, 5,
283
284 9, 9, 9, 9, 9, 9, 9, 9, 9,
285 0, 2, 1, 3, 5, 8, 6, 4, 7,
286 1, 0, 2, 5, 3, 6, 4, 8, 7,
287 2, 8, 1, 0, 3, 5, 7, 6, 4,
288 3, 2, 5, 8, 1, 4, 6, 7, 0,
289 4, 2, 0, 6, 1, 5, 8, 3, 7,
290 5, 3, 1, 2, 8, 6, 4, 0, 7,
291 1, 6, 0, 2, 4, 5, 8, 3, 7,
292 2, 7, 0, 1, 5, 4, 8, 6, 3,
293 2, 8, 3, 5, 1, 0, 7, 6, 4,
294
295 9, 9, 9, 9, 9, 9, 9, 9, 9,
296 2, 0, 6, 1, 4, 7, 5, 8, 3,
297 1, 6, 2, 0, 4, 5, 3, 7, 8,
298 2, 8, 7, 6, 4, 0, 1, 5, 3,
299 4, 2, 1, 0, 6, 8, 3, 5, 7,
300 4, 2, 6, 0, 1, 5, 7, 8, 3,
301 1, 2, 5, 0, 6, 3, 4, 7, 8,
302 6, 4, 0, 1, 2, 7, 5, 3, 8,
303 2, 7, 4, 6, 0, 1, 8, 5, 3,
304 2, 8, 7, 4, 6, 1, 3, 5, 0,
305
306 9, 9, 9, 9, 9, 9, 9, 9, 9,
307 5, 1, 2, 3, 6, 8, 0, 4, 7,
308 1, 5, 6, 3, 2, 0, 4, 8, 7,
309 2, 1, 5, 3, 6, 8, 7, 4, 0,
310 5, 3, 1, 2, 6, 8, 4, 7, 0,
311 1, 6, 2, 4, 5, 8, 0, 3, 7,
312 5, 1, 3, 6, 2, 0, 8, 4, 7,
313 1, 6, 5, 2, 0, 4, 3, 7, 8,
314 2, 7, 1, 6, 5, 0, 8, 3, 4,
315 2, 5, 1, 3, 6, 8, 4, 0, 7,
316
317 9, 9, 9, 9, 9, 9, 9, 9, 9,
318 1, 6, 2, 0, 5, 4, 3, 7, 8,
319 1, 6, 5, 4, 2, 3, 0, 7, 8,
320 2, 1, 6, 7, 4, 8, 5, 3, 0,
321 2, 1, 6, 5, 8, 4, 3, 0, 7,
322 6, 4, 1, 2, 0, 5, 7, 8, 3,
323 1, 6, 5, 2, 3, 0, 4, 8, 7,
324 6, 1, 4, 0, 2, 7, 5, 3, 8,
325 2, 7, 4, 6, 1, 5, 0, 8, 3,
326 2, 1, 6, 8, 4, 7, 3, 5, 0,
327
328 9, 9, 9, 9, 9, 9, 9, 9, 9,
329 2, 0, 4, 7, 6, 1, 8, 5, 3,
330 6, 1, 2, 0, 4, 7, 5, 8, 3,
331 2, 7, 8, 0, 1, 6, 4, 3, 5,
332 2, 4, 0, 8, 3, 1, 7, 6, 5,
333 4, 2, 7, 0, 6, 1, 8, 5, 3,
334 2, 1, 0, 8, 5, 6, 7, 4, 3,
335 2, 6, 4, 1, 7, 0, 5, 8, 3,
336 2, 7, 4, 0, 8, 6, 1, 5, 3,
337 2, 8, 7, 4, 1, 0, 3, 6, 5,
338
339 9, 9, 9, 9, 9, 9, 9, 9, 9,
340 2, 0, 8, 1, 3, 4, 6, 5, 7,
341 1, 2, 0, 6, 8, 5, 7, 3, 4,
342 2, 8, 7, 1, 0, 3, 6, 5, 4,
343 8, 3, 2, 5, 1, 0, 4, 7, 6,
344 2, 0, 4, 8, 5, 1, 7, 6, 3,
345 2, 1, 0, 8, 5, 3, 6, 4, 7,
346 2, 1, 6, 0, 8, 4, 5, 7, 3,
347 2, 7, 8, 4, 0, 6, 1, 5, 3,
348 2, 8, 3, 0, 7, 4, 1, 6, 5,
349];