Merge "Generalized intra 4x4 encoding for all sizes" into experimental

This commit is contained in:
Paul Wilkins 2013-05-22 06:52:32 -07:00 committed by Gerrit Code Review
commit 22d7f0703a
7 changed files with 151 additions and 37 deletions

View File

@ -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,

View File

@ -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,21 +379,44 @@ 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(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*/);
}
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*/);
}
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,
txfm_block_size,
txfm_block_size,
have_top, have_left,
have_right);
}
void vp9_intra4x4_predict(MACROBLOCKD *xd,
@ -400,16 +424,6 @@ void vp9_intra4x4_predict(MACROBLOCKD *xd,
BLOCK_SIZE_TYPE bsize,
int mode,
uint8_t *predictor, int pre_stride) {
const int bwl = b_width_log2(bsize);
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);
vp9_build_intra_predictors(predictor, pre_stride,
predictor, pre_stride,
mode, 4, 4, have_top, have_left,
have_right);
vp9_predict_intra_block(xd, block_idx, bsize, TX_4X4,
mode, predictor, pre_stride);
}

View File

@ -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_

View File

@ -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);

View File

@ -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);
}

View File

@ -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_

View File

@ -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);
}