summaryrefslogtreecommitdiff
path: root/vp8/encoder/rdopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/encoder/rdopt.c')
-rw-r--r--vp8/encoder/rdopt.c186
1 files changed, 171 insertions, 15 deletions
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index 66f342302..a2cd2651a 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -366,6 +366,13 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex) {
(const vp8_prob( *)[8][PREV_COEF_CONTEXTS][11]) cpi->common.fc.coef_probs_8x8,
BLOCK_TYPES_8X8);
+#if CONFIG_TX16X16
+ fill_token_costs(
+ cpi->mb.token_costs_16x16,
+ (const vp8_prob(*)[8][PREV_COEF_CONTEXTS][11]) cpi->common.fc.coef_probs_16x16,
+ BLOCK_TYPES_16X16);
+#endif
+
/*rough estimate for costing*/
cpi->common.kf_ymode_probs_index = cpi->common.base_qindex >> 4;
vp8_init_mode_costs(cpi);
@@ -809,6 +816,72 @@ static void macro_block_yrd_8x8(MACROBLOCK *mb,
*Rate = vp8_rdcost_mby_8x8(mb);
}
+#if CONFIG_TX16X16
+static int cost_coeffs_16x16(MACROBLOCK *mb, BLOCKD *b, int type,
+ ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
+ const int eob = b->eob;
+ int c = !type; /* start at coef 0, unless Y with Y2 */
+ int cost = 0, pt; /* surrounding block/prev coef predictor */
+ short *qcoeff_ptr = b->qcoeff;
+
+ VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
+
+# define QC16X16(I) ( qcoeff_ptr [vp8_default_zig_zag1d_16x16[I]] )
+
+ for (; c < eob; c++) {
+ int v = QC16X16(c);
+ int t = vp8_dct_value_tokens_ptr[v].Token;
+ cost += mb->token_costs_16x16[type][vp8_coef_bands_16x16[c]][pt][t];
+ cost += vp8_dct_value_cost_ptr[v];
+ pt = vp8_prev_token_class[t];
+ }
+
+# undef QC16X16
+ if (c < 256)
+ cost += mb->token_costs_16x16[type][vp8_coef_bands_16x16[c]]
+ [pt][DCT_EOB_TOKEN];
+
+ pt = (c != !type); // is eob first coefficient;
+ *a = *l = pt;
+ return cost;
+}
+
+static int vp8_rdcost_mby_16x16(MACROBLOCK *mb) {
+ int cost;
+ MACROBLOCKD *x = &mb->e_mbd;
+ ENTROPY_CONTEXT_PLANES t_above, t_left;
+ ENTROPY_CONTEXT *ta, *tl;
+
+ vpx_memcpy(&t_above, mb->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
+ vpx_memcpy(&t_left, mb->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
+
+ ta = (ENTROPY_CONTEXT *)&t_above;
+ tl = (ENTROPY_CONTEXT *)&t_left;
+
+ cost = cost_coeffs_16x16(mb, x->block, PLANE_TYPE_Y_WITH_DC, ta, tl);
+ return cost;
+}
+
+static void macro_block_yrd_16x16(MACROBLOCK *mb, int *Rate, int *Distortion,
+ const VP8_ENCODER_RTCD *rtcd) {
+ int d;
+
+ ENCODEMB_INVOKE(&rtcd->encodemb, submby)(
+ mb->src_diff,
+ *(mb->block[0].base_src),
+ mb->e_mbd.predictor,
+ mb->block[0].src_stride);
+
+ vp8_transform_mby_16x16(mb);
+ vp8_quantize_mby_16x16(mb);
+ d = ENCODEMB_INVOKE(&rtcd->encodemb, mberr)(mb, 0);
+
+ *Distortion = (d >> 2);
+ // rate
+ *Rate = vp8_rdcost_mby_16x16(mb);
+}
+#endif
+
static void copy_predictor(unsigned char *dst, const unsigned char *predictor) {
const unsigned int *p = (const unsigned int *)predictor;
unsigned int *d = (unsigned int *)dst;
@@ -1121,7 +1194,12 @@ static int64_t rd_pick_intra16x16mby_mode(VP8_COMP *cpi,
}
#endif
- macro_block_yrd_8x8(x, &ratey, &distortion, IF_RTCD(&cpi->rtcd));
+#if CONFIG_TX16X16
+ if (mode <= TM_PRED)
+ macro_block_yrd_16x16(x, &ratey, &distortion, IF_RTCD(&cpi->rtcd));
+ else
+#endif
+ macro_block_yrd_8x8(x, &ratey, &distortion, IF_RTCD(&cpi->rtcd));
// FIXME add compoundmode cost
// FIXME add rate for mode2
rate = ratey + x->mbmode_cost[x->e_mbd.frame_type]
@@ -3081,16 +3159,33 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
vp8_cost_bit(get_pred_prob(cm, xd, PRED_COMP), 0);
}
break;
+ case DC_PRED:
+ case V_PRED:
+ case H_PRED:
+ case TM_PRED:
case D45_PRED:
case D135_PRED:
case D117_PRED:
case D153_PRED:
case D27_PRED:
case D63_PRED:
- case DC_PRED:
- case V_PRED:
- case H_PRED:
- case TM_PRED:
+#if CONFIG_TX16X16
+ // FIXME: breaks lossless since 4x4 isn't allowed
+ x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
+ // FIXME compound intra prediction
+ RECON_INVOKE(&cpi->common.rtcd.recon, build_intra_predictors_mby)
+ (&x->e_mbd);
+ macro_block_yrd_16x16(x, &rate_y, &distortion,
+ IF_RTCD(&cpi->rtcd));
+ rate2 += rate_y;
+ distortion2 += distortion;
+ rate2 += x->mbmode_cost[x->e_mbd.frame_type][x->e_mbd.mode_info_context->mbmi.mode];
+ rate2 += uv_intra_rate_8x8;
+ rate_uv = uv_intra_rate_tokenonly_8x8;
+ distortion2 += uv_intra_distortion_8x8;
+ distortion_uv = uv_intra_distortion_8x8;
+ break;
+#else
x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
// FIXME compound intra prediction
RECON_INVOKE(&cpi->common.rtcd.recon, build_intra_predictors_mby)
@@ -3116,6 +3211,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
distortion_uv = uv_intra_distortion;
}
break;
+#endif
case NEWMV: {
int thissme;
@@ -3269,7 +3365,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
}
case ZEROMV:
-
// Trap vectors that reach beyond the UMV borders
// Note that ALL New MV, Nearest MV Near MV and Zero MV code drops through to this point
// because of the lack of break statements in the previous two cases.
@@ -3348,12 +3443,23 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
rate2 += vp8_cost_mv_ref(cpi, this_mode, mdcounts);
// Y cost and distortion
- if (cpi->common.txfm_mode == ALLOW_8X8)
- macro_block_yrd_8x8(x, &rate_y, &distortion,
- IF_RTCD(&cpi->rtcd));
- else
- macro_block_yrd(x, &rate_y, &distortion,
- IF_RTCD(&cpi->rtcd));
+#if CONFIG_TX16X16
+ if (this_mode == ZEROMV ||
+ this_mode == NEARESTMV ||
+ this_mode == NEARMV ||
+ this_mode == NEWMV)
+ macro_block_yrd_16x16(x, &rate_y, &distortion, IF_RTCD(&cpi->rtcd));
+ else {
+#endif
+ if (cpi->common.txfm_mode == ALLOW_8X8)
+ macro_block_yrd_8x8(x, &rate_y, &distortion,
+ IF_RTCD(&cpi->rtcd));
+ else
+ macro_block_yrd(x, &rate_y, &distortion,
+ IF_RTCD(&cpi->rtcd));
+#if CONFIG_TX16X16
+ }
+#endif
rate2 += rate_y;
distortion2 += distortion;
@@ -3361,7 +3467,14 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
// UV cost and distortion
vp8_build_inter16x16_predictors_mbuv(&x->e_mbd);
- if (cpi->common.txfm_mode == ALLOW_8X8)
+ if (cpi->common.txfm_mode == ALLOW_8X8
+#if CONFIG_TX16X16
+ || this_mode == ZEROMV ||
+ this_mode == NEARESTMV ||
+ this_mode == NEARMV ||
+ this_mode == NEWMV
+#endif
+ )
rd_inter16x16_uv_8x8(cpi, x, &rate_uv,
&distortion_uv,
cpi->common.full_pixel);
@@ -3487,9 +3600,21 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
&x->e_mbd.predictor[320], 16, 8);
/* Y cost and distortion */
- if (cpi->common.txfm_mode == ALLOW_8X8)
+ if (cpi->common.txfm_mode == ALLOW_8X8
+#if CONFIG_TX16X16
+ || this_mode == ZEROMV ||
+ this_mode == NEARESTMV ||
+ this_mode == NEARMV ||
+ this_mode == NEWMV
+#endif
+ )
+#if CONFIG_TX16X16
+ macro_block_yrd_16x16(x, &rate_y, &distortion,
+ IF_RTCD(&cpi->rtcd));
+#else
macro_block_yrd_8x8(x, &rate_y, &distortion,
IF_RTCD(&cpi->rtcd));
+#endif
else
macro_block_yrd(x, &rate_y, &distortion,
IF_RTCD(&cpi->rtcd));
@@ -3498,7 +3623,14 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
distortion2 += distortion;
/* UV cost and distortion */
- if (cpi->common.txfm_mode == ALLOW_8X8)
+ if (cpi->common.txfm_mode == ALLOW_8X8
+#if CONFIG_TX16X16
+ || this_mode == ZEROMV ||
+ this_mode == NEARESTMV ||
+ this_mode == NEARMV ||
+ this_mode == NEWMV
+#endif
+ )
rd_inter16x16_uv_8x8(cpi, x, &rate_uv,
&distortion_uv,
cpi->common.full_pixel);
@@ -3541,6 +3673,15 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
&& this_mode != B_PRED
&& this_mode != I8X8_PRED);
+#if CONFIGURE_TX16X16
+ if (this_mode <= TM_PRED ||
+ this_mode == NEWMV ||
+ this_mode == ZEROMV ||
+ this_mode == NEARESTMV ||
+ this_mode == NEARMV)
+ mb_skippable = mb_is_skippable_16x16(&x->e_mbd);
+ else
+#endif
if ((cpi->common.txfm_mode == ALLOW_8X8) && has_y2) {
if (x->e_mbd.mode_info_context->mbmi.ref_frame != INTRA_FRAME)
mb_skippable = mb_is_skippable_8x8(&x->e_mbd);
@@ -4002,10 +4143,25 @@ int vp8cx_pick_mode_inter_macroblock
}
/* test code: set transform size based on mode selection */
+#if CONFIG_TX16X16
+ if (xd->mode_info_context->mbmi.mode <= TM_PRED ||
+ xd->mode_info_context->mbmi.mode == NEWMV ||
+ xd->mode_info_context->mbmi.mode == ZEROMV ||
+ xd->mode_info_context->mbmi.mode == NEARMV ||
+ xd->mode_info_context->mbmi.mode == NEARESTMV) {
+ xd->mode_info_context->mbmi.txfm_size = TX_16X16;
+ cpi->t16x16_count++;
+ }
+ else if (cpi->common.txfm_mode == ALLOW_8X8
+ && xd->mode_info_context->mbmi.mode != I8X8_PRED
+ && xd->mode_info_context->mbmi.mode != B_PRED
+ && xd->mode_info_context->mbmi.mode != SPLITMV) {
+#else
if (cpi->common.txfm_mode == ALLOW_8X8
&& xd->mode_info_context->mbmi.mode != I8X8_PRED
&& xd->mode_info_context->mbmi.mode != B_PRED
&& xd->mode_info_context->mbmi.mode != SPLITMV) {
+#endif
xd->mode_info_context->mbmi.txfm_size = TX_8X8;
cpi->t8x8_count++;
} else {