aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2018-12-08 12:54:04 +0100
committerKostya Shishkov <kostya.shishkov@gmail.com>2018-12-08 12:54:04 +0100
commit43c8b55e9b586d6814b0588516eadf9bd12c9685 (patch)
tree08ed368b4167e829cd100a8917781809e0e8e251
parent7348405bb0e9c70c9f9cbf3f13bb7c2b7dd86d5b (diff)
downloadnihav-43c8b55e9b586d6814b0588516eadf9bd12c9685.tar.gz
h263+rv20: use modified dquant and chroma quant
-rw-r--r--src/codecs/h263/data.rs15
-rw-r--r--src/codecs/h263/decoder.rs3
-rw-r--r--src/codecs/h263/mod.rs3
-rw-r--r--src/codecs/h263/rv20.rs26
4 files changed, 35 insertions, 12 deletions
diff --git a/src/codecs/h263/data.rs b/src/codecs/h263/data.rs
index 38fa6ca..b5d3cb1 100644
--- a/src/codecs/h263/data.rs
+++ b/src/codecs/h263/data.rs
@@ -96,6 +96,21 @@ pub const H263_CBPC_B: &[(u8, u8)] = &[
pub const H263_DQUANT_TAB: &[i8] = &[-1, -2, 1, 2];
+pub const H263_MODIFIED_QUANT: [[u8; 32]; 2] = [
+ [
+ 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28
+ ], [
+ 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 31, 31, 26
+ ]
+];
+
+pub const H263_CHROMA_QUANT: [u8; 32] = [
+ 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 10, 11, 11,
+ 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15
+];
+
pub struct H263ShortCodeReader { tab: &'static [(u8, u8)] }
impl H263ShortCodeReader {
diff --git a/src/codecs/h263/decoder.rs b/src/codecs/h263/decoder.rs
index f871bbd..08b4751 100644
--- a/src/codecs/h263/decoder.rs
+++ b/src/codecs/h263/decoder.rs
@@ -243,6 +243,7 @@ impl H263BaseDecoder {
self.pred_coeffs.truncate(0);
self.pred_coeffs.resize(self.mb_w * self.mb_h, ZERO_PRED_COEFFS);
}
+ sstate.quant = slice.quant;
for mb_y in 0..self.mb_h {
for mb_x in 0..self.mb_w {
for i in 0..6 { for j in 0..64 { blk[i][j] = 0; } }
@@ -256,6 +257,7 @@ impl H263BaseDecoder {
}
cbpi.reset(self.mb_w);
sstate.reset_slice(mb_x, mb_y);
+ sstate.quant = slice.quant;
}
}
@@ -263,6 +265,7 @@ impl H263BaseDecoder {
let cbp = binfo.get_cbp();
cbpi.set_cbp(mb_x, cbp);
cbpi.set_q(mb_x, binfo.get_q());
+ sstate.quant = binfo.get_q();
if binfo.is_intra() {
if save_b_data {
self.mv_data.push(BlockMVInfo::Intra);
diff --git a/src/codecs/h263/mod.rs b/src/codecs/h263/mod.rs
index 50eed7d..aa274e7 100644
--- a/src/codecs/h263/mod.rs
+++ b/src/codecs/h263/mod.rs
@@ -137,6 +137,7 @@ pub struct SliceState {
pub first_mb: bool,
pub slice_mb_x: usize,
pub slice_mb_y: usize,
+ pub quant: u8,
}
const SLICE_NO_END: usize = 99999999;
@@ -160,7 +161,7 @@ impl SliceState {
pub fn new(is_iframe: bool) -> Self {
SliceState {
is_iframe: is_iframe, mb_x: 0, mb_y: 0, first_line: true, first_mb: true,
- slice_mb_x: 0, slice_mb_y: 0
+ slice_mb_x: 0, slice_mb_y: 0, quant: 0
}
}
pub fn next_mb(&mut self) {
diff --git a/src/codecs/h263/rv20.rs b/src/codecs/h263/rv20.rs
index 9e62875..3b9fa1b 100644
--- a/src/codecs/h263/rv20.rs
+++ b/src/codecs/h263/rv20.rs
@@ -129,7 +129,7 @@ impl<'a> RealVideo20BR<'a> {
let rl_cb = if sstate.is_iframe { &self.tables.aic_rl_cb } else { &self.tables.rl_cb };
let q_add = if quant == 0 || sstate.is_iframe { 0i16 } else { ((quant - 1) | 1) as i16 };
- let q = (quant * 2) as i16;
+ let q = if plane_no == 0 { (quant * 2) as i16 } else { H263_CHROMA_QUANT[quant as usize] as i16 };
while idx < 64 {
let code = br.read_cb(rl_cb)?;
let run;
@@ -181,6 +181,14 @@ fn decode_mv(br: &mut BitReader, mv_cb: &Codebook<u8>) -> DecoderResult<MV> {
Ok(MV::new(xval, yval))
}
+fn read_dquant(br: &mut BitReader, q: u8) -> DecoderResult<u8> {
+ if br.read_bool()? {
+ Ok(H263_MODIFIED_QUANT[br.read(1)? as usize][q as usize])
+ } else {
+ Ok(br.read(5)? as u8)
+ }
+}
+
impl<'a> BlockDecoder for RealVideo20BR<'a> {
#[allow(unused_variables)]
@@ -222,9 +230,9 @@ impl<'a> BlockDecoder for RealVideo20BR<'a> {
Ok(ret)
}
- fn decode_block_header(&mut self, info: &PicInfo, slice: &SliceInfo, _sstate: &SliceState) -> DecoderResult<BlockInfo> {
+ fn decode_block_header(&mut self, info: &PicInfo, _slice: &SliceInfo, sstate: &SliceState) -> DecoderResult<BlockInfo> {
let br = &mut self.br;
- let mut q = slice.get_quant();
+ let mut q = sstate.quant;
match info.get_mode() {
Type::I => {
let mut cbpc = br.read_cb(&self.tables.intra_mcbpc_cb)?;
@@ -243,8 +251,7 @@ impl<'a> BlockDecoder for RealVideo20BR<'a> {
let cbp = (cbpy << 2) | (cbpc & 3);
let dquant = (cbpc & 4) != 0;
if dquant {
- let idx = br.read(2)? as usize;
- q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8;
+ q = read_dquant(br, q)?;
}
let mut binfo = BlockInfo::new(Type::I, cbp, q);
binfo.set_acpred(acpred);
@@ -263,8 +270,7 @@ impl<'a> BlockDecoder for RealVideo20BR<'a> {
let cbpy = br.read_cb(&self.tables.cbpy_cb)?;
let cbp = (cbpy << 2) | (cbpc & 3);
if dquant {
- let idx = br.read(2)? as usize;
- q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8;
+ q = read_dquant(br, q)?;
}
let binfo = BlockInfo::new(Type::I, cbp, q);
return Ok(binfo);
@@ -276,8 +282,7 @@ impl<'a> BlockDecoder for RealVideo20BR<'a> {
// }
let cbp = (cbpy << 2) | (cbpc & 3);
if dquant {
- let idx = br.read(2)? as usize;
- q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8;
+ q = read_dquant(br, q)?;
}
let mut binfo = BlockInfo::new(Type::P, cbp, q);
if !is_4x4 {
@@ -312,8 +317,7 @@ impl<'a> BlockDecoder for RealVideo20BR<'a> {
} else { 0 };
if dquant {
- let idx = br.read(2)? as usize;
- q = ((q as i16) + (H263_DQUANT_TAB[idx] as i16)) as u8;
+ q = read_dquant(br, q)?;
}
if is_intra {