force_pitch: Option<u8>,
has_y2: bool,
- pdc_pred_val: i16,
- pdc_pred_count: usize,
+ pdc_pred_val: [i16; 2],
+ pdc_pred_count: [usize; 2],
ipred_ctx_y: IPredContext,
ipred_ctx_u: IPredContext,
}
Ok(())
}
- fn decode_residue(&mut self, bc: &mut BoolCoder, mb_x: usize, mb_idx: usize) {
+ fn decode_residue(&mut self, bc: &mut BoolCoder, mb_x: usize, mb_idx: usize, use_last: bool) {
let qmat_idx = if let Some(idx) = self.dstate.force_quant { (idx as usize) + 1 } else { 0 };
let mut sbparams = SBParams {
scan: &DEFAULT_SCAN_ORDER,
let y2block = &mut self.coeffs[24];
if self.mb_info[mb_idx].mb_type != VPMBType::Intra {
let mut dc = y2block[0];
- let pval = self.dstate.pdc_pred_val;
- if self.dstate.pdc_pred_count > 3 {
+ let pdc_idx = if use_last { 0 } else { 1 };
+ let pval = self.dstate.pdc_pred_val[pdc_idx];
+
+ if self.dstate.pdc_pred_count[pdc_idx] > 3 {
dc += pval;
y2block[0] = dc;
}
if (pval == 0) || (dc == 0) || ((pval ^ dc) < 0) {
- self.dstate.pdc_pred_val = dc;
- self.dstate.pdc_pred_count = 0;
+ self.dstate.pdc_pred_count[pdc_idx] = 0;
} else if dc == pval {
- self.dstate.pdc_pred_count += 1;
+ self.dstate.pdc_pred_count[pdc_idx] += 1;
}
+ self.dstate.pdc_pred_val[pdc_idx] = dc;
}
if has_ac[24] {
idct4x4(y2block);
- } else {
+ } else if y2block[0] != 0 {
idct4x4_dc(y2block);
}
for i in 0..16 {
for i in 0..24 {
if has_ac[i] {
idct4x4(&mut self.coeffs[i]);
- } else {
+ } else if self.coeffs[i][0] != 0 {
idct4x4_dc(&mut self.coeffs[i]);
}
}
}
}
}
+ let tr_edge = if has_top { ydst[yoff - ystride + 15] } else { 0x80 };
for y in 0..4 {
for x in 0..4 {
ipred_ctx_y.has_left = has_left || x > 0;
let bmode = self.ymodes[iidx + x];
let cur_yoff = yoff + x * 4;
- let has_tr = has_top && ((x < 3) || ((y == 0) && (mb_y < self.mb_w - 1)));
- let has_dl = ipred_ctx_y.has_left && (y < 3);
+ let has_tr = ipred_ctx_y.has_top && ((x < 3) || ((y == 0) && (mb_y < self.mb_w - 1)));
+ let has_dl = ipred_ctx_y.has_left && (x == 0) && (y < 3);
ipred_ctx_y.fill(ydst, cur_yoff, ystride,
if has_tr { 8 } else { 4 },
if has_dl { 8 } else { 4 });
tr_save[x * 4 + i] = ipred_ctx_y.top[i + 4];
}
}
+ if (mb_x == self.mb_w - 1) && has_top && (x == 3) {
+ for i in 0..4 {
+ ipred_ctx_y.top[i + 4] = tr_edge;
+ }
+ }
match bmode {
PredMode::DCPred => IPred4x4::ipred_dc(ydst, cur_yoff, ystride, ipred_ctx_y),
PredMode::TMPred => IPred4x4::ipred_tm(ydst, cur_yoff, ystride, ipred_ctx_y),
} else {
for y in 0..2 {
for x in 0..2 {
- let mut chroma_mv = self.mvs[iidx] + self.mvs[iidx + 1]
- + self.mvs[iidx + self.mv_stride]
- + self.mvs[iidx + self.mv_stride + 1];
- chroma_mv.x /= 4;
- chroma_mv.y /= 4;
+ let mut chroma_mv = self.mvs[iidx + x * 2] + self.mvs[iidx + x * 2 + 1]
+ + self.mvs[iidx + x * 2 + self.mv_stride]
+ + self.mvs[iidx + x * 2 + self.mv_stride + 1];
+ if chroma_mv.x < 0 {
+ chroma_mv.x += 1;
+ } else {
+ chroma_mv.x += 2;
+ }
+ if chroma_mv.y < 0 {
+ chroma_mv.y += 1;
+ } else {
+ chroma_mv.y += 2;
+ }
+ chroma_mv.x >>= 2;
+ chroma_mv.y >>= 2;
if pitch_smode == 0 {
- mc_block4x4(dst, uoff, ustride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
+ mc_block4x4(dst, uoff + x * 4, ustride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
chroma_mv.x, chroma_mv.y, refframe.clone(), 1, &mut mc_buf);
- mc_block4x4(dst, voff, vstride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
+ mc_block4x4(dst, voff + x * 4, vstride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
chroma_mv.x, chroma_mv.y, refframe.clone(), 2, &mut mc_buf);
} else {
- mc_block_special(dst, uoff, ustride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
+ mc_block_special(dst, uoff + x * 4, ustride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
chroma_mv.x, chroma_mv.y, refframe.clone(), 1, &mut mc_buf,
4, pitch_smode);
- mc_block_special(dst, voff, vstride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
+ mc_block_special(dst, voff + x * 4, vstride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
chroma_mv.x, chroma_mv.y, refframe.clone(), 2, &mut mc_buf,
4, pitch_smode);
}
self.set_dimensions(width, height);
self.dstate.reset();
+ } else {
+ if !self.shuf.has_refs() {
+ return Err(DecoderError::MissingReference);
+ }
}
self.read_features(&mut bc)?;
let mut mb_idx = 0;
self.pcache.reset();
- self.dstate.pdc_pred_val = 0;
- self.dstate.pdc_pred_count = 0;
+ if self.dstate.is_intra || (self.dstate.version > 0) {
+ self.dstate.pdc_pred_val = [0; 2];
+ self.dstate.pdc_pred_count = [0; 2];
+ }
let mut use_last = true;
for mb_y in 0..self.mb_h {
for mb_x in 0..self.mb_w {
self.mb_info[mb_idx].ymode = PredMode::Inter;
self.mb_info[mb_idx].uvmode = PredMode::Inter;
}
- self.decode_residue(&mut bc_main, mb_x, mb_idx);
+ self.decode_residue(&mut bc_main, mb_x, mb_idx, use_last);
match self.mb_info[mb_idx].mb_type {
VPMBType::Intra => {
self.recon_intra_mb(&mut dframe, mb_x, mb_y)?;
}
}
-pub fn get_decoder() -> Box<NADecoder> {
+pub fn get_decoder() -> Box<NADecoder + Send> {
Box::new(VP7Decoder::new())
}