summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYaowu Xu <yaowu@google.com>2011-10-20 15:32:34 -0400
committerYaowu Xu <yaowu@google.com>2011-10-28 12:07:21 -0700
commit88e24f07aed48593f455db9839cdf792c858f4d7 (patch)
tree2fad5afbf768cd1c9a93195a702eff65a38f2b79
parent3579baa115816b4bd93ba1d04a38bc07c381130a (diff)
downloadlibvpx-88e24f07aed48593f455db9839cdf792c858f4d7.tar
libvpx-88e24f07aed48593f455db9839cdf792c858f4d7.tar.gz
libvpx-88e24f07aed48593f455db9839cdf792c858f4d7.tar.bz2
libvpx-88e24f07aed48593f455db9839cdf792c858f4d7.zip
added code to clear 2nd order block when appropriate
It is discovered that in rare situations the 2nd order block may produce a few small magnitude coefficients that has no effect on reconstruction. The situations are a combination of low quantizer values (high quality) and low energy in residual signals (content dependent). This commit added code to detect such cases and reset the 2nd order block to all 0. Patch 1 to 4 used code to do all-zero-check on idct result buffer, and tests on derf set showed a consistent gain of .12%-.14% on all metrics.But due to a recent change Ie31d90b, the idct result buffer is not longer populated. So patch 5&6 use an alternative method to detect the situations. Tests on derf set now shows a consistent quality gain of .16%-.20%. As suggested by Jim, Patch 7&8 removed the condition of all first order block not having any coefficient, instead we reset 2nd order coefficients to all 0 if sum of absolute value of the coefficients is small. So it does slightly more than just detecting the oddity as discussed above, but tests on derf set now show a consistent gain of .20%-.23% on all metrics. It is worth noting here that this change does not have any effect on mid/high quantizer range, it only affects the quantizer value 18 or blow. Within this range, the change helps compression by up to 2.5% on clips in the derf set. Change-Id: I718e19cf59a4fc2462cb7070832759beb9f7e7dd
-rw-r--r--vp8/encoder/encodeintra.c3
-rw-r--r--vp8/encoder/encodemb.c44
2 files changed, 45 insertions, 2 deletions
diff --git a/vp8/encoder/encodeintra.c b/vp8/encoder/encodeintra.c
index 74e40323d..1c07cbdd5 100644
--- a/vp8/encoder/encodeintra.c
+++ b/vp8/encoder/encodeintra.c
@@ -94,7 +94,8 @@ void vp8_encode_intra16x16mby(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
RECON_INVOKE(&rtcd->common->recon, build_intra_predictors_mby)(&x->e_mbd);
- ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src), x->e_mbd.predictor, b->src_stride);
+ ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src),
+ x->e_mbd.predictor, b->src_stride);
vp8_transform_intra_mby(x);
diff --git a/vp8/encoder/encodemb.c b/vp8/encoder/encodemb.c
index b3c7df502..16f6875b1 100644
--- a/vp8/encoder/encodemb.c
+++ b/vp8/encoder/encodemb.c
@@ -469,12 +469,50 @@ static void optimize_b(MACROBLOCK *mb, int ib, int type,
d->eob = final_eob;
*a = *l = (d->eob != !type);
}
+static void check_reset_2nd_coeffs(MACROBLOCKD *x, int type,
+ ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
+{
+ int sum=0;
+ int i;
+ BLOCKD *bd = &x->block[24];
+
+ if(bd->dequant[0]>=35 && bd->dequant[1]>=35)
+ return;
+
+ for(i=0;i<bd->eob;i++)
+ {
+ int coef = bd->dqcoeff[vp8_default_zig_zag1d[i]];
+ sum+= (coef>=0)?coef:-coef;
+ if(sum>=35)
+ return;
+ }
+ /**************************************************************************
+ our inverse hadamard transform effectively is weighted sum of all 16 inputs
+ with weight either 1 or -1. It has a last stage scaling of (sum+3)>>3. And
+ dc only idct is (dc+4)>>3. So if all the sums are between -35 and 29, the
+ output after inverse wht and idct will be all zero. A sum of absolute value
+ smaller than 35 guarantees all 16 different (+1/-1) weighted sums in wht
+ fall between -35 and +35.
+ **************************************************************************/
+ if(sum < 35)
+ {
+ for(i=0;i<bd->eob;i++)
+ {
+ int rc = vp8_default_zig_zag1d[i];
+ bd->qcoeff[rc]=0;
+ bd->dqcoeff[rc]=0;
+ }
+ bd->eob = 0;
+ *a = *l = (bd->eob != !type);
+ }
+}
static void optimize_mb(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
{
int b;
int type;
int has_2nd_order;
+
ENTROPY_CONTEXT_PLANES t_above, t_left;
ENTROPY_CONTEXT *ta;
ENTROPY_CONTEXT *tl;
@@ -506,6 +544,8 @@ static void optimize_mb(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
b=24;
optimize_b(x, b, PLANE_TYPE_Y2,
ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd);
+ check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2,
+ ta + vp8_block2above[b], tl + vp8_block2left[b]);
}
}
@@ -539,7 +579,7 @@ void vp8_optimize_mby(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
for (b = 0; b < 16; b++)
{
optimize_b(x, b, type,
- ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd);
+ ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd);
}
@@ -548,6 +588,8 @@ void vp8_optimize_mby(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
b=24;
optimize_b(x, b, PLANE_TYPE_Y2,
ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd);
+ check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2,
+ ta + vp8_block2above[b], tl + vp8_block2left[b]);
}
}