]> git.nihav.org Git - nihav.git/blame_incremental - nihav-realmedia/src/codecs/rv30.rs
avi: fix handling of palette change chunk with 256 colours
[nihav.git] / nihav-realmedia / src / codecs / rv30.rs
... / ...
CommitLineData
1use nihav_core::formats;
2use nihav_core::io::bitreader::*;
3use nihav_core::io::intcode::*;
4use nihav_core::frame::*;
5use nihav_core::codecs::*;
6use nihav_codec_support::codecs::{MV, ZERO_MV};
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
53 Ok(RV34SliceHeader{ ftype, quant: q, deblock, pts, width: w, height: h, start, end: 0, set_idx: 0 })
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 }
83 fn predict_b_mv(&self, sstate: &SState, mvi: &MVInfo, mbtype: MBType, mvs: &[MV], _mbinfo: &[RV34MBInfo]) -> (MV, MV) {
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,
106 info: NACodecInfoRef,
107 dec: RV34Decoder,
108}
109
110impl RealVideo30Decoder {
111 fn new() -> Self {
112 RealVideo30Decoder{
113 bd: RealVideo30BR::new(),
114 info: NACodecInfoRef::default(),
115 dec: RV34Decoder::new(true, Box::new(RV30DSP::new())),
116 }
117 }
118}
119
120impl NADecoder for RealVideo30Decoder {
121 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
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));
125 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
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; }
135 for i in 0..=num_rpr {
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();
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
146 Ok(())
147 } else {
148 Err(DecoderError::InvalidData)
149 }
150 }
151 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
152 let src = pkt.get_buffer();
153
154 let (bufinfo, ftype, pts) = self.dec.parse_frame(supp, src.as_slice(), &mut self.bd)?;
155
156 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
157 frm.set_keyframe(ftype == FrameType::I);
158 frm.set_pts(Some(pts));
159 frm.set_frame_type(ftype);//if ftype == FrameType::B { FrameType::Skip } else { ftype } );
160 Ok(frm.into_ref())
161 }
162 fn flush(&mut self) {
163 self.dec.flush();
164 }
165}
166
167impl NAOptionHandler for RealVideo30Decoder {
168 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
169 fn set_options(&mut self, _options: &[NAOption]) { }
170 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
171}
172
173pub fn get_decoder() -> Box<dyn NADecoder + Send> {
174 Box::new(RealVideo30Decoder::new())
175}
176
177#[cfg(test)]
178mod test {
179 use nihav_core::codecs::RegisteredDecoders;
180 use nihav_core::demuxers::RegisteredDemuxers;
181 use nihav_codec_support::test::dec_video::*;
182 use crate::realmedia_register_all_decoders;
183 use crate::realmedia_register_all_demuxers;
184 #[test]
185 fn test_rv30() {
186 let mut dmx_reg = RegisteredDemuxers::new();
187 realmedia_register_all_demuxers(&mut dmx_reg);
188 let mut dec_reg = RegisteredDecoders::new();
189 realmedia_register_all_decoders(&mut dec_reg);
190
191 // sample from a private collection
192 test_decoding("realmedia", "realvideo3", "assets/RV/rv30_weighted_mc.rm", Some(700),
193 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
194 [0x2a4d13bf, 0x2f21f3c9, 0xcbd601be, 0x61a6405c],
195 [0x17ea48c7, 0x68334ff5, 0x6fb9729b, 0x9a93ed12],
196 [0xce42a48c, 0x0b5b7f0d, 0x3f66c4a1, 0x261f08e2],
197 [0x91ca8f5b, 0x1f578a93, 0x44e533f2, 0x83beec8a],
198 [0x8cb256a7, 0xb3889afd, 0x28806114, 0x9bbd5287],
199 [0x694570e2, 0x4b2df948, 0xc7d2e36d, 0xa5eb66b2],
200 [0xb9b68059, 0x0d420917, 0x4e0f33d4, 0x8d3a6b0b],
201 [0xb9d6bfa6, 0x04442a8e, 0x6fafc34e, 0xb418a23e],
202 [0xb94e226d, 0xbf8a5fc5, 0x6d9a03c6, 0x4a0d1a50],
203 [0xa2e76d33, 0x1b6996e4, 0xb6a26052, 0x3f5f6145],
204 [0x3b509515, 0x4aa2f4f9, 0x12a0c73b, 0x5b9b20d1],
205 [0x976e0e06, 0xf6194e6f, 0xe0fefc31, 0xf7587bd3],
206 [0x7b38660e, 0xa46f4080, 0xa493f422, 0x36eaaa3b],
207 [0x6375934a, 0xf2a23087, 0x367f9738, 0xf2251e09],
208 [0x54bcefe7, 0xbbc91dc7, 0x0acec7d7, 0x95cf6d02]]));
209 // sample: https://samples.mplayerhq.hu/real/VC-RV30/simpsons-clip.rm
210 test_decoding("realmedia", "realvideo3", "assets/RV/simpsons-clip.rm", Some(1337),
211 &dmx_reg, &dec_reg,
212 ExpectedTestResult::MD5([0x36604117, 0x415f95cc, 0xec38e776, 0x9818d3be]));
213 }
214}
215
216const RV30_QUANT_DC: [u8; 32] = [
217 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
218 16, 17, 18, 19, 20, 21, 22, 22, 22, 23, 23, 23, 24, 24, 25, 25
219];
220
221const RV30_MB_TYPES: [[MBType; 6]; 2] = [
222 [ MBType::MBSkip, MBType::MBP16x16, MBType::MBP8x8, MBType::Invalid, MBType::MBIntra, MBType::MBIntra16 ],
223 [ MBType::MBSkip, MBType::MBDirect, MBType::MBForward, MBType::MBBackward, MBType::MBIntra, MBType::MBIntra16 ],
224];
225
226const RV30_ITYPE_MAP: [i8; 9*9*2] = [
227 0, 0, 0, 1, 1, 0, 1, 1, 0, 2, 2, 0, 0, 3, 3, 0, 1, 2,
228 2, 1, 0, 4, 4, 0, 3, 1, 1, 3, 0, 5, 5, 0, 2, 2, 1, 4,
229 4, 1, 0, 6, 3, 2, 1, 5, 2, 3, 5, 1, 6, 0, 0, 7, 4, 2,
230 2, 4, 3, 3, 6, 1, 1, 6, 7, 0, 0, 8, 5, 2, 4, 3, 2, 5,
231 3, 4, 1, 7, 4, 4, 7, 1, 8, 0, 6, 2, 3, 5, 5, 3, 2, 6,
232 1, 8, 2, 7, 7, 2, 8, 1, 5, 4, 4, 5, 3, 6, 6, 3, 8, 2,
233 4, 6, 5, 5, 6, 4, 2, 8, 7, 3, 3, 7, 6, 5, 5, 6, 7, 4,
234 4, 7, 8, 3, 3, 8, 7, 5, 8, 4, 5, 7, 4, 8, 6, 6, 7, 6,
235 5, 8, 8, 5, 6, 7, 8, 6, 7, 7, 6, 8, 8, 7, 7, 8, 8, 8,
236];
237
238const RV30_ITYPE: [i8; 10*10*9] = [
239 0, 9, 9, 9, 9, 9, 9, 9, 9,
240 0, 2, 9, 9, 9, 9, 9, 9, 9,
241 9, 9, 9, 9, 9, 9, 9, 9, 9,
242 2, 0, 9, 9, 9, 9, 9, 9, 9,
243 9, 9, 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
250 0, 1, 9, 9, 9, 9, 9, 9, 9,
251 0, 2, 1, 6, 4, 8, 5, 7, 3,
252 1, 0, 2, 6, 5, 4, 3, 8, 7,
253 2, 8, 0, 1, 7, 4, 3, 6, 5,
254 2, 0, 1, 3, 8, 5, 4, 7, 6,
255 2, 0, 1, 4, 6, 7, 8, 3, 5,
256 0, 1, 5, 2, 6, 3, 8, 4, 7,
257 0, 1, 6, 2, 4, 7, 5, 8, 3,
258 2, 7, 0, 1, 4, 8, 6, 3, 5,
259 2, 8, 0, 1, 7, 3, 4, 5, 6,
260
261 1, 0, 9, 9, 9, 9, 9, 9, 9,
262 1, 2, 5, 6, 3, 0, 4, 8, 7,
263 1, 6, 2, 5, 3, 0, 4, 8, 7,
264 2, 1, 7, 6, 8, 3, 5, 0, 4,
265 1, 2, 5, 3, 6, 8, 4, 7, 0,
266 1, 6, 2, 0, 4, 5, 8, 7, 3,
267 1, 5, 2, 6, 3, 8, 4, 0, 7,
268 1, 6, 0, 2, 4, 5, 7, 3, 8,
269 2, 1, 7, 6, 0, 8, 5, 4, 3,
270 1, 2, 7, 8, 3, 4, 5, 6, 0,
271
272 9, 9, 9, 9, 9, 9, 9, 9, 9,
273 0, 2, 1, 8, 7, 6, 5, 4, 3,
274 1, 2, 0, 6, 5, 7, 4, 8, 3,
275 2, 8, 7, 1, 0, 6, 4, 3, 5,
276 2, 0, 8, 1, 3, 7, 5, 4, 6,
277 2, 0, 4, 1, 7, 8, 6, 3, 5,
278 2, 0, 1, 5, 8, 4, 6, 7, 3,
279 2, 0, 6, 1, 4, 7, 8, 5, 3,
280 2, 7, 8, 1, 0, 5, 4, 6, 3,
281 2, 8, 7, 1, 0, 4, 3, 6, 5,
282
283 9, 9, 9, 9, 9, 9, 9, 9, 9,
284 0, 2, 1, 3, 5, 8, 6, 4, 7,
285 1, 0, 2, 5, 3, 6, 4, 8, 7,
286 2, 8, 1, 0, 3, 5, 7, 6, 4,
287 3, 2, 5, 8, 1, 4, 6, 7, 0,
288 4, 2, 0, 6, 1, 5, 8, 3, 7,
289 5, 3, 1, 2, 8, 6, 4, 0, 7,
290 1, 6, 0, 2, 4, 5, 8, 3, 7,
291 2, 7, 0, 1, 5, 4, 8, 6, 3,
292 2, 8, 3, 5, 1, 0, 7, 6, 4,
293
294 9, 9, 9, 9, 9, 9, 9, 9, 9,
295 2, 0, 6, 1, 4, 7, 5, 8, 3,
296 1, 6, 2, 0, 4, 5, 3, 7, 8,
297 2, 8, 7, 6, 4, 0, 1, 5, 3,
298 4, 2, 1, 0, 6, 8, 3, 5, 7,
299 4, 2, 6, 0, 1, 5, 7, 8, 3,
300 1, 2, 5, 0, 6, 3, 4, 7, 8,
301 6, 4, 0, 1, 2, 7, 5, 3, 8,
302 2, 7, 4, 6, 0, 1, 8, 5, 3,
303 2, 8, 7, 4, 6, 1, 3, 5, 0,
304
305 9, 9, 9, 9, 9, 9, 9, 9, 9,
306 5, 1, 2, 3, 6, 8, 0, 4, 7,
307 1, 5, 6, 3, 2, 0, 4, 8, 7,
308 2, 1, 5, 3, 6, 8, 7, 4, 0,
309 5, 3, 1, 2, 6, 8, 4, 7, 0,
310 1, 6, 2, 4, 5, 8, 0, 3, 7,
311 5, 1, 3, 6, 2, 0, 8, 4, 7,
312 1, 6, 5, 2, 0, 4, 3, 7, 8,
313 2, 7, 1, 6, 5, 0, 8, 3, 4,
314 2, 5, 1, 3, 6, 8, 4, 0, 7,
315
316 9, 9, 9, 9, 9, 9, 9, 9, 9,
317 1, 6, 2, 0, 5, 4, 3, 7, 8,
318 1, 6, 5, 4, 2, 3, 0, 7, 8,
319 2, 1, 6, 7, 4, 8, 5, 3, 0,
320 2, 1, 6, 5, 8, 4, 3, 0, 7,
321 6, 4, 1, 2, 0, 5, 7, 8, 3,
322 1, 6, 5, 2, 3, 0, 4, 8, 7,
323 6, 1, 4, 0, 2, 7, 5, 3, 8,
324 2, 7, 4, 6, 1, 5, 0, 8, 3,
325 2, 1, 6, 8, 4, 7, 3, 5, 0,
326
327 9, 9, 9, 9, 9, 9, 9, 9, 9,
328 2, 0, 4, 7, 6, 1, 8, 5, 3,
329 6, 1, 2, 0, 4, 7, 5, 8, 3,
330 2, 7, 8, 0, 1, 6, 4, 3, 5,
331 2, 4, 0, 8, 3, 1, 7, 6, 5,
332 4, 2, 7, 0, 6, 1, 8, 5, 3,
333 2, 1, 0, 8, 5, 6, 7, 4, 3,
334 2, 6, 4, 1, 7, 0, 5, 8, 3,
335 2, 7, 4, 0, 8, 6, 1, 5, 3,
336 2, 8, 7, 4, 1, 0, 3, 6, 5,
337
338 9, 9, 9, 9, 9, 9, 9, 9, 9,
339 2, 0, 8, 1, 3, 4, 6, 5, 7,
340 1, 2, 0, 6, 8, 5, 7, 3, 4,
341 2, 8, 7, 1, 0, 3, 6, 5, 4,
342 8, 3, 2, 5, 1, 0, 4, 7, 6,
343 2, 0, 4, 8, 5, 1, 7, 6, 3,
344 2, 1, 0, 8, 5, 3, 6, 4, 7,
345 2, 1, 6, 0, 8, 4, 5, 7, 3,
346 2, 7, 8, 4, 0, 6, 1, 5, 3,
347 2, 8, 3, 0, 7, 4, 1, 6, 5,
348];