diff options
-rw-r--r-- | vp8/common/blockd.h | 10 | ||||
-rw-r--r-- | vp8/common/entropymode.c | 6 | ||||
-rw-r--r-- | vp8/common/postproc.c | 7 | ||||
-rw-r--r-- | vp8/common/reconinter.c | 2 | ||||
-rw-r--r-- | vp8/decoder/decodemv.c | 11 | ||||
-rw-r--r-- | vp8/decoder/decodframe.c | 20 | ||||
-rw-r--r-- | vp8/decoder/detokenize.c | 3 | ||||
-rw-r--r-- | vp8/encoder/bitstream.c | 5 | ||||
-rw-r--r-- | vp8/encoder/encodeframe.c | 10 | ||||
-rw-r--r-- | vp8/encoder/encodemb.c | 34 | ||||
-rw-r--r-- | vp8/encoder/onyx_int.h | 8 | ||||
-rw-r--r-- | vp8/encoder/rdopt.c | 385 | ||||
-rw-r--r-- | vp8/encoder/tokenize.c | 9 |
13 files changed, 383 insertions, 127 deletions
diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h index feb615066..de148066c 100644 --- a/vp8/common/blockd.h +++ b/vp8/common/blockd.h @@ -175,6 +175,14 @@ typedef enum { #define VP8_BINTRAMODES (B_HU_PRED + 1) /* 10 */ #define VP8_SUBMVREFS (1 + NEW4X4 - LEFT4X4) +typedef enum { + PARTITIONING_16X8 = 0, + PARTITIONING_8X16, + PARTITIONING_8X8, + PARTITIONING_4X4, + NB_PARTITIONINGS, +} SPLITMV_PARTITIONING_TYPE; + /* For keyframes, intra block modes are predicted by the (already decoded) modes for the Y blocks to the left and above us; for interframes, there is a single probability table. */ @@ -216,7 +224,7 @@ typedef struct { int mv_ref_index[MAX_REF_FRAMES]; #endif - unsigned char partitioning; + SPLITMV_PARTITIONING_TYPE partitioning; unsigned char mb_skip_coeff; /* does this mb has coefficients at all, 1=no coefficients, 0=need decode tokens */ unsigned char need_to_clamp_mvs; unsigned char need_to_clamp_secondmv; diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c index 5627aa43a..dd4be76fa 100644 --- a/vp8/common/entropymode.c +++ b/vp8/common/entropymode.c @@ -215,9 +215,9 @@ const vp8_tree_index vp8_uv_mode_tree[VP8_UV_MODES * 2 - 2] = { }; const vp8_tree_index vp8_mbsplit_tree[6] = { - -3, 2, - -2, 4, - -0, -1 + -PARTITIONING_4X4, 2, + -PARTITIONING_8X8, 4, + -PARTITIONING_16X8, -PARTITIONING_8X16, }; const vp8_tree_index vp8_mv_ref_tree[8] = { diff --git a/vp8/common/postproc.c b/vp8/common/postproc.c index 17bbe3281..388612e8a 100644 --- a/vp8/common/postproc.c +++ b/vp8/common/postproc.c @@ -783,7 +783,7 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t if (mi->mbmi.mode == SPLITMV) { switch (mi->mbmi.partitioning) { - case 0 : { /* mv_top_bottom */ + case PARTITIONING_16X8 : { /* mv_top_bottom */ union b_mode_info *bmi = &mi->bmi[0]; MV *mv = &bmi->mv.as_mv; @@ -803,7 +803,7 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t break; } - case 1 : { /* mv_left_right */ + case PARTITIONING_8X16 : { /* mv_left_right */ union b_mode_info *bmi = &mi->bmi[0]; MV *mv = &bmi->mv.as_mv; @@ -823,7 +823,7 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t break; } - case 2 : { /* mv_quarters */ + case PARTITIONING_8X8 : { /* mv_quarters */ union b_mode_info *bmi = &mi->bmi[0]; MV *mv = &bmi->mv.as_mv; @@ -858,6 +858,7 @@ int vp8_post_proc_frame(VP8_COMMON *oci, YV12_BUFFER_CONFIG *dest, vp8_ppflags_t vp8_blit_line(x0 + 12, x1, y0 + 12, y1, y_buffer, y_stride); break; } + case PARTITIONING_4X4: default : { union b_mode_info *bmi = mi->bmi; int bx0, by0; diff --git a/vp8/common/reconinter.c b/vp8/common/reconinter.c index a41d233ab..869abb2d2 100644 --- a/vp8/common/reconinter.c +++ b/vp8/common/reconinter.c @@ -965,7 +965,7 @@ static void build_inter4x4_predictors_mb(MACROBLOCKD *xd) { MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi; BLOCKD *blockd = xd->block; - if (xd->mode_info_context->mbmi.partitioning < 3) { + if (xd->mode_info_context->mbmi.partitioning != PARTITIONING_4X4) { blockd[ 0].bmi = xd->mode_info_context->bmi[ 0]; blockd[ 2].bmi = xd->mode_info_context->bmi[ 2]; blockd[ 8].bmi = xd->mode_info_context->bmi[ 8]; diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c index 72ff126f2..064d16426 100644 --- a/vp8/decoder/decodemv.c +++ b/vp8/decoder/decodemv.c @@ -1285,10 +1285,12 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, #if CONFIG_TX_SELECT 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))) { + (mbmi->ref_frame != INTRA_FRAME && !(mbmi->mode == SPLITMV && + mbmi->partitioning == PARTITIONING_4X4)))) { // FIXME(rbultje) code ternary symbol once all experiments are merged mbmi->txfm_size = vp8_read(bc, cm->prob_tx[0]); - if (mbmi->txfm_size != TX_4X4 && mbmi->mode != I8X8_PRED) + if (mbmi->txfm_size != TX_4X4 && mbmi->mode != I8X8_PRED && + mbmi->mode != SPLITMV) mbmi->txfm_size += vp8_read(bc, cm->prob_tx[1]); } else #endif @@ -1297,8 +1299,9 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi, (mbmi->ref_frame != INTRA_FRAME && mbmi->mode != SPLITMV))) { mbmi->txfm_size = TX_16X16; } else if (cm->txfm_mode >= ALLOW_8X8 && - ((mbmi->ref_frame == INTRA_FRAME && mbmi->mode != B_PRED) || - (mbmi->ref_frame != INTRA_FRAME && mbmi->mode != SPLITMV))) { + (!(mbmi->ref_frame == INTRA_FRAME && mbmi->mode == B_PRED) && + !(mbmi->ref_frame != INTRA_FRAME && mbmi->mode == SPLITMV && + mbmi->partitioning == PARTITIONING_4X4))) { mbmi->txfm_size = TX_8X8; } else { mbmi->txfm_size = TX_4X4; diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index cc19985fd..d961c7b2a 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -384,10 +384,16 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, } } } else if (mode == SPLITMV) { - DEQUANT_INVOKE(&pbi->dequant, idct_add_y_block) - (xd->qcoeff, xd->block[0].dequant, - xd->predictor, xd->dst.y_buffer, - xd->dst.y_stride, xd->eobs); + if (tx_size == TX_8X8) { + vp8_dequant_idct_add_y_block_8x8_c(xd->qcoeff, xd->block[0].dequant, + xd->predictor, xd->dst.y_buffer, + xd->dst.y_stride, xd->eobs, xd); + } else { + DEQUANT_INVOKE(&pbi->dequant, + idct_add_y_block)(xd->qcoeff, xd->block[0].dequant, + xd->predictor, xd->dst.y_buffer, + xd->dst.y_stride, xd->eobs); + } } else { BLOCKD *b = &xd->block[24]; @@ -489,8 +495,10 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd, if (!xd->mode_info_context->mbmi.encoded_as_sb) { #endif if ((tx_size == TX_8X8 && - xd->mode_info_context->mbmi.mode != I8X8_PRED) - || tx_size == TX_16X16) + xd->mode_info_context->mbmi.mode != I8X8_PRED && + xd->mode_info_context->mbmi.mode != SPLITMV) + || tx_size == TX_16X16 + ) DEQUANT_INVOKE(&pbi->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, diff --git a/vp8/decoder/detokenize.c b/vp8/decoder/detokenize.c index 0e5e54418..d33c602f0 100644 --- a/vp8/decoder/detokenize.c +++ b/vp8/decoder/detokenize.c @@ -493,7 +493,8 @@ int vp8_decode_mb_tokens_8x8(VP8D_COMP *pbi, MACROBLOCKD *xd, INT16 *qcoeff_ptr = &xd->qcoeff[0]; TX_TYPE tx_type = DCT_DCT; - int bufthred = (xd->mode_info_context->mbmi.mode == I8X8_PRED) ? 16 : 24; + int bufthred = (xd->mode_info_context->mbmi.mode == I8X8_PRED || + xd->mode_info_context->mbmi.mode == SPLITMV) ? 16 : 24; if (xd->mode_info_context->mbmi.mode != B_PRED && xd->mode_info_context->mbmi.mode != SPLITMV && xd->mode_info_context->mbmi.mode != I8X8_PRED) { diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c index 512057ea7..508ada85b 100644 --- a/vp8/encoder/bitstream.c +++ b/vp8/encoder/bitstream.c @@ -1219,7 +1219,8 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi, vp8_writer *const bc) { #if CONFIG_TX_SELECT if (((rf == INTRA_FRAME && mode <= I8X8_PRED) || - (rf != INTRA_FRAME && mode != SPLITMV)) && + (rf != INTRA_FRAME && !(mode == SPLITMV && + mi->partitioning == PARTITIONING_4X4))) && pc->txfm_mode == TX_MODE_SELECT && !((pc->mb_no_coeff_skip && mi->mb_skip_coeff) || (segfeature_active(xd, segment_id, SEG_LVL_EOB) && @@ -1227,7 +1228,7 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi, vp8_writer *const bc) { TX_SIZE sz = mi->txfm_size; // FIXME(rbultje) code ternary symbol once all experiments are merged vp8_write(bc, sz != TX_4X4, pc->prob_tx[0]); - if (sz != TX_4X4 && mode != I8X8_PRED) + if (sz != TX_4X4 && mode != I8X8_PRED && mode != SPLITMV) vp8_write(bc, sz != TX_8X8, pc->prob_tx[1]); } #endif diff --git a/vp8/encoder/encodeframe.c b/vp8/encoder/encodeframe.c index 4658a7946..af9b3f598 100644 --- a/vp8/encoder/encodeframe.c +++ b/vp8/encoder/encodeframe.c @@ -2161,7 +2161,9 @@ void vp8cx_encode_inter_macroblock (VP8_COMP *cpi, MACROBLOCK *x, if (mbmi->mode != B_PRED && mbmi->mode != I8X8_PRED && mbmi->mode != SPLITMV) { cpi->txfm_count[mbmi->txfm_size]++; - } else if (mbmi->mode == I8X8_PRED) { + } else if (mbmi->mode == I8X8_PRED || + (mbmi->mode == SPLITMV && + mbmi->partitioning != PARTITIONING_4X4)) { cpi->txfm_count_8x8p[mbmi->txfm_size]++; } } else @@ -2169,8 +2171,10 @@ void vp8cx_encode_inter_macroblock (VP8_COMP *cpi, MACROBLOCK *x, if (mbmi->mode != B_PRED && mbmi->mode != I8X8_PRED && mbmi->mode != SPLITMV && cpi->common.txfm_mode >= ALLOW_16X16) { mbmi->txfm_size = TX_16X16; - } else if (mbmi->mode != B_PRED && mbmi->mode != SPLITMV && - cpi->common.txfm_mode >= ALLOW_8X8) { + } else if (mbmi->mode != B_PRED && + !(mbmi->mode == SPLITMV && + mbmi->partitioning == PARTITIONING_4X4) && + cpi->common.txfm_mode >= ALLOW_8X8) { mbmi->txfm_size = TX_8X8; } else { mbmi->txfm_size = TX_4X4; diff --git a/vp8/encoder/encodemb.c b/vp8/encoder/encodemb.c index 0272a5cb6..92bb3d899 100644 --- a/vp8/encoder/encodemb.c +++ b/vp8/encoder/encodemb.c @@ -636,6 +636,7 @@ void vp8_optimize_mby_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) { ENTROPY_CONTEXT_PLANES t_above, t_left; ENTROPY_CONTEXT *ta; ENTROPY_CONTEXT *tl; + int has_2nd_order = x->e_mbd.mode_info_context->mbmi.mode != SPLITMV; if (!x->e_mbd.above_context || !x->e_mbd.left_context) return; @@ -645,7 +646,7 @@ void vp8_optimize_mby_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) { ta = (ENTROPY_CONTEXT *)&t_above; tl = (ENTROPY_CONTEXT *)&t_left; - type = PLANE_TYPE_Y_NO_DC; + type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC; for (b = 0; b < 16; b += 4) { optimize_b(x, b, type, ta + vp8_block2above_8x8[b], tl + vp8_block2left_8x8[b], @@ -655,8 +656,11 @@ void vp8_optimize_mby_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) { } // 8x8 always have 2nd roder haar block - check_reset_8x8_2nd_coeffs(&x->e_mbd, - ta + vp8_block2above_8x8[24], tl + vp8_block2left_8x8[24]); + if (has_2nd_order) { + check_reset_8x8_2nd_coeffs(&x->e_mbd, + ta + vp8_block2above_8x8[24], + tl + vp8_block2left_8x8[24]); + } } void vp8_optimize_mbuv_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) { @@ -896,11 +900,25 @@ void vp8_encode_inter16x16(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) { optimize_mb_16x16(x, rtcd); vp8_inverse_transform_mb_16x16(IF_RTCD(&rtcd->common->idct), xd); } else if (tx_size == TX_8X8) { - vp8_transform_mb_8x8(x); - vp8_quantize_mb_8x8(x); - if (x->optimize) - optimize_mb_8x8(x, rtcd); - vp8_inverse_transform_mb_8x8(IF_RTCD(&rtcd->common->idct), xd); + if (xd->mode_info_context->mbmi.mode == SPLITMV) { + assert(xd->mode_info_context->mbmi.partitioning != PARTITIONING_4X4); + vp8_transform_mby_8x8(x); + vp8_transform_mbuv_4x4(x); + vp8_quantize_mby_8x8(x); + vp8_quantize_mbuv_4x4(x); + if (x->optimize) { + vp8_optimize_mby_8x8(x, rtcd); + vp8_optimize_mbuv_4x4(x, rtcd); + } + vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), xd); + vp8_inverse_transform_mbuv_4x4(IF_RTCD(&rtcd->common->idct), xd); + } else { + vp8_transform_mb_8x8(x); + vp8_quantize_mb_8x8(x); + if (x->optimize) + optimize_mb_8x8(x, rtcd); + vp8_inverse_transform_mb_8x8(IF_RTCD(&rtcd->common->idct), xd); + } } else { transform_mb_4x4(x); vp8_quantize_mb_4x4(x); diff --git a/vp8/encoder/onyx_int.h b/vp8/encoder/onyx_int.h index 8746ab07c..ef17568ce 100644 --- a/vp8/encoder/onyx_int.h +++ b/vp8/encoder/onyx_int.h @@ -366,10 +366,10 @@ typedef struct VP8_ENCODER_RTCD { } VP8_ENCODER_RTCD; enum { - BLOCK_16X8, - BLOCK_8X16, - BLOCK_8X8, - BLOCK_4X4, + BLOCK_16X8 = PARTITIONING_16X8, + BLOCK_8X16 = PARTITIONING_8X16, + BLOCK_8X8 = PARTITIONING_8X8, + BLOCK_4X4 = PARTITIONING_4X4, BLOCK_16X16, BLOCK_MAX_SEGMENTS, BLOCK_32X32 = BLOCK_MAX_SEGMENTS, diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index 30f7e705e..8131f3303 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -1583,8 +1583,8 @@ static int64_t rd_pick_intra8x8block(VP8_COMP *cpi, MACROBLOCK *x, int ib, } else { *(a + vp8_block2above[ib]) = besta0; *(a + vp8_block2above[ib + 1]) = besta1; - *(l + vp8_block2above[ib]) = bestl0; - *(l + vp8_block2above[ib + 4]) = bestl1; + *(l + vp8_block2left[ib]) = bestl0; + *(l + vp8_block2left[ib + 4]) = bestl1; } return best_rd; @@ -2178,12 +2178,22 @@ static int64_t encode_inter_mb_segment_8x8(MACROBLOCK *x, int which_label, int *labelyrate, int *distortion, + int64_t *otherrd, ENTROPY_CONTEXT *ta, ENTROPY_CONTEXT *tl, const VP8_ENCODER_RTCD *rtcd) { int i, j; MACROBLOCKD *xd = &x->e_mbd; const int iblock[4] = { 0, 1, 4, 5 }; + int othercost = 0, otherdist = 0; + ENTROPY_CONTEXT_PLANES tac, tlc; + ENTROPY_CONTEXT *tacp = (ENTROPY_CONTEXT *) &tac, + *tlcp = (ENTROPY_CONTEXT *) &tlc; + + if (otherrd) { + memcpy(&tac, ta, sizeof(ENTROPY_CONTEXT_PLANES)); + memcpy(&tlc, tl, sizeof(ENTROPY_CONTEXT_PLANES)); + } *distortion = 0; *labelyrate = 0; @@ -2191,8 +2201,9 @@ static int64_t encode_inter_mb_segment_8x8(MACROBLOCK *x, int ib = vp8_i8x8_block[i]; if (labels[ib] == which_label) { - BLOCKD *bd = &xd->block[ib]; - BLOCK *be = &x->block[ib]; + int idx = (ib & 8) + ((ib & 2) << 1); + BLOCKD *bd = &xd->block[ib], *bd2 = &xd->block[idx]; + BLOCK *be = &x->block[ib], *be2 = &x->block[idx]; int thisdistortion; vp8_build_inter_predictors4b(xd, bd, 16); @@ -2200,24 +2211,66 @@ static int64_t encode_inter_mb_segment_8x8(MACROBLOCK *x, vp8_build_2nd_inter_predictors4b(xd, bd, 16); vp8_subtract_4b_c(be, bd, 16); - for (j = 0; j < 4; j += 2) { - bd = &xd->block[ib + iblock[j]]; - be = &x->block[ib + iblock[j]]; - x->vp8_short_fdct8x4(be->src_diff, be->coeff, 32); - x->quantize_b_4x4_pair(be, be + 1, bd, bd + 1); - thisdistortion = vp8_block_error_c(be->coeff, bd->dqcoeff, 32); + if (xd->mode_info_context->mbmi.txfm_size == TX_4X4) { + if (otherrd) { + x->vp8_short_fdct8x8(be->src_diff, be2->coeff, 32); + x->quantize_b_8x8(be2, bd2); + thisdistortion = vp8_block_error_c(be2->coeff, bd2->dqcoeff, 64); + otherdist += thisdistortion; + othercost += cost_coeffs(x, bd2, PLANE_TYPE_Y_WITH_DC, + tacp + vp8_block2above_8x8[idx], + tlcp + vp8_block2left_8x8[idx], TX_8X8); + } + for (j = 0; j < 4; j += 2) { + bd = &xd->block[ib + iblock[j]]; + be = &x->block[ib + iblock[j]]; + x->vp8_short_fdct8x4(be->src_diff, be->coeff, 32); + x->quantize_b_4x4_pair(be, be + 1, bd, bd + 1); + thisdistortion = vp8_block_error_c(be->coeff, bd->dqcoeff, 32); + *distortion += thisdistortion; + *labelyrate += cost_coeffs(x, bd, PLANE_TYPE_Y_WITH_DC, + ta + vp8_block2above[ib + iblock[j]], + tl + vp8_block2left[ib + iblock[j]], + TX_4X4); + *labelyrate += cost_coeffs(x, bd + 1, PLANE_TYPE_Y_WITH_DC, + ta + vp8_block2above[ib + iblock[j] + 1], + tl + vp8_block2left[ib + iblock[j]], + TX_4X4); + } + } else /* 8x8 */ { + if (otherrd) { + for (j = 0; j < 4; j += 2) { + BLOCKD *bd3 = &xd->block[ib + iblock[j]]; + BLOCK *be3 = &x->block[ib + iblock[j]]; + x->vp8_short_fdct8x4(be3->src_diff, be3->coeff, 32); + x->quantize_b_4x4_pair(be3, be3 + 1, bd3, bd3 + 1); + thisdistortion = vp8_block_error_c(be3->coeff, bd3->dqcoeff, 32); + otherdist += thisdistortion; + othercost += cost_coeffs(x, bd3, PLANE_TYPE_Y_WITH_DC, + tacp + vp8_block2above[ib + iblock[j]], + tlcp + vp8_block2left[ib + iblock[j]], + TX_4X4); + othercost += cost_coeffs(x, bd3 + 1, PLANE_TYPE_Y_WITH_DC, + tacp + vp8_block2above[ib + iblock[j] + 1], + tlcp + vp8_block2left[ib + iblock[j]], + TX_4X4); + } + } + x->vp8_short_fdct8x8(be->src_diff, be2->coeff, 32); + x->quantize_b_8x8(be2, bd2); + thisdistortion = vp8_block_error_c(be2->coeff, bd2->dqcoeff, 64); *distortion += thisdistortion; - *labelyrate += cost_coeffs(x, bd, PLANE_TYPE_Y_WITH_DC, - ta + vp8_block2above[ib + iblock[j]], - tl + vp8_block2left[ib + iblock[j]], TX_4X4); - *labelyrate += cost_coeffs(x, bd + 1, PLANE_TYPE_Y_WITH_DC, - ta + vp8_block2above[ib + iblock[j] + 1], - tl + vp8_block2left[ib + iblock[j]], - TX_4X4); + *labelyrate += cost_coeffs(x, bd2, PLANE_TYPE_Y_WITH_DC, + ta + vp8_block2above_8x8[idx], + tl + vp8_block2left_8x8[idx], TX_8X8); } } } *distortion >>= 2; + if (otherrd) { + othercost >>= 2; + *otherrd = RDCOST(x->rdmult, x->rddiv, othercost, otherdist); + } return RDCOST(x->rdmult, x->rddiv, *labelyrate, *distortion); } @@ -2229,7 +2282,8 @@ typedef struct { int_mv mvp; int64_t segment_rd; - int segment_num; + SPLITMV_PARTITIONING_TYPE segment_num; + TX_SIZE txfm_size; int r; int d; int segment_yrate; @@ -2255,9 +2309,14 @@ int mv_check_bounds(MACROBLOCK *x, int_mv *mv) { return r; } -static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, - BEST_SEG_INFO *bsi, unsigned int segmentation, - int_mv seg_mvs[16 /* n_blocks */][MAX_REF_FRAMES - 1]) { +static void rd_check_segment_txsize(VP8_COMP *cpi, MACROBLOCK *x, + BEST_SEG_INFO *bsi, + SPLITMV_PARTITIONING_TYPE segmentation, + TX_SIZE tx_size, int64_t *otherrds, + int64_t *rds, int *completed, + /* 16 = n_blocks */ + int_mv seg_mvs[16 /* n_blocks */] + [MAX_REF_FRAMES - 1]) { int i, j; int const *labels; int br = 0, bd = 0; @@ -2265,12 +2324,12 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi; int label_count; - int64_t this_segment_rd = 0; + int64_t this_segment_rd = 0, other_segment_rd; int label_mv_thresh; int rate = 0; int sbr = 0, sbd = 0; int segmentyrate = 0; - uint8_t best_eobs[16]; + uint8_t best_eobs[16] = { 0 }; vp8_variance_fn_ptr_t *v_fn_ptr; @@ -2298,20 +2357,23 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, label_mv_thresh = 1 * bsi->mvthresh / label_count; // Segmentation method overheads - rate = vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, vp8_mbsplit_encodings + segmentation); + rate = vp8_cost_token(vp8_mbsplit_tree, vp8_mbsplit_probs, + vp8_mbsplit_encodings + segmentation); rate += vp8_cost_mv_ref(cpi, SPLITMV, bsi->mdcounts); this_segment_rd += RDCOST(x->rdmult, x->rddiv, rate, 0); br += rate; + other_segment_rd = this_segment_rd; - for (i = 0; i < label_count; i++) { + mbmi->txfm_size = tx_size; + for (i = 0; i < label_count && this_segment_rd < bsi->segment_rd; i++) { int_mv mode_mv[B_MODE_COUNT], second_mode_mv[B_MODE_COUNT]; - int64_t best_label_rd = INT64_MAX; + int64_t best_label_rd = INT64_MAX, best_other_rd = INT64_MAX; B_PREDICTION_MODE mode_selected = ZERO4X4; int bestlabelyrate = 0; // search for the best motion vector on this segment for (this_mode = LEFT4X4; this_mode <= NEW4X4; this_mode ++) { - int64_t this_rd; + int64_t this_rd, other_rd; int distortion; int labelyrate; ENTROPY_CONTEXT_PLANES t_above_s, t_left_s; @@ -2333,21 +2395,23 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, BLOCK *c; BLOCKD *e; - // Is the best so far sufficiently good that we cant justify doing and new motion search. + /* Is the best so far sufficiently good that we cant justify doing + * and new motion search. */ if (best_label_rd < label_mv_thresh) break; if (cpi->compressor_speed) { - if (segmentation == BLOCK_8X16 || segmentation == BLOCK_16X8) { + if (segmentation == PARTITIONING_8X16 || + segmentation == PARTITIONING_16X8) { bsi->mvp.as_int = bsi->sv_mvp[i].as_int; - if (i == 1 && segmentation == BLOCK_16X8) + if (i == 1 && segmentation == PARTITIONING_16X8) bsi->mvp.as_int = bsi->sv_mvp[2].as_int; step_param = bsi->sv_istep[i]; } // use previous block's result as next block's MV predictor. - if (segmentation == BLOCK_4X4 && i > 0) { + if (segmentation == PARTITIONING_4X4 && i > 0) { bsi->mvp.as_int = x->e_mbd.block[i - 1].bmi.as_mv.first.as_int; if (i == 4 || i == 8 || i == 12) bsi->mvp.as_int = x->e_mbd.block[i - 4].bmi.as_mv.first.as_int; @@ -2379,7 +2443,8 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, // Should we do a full search (best quality only) if ((cpi->compressor_speed == 0) && (bestsme >> sseshift) > 4000) { /* Check if mvp_full is within the range. */ - vp8_clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max, x->mv_row_min, x->mv_row_max); + vp8_clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max, + x->mv_row_min, x->mv_row_max); thissme = cpi->full_search_sad(x, c, e, &mvp_full, sadpb, 16, v_fn_ptr, @@ -2389,7 +2454,8 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, bestsme = thissme; mode_mv[NEW4X4].as_int = e->bmi.as_mv.first.as_int; } else { - // The full search result is actually worse so re-instate the previous best vector + /* The full search result is actually worse so re-instate the + * previous best vector */ e->bmi.as_mv.first.as_int = mode_mv[NEW4X4].as_int; } } @@ -2399,15 +2465,16 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, int distortion; unsigned int sse; cpi->find_fractional_mv_step(x, c, e, &mode_mv[NEW4X4], - bsi->ref_mv, x->errorperbit, v_fn_ptr, XMVCOST, - &distortion, &sse); + bsi->ref_mv, x->errorperbit, v_fn_ptr, + XMVCOST, &distortion, &sse); // safe motion search result for use in compound prediction seg_mvs[i][mbmi->ref_frame - 1].as_int = mode_mv[NEW4X4].as_int; } } /* NEW4X4 */ else if (mbmi->second_ref_frame && this_mode == NEW4X4) { - // motion search not completed? Then skip newmv for this block with comppred + /* motion search not completed? Then skip newmv for this block with + * comppred */ if (seg_mvs[i][mbmi->second_ref_frame - 1].as_int == INVALID_MV || seg_mvs[i][mbmi->ref_frame - 1].as_int == INVALID_MV) { continue; @@ -2429,14 +2496,15 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, mv_check_bounds(x, &second_mode_mv[this_mode])) continue; - if (segmentation == BLOCK_4X4) { + if (segmentation == PARTITIONING_4X4) { this_rd = encode_inter_mb_segment(x, labels, i, &labelyrate, &distortion, ta_s, tl_s, IF_RTCD(&cpi->rtcd)); + other_rd = this_rd; } else { this_rd = encode_inter_mb_segment_8x8(x, labels, i, &labelyrate, - &distortion, ta_s, tl_s, - IF_RTCD(&cpi->rtcd)); + &distortion, &other_rd, + ta_s, tl_s, IF_RTCD(&cpi->rtcd)); } this_rd += RDCOST(x->rdmult, x->rddiv, rate, 0); rate += labelyrate; @@ -2447,9 +2515,20 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, bestlabelyrate = labelyrate; mode_selected = this_mode; best_label_rd = this_rd; - for (j = 0; j < 16; j++) - if (labels[j] == i) - best_eobs[j] = x->e_mbd.block[j].eob; + if (x->e_mbd.mode_info_context->mbmi.txfm_size == TX_4X4) { + for (j = 0; j < 16; j++) + if (labels[j] == i) + best_eobs[j] = x->e_mbd.block[j].eob; + } else { + for (j = 0; j < 4; j++) { + int ib = vp8_i8x8_block[j], idx = j * 4; + + if (labels[ib] == i) + best_eobs[idx] = x->e_mbd.block[idx].eob; + } + } + if (other_rd < best_other_rd) + best_other_rd = other_rd; vpx_memcpy(ta_b, ta_s, sizeof(ENTROPY_CONTEXT_PLANES)); vpx_memcpy(tl_b, tl_s, sizeof(ENTROPY_CONTEXT_PLANES)); @@ -2461,18 +2540,18 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, vpx_memcpy(tl, tl_b, sizeof(ENTROPY_CONTEXT_PLANES)); labels2mode(x, labels, i, mode_selected, &mode_mv[mode_selected], - &second_mode_mv[mode_selected], seg_mvs[i], bsi->ref_mv, bsi->second_ref_mv, XMVCOST); + &second_mode_mv[mode_selected], seg_mvs[i], + bsi->ref_mv, bsi->second_ref_mv, XMVCOST); br += sbr; bd += sbd; segmentyrate += bestlabelyrate; this_segment_rd += best_label_rd; - - if (this_segment_rd >= bsi->segment_rd) { - break; - } - - + other_segment_rd += best_other_rd; + if (rds) + rds[i] = this_segment_rd; + if (otherrds) + rds[i] = other_segment_rd; } /* for each label */ if (this_segment_rd < bsi->segment_rd) { @@ -2481,6 +2560,7 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, bsi->segment_yrate = segmentyrate; bsi->segment_rd = this_segment_rd; bsi->segment_num = segmentation; + bsi->txfm_size = mbmi->txfm_size; // store everything needed to come back to this!! for (i = 0; i < 16; i++) { @@ -2493,6 +2573,112 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, bsi->eobs[i] = best_eobs[i]; } } + + if (completed) { + *completed = i; + } +} + +static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x, + BEST_SEG_INFO *bsi, + unsigned int segmentation, + /* 16 = n_blocks */ + int_mv seg_mvs[16][MAX_REF_FRAMES - 1], + int64_t txfm_cache[NB_TXFM_MODES]) { +#if CONFIG_TX_SELECT + int i, n, c = vp8_mbsplit_count[segmentation]; + + if (segmentation == PARTITIONING_4X4) { + int64_t rd[16]; + + rd_check_segment_txsize(cpi, x, bsi, segmentation, TX_4X4, NULL, + rd, &n, seg_mvs); + if (n == c) { + for (i = 0; i < NB_TXFM_MODES; i++) { + if (rd[c - 1] < txfm_cache[i]) + txfm_cache[i] = rd[c - 1]; + } + } + } else { + int64_t diff, base_rd; + int cost4x4 = vp8_cost_bit(cpi->common.prob_tx[0], 0); + int cost8x8 = vp8_cost_bit(cpi->common.prob_tx[0], 1); + + if (cpi->common.txfm_mode == TX_MODE_SELECT) { + int64_t rd4x4[4], rd8x8[4]; + int n4x4, n8x8, nmin; + BEST_SEG_INFO bsi4x4, bsi8x8; + + /* factor in cost of cost4x4/8x8 in decision */ + vpx_memcpy(&bsi4x4, bsi, sizeof(*bsi)); + vpx_memcpy(&bsi8x8, bsi, sizeof(*bsi)); + rd_check_segment_txsize(cpi, x, &bsi4x4, segmentation, + TX_4X4, NULL, rd4x4, &n4x4, seg_mvs); + rd_check_segment_txsize(cpi, x, &bsi8x8, segmentation, + TX_8X8, NULL, rd8x8, &n8x8, seg_mvs); + if (bsi4x4.segment_num == segmentation) { + bsi4x4.segment_rd += RDCOST(x->rdmult, x->rddiv, cost4x4, 0); + if (bsi4x4.segment_rd < bsi->segment_rd) + vpx_memcpy(bsi, &bsi4x4, sizeof(*bsi)); + } + if (bsi8x8.segment_num == segmentation) { + bsi8x8.segment_rd += RDCOST(x->rdmult, x->rddiv, cost8x8, 0); + if (bsi8x8.segment_rd < bsi->segment_rd) + vpx_memcpy(bsi, &bsi8x8, sizeof(*bsi)); + } + n = n4x4 > n8x8 ? n4x4 : n8x8; + if (n == c) { + nmin = n4x4 < n8x8 ? n4x4 : n8x8; + diff = rd8x8[nmin - 1] - rd4x4[nmin - 1]; + if (n == n4x4) { + base_rd = rd4x4[c - 1]; + } else { + base_rd = rd8x8[c - 1] - diff; + } + } + } else { + int64_t rd[4], otherrd[4]; + + if (cpi->common.txfm_mode == ONLY_4X4) { + rd_check_segment_txsize(cpi, x, bsi, segmentation, TX_4X4, otherrd, + rd, &n, seg_mvs); + if (n == c) { + base_rd = rd[c - 1]; + diff = otherrd[c - 1] - rd[c - 1]; + } + } else /* use 8x8 transform */ { + rd_check_segment_txsize(cpi, x, bsi, segmentation, TX_8X8, otherrd, + rd, &n, seg_mvs); + if (n == c) { + diff = rd[c - 1] - otherrd[c - 1]; + base_rd = otherrd[c - 1]; + } + } + } + + if (n == c) { + if (base_rd < txfm_cache[ONLY_4X4]) { + txfm_cache[ONLY_4X4] = base_rd; + } + if (base_rd + diff < txfm_cache[1]) { + txfm_cache[ALLOW_8X8] = txfm_cache[ALLOW_16X16] = base_rd + diff; + } + if (diff < 0) { + base_rd += diff + RDCOST(x->rdmult, x->rddiv, cost8x8, 0); + } else { + base_rd += RDCOST(x->rdmult, x->rddiv, cost4x4, 0); + } + if (base_rd < txfm_cache[TX_MODE_SELECT]) { + txfm_cache[TX_MODE_SELECT] = base_rd; + } + } + } +#else + rd_check_segment_txsize(cpi, x, bsi, segmentation, + (segmentation == PARTITIONING_4X4 || + cpi->common.txfm_mode == ONLY_4X4) ? TX_4X4 : TX_8X8, + NULL, NULL, NULL, seg_mvs); +#endif } static __inline @@ -2508,17 +2694,26 @@ void vp8_cal_step_param(int sr, int *sp) { *sp = MAX_MVSEARCH_STEPS - 1 - step; } -static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, - int_mv *best_ref_mv, int_mv *second_best_ref_mv, int64_t best_rd, - int *mdcounts, int *returntotrate, - int *returnyrate, int *returndistortion, - int *skippable, int mvthresh, - int_mv seg_mvs[BLOCK_MAX_SEGMENTS - 1][16 /* n_blocks */][MAX_REF_FRAMES - 1]) { +static int rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, + int_mv *best_ref_mv, + int_mv *second_best_ref_mv, + int64_t best_rd, + int *mdcounts, + int *returntotrate, + int *returnyrate, + int *returndistortion, + int *skippable, int mvthresh, + int_mv seg_mvs[NB_PARTITIONINGS] + [16 /* n_blocks */] + [MAX_REF_FRAMES - 1], + int64_t txfm_cache[NB_TXFM_MODES]) { int i; BEST_SEG_INFO bsi; MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi; vpx_memset(&bsi, 0, sizeof(bsi)); + for (i = 0; i < NB_TXFM_MODES; i++) + txfm_cache[i] = INT64_MAX; bsi.segment_rd = best_rd; bsi.ref_mv = best_ref_mv; @@ -2526,6 +2721,7 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, bsi.mvp.as_int = best_ref_mv->as_int; bsi.mvthresh = mvthresh; bsi.mdcounts = mdcounts; + bsi.txfm_size = TX_4X4; for (i = 0; i < 16; i++) bsi.modes[i] = ZERO4X4; @@ -2533,15 +2729,19 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, if (cpi->compressor_speed == 0) { /* for now, we will keep the original segmentation order when in best quality mode */ - rd_check_segment(cpi, x, &bsi, BLOCK_16X8, seg_mvs[BLOCK_16X8]); - rd_check_segment(cpi, x, &bsi, BLOCK_8X16, seg_mvs[BLOCK_8X16]); - rd_check_segment(cpi, x, &bsi, BLOCK_8X8, seg_mvs[BLOCK_8X8]); - rd_check_segment(cpi, x, &bsi, BLOCK_4X4, seg_mvs[BLOCK_4X4]); + rd_check_segment(cpi, x, &bsi, PARTITIONING_16X8, + seg_mvs[PARTITIONING_16X8], txfm_cache); + rd_check_segment(cpi, x, &bsi, PARTITIONING_8X16, + seg_mvs[PARTITIONING_8X16], txfm_cache); + rd_check_segment(cpi, x, &bsi, PARTITIONING_8X8, + seg_mvs[PARTITIONING_8X8], txfm_cache); + rd_check_segment(cpi, x, &bsi, PARTITIONING_4X4, + seg_mvs[PARTITIONING_4X4], txfm_cache); } else { int sr; - rd_check_segment(cpi, x, &bsi, BLOCK_8X8, seg_mvs[BLOCK_8X8]); - + rd_check_segment(cpi, x, &bsi, PARTITIONING_8X8, + seg_mvs[PARTITIONING_8X8], txfm_cache); if (bsi.segment_rd < best_rd) { int tmp_col_min = x->mv_col_min; @@ -2557,34 +2757,40 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, bsi.sv_mvp[2].as_int = bsi.mvs[8].as_int; bsi.sv_mvp[3].as_int = bsi.mvs[10].as_int; - /* Use 8x8 result as 16x8/8x16's predictor MV. Adjust search range according to the closeness of 2 MV. */ + /* Use 8x8 result as 16x8/8x16's predictor MV. Adjust search range + * according to the closeness of 2 MV. */ /* block 8X16 */ - { - sr = MAXF((abs(bsi.sv_mvp[0].as_mv.row - bsi.sv_mvp[2].as_mv.row)) >> 3, (abs(bsi.sv_mvp[0].as_mv.col - bsi.sv_mvp[2].as_mv.col)) >> 3); - vp8_cal_step_param(sr, &bsi.sv_istep[0]); + sr = MAXF((abs(bsi.sv_mvp[0].as_mv.row - bsi.sv_mvp[2].as_mv.row)) >> 3, + (abs(bsi.sv_mvp[0].as_mv.col - bsi.sv_mvp[2].as_mv.col)) >> 3); + vp8_cal_step_param(sr, &bsi.sv_istep[0]); - sr = MAXF((abs(bsi.sv_mvp[1].as_mv.row - bsi.sv_mvp[3].as_mv.row)) >> 3, (abs(bsi.sv_mvp[1].as_mv.col - bsi.sv_mvp[3].as_mv.col)) >> 3); - vp8_cal_step_param(sr, &bsi.sv_istep[1]); + sr = MAXF((abs(bsi.sv_mvp[1].as_mv.row - bsi.sv_mvp[3].as_mv.row)) >> 3, + (abs(bsi.sv_mvp[1].as_mv.col - bsi.sv_mvp[3].as_mv.col)) >> 3); + vp8_cal_step_param(sr, &bsi.sv_istep[1]); - rd_check_segment(cpi, x, &bsi, BLOCK_8X16, seg_mvs[BLOCK_8X16]); - } + rd_check_segment(cpi, x, &bsi, PARTITIONING_8X16, + seg_mvs[PARTITIONING_8X16], txfm_cache); /* block 16X8 */ - { - sr = MAXF((abs(bsi.sv_mvp[0].as_mv.row - bsi.sv_mvp[1].as_mv.row)) >> 3, (abs(bsi.sv_mvp[0].as_mv.col - bsi.sv_mvp[1].as_mv.col)) >> 3); - vp8_cal_step_param(sr, &bsi.sv_istep[0]); + sr = MAXF((abs(bsi.sv_mvp[0].as_mv.row - bsi.sv_mvp[1].as_mv.row)) >> 3, + (abs(bsi.sv_mvp[0].as_mv.col - bsi.sv_mvp[1].as_mv.col)) >> 3); + vp8_cal_step_param(sr, &bsi.sv_istep[0]); - sr = MAXF((abs(bsi.sv_mvp[2].as_mv.row - bsi.sv_mvp[3].as_mv.row)) >> 3, (abs(bsi.sv_mvp[2].as_mv.col - bsi.sv_mvp[3].as_mv.col)) >> 3); - vp8_cal_step_param(sr, &bsi.sv_istep[1]); + sr = MAXF((abs(bsi.sv_mvp[2].as_mv.row - bsi.sv_mvp[3].as_mv.row)) >> 3, + (abs(bsi.sv_mvp[2].as_mv.col - bsi.sv_mvp[3].as_mv.col)) >> 3); + vp8_cal_step_param(sr, &bsi.sv_istep[1]); - rd_check_segment(cpi, x, &bsi, BLOCK_16X8, seg_mvs[BLOCK_16X8]); - } + rd_check_segment(cpi, x, &bsi, PARTITIONING_16X8, + seg_mvs[PARTITIONING_16X8], txfm_cache); /* If 8x8 is better than 16x8/8x16, then do 4x4 search */ /* Not skip 4x4 if speed=0 (good quality) */ - if (cpi->sf.no_skip_block4x4_search || bsi.segment_num == BLOCK_8X8) { /* || (sv_segment_rd8x8-bsi.segment_rd) < sv_segment_rd8x8>>5) */ + if (cpi->sf.no_skip_block4x4_search || + bsi.segment_num == PARTITIONING_8X8) { + /* || (sv_segment_rd8x8-bsi.segment_rd) < sv_segment_rd8x8>>5) */ bsi.mvp.as_int = bsi.sv_mvp[0].as_int; - rd_check_segment(cpi, x, &bsi, BLOCK_4X4, seg_mvs[BLOCK_4X4]); + rd_check_segment(cpi, x, &bsi, PARTITIONING_4X4, + seg_mvs[PARTITIONING_4X4], txfm_cache); } /* restore UMV window */ @@ -2608,9 +2814,12 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x, *returntotrate = bsi.r; *returndistortion = bsi.d; *returnyrate = bsi.segment_yrate; - *skippable = mby_is_skippable_4x4(&x->e_mbd, 0); + *skippable = bsi.txfm_size == TX_4X4 ? + mby_is_skippable_4x4(&x->e_mbd, 0) : + mby_is_skippable_8x8(&x->e_mbd, 0); /* save partitions */ + mbmi->txfm_size = bsi.txfm_size; mbmi->partitioning = bsi.segment_num; x->partition_info->count = vp8_mbsplit_count[bsi.segment_num]; @@ -3299,7 +3508,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int unsigned char *y_buffer[4], *u_buffer[4], *v_buffer[4]; unsigned int ref_costs[MAX_REF_FRAMES]; - int_mv seg_mvs[BLOCK_MAX_SEGMENTS - 1][16 /* n_blocks */][MAX_REF_FRAMES - 1]; + int_mv seg_mvs[NB_PARTITIONINGS][16 /* n_blocks */][MAX_REF_FRAMES - 1]; vpx_memset(mode8x8, 0, sizeof(mode8x8)); vpx_memset(&frame_mv, 0, sizeof(frame_mv)); @@ -3314,7 +3523,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int for (i = 0; i < NB_TXFM_MODES; i++) best_txfm_rd[i] = INT64_MAX; - for (i = 0; i < BLOCK_MAX_SEGMENTS - 1; i++) { + for (i = 0; i < NB_PARTITIONINGS; i++) { int j, k; for (j = 0; j < 16; j++) @@ -3680,12 +3889,12 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int (mbmi->ref_frame == GOLDEN_FRAME) ? cpi->rd_threshes[THR_NEWG] : this_rd_thresh; - mbmi->txfm_size = TX_4X4; // FIXME use 8x8 in case of 8x8/8x16/16x8 - tmp_rd = vp8_rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, - second_ref, best_yrd, mdcounts, - &rate, &rate_y, &distortion, - &skippable, - this_rd_thresh, seg_mvs); + tmp_rd = rd_pick_best_mbsegmentation(cpi, x, &best_ref_mv, + second_ref, best_yrd, mdcounts, + &rate, &rate_y, &distortion, + &skippable, + this_rd_thresh, seg_mvs, + txfm_cache); rate2 += rate; distortion2 += distortion; @@ -4081,7 +4290,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int if (!mode_excluded && this_rd != INT64_MAX) { for (i = 0; i < NB_TXFM_MODES; i++) { int64_t adj_rd; - if (this_mode != B_PRED && this_mode != SPLITMV) { + if (this_mode != B_PRED) { adj_rd = this_rd + txfm_cache[i] - txfm_cache[cm->txfm_mode]; } else { adj_rd = this_rd; diff --git a/vp8/encoder/tokenize.c b/vp8/encoder/tokenize.c index 575c7acf0..0cd10b188 100644 --- a/vp8/encoder/tokenize.c +++ b/vp8/encoder/tokenize.c @@ -589,7 +589,8 @@ void vp8_tokenize_mb(VP8_COMP *cpi, xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_16x16(xd); break; case TX_8X8: - if (xd->mode_info_context->mbmi.mode == I8X8_PRED) + if (xd->mode_info_context->mbmi.mode == I8X8_PRED || + xd->mode_info_context->mbmi.mode == SPLITMV) xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_8x8_4x4uv(xd, 0); else xd->mode_info_context->mbmi.mb_skip_coeff = mb_is_skippable_8x8(xd, has_y2_block); @@ -665,7 +666,8 @@ void vp8_tokenize_mb(VP8_COMP *cpi, *(A + vp8_block2above_8x8[b] + 1) = *(A + vp8_block2above_8x8[b]); *(L + vp8_block2left_8x8[b] + 1) = *(L + vp8_block2left_8x8[b]); } - if (xd->mode_info_context->mbmi.mode == I8X8_PRED) { + if (xd->mode_info_context->mbmi.mode == I8X8_PRED || + xd->mode_info_context->mbmi.mode == SPLITMV) { tokenize1st_order_chroma_4x4(xd, t, cpi, dry_run); } else { for (b = 16; b < 24; b += 4) { @@ -1260,7 +1262,8 @@ void vp8_stuff_mb(VP8_COMP *cpi, MACROBLOCKD *xd, TOKENEXTRA **t, int dry_run) { if (tx_size == TX_16X16) { vp8_stuff_mb_16x16(cpi, xd, t, dry_run); } else if (tx_size == TX_8X8) { - if (xd->mode_info_context->mbmi.mode == I8X8_PRED) { + if (xd->mode_info_context->mbmi.mode == I8X8_PRED || + xd->mode_info_context->mbmi.mode == SPLITMV) { vp8_stuff_mb_8x8_4x4uv(cpi, xd, t, dry_run); } else { vp8_stuff_mb_8x8(cpi, xd, t, dry_run); |