]>
Commit | Line | Data |
---|---|---|
5641dccf KS |
1 | use nihav_core::formats; |
2 | use nihav_core::io::bitreader::*; | |
3 | use nihav_core::io::intcode::*; | |
4 | use nihav_core::frame::*; | |
5 | use nihav_core::codecs::*; | |
b4d5b851 | 6 | use nihav_codec_support::codecs::{MV, ZERO_MV}; |
47527732 KS |
7 | use super::rv3040::*; |
8 | use super::rv30dsp::*; | |
9 | ||
10 | struct RealVideo30BR { | |
11 | rpr_bits: u8, | |
12 | width: usize, | |
13 | height: usize, | |
14 | widths: Vec<usize>, | |
15 | heights: Vec<usize>, | |
16 | } | |
17 | ||
18 | impl 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 | ||
30 | impl 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 | ||
104 | struct RealVideo30Decoder { | |
105 | bd: RealVideo30BR, | |
2422d969 | 106 | info: NACodecInfoRef, |
47527732 KS |
107 | dec: RV34Decoder, |
108 | } | |
109 | ||
110 | impl 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 | ||
120 | impl 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 { | |
47527732 KS |
148 | Err(DecoderError::InvalidData) |
149 | } | |
150 | } | |
3c69ce1b | 151 | fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> { |
47527732 KS |
152 | let src = pkt.get_buffer(); |
153 | ||
3c69ce1b | 154 | let (bufinfo, ftype, pts) = self.dec.parse_frame(supp, src.as_slice(), &mut self.bd)?; |
47527732 KS |
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 } ); | |
171860fc | 160 | Ok(frm.into_ref()) |
47527732 | 161 | } |
f9be4e75 KS |
162 | fn flush(&mut self) { |
163 | self.dec.flush(); | |
164 | } | |
47527732 KS |
165 | } |
166 | ||
7d57ae2f KS |
167 | impl 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 | ||
08a1fab7 | 173 | pub fn get_decoder() -> Box<dyn NADecoder + Send> { |
47527732 KS |
174 | Box::new(RealVideo30Decoder::new()) |
175 | } | |
176 | ||
177 | #[cfg(test)] | |
178 | mod test { | |
3167c45c KS |
179 | use nihav_core::codecs::RegisteredDecoders; |
180 | use nihav_core::demuxers::RegisteredDemuxers; | |
ce742854 | 181 | use nihav_codec_support::test::dec_video::*; |
78fb6560 | 182 | use crate::realmedia_register_all_decoders; |
e64739f8 | 183 | use crate::realmedia_register_all_demuxers; |
47527732 KS |
184 | #[test] |
185 | fn test_rv30() { | |
3167c45c KS |
186 | let mut dmx_reg = RegisteredDemuxers::new(); |
187 | realmedia_register_all_demuxers(&mut dmx_reg); | |
188 | let mut dec_reg = RegisteredDecoders::new(); | |
78fb6560 | 189 | realmedia_register_all_decoders(&mut dec_reg); |
3167c45c | 190 | |
886cde48 | 191 | // sample from a private collection |
70860638 KS |
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]])); | |
886cde48 | 209 | // sample: https://samples.mplayerhq.hu/real/VC-RV30/simpsons-clip.rm |
70860638 KS |
210 | test_decoding("realmedia", "realvideo3", "assets/RV/simpsons-clip.rm", Some(1337), |
211 | &dmx_reg, &dec_reg, | |
212 | ExpectedTestResult::MD5([0x36604117, 0x415f95cc, 0xec38e776, 0x9818d3be])); | |
47527732 KS |
213 | } |
214 | } | |
215 | ||
216 | const 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 | ||
221 | const 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 | ||
226 | const 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 | ||
238 | const 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 | ]; |