From 94191b5c82c429b5ba4fa8ca44bfb770ca52348c Mon Sep 17 00:00:00 2001 From: Jingning Han Date: Mon, 29 Apr 2013 12:43:38 -0700 Subject: [PATCH] Separate I4X4_PRED coding from macroblock modules Separate the functionality of I4X4_PRED from decode_mb. Use decode_atom_intra instead, to enable recursive partition of superblock down to 8x8. Change-Id: Ifc89a3be82225398954169d0a839abdbbfd8ca3b --- vp9/common/vp9_blockd.h | 51 +++++++++++++++++++------------ vp9/common/vp9_enums.h | 1 + vp9/decoder/vp9_decodframe.c | 71 +++++++++++++++++++++++++------------------ vp9/encoder/vp9_encodeframe.c | 2 +- vp9/encoder/vp9_encodeintra.c | 23 ++++++++------ vp9/encoder/vp9_encodeintra.h | 2 +- 6 files changed, 89 insertions(+), 61 deletions(-) diff --git a/vp9/common/vp9_blockd.h b/vp9/common/vp9_blockd.h index 8bb5a69..aebf4a1 100644 --- a/vp9/common/vp9_blockd.h +++ b/vp9/common/vp9_blockd.h @@ -200,49 +200,62 @@ typedef enum { MAX_REF_FRAMES = 4 } MV_REFERENCE_FRAME; -static INLINE int mi_width_log2(BLOCK_SIZE_TYPE sb_type) { +static INLINE int b_width_log2(BLOCK_SIZE_TYPE sb_type) { switch (sb_type) { + case BLOCK_SIZE_AB4X4: return 0; #if CONFIG_SB8X8 - case BLOCK_SIZE_SB8X16: - case BLOCK_SIZE_SB8X8: return 0; + case BLOCK_SIZE_SB8X8: + case BLOCK_SIZE_SB8X16: return 1; case BLOCK_SIZE_SB16X8: #endif case BLOCK_SIZE_MB16X16: - case BLOCK_SIZE_SB16X32: return 0 + CONFIG_SB8X8; + case BLOCK_SIZE_SB16X32: return 2; case BLOCK_SIZE_SB32X16: - case BLOCK_SIZE_SB32X64: - case BLOCK_SIZE_SB32X32: return 1 + CONFIG_SB8X8; + case BLOCK_SIZE_SB32X32: + case BLOCK_SIZE_SB32X64: return 3; case BLOCK_SIZE_SB64X32: - case BLOCK_SIZE_SB64X64: return 2 + CONFIG_SB8X8; + case BLOCK_SIZE_SB64X64: return 4; default: assert(0); } } -static INLINE int mi_height_log2(BLOCK_SIZE_TYPE sb_type) { +static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) { switch (sb_type) { + case BLOCK_SIZE_AB4X4: return 0; #if CONFIG_SB8X8 - case BLOCK_SIZE_SB16X8: - case BLOCK_SIZE_SB8X8: return 0; + case BLOCK_SIZE_SB8X8: + case BLOCK_SIZE_SB16X8: return 1; case BLOCK_SIZE_SB8X16: #endif case BLOCK_SIZE_MB16X16: - case BLOCK_SIZE_SB32X16: return 0 + CONFIG_SB8X8; + case BLOCK_SIZE_SB32X16: return 2; case BLOCK_SIZE_SB16X32: - case BLOCK_SIZE_SB64X32: - case BLOCK_SIZE_SB32X32: return 1 + CONFIG_SB8X8; + case BLOCK_SIZE_SB32X32: + case BLOCK_SIZE_SB64X32: return 3; case BLOCK_SIZE_SB32X64: - case BLOCK_SIZE_SB64X64: return 2 + CONFIG_SB8X8; + case BLOCK_SIZE_SB64X64: return 4; default: assert(0); } } -// parse block dimension in the unit of 4x4 blocks -static INLINE int b_width_log2(BLOCK_SIZE_TYPE sb_type) { - return mi_width_log2(sb_type) + 2 - CONFIG_SB8X8; +static INLINE int mi_width_log2(BLOCK_SIZE_TYPE sb_type) { +#if CONFIG_SB8X8 + int a = b_width_log2(sb_type) - 1; +#else + int a = b_width_log2(sb_type) - 2; +#endif + assert(a >= 0); + return a; } -static INLINE int b_height_log2(BLOCK_SIZE_TYPE sb_type) { - return mi_height_log2(sb_type) + 2 - CONFIG_SB8X8; +static INLINE int mi_height_log2(BLOCK_SIZE_TYPE sb_type) { +#if CONFIG_SB8X8 + int a = b_height_log2(sb_type) - 1; +#else + int a = b_height_log2(sb_type) - 2; +#endif + assert(a >= 0); + return a; } typedef struct { diff --git a/vp9/common/vp9_enums.h b/vp9/common/vp9_enums.h index fddbb55..b72b41e 100644 --- a/vp9/common/vp9_enums.h +++ b/vp9/common/vp9_enums.h @@ -23,6 +23,7 @@ #define MI_UV_SIZE (1 << (LOG2_MI_SIZE - 1)) typedef enum BLOCK_SIZE_TYPE { + BLOCK_SIZE_AB4X4, #if CONFIG_SB8X8 BLOCK_SIZE_SB8X8, BLOCK_SIZE_SB8X16, diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index 9e5c341..27eb4b1 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -300,7 +300,6 @@ static INLINE void dequant_add_y(MACROBLOCKD *xd, TX_TYPE tx_type, int idx) { } } - static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r) { TX_TYPE tx_type; int i = 0; @@ -338,32 +337,6 @@ static void decode_4x4(VP9D_COMP *pbi, MACROBLOCKD *xd, vp9_reader *r) { dst, xd->plane[1].dst.stride, xd->plane[2].eobs[i]); } - } else if (mode == I4X4_PRED) { - for (i = 0; i < 16; i++) { - int b_mode = xd->mode_info_context->bmi[i].as_mode.first; - uint8_t* dst; - dst = raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, i, - xd->plane[0].dst.buf, - xd->plane[0].dst.stride); -#if CONFIG_NEWBINTRAMODES - xd->mode_info_context->bmi[i].as_mode.context = - vp9_find_bpred_context(xd, i, dst, xd->plane[0].dst.stride); - if (!xd->mode_info_context->mbmi.mb_skip_coeff) - vp9_decode_coefs_4x4(pbi, xd, r, PLANE_TYPE_Y_WITH_DC, i); -#endif - vp9_intra4x4_predict(xd, i, b_mode, dst, xd->plane[0].dst.stride); - tx_type = get_tx_type_4x4(xd, i); - dequant_add_y(xd, tx_type, i); - } -#if CONFIG_NEWBINTRAMODES - if (!xd->mode_info_context->mbmi.mb_skip_coeff) - vp9_decode_mb_tokens_4x4_uv(pbi, xd, r); -#endif - vp9_build_intra_predictors_sbuv_s(xd, BLOCK_SIZE_MB16X16); - xd->itxm_add_uv_block(xd->plane[1].qcoeff, xd->plane[1].dst.buf, - xd->plane[1].dst.stride, xd->plane[1].eobs); - xd->itxm_add_uv_block(xd->plane[2].qcoeff, xd->plane[2].dst.buf, - xd->plane[1].dst.stride, xd->plane[2].eobs); } else if (mode == SPLITMV || get_tx_type_4x4(xd, 0) == DCT_DCT) { xd->itxm_add_y_block(xd->plane[0].qcoeff, xd->plane[0].dst.buf, xd->plane[0].dst.stride, xd); @@ -437,6 +410,38 @@ static void decode_block(int plane, int block, BLOCK_SIZE_TYPE bsize, } } +static void decode_atom_intra(VP9D_COMP *pbi, MACROBLOCKD *xd, + vp9_reader *r, + BLOCK_SIZE_TYPE bsize) { + int i = 0; + int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize); + int bc = 1 << (bwl + bhl); + int tx_type; + + for (i = 0; i < bc; i++) { + int b_mode = xd->mode_info_context->bmi[i].as_mode.first; + uint8_t* dst; + dst = raster_block_offset_uint8(xd, bsize, 0, i, + xd->plane[0].dst.buf, + xd->plane[0].dst.stride); +#if CONFIG_NEWBINTRAMODES + xd->mode_info_context->bmi[i].as_mode.context = + vp9_find_bpred_context(xd, i, dst, xd->plane[0].dst.stride); + if (!xd->mode_info_context->mbmi.mb_skip_coeff) + vp9_decode_coefs_4x4(pbi, xd, r, PLANE_TYPE_Y_WITH_DC, i); +#endif + vp9_intra4x4_predict(xd, i, b_mode, dst, xd->plane[0].dst.stride); + // TODO(jingning): refactor to use foreach_transformed_block_in_plane_ + tx_type = get_tx_type_4x4(xd, i); + dequant_add_y(xd, tx_type, i); + } +#if CONFIG_NEWBINTRAMODES + if (!xd->mode_info_context->mbmi.mb_skip_coeff) + vp9_decode_mb_tokens_4x4_uv(pbi, xd, r); +#endif + foreach_transformed_block_uv(xd, bsize, decode_block, xd); +} + static void decode_sb(VP9D_COMP *pbi, MACROBLOCKD *xd, int mi_row, int mi_col, vp9_reader *r, BLOCK_SIZE_TYPE bsize) { const int bwl = mi_width_log2(bsize), bhl = mi_height_log2(bsize); @@ -545,7 +550,12 @@ static void decode_mb(VP9D_COMP *pbi, MACROBLOCKD *xd, } else if (tx_size == TX_8X8) { decode_8x8(xd); } else { - decode_4x4(pbi, xd, r); + if (mbmi->mode == I4X4_PRED) + // TODO(jingning): we need to move this to decode_atom later and + // deprecate decode_mb, when SB8X8 is on. + decode_atom_intra(pbi, xd, r, BLOCK_SIZE_MB16X16); + else + decode_4x4(pbi, xd, r); } } @@ -671,10 +681,11 @@ static void decode_modes_b(VP9D_COMP *pbi, int mi_row, int mi_col, set_refs(pbi, mi_row, mi_col); // TODO(jingning): merge decode_sb_ and decode_mb_ - if (bsize > BLOCK_SIZE_MB16X16) + if (bsize > BLOCK_SIZE_MB16X16) { decode_sb(pbi, xd, mi_row, mi_col, r, bsize); - else + } else { decode_mb(pbi, xd, mi_row, mi_col, r); + } xd->corrupted |= vp9_reader_has_error(r); } diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 3877391..d40c604 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1946,7 +1946,7 @@ static void encode_macroblock(VP9_COMP *cpi, TOKENEXTRA **t, #endif if (mbmi->mode == I4X4_PRED) { vp9_encode_intra16x16mbuv(cm, x); - vp9_encode_intra4x4mby(x); + vp9_encode_intra4x4mby(x, BLOCK_SIZE_MB16X16); } else if (mbmi->mode == I8X8_PRED) { vp9_encode_intra8x8mby(x); vp9_encode_intra8x8mbuv(x); diff --git a/vp9/encoder/vp9_encodeintra.c b/vp9/encoder/vp9_encodeintra.c index 54c4f36..f6ddca8 100644 --- a/vp9/encoder/vp9_encodeintra.c +++ b/vp9/encoder/vp9_encodeintra.c @@ -16,7 +16,7 @@ #include "vp9/common/vp9_invtrans.h" #include "vp9/encoder/vp9_encodeintra.h" -static void encode_intra4x4block(MACROBLOCK *x, int ib); +static void encode_intra4x4block(MACROBLOCK *x, int ib, BLOCK_SIZE_TYPE bs); int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) { MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi; @@ -33,27 +33,28 @@ int vp9_encode_intra(VP9_COMP *cpi, MACROBLOCK *x, int use_16x16_pred) { for (i = 0; i < 16; i++) { x->e_mbd.mode_info_context->bmi[i].as_mode.first = B_DC_PRED; - encode_intra4x4block(x, i); + encode_intra4x4block(x, i, BLOCK_SIZE_MB16X16); } } return vp9_get_mb_ss(x->plane[0].src_diff); } -static void encode_intra4x4block(MACROBLOCK *x, int ib) { +static void encode_intra4x4block(MACROBLOCK *x, int ib, + BLOCK_SIZE_TYPE bsize) { MACROBLOCKD * const xd = &x->e_mbd; TX_TYPE tx_type; uint8_t* const src = - raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, ib, + raster_block_offset_uint8(xd, bsize, 0, ib, x->plane[0].src.buf, x->plane[0].src.stride); uint8_t* const dst = - raster_block_offset_uint8(xd, BLOCK_SIZE_MB16X16, 0, ib, + raster_block_offset_uint8(xd, bsize, 0, ib, xd->plane[0].dst.buf, xd->plane[0].dst.stride); int16_t* const src_diff = - raster_block_offset_int16(xd, BLOCK_SIZE_MB16X16, 0, ib, + raster_block_offset_int16(xd, bsize, 0, ib, x->plane[0].src_diff); int16_t* const diff = - raster_block_offset_int16(xd, BLOCK_SIZE_MB16X16, 0, ib, + raster_block_offset_int16(xd, bsize, 0, ib, xd->plane[0].diff); int16_t* const coeff = BLOCK_OFFSET(x->plane[0].coeff, ib, 16); @@ -88,11 +89,13 @@ static void encode_intra4x4block(MACROBLOCK *x, int ib) { vp9_recon_b(dst, diff, dst, xd->plane[0].dst.stride); } -void vp9_encode_intra4x4mby(MACROBLOCK *mb) { +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 < 16; i++) - encode_intra4x4block(mb, i); + for (i = 0; i < bc; i++) + encode_intra4x4block(mb, i, bsize); } void vp9_encode_intra16x16mby(VP9_COMMON *const cm, MACROBLOCK *x) { diff --git a/vp9/encoder/vp9_encodeintra.h b/vp9/encoder/vp9_encodeintra.h index 6576c94..7ec2f11 100644 --- a/vp9/encoder/vp9_encodeintra.h +++ b/vp9/encoder/vp9_encodeintra.h @@ -16,7 +16,7 @@ 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); +void vp9_encode_intra4x4mby(MACROBLOCK *mb, BLOCK_SIZE_TYPE bs); void vp9_encode_intra8x8mby(MACROBLOCK *x); void vp9_encode_intra8x8mbuv(MACROBLOCK *x); void vp9_encode_intra8x8(MACROBLOCK *x, int ib); -- 2.7.4