Commit c59e36fc authored by Ronald S. Bultje's avatar Ronald S. Bultje Committed by Gerrit Code Review
Browse files

Merge "Add proper skip support to intra frames." into experimental

parents 7a18c816 4f36b7c6
......@@ -1136,11 +1136,12 @@ static int64_t rd_pick_intra_sby_mode(VP8_COMP *cpi,
MACROBLOCK *x,
int *rate,
int *rate_tokenonly,
int *distortion) {
int *distortion,
int *skippable) {
MB_PREDICTION_MODE mode;
MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected);
int this_rate, this_rate_tokenonly;
int this_distortion;
int this_distortion, s;
int64_t best_rd = INT64_MAX, this_rd;
/* Y Search for 32x32 intra prediction mode */
......@@ -1150,7 +1151,7 @@ static int64_t rd_pick_intra_sby_mode(VP8_COMP *cpi,
build_intra_predictors_sby_s)(&x->e_mbd);
super_block_yrd_8x8(x, &this_rate_tokenonly,
&this_distortion, IF_RTCD(&cpi->rtcd), NULL);
&this_distortion, IF_RTCD(&cpi->rtcd), &s);
this_rate = this_rate_tokenonly +
x->mbmode_cost[x->e_mbd.frame_type]
[x->e_mbd.mode_info_context->mbmi.mode];
......@@ -1162,6 +1163,7 @@ static int64_t rd_pick_intra_sby_mode(VP8_COMP *cpi,
*rate = this_rate;
*rate_tokenonly = this_rate_tokenonly;
*distortion = this_distortion;
*skippable = s;
}
}
......@@ -1172,10 +1174,11 @@ static int64_t rd_pick_intra_sby_mode(VP8_COMP *cpi,
#endif
static int64_t rd_pick_intra16x16mby_mode(VP8_COMP *cpi,
MACROBLOCK *x,
int *Rate,
int *rate_y,
int *Distortion) {
MACROBLOCK *x,
int *Rate,
int *rate_y,
int *Distortion,
int *skippable) {
MB_PREDICTION_MODE mode;
MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected);
#if CONFIG_COMP_INTRA_PRED
......@@ -1187,6 +1190,8 @@ static int64_t rd_pick_intra16x16mby_mode(VP8_COMP *cpi,
int distortion;
int64_t best_rd = INT64_MAX;
int64_t this_rd;
int UNINITIALIZED_IS_SAFE(skip);
MACROBLOCKD *xd = &x->e_mbd;
// Y Search for 16x16 intra prediction mode
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
......@@ -1218,6 +1223,11 @@ static int64_t rd_pick_intra16x16mby_mode(VP8_COMP *cpi,
this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
if (this_rd < best_rd) {
#if CONFIG_TX16X16
skip = mby_is_skippable_16x16(xd);
#else
skip = mby_is_skippable_8x8(xd);
#endif
mode_selected = mode;
#if CONFIG_COMP_INTRA_PRED
mode2_selected = mode2;
......@@ -1232,6 +1242,7 @@ static int64_t rd_pick_intra16x16mby_mode(VP8_COMP *cpi,
#endif
}
*skippable = skip;
mbmi->mode = mode_selected;
#if CONFIG_COMP_INTRA_PRED
mbmi->second_mode = mode2_selected;
......@@ -1590,17 +1601,19 @@ static void rd_pick_intra_mbuv_mode(VP8_COMP *cpi,
MACROBLOCK *x,
int *rate,
int *rate_tokenonly,
int *distortion) {
int *distortion,
int *skippable) {
MB_PREDICTION_MODE mode;
MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected);
#if CONFIG_COMP_INTRA_PRED
MB_PREDICTION_MODE mode2;
MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode2_selected);
#endif
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
int64_t best_rd = INT64_MAX;
int UNINITIALIZED_IS_SAFE(d), UNINITIALIZED_IS_SAFE(r);
int rate_to;
int rate_to, UNINITIALIZED_IS_SAFE(skip);
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
#if CONFIG_COMP_INTRA_PRED
......@@ -1640,6 +1653,7 @@ static void rd_pick_intra_mbuv_mode(VP8_COMP *cpi,
this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
if (this_rd < best_rd) {
skip = mbuv_is_skippable(xd);
best_rd = this_rd;
d = distortion;
r = rate;
......@@ -1654,6 +1668,7 @@ static void rd_pick_intra_mbuv_mode(VP8_COMP *cpi,
*rate = r;
*distortion = d;
*skippable = skip;
mbmi->uv_mode = mode_selected;
#if CONFIG_COMP_INTRA_PRED
......@@ -1665,13 +1680,15 @@ static void rd_pick_intra_mbuv_mode_8x8(VP8_COMP *cpi,
MACROBLOCK *x,
int *rate,
int *rate_tokenonly,
int *distortion) {
int *distortion,
int *skippable) {
MACROBLOCKD *xd = &x->e_mbd;
MB_PREDICTION_MODE mode;
MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected);
MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
int64_t best_rd = INT64_MAX;
int UNINITIALIZED_IS_SAFE(d), UNINITIALIZED_IS_SAFE(r);
int rate_to;
int rate_to, UNINITIALIZED_IS_SAFE(skip);
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
int rate;
......@@ -1695,6 +1712,7 @@ static void rd_pick_intra_mbuv_mode_8x8(VP8_COMP *cpi,
this_rd = RDCOST(x->rdmult, x->rddiv, rate, distortion);
if (this_rd < best_rd) {
skip = mbuv_is_skippable_8x8(xd);
best_rd = this_rd;
d = distortion;
r = rate;
......@@ -1704,6 +1722,7 @@ static void rd_pick_intra_mbuv_mode_8x8(VP8_COMP *cpi,
}
*rate = r;
*distortion = d;
*skippable = skip;
mbmi->uv_mode = mode_selected;
}
......@@ -1711,9 +1730,10 @@ static void rd_pick_intra_mbuv_mode_8x8(VP8_COMP *cpi,
static void super_block_uvrd_8x8(MACROBLOCK *x,
int *rate,
int *distortion,
const VP8_ENCODER_RTCD *rtcd) {
const VP8_ENCODER_RTCD *rtcd,
int *skippable) {
MACROBLOCKD *const xd = &x->e_mbd;
int d = 0, r = 0, n;
int d = 0, r = 0, n, s = 1;
const uint8_t *usrc = x->src.u_buffer, *udst = xd->dst.u_buffer;
const uint8_t *vsrc = x->src.v_buffer, *vdst = xd->dst.v_buffer;
int src_uv_stride = x->src.uv_stride, dst_uv_stride = xd->dst.uv_stride;
......@@ -1736,6 +1756,7 @@ static void super_block_uvrd_8x8(MACROBLOCK *x,
dst_uv_stride);
vp8_transform_mbuv_8x8(x);
vp8_quantize_mbuv_8x8(x);
s &= mbuv_is_skippable_8x8(xd);
d += ENCODEMB_INVOKE(&rtcd->encodemb, mbuverr)(x) >> 2;
xd->above_context = ta + x_idx;
......@@ -1745,8 +1766,9 @@ static void super_block_uvrd_8x8(MACROBLOCK *x,
xd->above_context = ta;
xd->left_context = tl;
*distortion = (d >> 2);
*distortion = d;
*rate = r;
*skippable = s;
xd->left_context = tl;
xd->above_context = ta;
......@@ -1758,12 +1780,13 @@ static int64_t rd_pick_intra_sbuv_mode(VP8_COMP *cpi,
MACROBLOCK *x,
int *rate,
int *rate_tokenonly,
int *distortion) {
int *distortion,
int *skippable) {
MB_PREDICTION_MODE mode;
MB_PREDICTION_MODE UNINITIALIZED_IS_SAFE(mode_selected);
int64_t best_rd = INT64_MAX, this_rd;
int this_rate_tokenonly, this_rate;
int this_distortion;
int this_distortion, s;
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
x->e_mbd.mode_info_context->mbmi.uv_mode = mode;
......@@ -1771,7 +1794,7 @@ static int64_t rd_pick_intra_sbuv_mode(VP8_COMP *cpi,
build_intra_predictors_sbuv_s)(&x->e_mbd);
super_block_uvrd_8x8(x, &this_rate_tokenonly,
&this_distortion, IF_RTCD(&cpi->rtcd));
&this_distortion, IF_RTCD(&cpi->rtcd), &s);
this_rate = this_rate_tokenonly +
x->mbmode_cost[x->e_mbd.frame_type]
[x->e_mbd.mode_info_context->mbmi.mode];
......@@ -1783,6 +1806,7 @@ static int64_t rd_pick_intra_sbuv_mode(VP8_COMP *cpi,
*rate = this_rate;
*rate_tokenonly = this_rate_tokenonly;
*distortion = this_distortion;
*skippable = s;
}
}
......@@ -3056,17 +3080,17 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
vp8_update_zbin_extra(cpi, x);
rd_pick_intra_mbuv_mode(cpi, x, &uv_intra_rate,
&uv_intra_rate_tokenonly, &uv_intra_distortion);
&uv_intra_rate_tokenonly, &uv_intra_distortion,
&uv_intra_skippable);
uv_intra_mode = mbmi->uv_mode;
uv_intra_skippable = mbuv_is_skippable(&x->e_mbd);
/* rough estimate for now */
if (cpi->common.txfm_mode == ALLOW_8X8) {
rd_pick_intra_mbuv_mode_8x8(cpi, x, &uv_intra_rate_8x8,
&uv_intra_rate_tokenonly_8x8,
&uv_intra_distortion_8x8);
&uv_intra_distortion_8x8,
&uv_intra_skippable_8x8);
uv_intra_mode_8x8 = mbmi->uv_mode;
uv_intra_skippable_8x8 = mbuv_is_skippable_8x8(&x->e_mbd);
}
// Get estimates of reference frame costs for each reference frame
......@@ -3602,21 +3626,22 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
&& this_mode != B_PRED
&& this_mode != I8X8_PRED);
#if CONFIG_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 (mbmi->ref_frame != INTRA_FRAME)
if (mbmi->ref_frame != INTRA_FRAME) {
#if CONFIG_TX16X16
mb_skippable = mb_is_skippable_16x16(&x->e_mbd);
#else
mb_skippable = mb_is_skippable_8x8(&x->e_mbd);
else
#endif
} else {
#if CONFIG_TX16X16
mb_skippable = uv_intra_skippable_8x8
& mby_is_skippable_16x16(&x->e_mbd);
#else
mb_skippable = uv_intra_skippable_8x8
& mby_is_skippable_8x8(&x->e_mbd);
#endif
}
} else {
if (mbmi->ref_frame != INTRA_FRAME)
mb_skippable = mb_is_skippable(&x->e_mbd, has_y2);
......@@ -3878,26 +3903,37 @@ end:
void vp8_rd_pick_intra_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
int *returnrate,
int *returndist) {
VP8_COMMON *cm = &cpi->common;
MACROBLOCKD *xd = &x->e_mbd;
int rate_y, rate_uv;
int rate_y_tokenonly, rate_uv_tokenonly;
int error_y, error_uv;
int dist_y, dist_uv;
int y_skip, uv_skip;
x->e_mbd.mode_info_context->mbmi.txfm_size = TX_8X8;
error_uv = rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly,
&dist_uv);
&dist_uv, &uv_skip);
error_y = rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly,
&dist_y);
&dist_y, &y_skip);
// TODO(rbultje): add rate_uv
*returnrate = rate_y;
*returndist = dist_y + (dist_uv >> 2);
if (cpi->common.mb_no_coeff_skip && y_skip && uv_skip) {
*returnrate = rate_y + rate_uv - rate_y_tokenonly - rate_uv_tokenonly +
vp8_cost_bit(get_pred_prob(cm, xd, PRED_MBSKIP), 1);
*returndist = dist_y + (dist_uv >> 2);
} else {
*returnrate = rate_y + rate_uv;
if (cpi->common.mb_no_coeff_skip)
*returnrate += vp8_cost_bit(get_pred_prob(cm, xd, PRED_MBSKIP), 0);
*returndist = dist_y + (dist_uv >> 2);
}
}
#endif
void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x,
int *returnrate, int *returndist) {
VP8_COMMON *cm = &cpi->common;
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
int64_t error4x4, error16x16;
......@@ -3905,22 +3941,36 @@ void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x,
int64_t error4x4d;
int rate4x4d, dist4x4d;
#endif
int rate4x4, rate16x16 = 0, rateuv;
int dist4x4, dist16x16, distuv;
int rate4x4, rate16x16 = 0, rateuv, rateuv8x8;
int dist4x4, dist16x16, distuv, distuv8x8;
int rate;
int rate4x4_tokenonly = 0;
int rate16x16_tokenonly = 0;
int rateuv_tokenonly = 0;
int rateuv_tokenonly = 0, rateuv8x8_tokenonly = 0;
int64_t error8x8;
int rate8x8_tokenonly=0;
int rate8x8, dist8x8;
int mode16x16;
int mode8x8[2][4];
int dist;
int modeuv, modeuv8x8, uv_intra_skippable, uv_intra_skippable_8x8;
int y_intra16x16_skippable;
mbmi->ref_frame = INTRA_FRAME;
rd_pick_intra_mbuv_mode(cpi, x, &rateuv, &rateuv_tokenonly, &distuv);
rate = rateuv;
rd_pick_intra_mbuv_mode(cpi, x, &rateuv, &rateuv_tokenonly, &distuv,
&uv_intra_skippable);
modeuv = mbmi->uv_mode;
if (cpi->common.txfm_mode == ALLOW_8X8) {
rd_pick_intra_mbuv_mode_8x8(cpi, x, &rateuv8x8, &rateuv8x8_tokenonly,
&distuv8x8, &uv_intra_skippable_8x8);
modeuv8x8 = mbmi->uv_mode;
} else {
uv_intra_skippable_8x8 = uv_intra_skippable;
rateuv8x8 = rateuv;
distuv8x8 = distuv;
rateuv8x8_tokenonly = rateuv_tokenonly;
modeuv8x8 = modeuv;
}
// current macroblock under rate-distortion optimization test loop
#if CONFIG_HYBRIDTRANSFORM
......@@ -3928,7 +3978,8 @@ void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x,
#endif
error16x16 = rd_pick_intra16x16mby_mode(cpi, x, &rate16x16,
&rate16x16_tokenonly, &dist16x16);
&rate16x16_tokenonly, &dist16x16,
&y_intra16x16_skippable);
mode16x16 = mbmi->mode;
#if CONFIG_HYBRIDTRANSFORM
......@@ -3965,8 +4016,15 @@ void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x,
&dist4x4d, error16x16, 1, 0);
#endif
if (error8x8 > error16x16) {
if (cpi->common.mb_no_coeff_skip &&
y_intra16x16_skippable && uv_intra_skippable_8x8) {
mbmi->uv_mode = modeuv;
rate = rateuv8x8 + rate16x16 - rateuv8x8_tokenonly - rate16x16_tokenonly +
vp8_cost_bit(get_pred_prob(cm, xd, PRED_MBSKIP), 1);
dist = dist16x16 + (distuv8x8 >> 2);
} else if (error8x8 > error16x16) {
if (error4x4 < error16x16) {
rate = rateuv;
#if CONFIG_COMP_INTRA_PRED
rate += (error4x4d < error4x4) ? rate4x4d : rate4x4;
if (error4x4d >= error4x4) // FIXME save original modes etc.
......@@ -3978,14 +4036,17 @@ void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x,
rate += rate4x4;
#endif
mbmi->mode = B_PRED;
dist = dist4x4;
dist = dist4x4 + (distuv >> 2);
} else {
mbmi->mode = mode16x16;
rate += rate16x16;
dist = dist16x16;
rate = rate16x16 + rateuv8x8;
dist = dist16x16 + (distuv8x8 >> 2);
}
if (cpi->common.mb_no_coeff_skip)
rate += vp8_cost_bit(get_pred_prob(cm, xd, PRED_MBSKIP), 0);
} else {
if (error4x4 < error8x8) {
rate = rateuv;
#if CONFIG_COMP_INTRA_PRED
rate += (error4x4d < error4x4) ? rate4x4d : rate4x4;
if (error4x4d >= error4x4) // FIXME save original modes etc.
......@@ -3997,18 +4058,19 @@ void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x,
rate += rate4x4;
#endif
mbmi->mode = B_PRED;
dist = dist4x4;
dist = dist4x4 + (distuv >> 2);
} else {
mbmi->mode = I8X8_PRED;
set_i8x8_block_modes(x, mode8x8);
rate += rate8x8;
dist = dist8x8;
rate = rate8x8 + rateuv;
dist = dist8x8 + (distuv >> 2);
}
if (cpi->common.mb_no_coeff_skip)
rate += vp8_cost_bit(get_pred_prob(cm, xd, PRED_MBSKIP), 0);
}
// TODO(rbultje): should add rateuv here also
*returnrate = rate - rateuv;
*returndist = dist + (distuv >> 2);
*returnrate = rate;
*returndist = dist;
}
#if CONFIG_SUPERBLOCKS
......
......@@ -38,6 +38,7 @@ extern int mby_is_skippable_8x8(MACROBLOCKD *xd);
extern int mbuv_is_skippable_8x8(MACROBLOCKD *xd);
extern int mb_is_skippable_8x8(MACROBLOCKD *xd);
extern int mb_is_skippable_16x16(MACROBLOCKD *xd);
extern int mby_is_skippable_16x16(MACROBLOCKD *xd);
#ifdef ENTROPY_STATS
void init_context_counters();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment