Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Unified Diff: source/libvpx/vp9/encoder/vp9_rdopt.c

Issue 478033002: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_rd.c ('k') | source/libvpx/vp9/encoder/vp9_segmentation.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/libvpx/vp9/encoder/vp9_rdopt.c
===================================================================
--- source/libvpx/vp9/encoder/vp9_rdopt.c (revision 290053)
+++ source/libvpx/vp9/encoder/vp9_rdopt.c (working copy)
@@ -171,15 +171,27 @@
int64_t dist_sum = 0;
const int ref = xd->mi[0]->mbmi.ref_frame[0];
unsigned int sse;
+ const int shift = 8;
for (i = 0; i < MAX_MB_PLANE; ++i) {
struct macroblock_plane *const p = &x->plane[i];
struct macroblockd_plane *const pd = &xd->plane[i];
const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
- (void) cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
- pd->dst.buf, pd->dst.stride, &sse);
+ const unsigned int var = cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
+ pd->dst.buf, pd->dst.stride,
+ &sse);
+ if (!x->select_tx_size) {
+ if (sse < p->quant_thred[0] >> shift)
+ x->skip_txfm[i] = 1;
+ else if (var < p->quant_thred[1] >> shift)
+ x->skip_txfm[i] = 2;
+ else
+ x->skip_txfm[i] = 0;
+ }
+
+ x->bsse[i] = sse;
if (i == 0)
x->pred_sse[ref] = sse;
@@ -357,12 +369,32 @@
if (args->skip)
return;
- if (!is_inter_block(mbmi))
+ if (!is_inter_block(mbmi)) {
vp9_encode_block_intra(x, plane, block, plane_bsize, tx_size, &mbmi->skip);
- else
- vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
+ dist_block(plane, block, tx_size, args);
+ } else {
+ if (x->skip_txfm[plane] == 0) {
+ // full forward transform and quantization
+ vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
+ dist_block(plane, block, tx_size, args);
+ } else if (x->skip_txfm[plane] == 2) {
+ // compute DC coefficient
+ int16_t *const coeff = BLOCK_OFFSET(x->plane[plane].coeff, block);
+ int16_t *const dqcoeff = BLOCK_OFFSET(xd->plane[plane].dqcoeff, block);
+ vp9_xform_quant_dc(x, plane, block, plane_bsize, tx_size);
+ args->sse = x->bsse[plane] << 4;
+ args->dist = args->sse;
+ if (!x->plane[plane].eobs[block])
+ args->dist = args->sse - ((coeff[0] * coeff[0] -
+ (coeff[0] - dqcoeff[0]) * (coeff[0] - dqcoeff[0])) >> 2);
+ } else {
+ // skip forward transform
+ x->plane[plane].eobs[block] = 0;
+ args->sse = x->bsse[plane] << 4;
+ args->dist = args->sse;
+ }
+ }
- dist_block(plane, block, tx_size, args);
rate_block(plane, block, plane_bsize, tx_size, args);
rd1 = RDCOST(x->rdmult, x->rddiv, args->rate, args->dist);
rd2 = RDCOST(x->rdmult, x->rddiv, 0, args->sse);
@@ -434,22 +466,26 @@
mbmi->tx_size = MIN(max_tx_size, largest_tx_size);
txfm_rd_in_plane(x, rate, distortion, skip,
- &sse[mbmi->tx_size], ref_best_rd, 0, bs,
+ sse, ref_best_rd, 0, bs,
mbmi->tx_size, cpi->sf.use_fast_coef_costing);
cpi->tx_stepdown_count[0]++;
}
static void choose_tx_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
- int (*r)[2], int *rate,
- int64_t *d, int64_t *distortion,
- int *s, int *skip,
+ int *rate,
+ int64_t *distortion,
+ int *skip,
+ int64_t *psse,
int64_t tx_cache[TX_MODES],
+ int64_t ref_best_rd,
BLOCK_SIZE bs) {
const TX_SIZE max_tx_size = max_txsize_lookup[bs];
VP9_COMMON *const cm = &cpi->common;
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
vp9_prob skip_prob = vp9_get_skip_prob(cm, xd);
+ int r[TX_SIZES][2], s[TX_SIZES];
+ int64_t d[TX_SIZES], sse[TX_SIZES];
int64_t rd[TX_SIZES][2] = {{INT64_MAX, INT64_MAX},
{INT64_MAX, INT64_MAX},
{INT64_MAX, INT64_MAX},
@@ -466,6 +502,9 @@
s1 = vp9_cost_bit(skip_prob, 1);
for (n = TX_4X4; n <= max_tx_size; n++) {
+ txfm_rd_in_plane(x, &r[n][0], &d[n], &s[n],
+ &sse[n], ref_best_rd, 0, bs, n,
+ cpi->sf.use_fast_coef_costing);
r[n][1] = r[n][0];
if (r[n][0] < INT_MAX) {
for (m = 0; m <= n - (n == max_tx_size); m++) {
@@ -496,6 +535,7 @@
*distortion = d[mbmi->tx_size];
*rate = r[mbmi->tx_size][cm->tx_mode == TX_MODE_SELECT];
*skip = s[mbmi->tx_size];
+ *psse = sse[mbmi->tx_size];
tx_cache[ONLY_4X4] = rd[TX_4X4][0];
tx_cache[ALLOW_8X8] = rd[TX_8X8][0];
@@ -522,65 +562,39 @@
int64_t *psse, BLOCK_SIZE bs,
int64_t txfm_cache[TX_MODES],
int64_t ref_best_rd) {
- int r[TX_SIZES][2], s[TX_SIZES];
- int64_t d[TX_SIZES], sse[TX_SIZES];
MACROBLOCKD *xd = &x->e_mbd;
- MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
- const TX_SIZE max_tx_size = max_txsize_lookup[bs];
- TX_SIZE tx_size;
- assert(bs == mbmi->sb_type);
+ assert(bs == xd->mi[0]->mbmi.sb_type);
vp9_subtract_plane(x, bs, 0);
if (cpi->sf.tx_size_search_method == USE_LARGESTALL || xd->lossless) {
vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
- choose_largest_tx_size(cpi, x, rate, distortion, skip, sse, ref_best_rd,
+ choose_largest_tx_size(cpi, x, rate, distortion, skip, psse, ref_best_rd,
bs);
- if (psse)
- *psse = sse[mbmi->tx_size];
- return;
+ } else {
+ choose_tx_size_from_rd(cpi, x, rate, distortion, skip, psse,
+ txfm_cache, ref_best_rd, bs);
}
-
- for (tx_size = TX_4X4; tx_size <= max_tx_size; ++tx_size)
- txfm_rd_in_plane(x, &r[tx_size][0], &d[tx_size], &s[tx_size],
- &sse[tx_size], ref_best_rd, 0, bs, tx_size,
- cpi->sf.use_fast_coef_costing);
- choose_tx_size_from_rd(cpi, x, r, rate, d, distortion, s,
- skip, txfm_cache, bs);
-
- if (psse)
- *psse = sse[mbmi->tx_size];
}
static void intra_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
int64_t *distortion, int *skip,
- int64_t *psse, BLOCK_SIZE bs,
+ BLOCK_SIZE bs,
int64_t txfm_cache[TX_MODES],
int64_t ref_best_rd) {
- int64_t sse[TX_SIZES];
MACROBLOCKD *xd = &x->e_mbd;
- MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
+ int64_t sse;
- assert(bs == mbmi->sb_type);
+ assert(bs == xd->mi[0]->mbmi.sb_type);
if (cpi->sf.tx_size_search_method != USE_FULL_RD || xd->lossless) {
vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
- choose_largest_tx_size(cpi, x, rate, distortion, skip, sse, ref_best_rd,
+ choose_largest_tx_size(cpi, x, rate, distortion, skip, &sse, ref_best_rd,
bs);
} else {
- int r[TX_SIZES][2], s[TX_SIZES];
- int64_t d[TX_SIZES];
- TX_SIZE tx_size;
- for (tx_size = TX_4X4; tx_size <= max_txsize_lookup[bs]; ++tx_size)
- txfm_rd_in_plane(x, &r[tx_size][0], &d[tx_size],
- &s[tx_size], &sse[tx_size],
- ref_best_rd, 0, bs, tx_size,
- cpi->sf.use_fast_coef_costing);
- choose_tx_size_from_rd(cpi, x, r, rate, d, distortion, s, skip, txfm_cache,
- bs);
+ choose_tx_size_from_rd(cpi, x, rate, distortion, skip, &sse,
+ txfm_cache, ref_best_rd, bs);
}
- if (psse)
- *psse = sse[mbmi->tx_size];
}
@@ -834,7 +848,7 @@
mic->mbmi.mode = mode;
intra_super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
- &s, NULL, bsize, local_tx_cache, best_rd);
+ &s, bsize, local_tx_cache, best_rd);
if (this_rate_tokenonly == INT_MAX)
continue;
@@ -2006,6 +2020,86 @@
}
}
+static void rd_encode_breakout_test(VP9_COMP *cpi, MACROBLOCK *x,
+ BLOCK_SIZE bsize, int *rate2,
+ int64_t *distortion, int64_t *distortion_uv,
+ int *disable_skip) {
+ VP9_COMMON *cm = &cpi->common;
+ MACROBLOCKD *xd = &x->e_mbd;
+ const BLOCK_SIZE y_size = get_plane_block_size(bsize, &xd->plane[0]);
+ const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]);
+ unsigned int var, sse;
+ // Skipping threshold for ac.
+ unsigned int thresh_ac;
+ // Skipping threshold for dc
+ unsigned int thresh_dc;
+
+ var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride,
+ xd->plane[0].dst.buf,
+ xd->plane[0].dst.stride, &sse);
+
+ if (x->encode_breakout > 0) {
+ // Set a maximum for threshold to avoid big PSNR loss in low bitrate
+ // case. Use extreme low threshold for static frames to limit skipping.
+ const unsigned int max_thresh = (cpi->allow_encode_breakout ==
+ ENCODE_BREAKOUT_LIMITED) ? 128 : 36000;
+ // The encode_breakout input
+ const unsigned int min_thresh =
+ MIN(((unsigned int)x->encode_breakout << 4), max_thresh);
+
+ // Calculate threshold according to dequant value.
+ thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9;
+ thresh_ac = clamp(thresh_ac, min_thresh, max_thresh);
+
+ // Adjust threshold according to partition size.
+ thresh_ac >>= 8 - (b_width_log2(bsize) +
+ b_height_log2(bsize));
+ thresh_dc = (xd->plane[0].dequant[0] * xd->plane[0].dequant[0] >> 6);
+ } else {
+ thresh_ac = 0;
+ thresh_dc = 0;
+ }
+
+ // Y skipping condition checking
+ if (sse < thresh_ac || sse == 0) {
+ // dc skipping checking
+ if ((sse - var) < thresh_dc || sse == var) {
+ unsigned int sse_u, sse_v;
+ unsigned int var_u, var_v;
+
+ var_u = cpi->fn_ptr[uv_size].vf(x->plane[1].src.buf,
+ x->plane[1].src.stride,
+ xd->plane[1].dst.buf,
+ xd->plane[1].dst.stride, &sse_u);
+
+ // U skipping condition checking
+ if ((sse_u * 4 < thresh_ac || sse_u == 0) &&
+ (sse_u - var_u < thresh_dc || sse_u == var_u)) {
+ var_v = cpi->fn_ptr[uv_size].vf(x->plane[2].src.buf,
+ x->plane[2].src.stride,
+ xd->plane[2].dst.buf,
+ xd->plane[2].dst.stride, &sse_v);
+
+ // V skipping condition checking
+ if ((sse_v * 4 < thresh_ac || sse_v == 0) &&
+ (sse_v - var_v < thresh_dc || sse_v == var_v)) {
+ x->skip = 1;
+
+ // The cost of skip bit needs to be added.
+ *rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
+
+ // Scaling factor for SSE from spatial domain to frequency domain
+ // is 16. Adjust distortion accordingly.
+ *distortion_uv = (sse_u + sse_v) << 4;
+ *distortion = (sse << 4) + *distortion_uv;
+
+ *disable_skip = 1;
+ }
+ }
+ }
+ }
+}
+
static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
BLOCK_SIZE bsize,
int64_t txfm_cache[],
@@ -2040,10 +2134,13 @@
int orig_dst_stride[MAX_MB_PLANE];
int rs = 0;
INTERP_FILTER best_filter = SWITCHABLE;
+ int skip_txfm[MAX_MB_PLANE] = {0};
+ int64_t bsse[MAX_MB_PLANE] = {0};
int bsl = mi_width_log2_lookup[bsize];
int pred_filter_search = cpi->sf.cb_pred_filter_search ?
- (((mi_row + mi_col) >> bsl)) & 0x01 : 0;
+ (((mi_row + mi_col) >> bsl) +
+ get_chessboard_index(cm->current_video_frame)) & 0x1 : 0;
if (pred_filter_search) {
INTERP_FILTER af = SWITCHABLE, lf = SWITCHABLE;
@@ -2201,6 +2298,8 @@
best_filter = mbmi->interp_filter;
if (cm->interp_filter == SWITCHABLE && i && !intpel_mv)
best_needs_copy = !best_needs_copy;
+ vpx_memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
+ vpx_memcpy(bsse, x->bsse, sizeof(bsse));
}
if ((cm->interp_filter == SWITCHABLE && newbest) ||
@@ -2248,83 +2347,14 @@
*rate2 += vp9_get_switchable_rate(cpi);
if (!is_comp_pred) {
- if (cpi->allow_encode_breakout) {
- const BLOCK_SIZE y_size = get_plane_block_size(bsize, &xd->plane[0]);
- const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]);
- unsigned int var, sse;
- // Skipping threshold for ac.
- unsigned int thresh_ac;
- // Skipping threshold for dc
- unsigned int thresh_dc;
+ if (cpi->allow_encode_breakout)
+ rd_encode_breakout_test(cpi, x, bsize, rate2, distortion, distortion_uv,
+ disable_skip);
+ }
- var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride,
- xd->plane[0].dst.buf,
- xd->plane[0].dst.stride, &sse);
+ vpx_memcpy(x->skip_txfm, skip_txfm, sizeof(skip_txfm));
+ vpx_memcpy(x->bsse, bsse, sizeof(bsse));
- if (x->encode_breakout > 0) {
- // Set a maximum for threshold to avoid big PSNR loss in low bitrate
- // case. Use extreme low threshold for static frames to limit skipping.
- const unsigned int max_thresh = (cpi->allow_encode_breakout ==
- ENCODE_BREAKOUT_LIMITED) ? 128 : 36000;
- // The encode_breakout input
- const unsigned int min_thresh =
- MIN(((unsigned int)x->encode_breakout << 4), max_thresh);
-
- // Calculate threshold according to dequant value.
- thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9;
- thresh_ac = clamp(thresh_ac, min_thresh, max_thresh);
-
- // Adjust threshold according to partition size.
- thresh_ac >>= 8 - (b_width_log2(bsize) +
- b_height_log2(bsize));
- thresh_dc = (xd->plane[0].dequant[0] * xd->plane[0].dequant[0] >> 6);
- } else {
- thresh_ac = 0;
- thresh_dc = 0;
- }
-
- // Y skipping condition checking
- if (sse < thresh_ac || sse == 0) {
- // dc skipping checking
- if ((sse - var) < thresh_dc || sse == var) {
- unsigned int sse_u, sse_v;
- unsigned int var_u, var_v;
-
- var_u = cpi->fn_ptr[uv_size].vf(x->plane[1].src.buf,
- x->plane[1].src.stride,
- xd->plane[1].dst.buf,
- xd->plane[1].dst.stride, &sse_u);
-
- // U skipping condition checking
- if ((sse_u * 4 < thresh_ac || sse_u == 0) &&
- (sse_u - var_u < thresh_dc || sse_u == var_u)) {
- var_v = cpi->fn_ptr[uv_size].vf(x->plane[2].src.buf,
- x->plane[2].src.stride,
- xd->plane[2].dst.buf,
- xd->plane[2].dst.stride, &sse_v);
-
- // V skipping condition checking
- if ((sse_v * 4 < thresh_ac || sse_v == 0) &&
- (sse_v - var_v < thresh_dc || sse_v == var_v)) {
- x->skip = 1;
-
- // The cost of skip bit needs to be added.
- *rate2 += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
-
- // Scaling factor for SSE from spatial domain to frequency domain
- // is 16. Adjust distortion accordingly.
- *distortion_uv = (sse_u + sse_v) << 4;
- *distortion = (sse << 4) + *distortion_uv;
-
- *disable_skip = 1;
- this_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
- }
- }
- }
- }
- }
- }
-
if (!x->skip) {
int skippable_y, skippable_uv;
int64_t sseuv = INT64_MAX;
@@ -2528,9 +2558,8 @@
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
x->pred_mv_sad[ref_frame] = INT_MAX;
if (cpi->ref_frame_flags & flag_list[ref_frame]) {
- setup_buffer_inter(cpi, x, tile,
- ref_frame, bsize, mi_row, mi_col,
- frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
+ setup_buffer_inter(cpi, x, tile, ref_frame, bsize, mi_row, mi_col,
+ frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
}
frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
frame_mv[ZEROMV][ref_frame].as_int = 0;
@@ -2636,6 +2665,7 @@
case NONE:
case MAX_REF_FRAMES:
assert(0 && "Invalid Reference frame");
+ break;
}
}
if (mode_skip_mask & (1 << mode_index))
@@ -2652,6 +2682,55 @@
continue;
second_ref_frame = vp9_mode_order[mode_index].ref_frame[1];
+ if (cpi->sf.motion_field_mode_search) {
+ const int mi_width = MIN(num_8x8_blocks_wide_lookup[bsize],
+ tile->mi_col_end - mi_col);
+ const int mi_height = MIN(num_8x8_blocks_high_lookup[bsize],
+ tile->mi_row_end - mi_row);
+ const int bsl = mi_width_log2(bsize);
+ int cb_partition_search_ctrl = (((mi_row + mi_col) >> bsl)
+ + get_chessboard_index(cm->current_video_frame)) & 0x1;
+ MB_MODE_INFO *ref_mbmi;
+ int const_motion = 1;
+ int skip_ref_frame = !cb_partition_search_ctrl;
+ MV_REFERENCE_FRAME rf = NONE;
+ int_mv ref_mv;
+ ref_mv.as_int = INVALID_MV;
+
+ if ((mi_row - 1) >= tile->mi_row_start) {
+ ref_mv = xd->mi[-xd->mi_stride]->mbmi.mv[0];
+ rf = xd->mi[-xd->mi_stride]->mbmi.ref_frame[0];
+ for (i = 0; i < mi_width; ++i) {
+ ref_mbmi = &xd->mi[-xd->mi_stride + i]->mbmi;
+ const_motion &= (ref_mv.as_int == ref_mbmi->mv[0].as_int) &&
+ (ref_frame == ref_mbmi->ref_frame[0]);
+ skip_ref_frame &= (rf == ref_mbmi->ref_frame[0]);
+ }
+ }
+
+ if ((mi_col - 1) >= tile->mi_col_start) {
+ if (ref_mv.as_int == INVALID_MV)
+ ref_mv = xd->mi[-1]->mbmi.mv[0];
+ if (rf == NONE)
+ rf = xd->mi[-1]->mbmi.ref_frame[0];
+ for (i = 0; i < mi_height; ++i) {
+ ref_mbmi = &xd->mi[i * xd->mi_stride - 1]->mbmi;
+ const_motion &= (ref_mv.as_int == ref_mbmi->mv[0].as_int) &&
+ (ref_frame == ref_mbmi->ref_frame[0]);
+ skip_ref_frame &= (rf == ref_mbmi->ref_frame[0]);
+ }
+ }
+
+ if (skip_ref_frame && this_mode != NEARESTMV && this_mode != NEWMV)
+ if (rf > INTRA_FRAME)
+ if (ref_frame != rf)
+ continue;
+
+ if (const_motion)
+ if (this_mode == NEARMV || this_mode == ZEROMV)
+ continue;
+ }
+
comp_pred = second_ref_frame > INTRA_FRAME;
if (comp_pred) {
if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
@@ -2722,7 +2801,7 @@
if (ref_frame == INTRA_FRAME) {
TX_SIZE uv_tx;
- intra_super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL,
+ intra_super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
bsize, tx_cache, best_rd);
if (rate_y == INT_MAX)
@@ -3233,6 +3312,7 @@
case NONE:
case MAX_REF_FRAMES:
assert(0 && "Invalid Reference frame");
+ break;
}
}
if (mode_skip_mask & (1 << ref_index))
@@ -3277,13 +3357,10 @@
vp9_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
continue;
- if (comp_pred) {
- mode_excluded = mode_excluded ? mode_excluded
- : cm->reference_mode == SINGLE_REFERENCE;
- } else if (ref_frame != INTRA_FRAME) {
- mode_excluded = mode_excluded ? mode_excluded
- : cm->reference_mode == COMPOUND_REFERENCE;
- }
+ if (comp_pred)
+ mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
+ else if (ref_frame != INTRA_FRAME)
+ mode_excluded = cm->reference_mode == COMPOUND_REFERENCE;
// If the segment reference frame feature is enabled....
// then do nothing if the current ref frame is not allowed..
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_rd.c ('k') | source/libvpx/vp9/encoder/vp9_segmentation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698