From 232d90d8fd47cdc07625036bdd0e4c8f009b8c10 Mon Sep 17 00:00:00 2001 From: Yaowu Xu Date: Wed, 15 May 2013 17:21:15 -0700 Subject: [PATCH] Generalized intra 4x4 encoding for all sizes Change-Id: I1b86744fa247233c8df031b3f4b87b212c8dd094 --- vp9/common/vp9_reconinter.h | 1 - vp9/common/vp9_reconintra.c | 56 ++++++++++++------- vp9/common/vp9_reconintra.h | 6 ++ vp9/encoder/vp9_encodeframe.c | 2 +- vp9/encoder/vp9_encodeintra.c | 11 +--- vp9/encoder/vp9_encodeintra.h | 3 +- vp9/encoder/vp9_encodemb.c | 101 ++++++++++++++++++++++++++++++++++ 7 files changed, 147 insertions(+), 33 deletions(-) diff --git a/vp9/common/vp9_reconinter.h b/vp9/common/vp9_reconinter.h index af289d27e..4e521850d 100644 --- a/vp9/common/vp9_reconinter.h +++ b/vp9/common/vp9_reconinter.h @@ -15,7 +15,6 @@ #include "vp9/common/vp9_onyxc_int.h" struct subpix_fn_table; - void vp9_build_inter_predictors_sby(MACROBLOCKD *xd, int mb_row, int mb_col, diff --git a/vp9/common/vp9_reconintra.c b/vp9/common/vp9_reconintra.c index ea4805f33..1588f33ce 100644 --- a/vp9/common/vp9_reconintra.c +++ b/vp9/common/vp9_reconintra.c @@ -13,6 +13,7 @@ #include "./vpx_config.h" #include "vp9_rtcd.h" #include "vp9/common/vp9_reconintra.h" +#include "vp9/common/vp9_onyxc_int.h" #include "vpx_mem/vpx_mem.h" static void d27_predictor(uint8_t *ypred_ptr, int y_stride, @@ -378,38 +379,51 @@ void vp9_build_intra_predictors_sby_s(MACROBLOCKD *xd, void vp9_build_intra_predictors_sbuv_s(MACROBLOCKD *xd, BLOCK_SIZE_TYPE bsize) { - int p; + const int bwl = b_width_log2(bsize), bw = 2 << bwl; + const int bhl = b_height_log2(bsize), bh = 2 << bhl; - for (p = 1; p < MAX_MB_PLANE; p++) { - const struct macroblockd_plane* const pd = &xd->plane[p]; - const int bwl = b_width_log2(bsize) - pd->subsampling_x; - const int bw = 4 << bwl; - const int bhl = b_height_log2(bsize) - pd->subsampling_y; - const int bh = 4 << bhl; - - vp9_build_intra_predictors(pd->dst.buf, pd->dst.stride, - pd->dst.buf, pd->dst.stride, - xd->mode_info_context->mbmi.uv_mode, - bw, bh, xd->up_available, - xd->left_available, 0 /*xd->right_available*/); - } + vp9_build_intra_predictors(xd->plane[1].dst.buf, xd->plane[1].dst.stride, + xd->plane[1].dst.buf, xd->plane[1].dst.stride, + xd->mode_info_context->mbmi.uv_mode, + bw, bh, xd->up_available, + xd->left_available, 0 /*xd->right_available*/); + vp9_build_intra_predictors(xd->plane[2].dst.buf, xd->plane[1].dst.stride, + xd->plane[2].dst.buf, xd->plane[1].dst.stride, + xd->mode_info_context->mbmi.uv_mode, + bw, bh, xd->up_available, + xd->left_available, 0 /*xd->right_available*/); } -void vp9_intra4x4_predict(MACROBLOCKD *xd, - int block_idx, - BLOCK_SIZE_TYPE bsize, - int mode, - uint8_t *predictor, int pre_stride) { - const int bwl = b_width_log2(bsize); +void vp9_predict_intra_block(MACROBLOCKD *xd, + int block_idx, + BLOCK_SIZE_TYPE bsize, + TX_SIZE tx_size, + int mode, + uint8_t *predictor, int pre_stride) { + const int bwl = b_width_log2(bsize) - tx_size; const int wmask = (1 << bwl) - 1; const int have_top = (block_idx >> bwl) || xd->up_available; const int have_left = (block_idx & wmask) || xd->left_available; const int have_right = ((block_idx & wmask) != wmask); + const int txfm_block_size = 4 << tx_size; + assert(bwl >= 0); vp9_build_intra_predictors(predictor, pre_stride, predictor, pre_stride, - mode, 4, 4, have_top, have_left, + mode, + txfm_block_size, + txfm_block_size, + have_top, have_left, have_right); } + +void vp9_intra4x4_predict(MACROBLOCKD *xd, + int block_idx, + BLOCK_SIZE_TYPE bsize, + int mode, + uint8_t *predictor, int pre_stride) { + vp9_predict_intra_block(xd, block_idx, bsize, TX_4X4, + mode, predictor, pre_stride); +} diff --git a/vp9/common/vp9_reconintra.h b/vp9/common/vp9_reconintra.h index 1a715c3ee..faecd6be7 100644 --- a/vp9/common/vp9_reconintra.h +++ b/vp9/common/vp9_reconintra.h @@ -21,4 +21,10 @@ B_PREDICTION_MODE vp9_find_dominant_direction(uint8_t *ptr, B_PREDICTION_MODE vp9_find_bpred_context(MACROBLOCKD *xd, int block, uint8_t *ptr, int stride); +void vp9_predict_intra_block(MACROBLOCKD *xd, + int block_idx, + BLOCK_SIZE_TYPE bsize, + TX_SIZE tx_size, + int mode, + uint8_t *predictor, int pre_stride); #endif // VP9_COMMON_VP9_RECONINTRA_H_ diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index b6f611c87..277f92ce7 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1707,7 +1707,7 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, if (mbmi->mode == I4X4_PRED) { assert(bsize == BLOCK_SIZE_SB8X8 && mbmi->txfm_size == TX_4X4); #endif - vp9_encode_intra4x4mby(x, BLOCK_SIZE_SB8X8); + vp9_encode_intra4x4mby(cm, x, BLOCK_SIZE_SB8X8); vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_SB8X8); vp9_encode_sbuv(cm, x, BLOCK_SIZE_SB8X8); diff --git a/vp9/encoder/vp9_encodeintra.c b/vp9/encoder/vp9_encodeintra.c index f8cf50f84..91866b28f 100644 --- a/vp9/encoder/vp9_encodeintra.c +++ b/vp9/encoder/vp9_encodeintra.c @@ -80,15 +80,6 @@ static void encode_intra4x4block(MACROBLOCK *x, int ib, } } -void vp9_encode_intra4x4mby(MACROBLOCK *mb, BLOCK_SIZE_TYPE bsize) { - int i; - int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize); - int bc = 1 << (bwl + bhl); - - for (i = 0; i < bc; i++) - encode_intra4x4block(mb, i, bsize); -} - void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x) { MACROBLOCKD *xd = &x->e_mbd; @@ -102,3 +93,5 @@ void vp9_encode_intra16x16mbuv(VP9_COMMON *const cm, MACROBLOCK *x) { vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_MB16X16); vp9_encode_sbuv(cm, x, BLOCK_SIZE_MB16X16); } + + diff --git a/vp9/encoder/vp9_encodeintra.h b/vp9/encoder/vp9_encodeintra.h index c26200494..22a046e35 100644 --- a/vp9/encoder/vp9_encodeintra.h +++ b/vp9/encoder/vp9_encodeintra.h @@ -16,5 +16,6 @@ int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred); void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x); void vp9_encode_intra16x16mbuv(VP9_COMMON *const cm, MACROBLOCK *x); -void vp9_encode_intra4x4mby(MACROBLOCK *mb, BLOCK_SIZE_TYPE bs); +void vp9_encode_intra4x4mby(VP9_COMMON *const cm, MACROBLOCK *mb, + BLOCK_SIZE_TYPE bs); #endif // VP9_ENCODER_VP9_ENCODEINTRA_H_ diff --git a/vp9/encoder/vp9_encodemb.c b/vp9/encoder/vp9_encodemb.c index 5990773bb..d9cd09163 100644 --- a/vp9/encoder/vp9_encodemb.c +++ b/vp9/encoder/vp9_encodemb.c @@ -604,3 +604,104 @@ void vp9_encode_sb(VP9_COMMON *const cm, MACROBLOCK *x, foreach_transformed_block(xd, bsize, encode_block, &arg); } + +static void encode_block_intra(int plane, int block, BLOCK_SIZE_TYPE bsize, + int ss_txfrm_size, void *arg) { + struct encode_b_args* const args = arg; + MACROBLOCK* const x = args->x; + MACROBLOCKD* const xd = &x->e_mbd; + const TX_SIZE tx_size = (TX_SIZE)(ss_txfrm_size / 2); + const int bw = 4 << (b_width_log2(bsize) - xd->plane[plane].subsampling_x); + const int raster_block = txfrm_block_to_raster_block(xd, bsize, plane, + block, ss_txfrm_size); + uint8_t* const src = + raster_block_offset_uint8(xd, bsize, plane, raster_block, + x->plane[plane].src.buf, + x->plane[plane].src.stride); + uint8_t* const dst = + raster_block_offset_uint8(xd, bsize, plane, raster_block, + xd->plane[plane].dst.buf, + xd->plane[plane].dst.stride); + int16_t* const src_diff = + raster_block_offset_int16(xd, bsize, plane, + raster_block, x->plane[plane].src_diff); + + const int txfm_b_size = 4 << tx_size; + int ib = raster_block; + + TX_TYPE tx_type; + + if (tx_size <= TX_16X16) + tx_type = txfm_map(xd->mode_info_context->bmi[ib].as_mode.first); + else + tx_type = DCT_DCT; + + vp9_predict_intra_block(&x->e_mbd, ib, bsize, tx_size, + xd->mode_info_context->bmi[ib].as_mode.first, + dst, xd->plane[plane].dst.stride); + vp9_subtract_block(txfm_b_size, txfm_b_size, + src_diff, bw, + src, x->plane[plane].src.stride, + dst, xd->plane[plane].dst.stride); + + xform_quant(plane, block, bsize, ss_txfrm_size, arg); + + /* + if (x->optimize) + vp9_optimize_b(plane, block, bsize, ss_txfrm_size, args->cm, x, args->ctx); + */ + + switch (ss_txfrm_size / 2) { + case TX_32X32: + vp9_short_idct32x32_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff, + block, 16), dst, xd->plane[plane].dst.stride); + break; + case TX_16X16: + tx_type = plane == 0 ? get_tx_type_16x16(xd, raster_block) : DCT_DCT; + if (tx_type == DCT_DCT) { + vp9_short_idct16x16_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff, + block, 16), dst, xd->plane[plane].dst.stride); + } else { + vp9_short_iht16x16_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff, + block, 16), dst, xd->plane[plane].dst.stride, + tx_type); + } + break; + case TX_8X8: + tx_type = plane == 0 ? get_tx_type_8x8(xd, raster_block) : DCT_DCT; + if (tx_type == DCT_DCT) { + vp9_short_idct8x8_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff, + block, 16), dst, xd->plane[plane].dst.stride); + } else { + vp9_short_iht8x8_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff, + block, 16), dst, xd->plane[plane].dst.stride, + tx_type); + } + break; + case TX_4X4: + tx_type = plane == 0 ? get_tx_type_4x4(xd, raster_block) : DCT_DCT; + if (tx_type == DCT_DCT) { + // this is like vp9_short_idct4x4 but has a special case around eob<=1 + // which is significant (not just an optimization) for the lossless + // case. + vp9_inverse_transform_b_4x4_add(xd, xd->plane[plane].eobs[block], + BLOCK_OFFSET(xd->plane[plane].dqcoeff, block, 16), dst, + xd->plane[plane].dst.stride); + } else { + vp9_short_iht4x4_add(BLOCK_OFFSET(xd->plane[plane].dqcoeff, block, 16), + dst, xd->plane[plane].dst.stride, tx_type); + } + break; + } +} + +void vp9_encode_intra4x4mby(VP9_COMMON *const cm, MACROBLOCK *x, + BLOCK_SIZE_TYPE bsize) { + MACROBLOCKD* const xd = &x->e_mbd; + struct optimize_ctx ctx; + struct encode_b_args arg = {cm, x, &ctx}; + + foreach_transformed_block_in_plane(xd, bsize, 0, + encode_block_intra, &arg); +} + -- 2.40.0