Commit 1d4fbeb3 authored by Ronald S. Bultje's avatar Ronald S. Bultje

Implement tx_select for superblock encoding.

Also split superblock handling code out of decode_macroblock() into
a new function decode_superblock(), for easier readability.

Derf +0.05%, HD +0.2%, STDHD +0.1%. We can likely get further gains
by allowing to select mb_skip_coeff for a subset of the complete SB
or something along those lines, because although this change allows
coding smaller transforms for bigger predictors, it increases the
overhead of coding EOBs to skip the parts where the residual is
near-zero, and thus the overall gain is not as high as we'd expect.

Change-Id: I552ce1286487267f504e3090b683e15515791efa
parent 8959c8b1
......@@ -186,11 +186,6 @@ static void kfread_modes(VP9D_COMP *pbi,
m->mbmi.second_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
#endif
#if CONFIG_SUPERBLOCKS
if (m->mbmi.encoded_as_sb)
m->mbmi.txfm_size = TX_8X8;
else
#endif
if (cm->txfm_mode == TX_MODE_SELECT && m->mbmi.mb_skip_coeff == 0 &&
m->mbmi.mode <= I8X8_PRED) {
// FIXME(rbultje) code ternary symbol once all experiments are merged
......@@ -1132,11 +1127,6 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
#endif
}
#if CONFIG_SUPERBLOCKS
if (mbmi->encoded_as_sb)
mbmi->txfm_size = TX_8X8;
else
#endif
if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 &&
((mbmi->ref_frame == INTRA_FRAME && mbmi->mode <= I8X8_PRED) ||
(mbmi->ref_frame != INTRA_FRAME && !(mbmi->mode == SPLITMV &&
......
......@@ -205,6 +205,146 @@ static void skip_recon_mb(VP9D_COMP *pbi, MACROBLOCKD *xd) {
}
}
#if CONFIG_SUPERBLOCKS
static void decode_superblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
int mb_row, unsigned int mb_col,
BOOL_DECODER* const bc) {
int i, n, eobtotal;
TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
VP9_COMMON *const pc = &pbi->common;
MODE_INFO *orig_mi = xd->mode_info_context;
assert(xd->mode_info_context->mbmi.encoded_as_sb);
// re-initialize macroblock dequantizer before detokenization
if (xd->segmentation_enabled)
mb_init_dequantizer(pbi, xd);
if (pbi->common.frame_type != KEY_FRAME)
vp9_setup_interp_filters(xd, xd->mode_info_context->mbmi.interp_filter, pc);
if (xd->mode_info_context->mbmi.mb_skip_coeff) {
vp9_reset_mb_tokens_context(xd);
if (mb_col < pc->mb_cols - 1)
xd->above_context++;
if (mb_row < pc->mb_rows - 1)
xd->left_context++;
vp9_reset_mb_tokens_context(xd);
if (mb_col < pc->mb_cols - 1)
xd->above_context--;
if (mb_row < pc->mb_rows - 1)
xd->left_context--;
/* Special case: Force the loopfilter to skip when eobtotal and
* mb_skip_coeff are zero.
*/
skip_recon_mb(pbi, xd);
return;
}
/* do prediction */
if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
vp9_build_intra_predictors_sby_s(xd);
vp9_build_intra_predictors_sbuv_s(xd);
} else {
vp9_build_inter32x32_predictors_sb(xd, xd->dst.y_buffer,
xd->dst.u_buffer, xd->dst.v_buffer,
xd->dst.y_stride, xd->dst.uv_stride);
}
/* dequantization and idct */
for (n = 0; n < 4; n++) {
BLOCKD *b = &xd->block[24];
int x_idx = n & 1, y_idx = n >> 1;
if (mb_col + x_idx >= pc->mb_cols || mb_row + y_idx >= pc->mb_rows)
continue;
xd->above_context = pc->above_context + mb_col + x_idx;
xd->left_context = pc->left_context + y_idx;
xd->mode_info_context = orig_mi + x_idx + y_idx * pc->mode_info_stride;
for (i = 0; i < 25; i++) {
xd->block[i].eob = 0;
xd->eobs[i] = 0;
}
if (tx_size == TX_16X16) {
eobtotal = vp9_decode_mb_tokens_16x16(pbi, xd, bc);
} else if (tx_size == TX_8X8) {
eobtotal = vp9_decode_mb_tokens_8x8(pbi, xd, bc);
} else {
eobtotal = vp9_decode_mb_tokens(pbi, xd, bc);
}
if (eobtotal == 0) { // skip loopfilter
xd->mode_info_context->mbmi.mb_skip_coeff = 1;
continue;
}
if (tx_size == TX_16X16) {
vp9_dequant_idct_add_16x16(xd->qcoeff, xd->block[0].dequant,
xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
xd->dst.y_stride, xd->dst.y_stride);
vp9_dequant_idct_add_uv_block_8x8_inplace_c(xd->qcoeff + 16 * 16,
xd->block[16].dequant,
xd->dst.u_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
xd->dst.v_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
xd->dst.uv_stride, xd->eobs + 16, xd);
} else if (tx_size == TX_8X8) {
vp9_dequantize_b_2x2(b);
IDCT_INVOKE(RTCD_VTABLE(idct), ihaar2)(&b->dqcoeff[0], b->diff, 8);
((int *)b->qcoeff)[0] = 0; // 2nd order block are set to 0 after idct
((int *)b->qcoeff)[1] = 0;
((int *)b->qcoeff)[2] = 0;
((int *)b->qcoeff)[3] = 0;
((int *)b->qcoeff)[4] = 0;
((int *)b->qcoeff)[5] = 0;
((int *)b->qcoeff)[6] = 0;
((int *)b->qcoeff)[7] = 0;
vp9_dequant_dc_idct_add_y_block_8x8_inplace_c(xd->qcoeff,
xd->block[0].dequant,
xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
xd->dst.y_stride, xd->eobs, xd->block[24].diff, xd);
vp9_dequant_idct_add_uv_block_8x8_inplace_c(xd->qcoeff + 16 * 16,
xd->block[16].dequant,
xd->dst.u_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
xd->dst.v_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
xd->dst.uv_stride, xd->eobs + 16, xd);
} else {
vp9_dequantize_b(b);
if (xd->eobs[24] > 1) {
IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh16)(&b->dqcoeff[0], b->diff);
((int *)b->qcoeff)[0] = 0;
((int *)b->qcoeff)[1] = 0;
((int *)b->qcoeff)[2] = 0;
((int *)b->qcoeff)[3] = 0;
((int *)b->qcoeff)[4] = 0;
((int *)b->qcoeff)[5] = 0;
((int *)b->qcoeff)[6] = 0;
((int *)b->qcoeff)[7] = 0;
} else {
IDCT_INVOKE(RTCD_VTABLE(idct), iwalsh1)(&b->dqcoeff[0], b->diff);
((int *)b->qcoeff)[0] = 0;
}
vp9_dequant_dc_idct_add_y_block_4x4_inplace_c(xd->qcoeff,
xd->block[0].dequant,
xd->dst.y_buffer + y_idx * 16 * xd->dst.y_stride + x_idx * 16,
xd->dst.y_stride, xd->eobs, xd->block[24].diff, xd);
vp9_dequant_idct_add_uv_block_4x4_inplace_c(xd->qcoeff + 16 * 16,
xd->block[16].dequant,
xd->dst.u_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
xd->dst.v_buffer + y_idx * 8 * xd->dst.uv_stride + x_idx * 8,
xd->dst.uv_stride, xd->eobs + 16, xd);
}
}
xd->above_context = pc->above_context + mb_col;
xd->left_context = pc->left_context;
xd->mode_info_context = orig_mi;
}
#endif
static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
int mb_row, unsigned int mb_col,
BOOL_DECODER* const bc) {
......@@ -213,9 +353,9 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
int i;
int tx_size;
TX_TYPE tx_type;
VP9_COMMON *pc = &pbi->common;
#if CONFIG_SUPERBLOCKS
int orig_skip_flag = xd->mode_info_context->mbmi.mb_skip_coeff;
assert(!xd->mode_info_context->mbmi.encoded_as_sb);
#endif
// re-initialize macroblock dequantizer before detokenization
......@@ -227,20 +367,6 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
if (xd->mode_info_context->mbmi.mb_skip_coeff) {
vp9_reset_mb_tokens_context(xd);
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb &&
(mb_col < pc->mb_cols - 1 || mb_row < pc->mb_rows - 1)) {
if (mb_col < pc->mb_cols - 1)
xd->above_context++;
if (mb_row < pc->mb_rows - 1)
xd->left_context++;
vp9_reset_mb_tokens_context(xd);
if (mb_col < pc->mb_cols - 1)
xd->above_context--;
if (mb_row < pc->mb_rows - 1)
xd->left_context--;
}
#endif
} else if (!bool_error(bc)) {
for (i = 0; i < 25; i++) {
xd->block[i].eob = 0;
......@@ -267,14 +393,8 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
* mb_skip_coeff are zero.
* */
xd->mode_info_context->mbmi.mb_skip_coeff = 1;
#if CONFIG_SUPERBLOCKS
if (!xd->mode_info_context->mbmi.encoded_as_sb || orig_skip_flag)
#endif
{
skip_recon_mb(pbi, xd);
return;
}
skip_recon_mb(pbi, xd);
return;
}
// moved to be performed before detokenization
......@@ -283,12 +403,6 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
/* do prediction */
if (xd->mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
vp9_build_intra_predictors_sby_s(xd);
vp9_build_intra_predictors_sbuv_s(xd);
} else
#endif
if (mode != I8X8_PRED) {
vp9_build_intra_predictors_mbuv(xd);
if (mode != B_PRED) {
......@@ -296,13 +410,6 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
}
}
} else {
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
vp9_build_inter32x32_predictors_sb(xd, xd->dst.y_buffer,
xd->dst.u_buffer, xd->dst.v_buffer,
xd->dst.y_stride, xd->dst.uv_stride);
} else
#endif
vp9_build_inter_predictors_mb(xd);
}
......@@ -404,40 +511,9 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
16, xd->dst.y_stride);
}
} else if (tx_size == TX_8X8) {
#if CONFIG_SUPERBLOCKS
void *orig = xd->mode_info_context;
int n, num = xd->mode_info_context->mbmi.encoded_as_sb ? 4 : 1;
for (n = 0; n < num; n++) {
int x_idx = n & 1, y_idx = n >> 1;
if (num == 4 && (mb_col + x_idx >= pc->mb_cols ||
mb_row + y_idx >= pc->mb_rows))
continue;
if (n != 0) {
for (i = 0; i < 25; i++) {
xd->block[i].eob = 0;
xd->eobs[i] = 0;
}
xd->above_context = pc->above_context + mb_col + (n & 1);
xd->left_context = pc->left_context + (n >> 1);
xd->mode_info_context = orig;
xd->mode_info_context += (n & 1);
xd->mode_info_context += (n >> 1) * pc->mode_info_stride;
if (!orig_skip_flag) {
eobtotal = vp9_decode_mb_tokens_8x8(pbi, xd, bc);
if (eobtotal == 0) // skip loopfilter
xd->mode_info_context->mbmi.mb_skip_coeff = 1;
} else {
vp9_reset_mb_tokens_context(xd);
}
}
if (xd->mode_info_context->mbmi.mb_skip_coeff)
continue; // only happens for SBs, which are already in dest buffer
#endif
vp9_dequantize_b_2x2(b);
IDCT_INVOKE(RTCD_VTABLE(idct), ihaar2)(&b->dqcoeff[0], b->diff, 8);
((int *)b->qcoeff)[0] = 0;// 2nd order block are set to 0 after inverse transform
((int *)b->qcoeff)[0] = 0; // 2nd order block are set to 0 after idct
((int *)b->qcoeff)[1] = 0;
((int *)b->qcoeff)[2] = 0;
((int *)b->qcoeff)[3] = 0;
......@@ -445,27 +521,9 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
((int *)b->qcoeff)[5] = 0;
((int *)b->qcoeff)[6] = 0;
((int *)b->qcoeff)[7] = 0;
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb) {
vp9_dequant_dc_idct_add_y_block_8x8_inplace_c(xd->qcoeff,
xd->block[0].dequant,
xd->dst.y_buffer + (n >> 1) * 16 * xd->dst.y_stride + (n & 1) * 16,
xd->dst.y_stride, xd->eobs, xd->block[24].diff, xd);
// do UV inline also
vp9_dequant_idct_add_uv_block_8x8_inplace_c(xd->qcoeff + 16 * 16,
xd->block[16].dequant,
xd->dst.u_buffer + (n >> 1) * 8 * xd->dst.uv_stride + (n & 1) * 8,
xd->dst.v_buffer + (n >> 1) * 8 * xd->dst.uv_stride + (n & 1) * 8,
xd->dst.uv_stride, xd->eobs + 16, xd);
} else
#endif
vp9_dequant_dc_idct_add_y_block_8x8(xd->qcoeff,
xd->block[0].dequant, xd->predictor, xd->dst.y_buffer,
xd->dst.y_stride, xd->eobs, xd->block[24].diff, xd);
#if CONFIG_SUPERBLOCKS
}
xd->mode_info_context = orig;
#endif
} else {
vp9_dequantize_b(b);
if (xd->eobs[24] > 1) {
......@@ -489,25 +547,19 @@ static void decode_macroblock(VP9D_COMP *pbi, MACROBLOCKD *xd,
}
}
#if CONFIG_SUPERBLOCKS
if (!xd->mode_info_context->mbmi.encoded_as_sb) {
#endif
if ((tx_size == TX_8X8 &&
xd->mode_info_context->mbmi.mode != I8X8_PRED &&
xd->mode_info_context->mbmi.mode != SPLITMV)
|| tx_size == TX_16X16
)
vp9_dequant_idct_add_uv_block_8x8
(xd->qcoeff + 16 * 16, xd->block[16].dequant,
xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
xd->dst.uv_stride, xd->eobs + 16, xd); //
else if (xd->mode_info_context->mbmi.mode != I8X8_PRED)
pbi->idct_add_uv_block(xd->qcoeff + 16 * 16, xd->block[16].dequant,
xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
xd->dst.uv_stride, xd->eobs + 16);
#if CONFIG_SUPERBLOCKS
}
#endif
if ((tx_size == TX_8X8 &&
xd->mode_info_context->mbmi.mode != I8X8_PRED &&
xd->mode_info_context->mbmi.mode != SPLITMV)
|| tx_size == TX_16X16
)
vp9_dequant_idct_add_uv_block_8x8
(xd->qcoeff + 16 * 16, xd->block[16].dequant,
xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
xd->dst.uv_stride, xd->eobs + 16, xd);
else if (xd->mode_info_context->mbmi.mode != I8X8_PRED)
pbi->idct_add_uv_block(xd->qcoeff + 16 * 16, xd->block[16].dequant,
xd->predictor + 16 * 16, xd->dst.u_buffer, xd->dst.v_buffer,
xd->dst.uv_stride, xd->eobs + 16);
}
......@@ -661,9 +713,15 @@ decode_sb_row(VP9D_COMP *pbi, VP9_COMMON *pc, int mbrow, MACROBLOCKD *xd,
mi[pc->mode_info_stride + 1] = mi[0];
}
}
if (xd->mode_info_context->mbmi.encoded_as_sb) {
decode_superblock(pbi, xd, mb_row, mb_col, bc);
} else {
#endif
vp9_intra_prediction_down_copy(xd);
decode_macroblock(pbi, xd, mb_row, mb_col, bc);
#if CONFIG_SUPERBLOCKS
}
#endif
vp9_intra_prediction_down_copy(xd);
decode_macroblock(pbi, xd, mb_row, mb_col, bc);
/* check if the boolean decoder has suffered an error */
xd->corrupted |= bool_error(bc);
......
......@@ -73,12 +73,24 @@ void vp9_dequant_dc_idct_add_y_block_8x8_inplace_c(short *q, short *dq,
int stride,
unsigned short *eobs,
short *dc, MACROBLOCKD *xd);
void vp9_dequant_dc_idct_add_y_block_4x4_inplace_c(short *q, short *dq,
unsigned char *dst,
int stride, char *eobs,
short *dc, MACROBLOCKD *xd);
void vp9_dequant_idct_add_uv_block_8x8_inplace_c(short *q, short *dq,
unsigned char *dstu,
unsigned char *dstv,
int stride,
unsigned short *eobs,
MACROBLOCKD *xd);
void vp9_dequant_idct_add_uv_block_4x4_inplace_c(short *q, short *dq,
unsigned char *dstu,
unsigned char *dstv,
int stride, char *eobs,
MACROBLOCKD *xd);
#endif
#endif
......@@ -36,6 +36,30 @@ void vp9_dequant_dc_idct_add_y_block_c(short *q, short *dq,
}
}
#if CONFIG_SUPERBLOCKS
void vp9_dequant_dc_idct_add_y_block_4x4_inplace_c(short *q, short *dq,
unsigned char *dst,
int stride, char *eobs,
short *dc, MACROBLOCKD *xd) {
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
if (*eobs++ > 1)
vp9_dequant_dc_idct_add_c(q, dq, dst, dst, stride, stride, dc[0]);
else
vp9_dc_only_idct_add_c(dc[0], dst, dst, stride, stride);
q += 16;
dst += 4;
dc++;
}
dst += 4 * stride - 16;
}
}
#endif
void vp9_dequant_idct_add_y_block_c(short *q, short *dq,
unsigned char *pre,
unsigned char *dst,
......@@ -103,6 +127,47 @@ void vp9_dequant_idct_add_uv_block_c(short *q, short *dq, unsigned char *pre,
}
}
#if CONFIG_SUPERBLOCKS
void vp9_dequant_idct_add_uv_block_4x4_inplace_c(short *q, short *dq,
unsigned char *dstu,
unsigned char *dstv,
int stride, char *eobs,
MACROBLOCKD *xd) {
int i, j;
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
if (*eobs++ > 1) {
vp9_dequant_idct_add_c(q, dq, dstu, dstu, stride, stride);
} else {
vp9_dc_only_idct_add_c(q[0]*dq[0], dstu, dstu, stride, stride);
((int *)q)[0] = 0;
}
q += 16;
dstu += 4;
}
dstu += 4 * stride - 8;
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
if (*eobs++ > 1) {
vp9_dequant_idct_add_c(q, dq, dstv, dstv, stride, stride);
} else {
vp9_dc_only_idct_add_c(q[0]*dq[0], dstv, dstv, stride, stride);
((int *)q)[0] = 0;
}
q += 16;
dstv += 4;
}
dstv += 4 * stride - 8;
}
}
#endif
void vp9_dequant_dc_idct_add_y_block_8x8_c(short *q, short *dq,
unsigned char *pre,
......
......@@ -919,7 +919,7 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
MB_MODE_INFO *mi;
MV_REFERENCE_FRAME rf;
MB_PREDICTION_MODE mode;
int segment_id;
int segment_id, skip_coeff;
int dy = row_delta[i];
int dx = col_delta[i];
......@@ -973,10 +973,11 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
}
}
skip_coeff = 1;
if (pc->mb_no_coeff_skip &&
(!vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
(vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) != 0))) {
int skip_coeff = mi->mb_skip_coeff;
skip_coeff = mi->mb_skip_coeff;
#if CONFIG_SUPERBLOCKS
if (mi->encoded_as_sb) {
skip_coeff &= m[1].mbmi.mb_skip_coeff;
......@@ -1107,6 +1108,7 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
cpi->common.mcomp_filter_type);
}
}
if (mi->second_ref_frame &&
(mode == NEWMV || mode == SPLITMV)) {
int_mv n1, n2;
......@@ -1244,15 +1246,11 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
}
}
if (
#if CONFIG_SUPERBLOCKS
!mi->encoded_as_sb &&
#endif
((rf == INTRA_FRAME && mode <= I8X8_PRED) ||
if (((rf == INTRA_FRAME && mode <= I8X8_PRED) ||
(rf != INTRA_FRAME && !(mode == SPLITMV &&
mi->partitioning == PARTITIONING_4X4))) &&
pc->txfm_mode == TX_MODE_SELECT &&
!((pc->mb_no_coeff_skip && mi->mb_skip_coeff) ||
!((pc->mb_no_coeff_skip && skip_coeff) ||
(vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) == 0))) {
TX_SIZE sz = mi->txfm_size;
......@@ -1389,11 +1387,7 @@ static void write_mb_modes_kf(const VP9_COMMON *c,
} else
write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
if (
#if CONFIG_SUPERBLOCKS
!m->mbmi.encoded_as_sb &&
#endif
ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
if (ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
!((c->mb_no_coeff_skip && m->mbmi.mb_skip_coeff) ||
(vp9_segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
vp9_get_segdata(xd, segment_id, SEG_LVL_EOB) == 0))) {
......
......@@ -55,7 +55,8 @@ int mb_row_debug, mb_col_debug;
static void encode_inter_macroblock(VP9_COMP *cpi, MACROBLOCK *x,
TOKENEXTRA **t, int recon_yoffset,
int recon_uvoffset, int output_enabled);
int recon_uvoffset, int output_enabled,
int mb_col, int mb_row);
static void encode_inter_superblock(VP9_COMP *cpi, MACROBLOCK *x,
TOKENEXTRA **t, int recon_yoffset,
......@@ -65,7 +66,7 @@ static void encode_intra_macro_block(VP9_COMP *cpi, MACROBLOCK *x,
TOKENEXTRA **t, int output_enabled);
static void encode_intra_super_block(VP9_COMP *cpi, MACROBLOCK *x,
TOKENEXTRA **t, int mb_col);
TOKENEXTRA **t, int mb_col, int mb_row);
static void adjust_act_zbin(VP9_COMP *cpi, MACROBLOCK *x);
......@@ -466,9 +467,9 @@ static void update_state(VP9_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
cpi->prediction_error += ctx->distortion;
cpi->intra_error += ctx->intra_error;
cpi->rd_comp_pred_diff[0] += ctx->single_pred_diff;
cpi->rd_comp_pred_diff[1] += ctx->comp_pred_diff;
cpi->rd_comp_pred_diff[2] += ctx->hybrid_pred_diff;
cpi->rd_comp_pred_diff[SINGLE_PREDICTION_ONLY] += ctx->single_pred_diff;
cpi->rd_comp_pred_diff[COMP_PREDICTION_ONLY] += ctx->comp_pred_diff;
cpi->rd_comp_pred_diff[HYBRID_PREDICTION] += ctx->hybrid_pred_diff;
}
}
......@@ -645,7 +646,7 @@ static void pick_mb_modes(VP9_COMP *cpi,
// Dummy encode, do not do the tokenization
encode_inter_macroblock(cpi, x, tp,
recon_yoffset, recon_uvoffset, 0);
recon_yoffset, recon_uvoffset, 0, mb_col, mb_row);
seg_id = mbmi->segment_id;
if (cpi->mb.e_mbd.segmentation_enabled && seg_id == 0) {
......@@ -975,7 +976,7 @@ static void encode_sb(VP9_COMP *cpi,
if (cm->frame_type == KEY_FRAME) {
#if CONFIG_SUPERBLOCKS
if (xd->mode_info_context->mbmi.encoded_as_sb)
encode_intra_super_block(cpi, x, tp, mb_col);
encode_intra_super_block(cpi, x, tp, mb_col, mb_row);
else
#endif
encode_intra_macro_block(cpi, x, tp, 1);
......@@ -1005,8 +1006,8 @@ static void encode_sb(VP9_COMP *cpi,
mb_col, mb_row);
else
#endif
encode_inter_macroblock(cpi, x, tp,
recon_yoffset, recon_uvoffset, 1);
encode_inter_macroblock(cpi, x, tp, recon_yoffset, recon_uvoffset, 1,
mb_col, mb_row);
// Note the encoder may have changed the segment_id
#ifdef MODE_STATS
......@@ -1431,7 +1432,7 @@ static int check_dual_ref_flags(VP9_COMP *cpi) {
static void reset_skip_txfm_size(VP9_COMP *cpi, TX_SIZE txfm_max) {
VP9_COMMON *cm = &cpi->common;
int mb_row, mb_col, mis = cm->mode_info_stride, segment_id;
int mb_row, mb_col, mis = cm->mode_info_stride, segment_id, skip;
MODE_INFO *mi, *mi_ptr = cm->mi;
#if CONFIG_SUPERBLOCKS
MODE_INFO *sb_mi_ptr = cm->mi, *sb_mi;
......@@ -1451,17 +1452,45 @@ static void reset_skip_txfm_size(VP9_COMP *cpi, TX_SIZE txfm_max) {
#if CONFIG_SUPERBLOCKS
sb_mbmi = &sb_mi->mbmi;
#endif
if (
if (mbmi->txfm_size > txfm_max) {
#if CONFIG_SUPERBLOCKS
if (sb_mbmi->encoded_as_sb) {
if (!((mb_col & 1) || (mb_row & 1))) {
segment_id = mbmi->segment_id;
skip = mbmi->mb_skip_coeff;
if (mb_col < cm->mb_cols - 1) {
segment_id = segment_id && mi[1].mbmi.segment_id;
skip = skip && mi[1].mbmi.mb_skip_coeff;
}
if (mb_row < cm-></