ref: af660715c01fc5403700c49686885b2f0ee6133b
parent: 1b5421f3c5a8cf76db2fc8b939be706ad63530e7
author: Ronald S. Bultje <[email protected]>
date: Thu Jun 27 13:41:54 EDT 2013
Make coefficient skip condition an explicit RD choice. This commit replaces zrun_zbin_boost, a method of biasing non-zero coefficients following runs of zero-coefficients to be rounded towards zero, with an explicit skip-block choice in the RD loop. The logic is basically that if individual coefficients should be rounded towards zero (from a RD point of view), the trellis/optimize loop should take care of it. If whole blocks should be zero (from a RD point of view), a single RD check is much more efficient than a complete serialization of the quantization loop. Quality change: derf +0.5% psnr, +1.6% ssim; yt +0.6% psnr, +1.1% ssim. SIMD for quantize will follow in a separate patch. Results for other test sets pending. Change-Id: Ife5fa641163ac5150ac428011e87188f1937c1f4
--- a/vp9/common/vp9_rtcd_defs.sh
+++ b/vp9/common/vp9_rtcd_defs.sh
@@ -558,7 +558,7 @@
specialize vp9_get_mb_ss mmx sse2
# ENCODEMB INVOKE
-prototype int64_t vp9_block_error "int16_t *coeff, int16_t *dqcoeff, intptr_t block_size"
+prototype int64_t vp9_block_error "int16_t *coeff, int16_t *dqcoeff, intptr_t block_size, int64_t *ssz"
specialize vp9_block_error sse2
prototype void vp9_subtract_block "int rows, int cols, int16_t *diff_ptr, ptrdiff_t diff_stride, const uint8_t *src_ptr, ptrdiff_t src_stride, const uint8_t *pred_ptr, ptrdiff_t pred_stride"
--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -68,7 +68,6 @@
int16_t *quant;
uint8_t *quant_shift;
int16_t *zbin;
- int16_t *zrun_zbin_boost;
int16_t *round;
// Zbin Over Quant value
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -268,11 +268,7 @@
DECLARE_ALIGNED(16, unsigned char, a_quant_shift[QINDEX_RANGE][16]);
DECLARE_ALIGNED(16, short, a_zbin[QINDEX_RANGE][16]);
DECLARE_ALIGNED(16, short, a_round[QINDEX_RANGE][16]);
-
- DECLARE_ALIGNED(16, short, zrun_zbin_boost_a[QINDEX_RANGE][16]);
#endif
- DECLARE_ALIGNED(16, short, zrun_zbin_boost_y[QINDEX_RANGE][16]);
- DECLARE_ALIGNED(16, short, zrun_zbin_boost_uv[QINDEX_RANGE][16]);
MACROBLOCK mb;
VP9_COMMON common;
--- a/vp9/encoder/vp9_quantize.c
+++ b/vp9/encoder/vp9_quantize.c
@@ -21,8 +21,7 @@
extern int enc_debug;
#endif
-static void quantize(int16_t *zbin_boost_orig_ptr,
- int16_t *coeff_ptr, int n_coeffs, int skip_block,
+static void quantize(int16_t *coeff_ptr, int n_coeffs, int skip_block,
int16_t *zbin_ptr, int16_t *round_ptr, int16_t *quant_ptr,
uint8_t *quant_shift_ptr,
int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr,
@@ -31,8 +30,6 @@
int i, rc, eob;
int zbins[2], nzbins[2], zbin;
int x, y, z, sz;
- int zero_run = 0;
- int16_t *zbin_boost_ptr = zbin_boost_orig_ptr;
int zero_flag = n_coeffs;
vpx_memset(qcoeff_ptr, 0, n_coeffs*sizeof(int16_t));
@@ -65,8 +62,7 @@
rc = scan[i];
z = coeff_ptr[rc];
- zbin = (zbins[rc != 0] + zbin_boost_ptr[zero_run]);
- zero_run += (zero_run < 15);
+ zbin = (zbins[rc != 0]);
sz = (z >> 31); // sign of z
x = (z ^ sz) - sz;
@@ -81,7 +77,6 @@
if (y) {
eob = i; // last nonzero coeffs
- zero_run = 0; // set zero_run
}
}
}
@@ -90,8 +85,7 @@
}
// This function works well for large transform size.
-static void quantize_sparse(int16_t *zbin_boost_orig_ptr,
- int16_t *coeff_ptr, int n_coeffs, int skip_block,
+static void quantize_sparse(int16_t *coeff_ptr, int n_coeffs, int skip_block,
int16_t *zbin_ptr, int16_t *round_ptr,
int16_t *quant_ptr, uint8_t *quant_shift_ptr,
int16_t *qcoeff_ptr, int16_t *dqcoeff_ptr,
@@ -101,10 +95,7 @@
int i, rc, eob;
int zbins[2], nzbins[2], zbin;
int x, y, z, sz;
- int zero_run = 0;
- int16_t *zbin_boost_ptr = zbin_boost_orig_ptr;
int idx = 0;
- int pre_idx = 0;
vpx_memset(qcoeff_ptr, 0, n_coeffs*sizeof(int16_t));
vpx_memset(dqcoeff_ptr, 0, n_coeffs*sizeof(int16_t));
@@ -135,11 +126,8 @@
rc = scan[idx_arr[i]];
// Calculate ZBIN
- zero_run += idx_arr[i] - pre_idx;
- if(zero_run > 15) zero_run = 15;
- zbin = (zbins[rc != 0] + zbin_boost_ptr[zero_run]);
+ zbin = (zbins[rc != 0]);
- pre_idx = idx_arr[i];
z = coeff_ptr[rc] * 2;
sz = (z >> 31); // sign of z
x = (z ^ sz) - sz; // x = abs(z)
@@ -155,7 +143,6 @@
if (y) {
eob = idx_arr[i]; // last nonzero coeffs
- zero_run = -1; // set zero_run
}
}
}
@@ -189,8 +176,7 @@
// Save index of picked coefficient in pre-scan pass.
int idx_arr[1024];
- quantize_sparse(mb->plane[plane].zrun_zbin_boost,
- BLOCK_OFFSET(mb->plane[plane].coeff, block, 16),
+ quantize_sparse(BLOCK_OFFSET(mb->plane[plane].coeff, block, 16),
n_coeffs, mb->skip_block,
mb->plane[plane].zbin,
mb->plane[plane].round,
@@ -204,8 +190,7 @@
scan, idx_arr);
}
else {
- quantize(mb->plane[plane].zrun_zbin_boost,
- BLOCK_OFFSET(mb->plane[plane].coeff, block, 16),
+ quantize(BLOCK_OFFSET(mb->plane[plane].coeff, block, 16),
n_coeffs, mb->skip_block,
mb->plane[plane].zbin,
mb->plane[plane].round,
@@ -226,8 +211,7 @@
const struct plane_block_idx pb_idx = plane_block_idx(y_blocks, b_idx);
const int *pt_scan = get_scan_4x4(tx_type);
- quantize(mb->plane[pb_idx.plane].zrun_zbin_boost,
- BLOCK_OFFSET(mb->plane[pb_idx.plane].coeff, pb_idx.block, 16),
+ quantize(BLOCK_OFFSET(mb->plane[pb_idx.plane].coeff, pb_idx.block, 16),
16, mb->skip_block,
mb->plane[pb_idx.plane].zbin,
mb->plane[pb_idx.plane].round,
@@ -261,9 +245,6 @@
#endif
int q;
- static const int zbin_boost[16] = { 0, 0, 0, 8, 8, 8, 10, 12,
- 14, 16, 20, 24, 28, 32, 36, 40 };
-
for (q = 0; q < QINDEX_RANGE; q++) {
int qzbin_factor = (vp9_dc_quant(q, 0) < 148) ? 84 : 80;
int qrounding_factor = 48;
@@ -277,7 +258,6 @@
cpi->y_zbin[q][0] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
cpi->y_round[q][0] = (qrounding_factor * quant_val) >> 7;
cpi->common.y_dequant[q][0] = quant_val;
- cpi->zrun_zbin_boost_y[q][0] = (quant_val * zbin_boost[0]) >> 7;
quant_val = vp9_dc_quant(q, cpi->common.uv_dc_delta_q);
invert_quant(cpi->uv_quant[q] + 0, cpi->uv_quant_shift[q] + 0, quant_val);
@@ -284,7 +264,6 @@
cpi->uv_zbin[q][0] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
cpi->uv_round[q][0] = (qrounding_factor * quant_val) >> 7;
cpi->common.uv_dequant[q][0] = quant_val;
- cpi->zrun_zbin_boost_uv[q][0] = (quant_val * zbin_boost[0]) >> 7;
#if CONFIG_ALPHA
quant_val = vp9_dc_quant(q, cpi->common.a_dc_delta_q);
@@ -292,7 +271,6 @@
cpi->a_zbin[q][0] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
cpi->a_round[q][0] = (qrounding_factor * quant_val) >> 7;
cpi->common.a_dequant[q][0] = quant_val;
- cpi->zrun_zbin_boost_a[q][0] = (quant_val * zbin_boost[0]) >> 7;
#endif
quant_val = vp9_ac_quant(q, 0);
@@ -310,15 +288,11 @@
invert_quant(cpi->y_quant[q] + rc, cpi->y_quant_shift[q] + rc, quant_val);
cpi->y_zbin[q][rc] = ROUND_POWER_OF_TWO(qzbin_factor * quant_val, 7);
cpi->y_round[q][rc] = (qrounding_factor * quant_val) >> 7;
- cpi->zrun_zbin_boost_y[q][i] =
- ROUND_POWER_OF_TWO(quant_val * zbin_boost[i], 7);
invert_quant(cpi->uv_quant[q] + rc, cpi->uv_quant_shift[q] + rc,
quant_uv_val);
cpi->uv_zbin[q][rc] = ROUND_POWER_OF_TWO(qzbin_factor * quant_uv_val, 7);
cpi->uv_round[q][rc] = (qrounding_factor * quant_uv_val) >> 7;
- cpi->zrun_zbin_boost_uv[q][i] =
- ROUND_POWER_OF_TWO(quant_uv_val * zbin_boost[i], 7);
#if CONFIG_ALPHA
invert_quant(cpi->a_quant[q] + rc, cpi->a_quant_shift[q] + rc,
@@ -326,8 +300,6 @@
cpi->a_zbin[q][rc] =
ROUND_POWER_OF_TWO(qzbin_factor * quant_alpha_val, 7);
cpi->a_round[q][rc] = (qrounding_factor * quant_alpha_val) >> 7;
- cpi->zrun_zbin_boost_a[q][i] =
- ROUND_POWER_OF_TWO(quant_alpha_val * zbin_boost[i], 7);
#endif
}
}
@@ -348,7 +320,6 @@
x->plane[0].quant_shift = cpi->y_quant_shift[qindex];
x->plane[0].zbin = cpi->y_zbin[qindex];
x->plane[0].round = cpi->y_round[qindex];
- x->plane[0].zrun_zbin_boost = cpi->zrun_zbin_boost_y[qindex];
x->plane[0].zbin_extra = (int16_t)zbin_extra;
x->e_mbd.plane[0].dequant = cpi->common.y_dequant[qindex];
@@ -361,7 +332,6 @@
x->plane[i].quant_shift = cpi->uv_quant_shift[qindex];
x->plane[i].zbin = cpi->uv_zbin[qindex];
x->plane[i].round = cpi->uv_round[qindex];
- x->plane[i].zrun_zbin_boost = cpi->zrun_zbin_boost_uv[qindex];
x->plane[i].zbin_extra = (int16_t)zbin_extra;
x->e_mbd.plane[i].dequant = cpi->common.uv_dequant[qindex];
}
@@ -371,7 +341,6 @@
x->plane[3].quant_shift = cpi->a_quant_shift[qindex];
x->plane[3].zbin = cpi->a_zbin[qindex];
x->plane[3].round = cpi->a_round[qindex];
- x->plane[3].zrun_zbin_boost = cpi->zrun_zbin_boost_a[qindex];
x->plane[3].zbin_extra = (int16_t)zbin_extra;
x->e_mbd.plane[3].dequant = cpi->common.a_dequant[qindex];
#endif
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -283,15 +283,17 @@
}
int64_t vp9_block_error_c(int16_t *coeff, int16_t *dqcoeff,
- intptr_t block_size) {
+ intptr_t block_size, int64_t *ssz) {
int i;
- int64_t error = 0;
+ int64_t error = 0, sqcoeff = 0;
for (i = 0; i < block_size; i++) {
int this_diff = coeff[i] - dqcoeff[i];
error += (unsigned)this_diff * this_diff;
+ sqcoeff += (unsigned) coeff[i] * coeff[i];
}
+ *ssz = sqcoeff;
return error;
}
@@ -501,27 +503,31 @@
}
static int64_t block_error_sby(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize,
- int shift) {
+ int shift, int64_t *sse) {
struct macroblockd_plane *p = &x->e_mbd.plane[0];
const int bw = plane_block_width(bsize, p);
const int bh = plane_block_height(bsize, p);
- return vp9_block_error(x->plane[0].coeff, x->e_mbd.plane[0].dqcoeff,
- bw * bh) >> shift;
+ int64_t e = vp9_block_error(x->plane[0].coeff, x->e_mbd.plane[0].dqcoeff,
+ bw * bh, sse) >> shift;
+ *sse >>= shift;
+ return e;
}
static int64_t block_error_sbuv(MACROBLOCK *x, BLOCK_SIZE_TYPE bsize,
- int shift) {
- int64_t sum = 0;
+ int shift, int64_t *sse) {
+ int64_t sum = 0, this_sse;
int plane;
+ *sse = 0;
for (plane = 1; plane < MAX_MB_PLANE; plane++) {
struct macroblockd_plane *p = &x->e_mbd.plane[plane];
const int bw = plane_block_width(bsize, p);
const int bh = plane_block_height(bsize, p);
sum += vp9_block_error(x->plane[plane].coeff, x->e_mbd.plane[plane].dqcoeff,
- bw * bh);
+ bw * bh, &this_sse);
+ *sse += this_sse;
}
-
+ *sse >>= shift;
return sum >> shift;
}
@@ -581,7 +587,7 @@
static void super_block_yrd_for_txfm(VP9_COMMON *const cm, MACROBLOCK *x,
int *rate, int64_t *distortion,
- int *skippable,
+ int *skippable, int64_t *sse,
BLOCK_SIZE_TYPE bsize, TX_SIZE tx_size) {
MACROBLOCKD *const xd = &x->e_mbd;
xd->mode_info_context->mbmi.txfm_size = tx_size;
@@ -591,7 +597,7 @@
else
vp9_xform_quant_sby(cm, x, bsize);
- *distortion = block_error_sby(x, bsize, tx_size == TX_32X32 ? 0 : 2);
+ *distortion = block_error_sby(x, bsize, tx_size == TX_32X32 ? 0 : 2, sse);
*rate = rdcost_plane(cm, x, 0, bsize, tx_size);
*skippable = vp9_sby_is_skippable(xd, bsize);
}
@@ -598,11 +604,11 @@
static void super_block_yrd(VP9_COMP *cpi,
MACROBLOCK *x, int *rate, int64_t *distortion,
- int *skip, BLOCK_SIZE_TYPE bs,
+ int *skip, int64_t *psse, BLOCK_SIZE_TYPE bs,
int64_t txfm_cache[NB_TXFM_MODES]) {
VP9_COMMON *const cm = &cpi->common;
int r[TX_SIZE_MAX_SB][2], s[TX_SIZE_MAX_SB];
- int64_t d[TX_SIZE_MAX_SB];
+ int64_t d[TX_SIZE_MAX_SB], sse[TX_SIZE_MAX_SB];
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
@@ -621,25 +627,27 @@
mbmi->txfm_size = TX_4X4;
}
vpx_memset(txfm_cache, 0, NB_TXFM_MODES * sizeof(int64_t));
- super_block_yrd_for_txfm(cm, x, rate, distortion, skip, bs,
+ super_block_yrd_for_txfm(cm, x, rate, distortion, skip, &sse[0], bs,
mbmi->txfm_size);
return;
}
if (bs >= BLOCK_SIZE_SB32X32)
super_block_yrd_for_txfm(cm, x, &r[TX_32X32][0], &d[TX_32X32], &s[TX_32X32],
- bs, TX_32X32);
+ &sse[TX_32X32], bs, TX_32X32);
if (bs >= BLOCK_SIZE_MB16X16)
super_block_yrd_for_txfm(cm, x, &r[TX_16X16][0], &d[TX_16X16], &s[TX_16X16],
- bs, TX_16X16);
- super_block_yrd_for_txfm(cm, x, &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8], bs,
- TX_8X8);
- super_block_yrd_for_txfm(cm, x, &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4], bs,
- TX_4X4);
+ &sse[TX_16X16], bs, TX_16X16);
+ super_block_yrd_for_txfm(cm, x, &r[TX_8X8][0], &d[TX_8X8], &s[TX_8X8],
+ &sse[TX_8X8], bs, TX_8X8);
+ super_block_yrd_for_txfm(cm, x, &r[TX_4X4][0], &d[TX_4X4], &s[TX_4X4],
+ &sse[TX_4X4], bs, TX_4X4);
choose_txfm_size_from_rd(cpi, x, r, rate, d, distortion, s,
skip, txfm_cache,
TX_32X32 - (bs < BLOCK_SIZE_SB32X32)
- (bs < BLOCK_SIZE_MB16X16));
+ if (psse)
+ *psse = sse[mbmi->txfm_size];
}
static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
@@ -688,6 +696,8 @@
for (idy = 0; idy < bh; ++idy) {
for (idx = 0; idx < bw; ++idx) {
+ int64_t ssz;
+
block = ib + idy * 2 + idx;
xd->mode_info_context->bmi[block].as_mode.first = mode;
src = raster_block_offset_uint8(xd, BLOCK_SIZE_SB8X8, 0, block,
@@ -718,7 +728,8 @@
ratey += cost_coeffs(cm, x, 0, block, PLANE_TYPE_Y_WITH_DC,
tempa + idx, templ + idy, TX_4X4, 16);
distortion += vp9_block_error(coeff, BLOCK_OFFSET(pd->dqcoeff,
- block, 16), 16) >> 2;
+ block, 16),
+ 16, &ssz) >> 2;
if (best_tx_type != DCT_DCT)
vp9_short_iht4x4_add(BLOCK_OFFSET(pd->dqcoeff, block, 16),
@@ -881,7 +892,7 @@
}
x->e_mbd.mode_info_context->mbmi.mode = mode;
- super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s,
+ super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion, &s, NULL,
bsize, local_txfm_cache);
this_rate = this_rate_tokenonly + bmode_costs[mode];
@@ -914,15 +925,18 @@
static void super_block_uvrd_for_txfm(VP9_COMMON *const cm, MACROBLOCK *x,
int *rate, int64_t *distortion,
- int *skippable, BLOCK_SIZE_TYPE bsize,
+ int *skippable, int64_t *sse,
+ BLOCK_SIZE_TYPE bsize,
TX_SIZE uv_tx_size) {
MACROBLOCKD *const xd = &x->e_mbd;
+ int64_t dummy;
if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME)
vp9_encode_intra_block_uv(cm, x, bsize);
else
vp9_xform_quant_sbuv(cm, x, bsize);
- *distortion = block_error_sbuv(x, bsize, uv_tx_size == TX_32X32 ? 0 : 2);
+ *distortion = block_error_sbuv(x, bsize, uv_tx_size == TX_32X32 ? 0 : 2,
+ sse ? sse : &dummy);
*rate = rdcost_uv(cm, x, bsize, uv_tx_size);
*skippable = vp9_sbuv_is_skippable(xd, bsize);
}
@@ -929,7 +943,7 @@
static void super_block_uvrd(VP9_COMMON *const cm, MACROBLOCK *x,
int *rate, int64_t *distortion, int *skippable,
- BLOCK_SIZE_TYPE bsize) {
+ int64_t *sse, BLOCK_SIZE_TYPE bsize) {
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mode_info_context->mbmi;
TX_SIZE uv_txfm_size = get_uv_tx_size(mbmi);
@@ -937,7 +951,7 @@
if (mbmi->ref_frame[0] > INTRA_FRAME)
vp9_subtract_sbuv(x, bsize);
- super_block_uvrd_for_txfm(cm, x, rate, distortion, skippable, bsize,
+ super_block_uvrd_for_txfm(cm, x, rate, distortion, skippable, sse, bsize,
uv_txfm_size);
}
@@ -954,7 +968,7 @@
for (mode = DC_PRED; mode <= TM_PRED; mode++) {
x->e_mbd.mode_info_context->mbmi.uv_mode = mode;
super_block_uvrd(&cpi->common, x, &this_rate_tokenonly,
- &this_distortion, &s, bsize);
+ &this_distortion, &s, NULL, bsize);
this_rate = this_rate_tokenonly +
x->intra_uv_mode_cost[x->e_mbd.frame_type][mode];
this_rd = RDCOST(x->rdmult, x->rddiv, this_rate, this_distortion);
@@ -1151,6 +1165,8 @@
k = i;
for (idy = 0; idy < bh / 4; ++idy) {
for (idx = 0; idx < bw / 4; ++idx) {
+ int64_t ssz;
+
k += (idy * 2 + idx);
src_diff = raster_block_offset_int16(xd, BLOCK_SIZE_SB8X8, 0, k,
x->plane[0].src_diff);
@@ -1159,7 +1175,7 @@
x->quantize_b_4x4(x, k, DCT_DCT, 16);
thisdistortion += vp9_block_error(coeff,
BLOCK_OFFSET(xd->plane[0].dqcoeff,
- k, 16), 16);
+ k, 16), 16, &ssz);
thisrate += cost_coeffs(cm, x, 0, k, PLANE_TYPE_Y_WITH_DC,
ta + (k & 1),
tl + (k >> 1), TX_4X4, 16);
@@ -2238,7 +2254,8 @@
INTERPOLATIONFILTERTYPE *best_filter,
int_mv *frame_mv,
int mi_row, int mi_col,
- int_mv single_newmv[MAX_REF_FRAMES]) {
+ int_mv single_newmv[MAX_REF_FRAMES],
+ int64_t *psse) {
VP9_COMMON *cm = &cpi->common;
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
@@ -2467,9 +2484,10 @@
if (!x->skip) {
int skippable_y, skippable_uv;
+ int64_t sseuv = INT_MAX;
// Y cost and distortion
- super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y,
+ super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
bsize, txfm_cache);
*rate2 += *rate_y;
@@ -2476,8 +2494,9 @@
*distortion += *distortion_y;
super_block_uvrd(cm, x, rate_uv, distortion_uv,
- &skippable_uv, bsize);
+ &skippable_uv, &sseuv, bsize);
+ *psse += sseuv;
*rate2 += *rate_uv;
*distortion += *distortion_uv;
*skippable = skippable_y && skippable_uv;
@@ -2611,6 +2630,7 @@
int bws = (1 << bwsl) / 4; // mode_info step for subsize
int bhsl = b_height_log2(bsize);
int bhs = (1 << bhsl) / 4; // mode_info step for subsize
+ int best_skip2 = 0;
for (i = 0; i < 4; i++) {
int j;
@@ -2702,6 +2722,8 @@
int skippable;
int64_t txfm_cache[NB_TXFM_MODES];
int i;
+ int this_skip2 = 0;
+ int64_t total_sse = INT_MAX;
for (i = 0; i < NB_TXFM_MODES; ++i)
txfm_cache[i] = INT64_MAX;
@@ -2863,7 +2885,7 @@
txfm_cache[i] = txfm_cache[ONLY_4X4];
} else if (ref_frame == INTRA_FRAME) {
TX_SIZE uv_tx;
- super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
+ super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL,
bsize, txfm_cache);
uv_tx = mbmi->txfm_size;
@@ -2989,7 +3011,7 @@
BLOCK_SIZE_SB8X8);
vp9_subtract_sbuv(x, BLOCK_SIZE_SB8X8);
super_block_uvrd_for_txfm(cm, x, &rate_uv, &distortion_uv,
- &uv_skippable, BLOCK_SIZE_SB8X8, TX_4X4);
+ &uv_skippable, NULL, BLOCK_SIZE_SB8X8, TX_4X4);
rate2 += rate_uv;
distortion2 += distortion_uv;
skippable = skippable && uv_skippable;
@@ -3017,7 +3039,7 @@
&mode_excluded, &disable_skip,
&tmp_best_filter, frame_mv[this_mode],
mi_row, mi_col,
- single_newmv);
+ single_newmv, &total_sse);
if (this_rd == INT64_MAX)
continue;
}
@@ -3062,10 +3084,29 @@
rate2 += prob_skip_cost;
}
}
+ } else if (mb_skip_allowed && ref_frame != INTRA_FRAME &&
+ this_mode != SPLITMV) {
+ if (RDCOST(x->rdmult, x->rddiv, rate_y + rate_uv, distortion2) <
+ RDCOST(x->rdmult, x->rddiv, 0, total_sse)) {
+ // Add in the cost of the no skip flag.
+ int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob(cm, xd,
+ PRED_MBSKIP), 0);
+ rate2 += prob_skip_cost;
+ } else {
+ int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob(cm, xd,
+ PRED_MBSKIP), 1);
+ rate2 += prob_skip_cost;
+ distortion2 = total_sse;
+ assert(total_sse >= 0);
+ rate2 -= (rate_y + rate_uv);
+ rate_y = 0;
+ rate_uv = 0;
+ this_skip2 = 1;
+ }
} else if (mb_skip_allowed) {
// Add in the cost of the no skip flag.
int prob_skip_cost = vp9_cost_bit(vp9_get_pred_prob(cm, xd,
- PRED_MBSKIP), 0);
+ PRED_MBSKIP), 0);
rate2 += prob_skip_cost;
}
@@ -3119,6 +3160,7 @@
*returndistortion = distortion2;
best_rd = this_rd;
best_mbmode = *mbmi;
+ best_skip2 = this_skip2;
best_partition = *x->partition_info;
if (this_mode == I4X4_PRED || this_mode == SPLITMV)
@@ -3301,6 +3343,7 @@
// macroblock modes
*mbmi = best_mbmode;
+ x->skip |= best_skip2;
if (best_mbmode.ref_frame[0] == INTRA_FRAME &&
best_mbmode.sb_type < BLOCK_SIZE_SB8X8) {
for (i = 0; i < 4; i++)
--- a/vp9/encoder/x86/vp9_error_sse2.asm
+++ b/vp9/encoder/x86/vp9_error_sse2.asm
@@ -12,20 +12,22 @@
SECTION .text
-; void vp9_block_error(int16_t *coeff, int16_t *dqcoeff, intptr_t block_size)
+; int64_t vp9_block_error(int16_t *coeff, int16_t *dqcoeff, intptr_t block_size,
+; int64_t *ssz)
INIT_XMM sse2
-cglobal block_error, 3, 3, 6, uqc, dqc, size
- pxor m4, m4 ; accumulator
+cglobal block_error, 3, 3, 8, uqc, dqc, size, ssz
+ pxor m4, m4 ; sse accumulator
+ pxor m6, m6 ; ssz accumulator
pxor m5, m5 ; dedicated zero register
lea uqcq, [uqcq+sizeq*2]
lea dqcq, [dqcq+sizeq*2]
neg sizeq
.loop:
- mova m0, [uqcq+sizeq*2]
- mova m2, [dqcq+sizeq*2]
- mova m1, [uqcq+sizeq*2+mmsize]
- mova m3, [dqcq+sizeq*2+mmsize]
+ mova m2, [uqcq+sizeq*2]
+ mova m0, [dqcq+sizeq*2]
+ mova m3, [uqcq+sizeq*2+mmsize]
+ mova m1, [dqcq+sizeq*2+mmsize]
psubw m0, m2
psubw m1, m3
; individual errors are max. 15bit+sign, so squares are 30bit, and
@@ -32,25 +34,40 @@
; thus the sum of 2 should fit in a 31bit integer (+ unused sign bit)
pmaddwd m0, m0
pmaddwd m1, m1
+ pmaddwd m2, m2
+ pmaddwd m3, m3
; accumulate in 64bit
- punpckldq m2, m0, m5
+ punpckldq m7, m0, m5
punpckhdq m0, m5
- punpckldq m3, m1, m5
- punpckhdq m1, m5
- paddq m4, m2
+ paddq m4, m7
+ punpckldq m7, m1, m5
paddq m4, m0
- paddq m4, m3
+ punpckhdq m1, m5
+ paddq m4, m7
+ punpckldq m7, m2, m5
paddq m4, m1
+ punpckhdq m2, m5
+ paddq m6, m7
+ punpckldq m7, m3, m5
+ paddq m6, m2
+ punpckhdq m3, m5
+ paddq m6, m7
+ paddq m6, m3
add sizeq, mmsize
jl .loop
; accumulate horizontally and store in return value
movhlps m5, m4
+ movhlps m7, m6
paddq m4, m5
+ paddq m6, m7
%if ARCH_X86_64
movq rax, m4
+ movq [sszq], m6
%else
+ mov eax, sszm
pshufd m5, m4, 0x1
+ movq [eax], m6
movd eax, m4
movd edx, m5
%endif