From c8f56d23039865b0bd03ea8c518b5691f2be02c7 Mon Sep 17 00:00:00 2001 From: hui su <huisu@google.com> Date: Mon, 25 Apr 2016 12:40:56 -0700 Subject: [PATCH] VP9: enable trellis quantization optimization for intra blocks Coding gain: lowres 0.18% midres 0.23% hdres 0.36% Change-Id: I044c8afbc481fc55b23d440352941071355b0afb --- vp9/encoder/vp9_encodeframe.c | 2 +- vp9/encoder/vp9_encodemb.c | 35 +++++++++++++++++++++++++++++++++-- vp9/encoder/vp9_encodemb.h | 3 ++- vp9/encoder/vp9_firstpass.c | 2 +- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 5b679d25e..7bca8a277 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -4339,7 +4339,7 @@ static void encode_superblock(VP9_COMP *cpi, ThreadData *td, int plane; mi->skip = 1; for (plane = 0; plane < MAX_MB_PLANE; ++plane) - vp9_encode_intra_block_plane(x, VPXMAX(bsize, BLOCK_8X8), plane); + vp9_encode_intra_block_plane(x, VPXMAX(bsize, BLOCK_8X8), plane, 1); if (output_enabled) sum_intra_stats(td->counts, mi); vp9_tokenize_sb(cpi, td, t, !output_enabled, seg_skip, diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c index c5e8bc6d3..50387d770 100644 --- a/vp9/encoder/vp9_encodemb.c +++ b/vp9/encoder/vp9_encodemb.c @@ -785,10 +785,19 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, const int src_stride = p->src.stride; const int dst_stride = pd->dst.stride; int i, j; + struct optimize_ctx *const ctx = args->ctx; + ENTROPY_CONTEXT *a = NULL; + ENTROPY_CONTEXT *l = NULL; + int entropy_ctx = 0; txfrm_block_to_raster_xy(plane_bsize, tx_size, block, &i, &j); dst = &pd->dst.buf[4 * (j * dst_stride + i)]; src = &p->src.buf[4 * (j * src_stride + i)]; src_diff = &p->src_diff[4 * (j * diff_stride + i)]; + if (args->ctx != NULL) { + a = &ctx->ta[plane][i]; + l = &ctx->tl[plane][j]; + entropy_ctx = combine_entropy_contexts(*a, *l); + } if (tx_size == TX_4X4) { tx_type = get_tx_type_4x4(get_plane_type(plane), xd, block); @@ -907,6 +916,9 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, pd->dequant, eob, scan_order->scan, scan_order->iscan); } + if (args->ctx != NULL) { + *a = *l = optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; + } if (!x->skip_encode && *eob) vp9_idct32x32_add(dqcoeff, dst, dst_stride, *eob); break; @@ -920,6 +932,9 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, pd->dequant, eob, scan_order->scan, scan_order->iscan); } + if (args->ctx != NULL) { + *a = *l = optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; + } if (!x->skip_encode && *eob) vp9_iht16x16_add(tx_type, dqcoeff, dst, dst_stride, *eob); break; @@ -933,6 +948,9 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, pd->dequant, eob, scan_order->scan, scan_order->iscan); } + if (args->ctx != NULL) { + *a = *l = optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; + } if (!x->skip_encode && *eob) vp9_iht8x8_add(tx_type, dqcoeff, dst, dst_stride, *eob); break; @@ -949,7 +967,9 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, pd->dequant, eob, scan_order->scan, scan_order->iscan); } - + if (args->ctx != NULL) { + *a = *l = optimize_b(x, plane, block, tx_size, entropy_ctx) > 0; + } if (!x->skip_encode && *eob) { if (tx_type == DCT_DCT) // this is like vp9_short_idct4x4 but has a special case around eob<=1 @@ -968,10 +988,21 @@ void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, *(args->skip) = 0; } -void vp9_encode_intra_block_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) { +void vp9_encode_intra_block_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane, + int enable_optimize_b) { const MACROBLOCKD *const xd = &x->e_mbd; + struct optimize_ctx ctx; struct encode_b_args arg = {x, NULL, &xd->mi[0]->skip}; + if (enable_optimize_b && x->optimize && + (!x->skip_recode || !x->skip_optimize)) { + const struct macroblockd_plane* const pd = &xd->plane[plane]; + const TX_SIZE tx_size = plane ? get_uv_tx_size(xd->mi[0], pd) : + xd->mi[0]->tx_size; + vp9_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]); + arg.ctx = &ctx; + } + vp9_foreach_transformed_block_in_plane(xd, bsize, plane, vp9_encode_block_intra, &arg); } diff --git a/vp9/encoder/vp9_encodemb.h b/vp9/encoder/vp9_encodemb.h index 97df8a66b..25b0b23e0 100644 --- a/vp9/encoder/vp9_encodemb.h +++ b/vp9/encoder/vp9_encodemb.h @@ -37,7 +37,8 @@ void vp9_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane); void vp9_encode_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg); -void vp9_encode_intra_block_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane); +void vp9_encode_intra_block_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane, + int enable_optimize_b); #ifdef __cplusplus } // extern "C" diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index 3e34c012c..0819f5829 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -741,7 +741,7 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) { xd->mi[0]->mode = DC_PRED; xd->mi[0]->tx_size = use_dc_pred ? (bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4; - vp9_encode_intra_block_plane(x, bsize, 0); + vp9_encode_intra_block_plane(x, bsize, 0, 0); this_error = vpx_get_mb_ss(x->plane[0].src_diff); // Keep a record of blocks that have almost no intra error residual