all_decoders = ["all_video_decoders", "all_audio_decoders"]
-all_video_decoders = ["decoder_gdvvid", "decoder_indeo2", "decoder_indeo3", "decoder_indeo4", "decoder_indeo5", "decoder_intel263"]
+all_video_decoders = ["decoder_gdvvid", "decoder_indeo2", "decoder_indeo3", "decoder_indeo4", "decoder_indeo5", "decoder_intel263", "decoder_realvideo1"]
decoder_gdvvid = ["decoders"]
decoder_indeo2 = ["decoders"]
decoder_indeo3 = ["decoders"]
decoder_indeo4 = ["decoders"]
decoder_indeo5 = ["decoders"]
decoder_intel263 = ["h263", "decoders"]
+decoder_realvideo1 = ["h263", "decoders"]
all_audio_decoders = ["decoder_pcm", "decoder_imc"]
decoder_pcm = ["decoders"]
mb_stride: usize,
mb_start: usize,
top: bool,
- umv: bool,
+ mvmode: MVMode,
}
impl MVInfo {
- fn new() -> Self { MVInfo{ mv: Vec::new(), mb_w: 0, mb_stride: 0, mb_start: 0, top: true, umv: false } }
- fn reset(&mut self, mb_w: usize, mb_start: usize, umv: bool) {
+ fn new() -> Self { MVInfo{ mv: Vec::new(), mb_w: 0, mb_stride: 0, mb_start: 0, top: true, mvmode: MVMode::Old } }
+ fn reset(&mut self, mb_w: usize, mb_start: usize, mvmode: MVMode) {
self.mb_start = mb_start;
self.mb_w = mb_w;
self.mb_stride = mb_w * 2;
self.top = true;
self.mv.resize(self.mb_stride * 3, ZERO_MV);
- self.umv = umv;
+ self.mvmode = mvmode;
}
fn update_row(&mut self) {
self.mb_start = self.mb_w + 1;
_ => { return ZERO_MV; }
}
let pred_mv = MV::pred(A, B, C);
- let new_mv = MV::add_umv(pred_mv, diff, self.umv);
+ let new_mv = MV::add_umv(pred_mv, diff, self.mvmode);
if !use4 {
self.mv[self.mb_stride * 1 + mb_x * 2 + 0] = new_mv;
self.mv[self.mb_stride * 1 + mb_x * 2 + 1] = new_mv;
let mut buf = bufinfo.get_vbuf().unwrap();
let mut slice = Slice::get_default_slice(&pinfo);
- mvi.reset(self.mb_w, 0, pinfo.get_umv());
+ mvi.reset(self.mb_w, 0, pinfo.get_mvmode());
cbpi.reset(self.mb_w);
let mut blk: [[i16; 64]; 6] = [[0; 64]; 6];
if ((mb_x != 0) || (mb_y != 0)) && bd.is_slice_end() {
slice = bd.decode_slice_header(&pinfo)?;
- mvi.reset(self.mb_w, mb_x, pinfo.get_umv());
+ //mvi.reset(self.mb_w, mb_x, pinfo.get_mvmode());
//cbpi.reset(self.mb_w);
}
b_mb.mv_b[0] = binfo.get_mv2(0);
} else if binfo.get_num_mvs() == 1 {
let src_mv = binfo.get_mv(0).scale(bsdiff, tsdiff);
- let mv_f = MV::add_umv(src_mv, binfo.get_mv2(0), pinfo.get_umv());
+ let mv_f = MV::add_umv(src_mv, binfo.get_mv2(0), pinfo.get_mvmode());
let mv_b = MV::b_sub(binfo.get_mv(0), mv_f, binfo.get_mv2(0), bsdiff, tsdiff);
b_mb.mv_f[0] = mv_f;
b_mb.mv_b[0] = mv_b;
} else {
for blk_no in 0..4 {
let src_mv = binfo.get_mv(blk_no).scale(bsdiff, tsdiff);
- let mv_f = MV::add_umv(src_mv, binfo.get_mv2(0), pinfo.get_umv());
+ let mv_f = MV::add_umv(src_mv, binfo.get_mv2(0), pinfo.get_mvmode());
let mv_b = MV::b_sub(binfo.get_mv(blk_no), mv_f, binfo.get_mv2(0), bsdiff, tsdiff);
b_mb.mv_f[blk_no] = mv_f;
b_mb.mv_b[blk_no] = mv_b;
self.mb_w = (w + 15) >> 4;
let ftype = if is_intra { Type::I } else { Type::P };
- let picinfo = PicInfo::new(w, h, ftype, quant as u8, apm, umv, tr, pbinfo, deblock);
+ let mvmode = if umv { MVMode::UMV } else { MVMode::Long };
+ let picinfo = PicInfo::new(w, h, ftype, quant as u8, apm, mvmode, tr, pbinfo, deblock);
Ok(picinfo)
}
#[cfg(feature="decoder_intel263")]
pub mod intel263;
+#[cfg(feature="decoder_realvideo1")]
+pub mod rv10;
pub trait BlockDecoder {
fn decode_pichdr(&mut self) -> DecoderResult<PicInfo>;
mode: Type,
quant: u8,
apm: bool,
- umv: bool,
+ mvmode: MVMode,
pb: Option<PBInfo>,
ts: u8,
deblock: bool,
#[allow(dead_code)]
impl PicInfo {
- pub fn new(w: usize, h: usize, mode: Type, quant: u8, apm: bool, umv: bool, ts: u8, pb: Option<PBInfo>, deblock: bool) -> Self {
- PicInfo{ w: w, h: h, mode: mode, quant: quant, apm: apm, umv: umv, ts: ts, pb: pb, deblock: deblock }
+ pub fn new(w: usize, h: usize, mode: Type, quant: u8, apm: bool, mvmode: MVMode, ts: u8, pb: Option<PBInfo>, deblock: bool) -> Self {
+ PicInfo{ w: w, h: h, mode: mode, quant: quant, apm: apm, mvmode: mvmode, ts: ts, pb: pb, deblock: deblock }
}
pub fn get_width(&self) -> usize { self.w }
pub fn get_height(&self) -> usize { self.h }
pub fn get_mode(&self) -> Type { self.mode }
pub fn get_quant(&self) -> u8 { self.quant }
pub fn get_apm(&self) -> bool { self.apm }
- pub fn get_umv(&self) -> bool { self.umv }
+ pub fn get_mvmode(&self) -> MVMode { self.mvmode }
pub fn is_pb(&self) -> bool { self.pb.is_some() }
pub fn get_ts(&self) -> u8 { self.ts }
pub fn get_pbinfo(&self) -> PBInfo { self.pb.unwrap() }
pub fn get_num_mv(&self) -> usize { self.num_mv }
}
+#[derive(Debug,Clone,Copy)]
+pub enum MVMode {
+ Old,
+ Long,
+ UMV,
+}
+
#[derive(Debug,Clone,Copy)]
pub struct MV {
x: i16,
}
MV { x: x, y: y }
}
- fn add_umv(pred_mv: MV, add: MV, umv: bool) -> Self {
+ fn add_umv(pred_mv: MV, add: MV, mvmode: MVMode) -> Self {
let mut new_mv = pred_mv + add;
- if umv {
- if pred_mv.x > 32 && new_mv.x > 63 { new_mv.x -= 64; }
- if pred_mv.x < -31 && new_mv.x < -63 { new_mv.x += 64; }
- if pred_mv.y > 32 && new_mv.y > 63 { new_mv.y -= 64; }
- if pred_mv.y < -31 && new_mv.y < -63 { new_mv.y += 64; }
- } else {
- if new_mv.x > 31 { new_mv.x -= 64; }
- else if new_mv.x < -32 { new_mv.x += 64; }
- if new_mv.y > 31 { new_mv.y -= 64; }
- else if new_mv.y < -32 { new_mv.y += 64; }
- }
+ match mvmode {
+ MVMode::Old => {
+ if new_mv.x >= 64 { new_mv.x -= 64; }
+ else if new_mv.x <= -64 { new_mv.x += 64; }
+ if new_mv.y >= 64 { new_mv.y -= 64; }
+ else if new_mv.y <= -64 { new_mv.y += 64; }
+ },
+ MVMode::Long => {
+ if new_mv.x > 31 { new_mv.x -= 64; }
+ else if new_mv.x < -32 { new_mv.x += 64; }
+ if new_mv.y > 31 { new_mv.y -= 64; }
+ else if new_mv.y < -32 { new_mv.y += 64; }
+ },
+ MVMode::UMV => {
+ if pred_mv.x > 32 && new_mv.x > 63 { new_mv.x -= 64; }
+ if pred_mv.x < -31 && new_mv.x < -63 { new_mv.x += 64; }
+ if pred_mv.y > 32 && new_mv.y > 63 { new_mv.y -= 64; }
+ if pred_mv.y < -31 && new_mv.y < -63 { new_mv.y += 64; }
+ },
+ };
new_mv
}
fn scale(&self, trb: u8, trd: u8) -> Self {
}
macro_rules! validate {
- ($a:expr) => { if !$a { return Err(DecoderError::InvalidData); } };
+ ($a:expr) => { if !$a { println!("check failed at {}:{}", file!(), line!()); return Err(DecoderError::InvalidData); } };
}
#[allow(dead_code)]
DecoderInfo { name: "indeo5", get_decoder: indeo::indeo5::get_decoder },
#[cfg(feature="decoder_intel263")]
DecoderInfo { name: "intel263", get_decoder: h263::intel263::get_decoder },
+#[cfg(feature="decoder_realvideo1")]
+ DecoderInfo { name: "realvideo1", get_decoder: h263::rv10::get_decoder },
#[cfg(feature="decoder_pcm")]
DecoderInfo { name: "pcm", get_decoder: pcm::get_decoder },