use nihav_core::io::codebook::*;
use nihav_core::io::intcode::*;
use nihav_core::codecs::*;
+use nihav_codec_support::codecs::{MV, ZERO_MV};
use super::rv3040::*;
use super::rv40dsp::*;
RealVideo40BR {
width: 0,
height: 0,
- aic_top_cb: aic_top_cb,
- aic_mode1_cb: aic_mode1_cb,
- aic_mode2_cb: aic_mode2_cb,
- ptype_cb: ptype_cb,
- btype_cb: btype_cb,
+ aic_top_cb,
+ aic_mode1_cb,
+ aic_mode2_cb,
+ ptype_cb,
+ btype_cb,
had_skip_run: false,
}
}
- fn predict_b_mv_component(&self, sstate: &SState, mvi: &MVInfo, mbinfo: &Vec<RV34MBInfo>, mbtype: MBType, fwd: bool) -> MV {
+ fn predict_b_mv_component(&self, sstate: &SState, mvi: &MVInfo, mbinfo: &[RV34MBInfo], mbtype: MBType, fwd: bool) -> MV {
let mut pred_mvs: [MV; 3] = [ZERO_MV; 3];
let mut mv_count: usize = 0;
let mb_x = sstate.mb_x;
self.had_skip_run = false;
- Ok(RV34SliceHeader{ ftype: ftype, quant: q, deblock: deblock, pts: pts, width: w, height: h, start: start, end: 0, set_idx: set_idx })
+ Ok(RV34SliceHeader{ ftype, quant: q, deblock, pts, width: w, height: h, start, end: 0, set_idx })
}
fn decode_intra_pred(&mut self, br: &mut BitReader, types: &mut [i8], mut pos: usize, tstride: usize, has_top: bool) -> DecoderResult<()> {
let start;
mbtype = if ftype == FrameType::P { br.read_cb(&self.ptype_cb[idx])? }
else { br.read_cb(&self.btype_cb[idx])? };
}
- Ok(MBInfo { mbtype: mbtype, skip_run: 0, dquant: dquant })
+ Ok(MBInfo { mbtype, skip_run: 0, dquant })
}
- fn predict_b_mv(&self, sstate: &SState, mvi: &MVInfo, mbtype: MBType, mvs: &[MV], mbinfo: &Vec<RV34MBInfo>) -> (MV, MV) {
+ fn predict_b_mv(&self, sstate: &SState, mvi: &MVInfo, mbtype: MBType, mvs: &[MV], mbinfo: &[RV34MBInfo]) -> (MV, MV) {
let mut mv_f = self.predict_b_mv_component(sstate, mvi, mbinfo, mbtype, true);
let mut mv_b = self.predict_b_mv_component(sstate, mvi, mbinfo, mbtype, false);
}
impl NADecoder for RealVideo40Decoder {
- fn init(&mut self, _supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
+ fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
let fmt = formats::YUV420_FORMAT;
let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt));
{
println!("edata:");
-for i in 0..src.len() { print!(" {:02X}", src[i]); } println!("");
+for i in 0..src.len() { print!(" {:02X}", src[i]); } println!();
}
if src.len() < 2 { return Err(DecoderError::InvalidData); }
self.bd.width = vinfo.get_width();
self.bd.height = vinfo.get_height();
+
+ supp.pool_u8.set_dec_bufs(3);
+ supp.pool_u8.prealloc_video(NAVideoInfo::new(self.bd.width, self.bd.height, false, fmt), 4)?;
+
Ok(())
} else {
println!("???");
Err(DecoderError::InvalidData)
}
}
- fn decode(&mut self, _supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
+ fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
let src = pkt.get_buffer();
- let (bufinfo, ftype, ts) = self.dec.parse_frame(src.as_slice(), &mut self.bd)?;
+ let (bufinfo, ftype, ts) = self.dec.parse_frame(supp, src.as_slice(), &mut self.bd)?;
let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
frm.set_keyframe(ftype == FrameType::I);
frm.set_pts(Some(ts));
Ok(frm.into_ref())
}
+ fn flush(&mut self) {
+ self.dec.flush();
+ }
+}
+
+impl NAOptionHandler for RealVideo40Decoder {
+ fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
+ fn set_options(&mut self, _options: &[NAOption]) { }
+ fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
}
-pub fn get_decoder() -> Box<NADecoder> {
+pub fn get_decoder() -> Box<dyn NADecoder + Send> {
Box::new(RealVideo40Decoder::new())
}
mod test {
use nihav_core::codecs::RegisteredDecoders;
use nihav_core::demuxers::RegisteredDemuxers;
- use nihav_core::test::dec_video::*;
- use crate::codecs::realmedia_register_all_codecs;
- use crate::demuxers::realmedia_register_all_demuxers;
+ use nihav_codec_support::test::dec_video::*;
+ use crate::realmedia_register_all_decoders;
+ use crate::realmedia_register_all_demuxers;
+ // samples from a private collection
#[test]
fn test_rv40() {
let mut dmx_reg = RegisteredDemuxers::new();
realmedia_register_all_demuxers(&mut dmx_reg);
let mut dec_reg = RegisteredDecoders::new();
- realmedia_register_all_codecs(&mut dec_reg);
+ realmedia_register_all_decoders(&mut dec_reg);
-// test_file_decoding("realmedia", "assets/RV/rv40_ralf.rmvb", Some(1000), true, false, /*None*/Some("rv40"));
- test_file_decoding("realmedia", "assets/RV/rv40_weighted_mc.rmvb", Some(400), true, false, None/*Some("rv40")*/, &dmx_reg, &dec_reg);
-// test_file_decoding("realmedia", "assets/RV/rv40_weighted_mc_2.rmvb", Some(1000), true, false, /*None*/Some("rv40"));
-//panic!("end");
+ test_decoding("realmedia", "realvideo4", "assets/RV/rv40_weighted_mc.rmvb", Some(1500),
+ &dmx_reg, &dec_reg,ExpectedTestResult::MD5Frames(vec![
+ [0x27cf336a, 0xc1686c50, 0x5304783d, 0x6e77ffa2],
+ [0x91f236c7, 0x3bda2d38, 0x961a0243, 0xda803cf1],
+ [0x4075d7e8, 0xbcd7f85b, 0x1c0dd34b, 0x405d0a5d],
+ [0x642498b7, 0xb57aa202, 0x69ea0d23, 0x1cc0794f],
+ [0x1c1a4df8, 0x7e3fbd7d, 0x7fdeb57f, 0xf5d65179],
+ [0x86a5dcdd, 0xd66caabf, 0xdfe1fc99, 0xb3443375],
+ [0x86846664, 0xbee4268d, 0xc1e017e6, 0xc9d984c8],
+ [0x0ecbe176, 0x81e5aca6, 0xb7bda49c, 0x34007e7b],
+ [0x48c8a90e, 0xed003b8a, 0xc9e7e9a6, 0x54b1eca8],
+ [0x540cbc0b, 0x6d7afaa8, 0xb0951c1f, 0xed22089e],
+ [0x73190f85, 0x9cd72603, 0x1063ca54, 0xd4f82c7f],
+ [0xef6206e8, 0x6affb292, 0xe12b7c9c, 0x37416240],
+ [0x59f61c91, 0x66b2a632, 0x46556395, 0x74fbc1de],
+ [0xd75635ca, 0x60d13826, 0xfa41d914, 0x9cfded0e],
+ [0x7a8c4396, 0x6f3eda39, 0x4238dbaf, 0xa9052803]]));
+ test_decoding("realmedia", "realvideo4", "assets/RV/rv40_weighted_mc_2.rmvb", Some(2000),
+ &dmx_reg, &dec_reg,
+ ExpectedTestResult::MD5([0x4224b9d6, 0x32e3ff63, 0x02df9e60, 0xfa0548ee]));
}
}