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

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

Issue 812033011: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 5 years, 11 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_encodeframe.h ('k') | source/libvpx/vp9/encoder/vp9_encodemb.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/libvpx/vp9/encoder/vp9_encodeframe.c
===================================================================
--- source/libvpx/vp9/encoder/vp9_encodeframe.c (revision 293588)
+++ source/libvpx/vp9/encoder/vp9_encodeframe.c (working copy)
@@ -36,6 +36,7 @@
#include "vp9/encoder/vp9_encodeframe.h"
#include "vp9/encoder/vp9_encodemb.h"
#include "vp9/encoder/vp9_encodemv.h"
+#include "vp9/encoder/vp9_ethread.h"
#include "vp9/encoder/vp9_extend.h"
#include "vp9/encoder/vp9_pickmode.h"
#include "vp9/encoder/vp9_rd.h"
@@ -54,9 +55,6 @@
int mi_row, int mi_col, BLOCK_SIZE bsize,
PICK_MODE_CONTEXT *ctx);
-// Motion vector component magnitude threshold for defining fast motion.
-#define FAST_MOTION_MV_THRESH 24
-
// This is used as a reference when computing the source variance for the
// purposes of activity masking.
// Eventually this should be replaced by custom no-reference routines,
@@ -188,10 +186,10 @@
// Lighter version of set_offsets that only sets the mode info
// pointers.
-static INLINE void set_modeinfo_offsets(VP9_COMMON *const cm,
- MACROBLOCKD *const xd,
- int mi_row,
- int mi_col) {
+static INLINE void set_mode_info_offsets(VP9_COMMON *const cm,
+ MACROBLOCKD *const xd,
+ int mi_row,
+ int mi_col) {
const int idx_str = xd->mi_stride * mi_row + mi_col;
xd->mi = cm->mi + idx_str;
xd->mi[0].src_mi = &xd->mi[0];
@@ -209,7 +207,7 @@
set_skip_context(xd, mi_row, mi_col);
- set_modeinfo_offsets(cm, xd, mi_row, mi_col);
+ set_mode_info_offsets(cm, xd, mi_row, mi_col);
mbmi = &xd->mi[0].src_mi->mbmi;
@@ -269,9 +267,8 @@
int mi_row, int mi_col,
BLOCK_SIZE bsize) {
if (cpi->common.mi_cols > mi_col && cpi->common.mi_rows > mi_row) {
- set_modeinfo_offsets(&cpi->common, xd, mi_row, mi_col);
+ set_mode_info_offsets(&cpi->common, xd, mi_row, mi_col);
xd->mi[0].src_mi->mbmi.sb_type = bsize;
- duplicate_mode_info_in_sb(&cpi->common, xd, mi_row, mi_col, bsize);
}
}
@@ -278,7 +275,7 @@
typedef struct {
int64_t sum_square_error;
int64_t sum_error;
- int count;
+ int log2_count;
int variance;
} var;
@@ -327,7 +324,6 @@
static void tree_to_node(void *data, BLOCK_SIZE bsize, variance_node *node) {
int i;
node->part_variances = NULL;
- vpx_memset(node->split, 0, sizeof(node->split));
switch (bsize) {
case BLOCK_64X64: {
v64x64 *vt = (v64x64 *) data;
@@ -375,18 +371,18 @@
static void fill_variance(int64_t s2, int64_t s, int c, var *v) {
v->sum_square_error = s2;
v->sum_error = s;
- v->count = c;
- if (c > 0)
- v->variance = (int)(256 *
- (v->sum_square_error - v->sum_error * v->sum_error /
- v->count) / v->count);
- else
- v->variance = 0;
+ v->log2_count = c;
}
+static void get_variance(var *v) {
+ v->variance = (int)(256 * (v->sum_square_error -
+ ((v->sum_error * v->sum_error) >> v->log2_count)) >> v->log2_count);
+}
+
void sum_2_variances(const var *a, const var *b, var *r) {
+ assert(a->log2_count == b->log2_count);
fill_variance(a->sum_square_error + b->sum_square_error,
- a->sum_error + b->sum_error, a->count + b->count, r);
+ a->sum_error + b->sum_error, a->log2_count + 1, r);
}
static void fill_variance_tree(void *data, BLOCK_SIZE bsize) {
@@ -424,8 +420,9 @@
if (cm->frame_type == KEY_FRAME) {
bsize_ref = BLOCK_8X8;
- // Choose lower thresholds for key frame variance to favor split.
- threshold_bsize_ref = threshold >> 1;
+ // Choose lower thresholds for key frame variance to favor split, but keep
+ // threshold for splitting to 4x4 block still fairly high for now.
+ threshold_bsize_ref = threshold << 2;
threshold_low = threshold >> 2;
}
@@ -433,6 +430,7 @@
// variance is below threshold, otherwise split will be selected.
// No check for vert/horiz split as too few samples for variance.
if (bsize == bsize_ref) {
+ get_variance(&vt.part_variances->none);
if (mi_col + block_width / 2 < cm->mi_cols &&
mi_row + block_height / 2 < cm->mi_rows &&
vt.part_variances->none.variance < threshold_bsize_ref) {
@@ -441,6 +439,7 @@
}
return 0;
} else if (bsize > bsize_ref) {
+ get_variance(&vt.part_variances->none);
// For key frame, for bsize above 32X32, or very high variance, take split.
if (cm->frame_type == KEY_FRAME &&
(bsize > BLOCK_32X32 ||
@@ -454,24 +453,32 @@
set_block_size(cpi, xd, mi_row, mi_col, bsize);
return 1;
}
+
// Check vertical split.
- if (mi_row + block_height / 2 < cm->mi_rows &&
- vt.part_variances->vert[0].variance < threshold_low &&
- vt.part_variances->vert[1].variance < threshold_low) {
- BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
- set_block_size(cpi, xd, mi_row, mi_col, subsize);
- set_block_size(cpi, xd, mi_row, mi_col + block_width / 2, subsize);
- return 1;
+ if (mi_row + block_height / 2 < cm->mi_rows) {
+ get_variance(&vt.part_variances->vert[0]);
+ get_variance(&vt.part_variances->vert[1]);
+ if (vt.part_variances->vert[0].variance < threshold_low &&
+ vt.part_variances->vert[1].variance < threshold_low) {
+ BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
+ set_block_size(cpi, xd, mi_row, mi_col, subsize);
+ set_block_size(cpi, xd, mi_row, mi_col + block_width / 2, subsize);
+ return 1;
+ }
}
// Check horizontal split.
- if (mi_col + block_width / 2 < cm->mi_cols &&
- vt.part_variances->horz[0].variance < threshold_low &&
- vt.part_variances->horz[1].variance < threshold_low) {
- BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
- set_block_size(cpi, xd, mi_row, mi_col, subsize);
- set_block_size(cpi, xd, mi_row + block_height / 2, mi_col, subsize);
- return 1;
+ if (mi_col + block_width / 2 < cm->mi_cols) {
+ get_variance(&vt.part_variances->horz[0]);
+ get_variance(&vt.part_variances->horz[1]);
+ if (vt.part_variances->horz[0].variance < threshold_low &&
+ vt.part_variances->horz[1].variance < threshold_low) {
+ BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
+ set_block_size(cpi, xd, mi_row, mi_col, subsize);
+ set_block_size(cpi, xd, mi_row + block_height / 2, mi_col, subsize);
+ return 1;
+ }
}
+
return 0;
}
return 0;
@@ -498,7 +505,6 @@
const struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf;
vp9_clear_system_state();
- vp9_zero(vt);
set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64);
if (xd->mb_to_right_edge < 0)
@@ -574,7 +580,7 @@
// If variance is based on 8x8 downsampling, we stop here and have
// one sample for 8x8 block (so use 1 for count in fill_variance),
// which of course means variance = 0 for 8x8 block.
- fill_variance(sse, sum, 1, &vst->split[k].part_variances.none);
+ fill_variance(sse, sum, 0, &vst->split[k].part_variances.none);
} else {
// For key frame, go down to 4x4.
v8x8 *vst2 = &vst->split[k];
@@ -584,7 +590,16 @@
unsigned int sse = 0;
int sum = 0;
if (x4_idx < pixels_wide && y4_idx < pixels_high) {
+#if CONFIG_VP9_HIGHBITDEPTH
+ int s_avg;
+ if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
+ s_avg = vp9_highbd_avg_4x4(s + y4_idx * sp + x4_idx, sp);
+ } else {
+ s_avg = vp9_avg_4x4(s + y4_idx * sp + x4_idx, sp);
+ }
+#else
int s_avg = vp9_avg_4x4(s + y4_idx * sp + x4_idx, sp);
+#endif
// For key frame, reference is set to 128.
sum = s_avg - 128;
sse = sum * sum;
@@ -592,7 +607,7 @@
// If variance is based on 4x4 downsampling, we stop here and have
// one sample for 4x4 block (so use 1 for count in fill_variance),
// which of course means variance = 0 for 4x4 block.
- fill_variance(sse, sum, 1, &vst2->split[m].part_variances.none);
+ fill_variance(sse, sum, 0, &vst2->split[m].part_variances.none);
}
}
}
@@ -638,8 +653,6 @@
for (k = 0; k < 4; ++k) {
const int x8_idx = (k & 1);
const int y8_idx = (k >> 1);
- // TODO(marpan): Allow for setting 4x4 partition on key frame.
- /*
if (cm->frame_type == KEY_FRAME) {
if (!set_vt_partitioning(cpi, xd,
&vt.split[i].split[j].split[k],
@@ -652,12 +665,11 @@
BLOCK_4X4);
}
} else {
- */
set_block_size(cpi, xd,
(mi_row + y32_idx + y16_idx + y8_idx),
(mi_col + x32_idx + x16_idx + x8_idx),
BLOCK_8X8);
- // }
+ }
}
}
}
@@ -700,7 +712,7 @@
mi_addr->src_mi = mi_addr;
// If segmentation in use
- if (seg->enabled && output_enabled) {
+ if (seg->enabled) {
// For in frame complexity AQ copy the segment id from the segment map.
if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
const uint8_t *const map = seg->update_map ? cpi->segmentation_map
@@ -863,6 +875,18 @@
vp9_rd_cost_init(rd_cost);
}
+static int set_segment_rdmult(VP9_COMP *const cpi,
+ MACROBLOCK *const x,
+ int8_t segment_id) {
+ int segment_qindex;
+ VP9_COMMON *const cm = &cpi->common;
+ vp9_init_plane_quantizers(cpi, x);
+ vp9_clear_system_state();
+ segment_qindex = vp9_get_qindex(&cm->seg, segment_id,
+ cm->base_qindex);
+ return vp9_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
+}
+
static void rd_pick_sb_modes(VP9_COMP *cpi,
TileDataEnc *tile_data,
MACROBLOCK *const x,
@@ -919,7 +943,6 @@
if (aq_mode == VARIANCE_AQ) {
const int energy = bsize <= BLOCK_16X16 ? x->mb_energy
: vp9_block_energy(cpi, x, bsize);
- int segment_qindex;
if (cm->frame_type == KEY_FRAME ||
cpi->refresh_alt_ref_frame ||
(cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref)) {
@@ -929,18 +952,9 @@
: cm->last_frame_seg_map;
mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
}
- vp9_init_plane_quantizers(cpi, x);
- vp9_clear_system_state();
- segment_qindex = vp9_get_qindex(&cm->seg, mbmi->segment_id,
- cm->base_qindex);
- x->rdmult = vp9_compute_rd_mult(cpi, segment_qindex + cm->y_dc_delta_q);
+ x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
} else if (aq_mode == COMPLEXITY_AQ) {
- const int mi_offset = mi_row * cm->mi_cols + mi_col;
- unsigned char complexity = cpi->complexity_map[mi_offset];
- const int is_edge = (mi_row <= 1) || (mi_row >= (cm->mi_rows - 2)) ||
- (mi_col <= 1) || (mi_col >= (cm->mi_cols - 2));
- if (!is_edge && (complexity > 128))
- x->rdmult += ((x->rdmult * (complexity - 128)) / 256);
+ x->rdmult = set_segment_rdmult(cpi, x, mbmi->segment_id);
} else if (aq_mode == CYCLIC_REFRESH_AQ) {
const uint8_t *const map = cm->seg.update_map ? cpi->segmentation_map
: cm->last_frame_seg_map;
@@ -967,6 +981,16 @@
}
}
+
+ // Examine the resulting rate and for AQ mode 2 make a segment choice.
+ if ((rd_cost->rate != INT_MAX) &&
+ (aq_mode == COMPLEXITY_AQ) && (bsize >= BLOCK_16X16) &&
+ (cm->frame_type == KEY_FRAME ||
+ cpi->refresh_alt_ref_frame ||
+ (cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
+ vp9_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
+ }
+
x->rdmult = orig_rdmult;
// TODO(jingning) The rate-distortion optimization flow needs to be
@@ -983,22 +1007,20 @@
const MACROBLOCKD *const xd = &x->e_mbd;
const MODE_INFO *const mi = xd->mi[0].src_mi;
const MB_MODE_INFO *const mbmi = &mi->mbmi;
+ const BLOCK_SIZE bsize = mbmi->sb_type;
if (!frame_is_intra_only(cm)) {
+ FRAME_COUNTS *const counts = td->counts;
+ const int inter_block = is_inter_block(mbmi);
const int seg_ref_active = vp9_segfeature_active(&cm->seg, mbmi->segment_id,
SEG_LVL_REF_FRAME);
if (!seg_ref_active) {
- FRAME_COUNTS *const counts = td->counts;
- const int inter_block = is_inter_block(mbmi);
-
counts->intra_inter[vp9_get_intra_inter_context(xd)][inter_block]++;
-
// If the segment reference feature is enabled we have only a single
// reference frame allowed for the segment so exclude it from
// the reference frame counts used to work out probabilities.
if (inter_block) {
const MV_REFERENCE_FRAME ref0 = mbmi->ref_frame[0];
-
if (cm->reference_mode == REFERENCE_MODE_SELECT)
counts->comp_inter[vp9_get_reference_mode_context(cm, xd)]
[has_second_ref(mbmi)]++;
@@ -1015,6 +1037,25 @@
}
}
}
+ if (inter_block &&
+ !vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
+ const int mode_ctx = mbmi->mode_context[mbmi->ref_frame[0]];
+ if (bsize >= BLOCK_8X8) {
+ const PREDICTION_MODE mode = mbmi->mode;
+ ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
+ } else {
+ const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
+ const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
+ int idx, idy;
+ for (idy = 0; idy < 2; idy += num_4x4_h) {
+ for (idx = 0; idx < 2; idx += num_4x4_w) {
+ const int j = idy * 2 + idx;
+ const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
+ ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
+ }
+ }
+ }
+ }
}
}
@@ -1164,7 +1205,7 @@
}
break;
default:
- assert("Invalid partition type.");
+ assert(0 && "Invalid partition type.");
break;
}
@@ -1357,11 +1398,8 @@
const int bh = num_8x8_blocks_high_lookup[mi->mbmi.sb_type];
const int x_mis = MIN(bw, cm->mi_cols - mi_col);
const int y_mis = MIN(bh, cm->mi_rows - mi_row);
- MV_REF *const frame_mvs =
- cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
- int w, h;
- *(xd->mi[0].src_mi) = ctx->mic;
+ xd->mi[0] = ctx->mic;
xd->mi[0].src_mi = &xd->mi[0];
if (seg->enabled && cpi->oxcf.aq_mode) {
@@ -1382,21 +1420,31 @@
if (is_inter_block(mbmi)) {
vp9_update_mv_count(td);
-
if (cm->interp_filter == SWITCHABLE) {
const int pred_ctx = vp9_get_pred_context_switchable_interp(xd);
++td->counts->switchable_interp[pred_ctx][mbmi->interp_filter];
}
+
+ if (mbmi->sb_type < BLOCK_8X8) {
+ mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
+ mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
+ }
}
- for (h = 0; h < y_mis; ++h) {
- MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
- for (w = 0; w < x_mis; ++w) {
- MV_REF *const mv = frame_mv + w;
- mv->ref_frame[0] = mi->src_mi->mbmi.ref_frame[0];
- mv->ref_frame[1] = mi->src_mi->mbmi.ref_frame[1];
- mv->mv[0].as_int = mi->src_mi->mbmi.mv[0].as_int;
- mv->mv[1].as_int = mi->src_mi->mbmi.mv[1].as_int;
+ if (cm->use_prev_frame_mvs) {
+ MV_REF *const frame_mvs =
+ cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
+ int w, h;
+
+ for (h = 0; h < y_mis; ++h) {
+ MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
+ for (w = 0; w < x_mis; ++w) {
+ MV_REF *const mv = frame_mv + w;
+ mv->ref_frame[0] = mi->src_mi->mbmi.ref_frame[0];
+ mv->ref_frame[1] = mi->src_mi->mbmi.ref_frame[1];
+ mv->mv[0].as_int = mi->src_mi->mbmi.mv[0].as_int;
+ mv->mv[1].as_int = mi->src_mi->mbmi.mv[1].as_int;
+ }
}
}
@@ -1491,7 +1539,7 @@
output_enabled, subsize, pc_tree->split[3]);
break;
default:
- assert("Invalid partition type.");
+ assert(0 && "Invalid partition type.");
break;
}
@@ -1761,14 +1809,6 @@
if (do_recon) {
int output_enabled = (bsize == BLOCK_64X64);
-
- // Check the projected output rate for this SB against it's target
- // and and if necessary apply a Q delta using segmentation to get
- // closer to the target.
- if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
- vp9_select_in_frame_q_segment(cpi, x, bsize, mi_row, mi_col,
- output_enabled, chosen_rdc.rate);
- }
encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled, bsize,
pc_tree);
}
@@ -2500,13 +2540,6 @@
if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
pc_tree->index != 3) {
int output_enabled = (bsize == BLOCK_64X64);
-
- // Check the projected output rate for this SB against it's target
- // and and if necessary apply a Q delta using segmentation to get
- // closer to the target.
- if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map)
- vp9_select_in_frame_q_segment(cpi, x, bsize, mi_row, mi_col,
- output_enabled, best_rdc.rate);
encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled,
bsize, pc_tree);
}
@@ -2662,6 +2695,15 @@
return cpi->common.tx_mode;
}
+static void hybrid_intra_mode_search(VP9_COMP *cpi, MACROBLOCK *const x,
+ RD_COST *rd_cost, BLOCK_SIZE bsize,
+ PICK_MODE_CONTEXT *ctx) {
+ if (bsize < BLOCK_16X16)
+ vp9_rd_pick_intra_mode_sb(cpi, x, rd_cost, bsize, ctx, INT64_MAX);
+ else
+ vp9_pick_intra_mode(cpi, x, rd_cost, bsize, ctx);
+}
+
static void nonrd_pick_sb_modes(VP9_COMP *cpi,
TileDataEnc *tile_data, MACROBLOCK *const x,
int mi_row, int mi_col, RD_COST *rd_cost,
@@ -2679,12 +2721,15 @@
x->rdmult = vp9_cyclic_refresh_get_rdmult(cpi->cyclic_refresh);
if (cm->frame_type == KEY_FRAME)
- vp9_pick_intra_mode(cpi, x, rd_cost, bsize, ctx);
+ hybrid_intra_mode_search(cpi, x, rd_cost, bsize, ctx);
else if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP))
set_mode_info_seg_skip(x, cm->tx_mode, rd_cost, bsize);
- else
+ else if (bsize >= BLOCK_8X8)
vp9_pick_inter_mode(cpi, x, tile_data, mi_row, mi_col,
rd_cost, bsize, ctx);
+ else
+ vp9_pick_inter_mode_sub8x8(cpi, x, tile_data, mi_row, mi_col,
+ rd_cost, bsize, ctx);
duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
@@ -2710,27 +2755,27 @@
switch (partition) {
case PARTITION_NONE:
- set_modeinfo_offsets(cm, xd, mi_row, mi_col);
+ set_mode_info_offsets(cm, xd, mi_row, mi_col);
*(xd->mi[0].src_mi) = pc_tree->none.mic;
duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
break;
case PARTITION_VERT:
- set_modeinfo_offsets(cm, xd, mi_row, mi_col);
+ set_mode_info_offsets(cm, xd, mi_row, mi_col);
*(xd->mi[0].src_mi) = pc_tree->vertical[0].mic;
duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
if (mi_col + hbs < cm->mi_cols) {
- set_modeinfo_offsets(cm, xd, mi_row, mi_col + hbs);
+ set_mode_info_offsets(cm, xd, mi_row, mi_col + hbs);
*(xd->mi[0].src_mi) = pc_tree->vertical[1].mic;
duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col + hbs, bsize);
}
break;
case PARTITION_HORZ:
- set_modeinfo_offsets(cm, xd, mi_row, mi_col);
+ set_mode_info_offsets(cm, xd, mi_row, mi_col);
*(xd->mi[0].src_mi) = pc_tree->horizontal[0].mic;
duplicate_mode_info_in_sb(cm, xd, mi_row, mi_col, bsize);
if (mi_row + hbs < cm->mi_rows) {
- set_modeinfo_offsets(cm, xd, mi_row + hbs, mi_col);
+ set_mode_info_offsets(cm, xd, mi_row + hbs, mi_col);
*(xd->mi[0].src_mi) = pc_tree->horizontal[1].mic;
duplicate_mode_info_in_sb(cm, xd, mi_row + hbs, mi_col, bsize);
}
@@ -2775,7 +2820,6 @@
int do_recon, int64_t best_rd,
PC_TREE *pc_tree) {
const SPEED_FEATURES *const sf = &cpi->sf;
- const VP9EncoderConfig *const oxcf = &cpi->oxcf;
VP9_COMMON *const cm = &cpi->common;
TileInfo *const tile_info = &tile_data->tile_info;
MACROBLOCK *const x = &td->mb;
@@ -3007,14 +3051,6 @@
if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX && do_recon) {
int output_enabled = (bsize == BLOCK_64X64);
-
- // Check the projected output rate for this SB against it's target
- // and and if necessary apply a Q delta using segmentation to get
- // closer to the target.
- if ((oxcf->aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
- vp9_select_in_frame_q_segment(cpi, x, bsize, mi_row, mi_col,
- output_enabled, best_rdc.rate);
- }
encode_sb_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled,
bsize, pc_tree);
}
@@ -3105,7 +3141,7 @@
if (mi_row + hbs < cm->mi_rows) {
pc_tree->horizontal[1].pred_pixel_ready = 1;
nonrd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col,
- &this_rdc, subsize, &pc_tree->horizontal[0]);
+ &this_rdc, subsize, &pc_tree->horizontal[1]);
pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0];
pc_tree->horizontal[1].skip = x->skip;
@@ -3147,7 +3183,7 @@
}
break;
default:
- assert("Invalid partition type.");
+ assert(0 && "Invalid partition type.");
break;
}
}
@@ -3164,7 +3200,7 @@
TOKENEXTRA **tp,
int mi_row, int mi_col,
BLOCK_SIZE bsize, int output_enabled,
- RD_COST *rd_cost, PC_TREE *pc_tree) {
+ RD_COST *dummy_cost, PC_TREE *pc_tree) {
VP9_COMMON *const cm = &cpi->common;
TileInfo *tile_info = &tile_data->tile_info;
MACROBLOCK *const x = &td->mb;
@@ -3173,9 +3209,7 @@
const int mis = cm->mi_stride;
PARTITION_TYPE partition;
BLOCK_SIZE subsize;
- RD_COST this_rdc;
- vp9_rd_cost_reset(&this_rdc);
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols)
return;
@@ -3190,7 +3224,7 @@
switch (partition) {
case PARTITION_NONE:
pc_tree->none.pred_pixel_ready = 1;
- nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, rd_cost,
+ nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost,
subsize, &pc_tree->none);
pc_tree->none.mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->none.skip_txfm[0] = x->skip_txfm[0];
@@ -3200,7 +3234,7 @@
break;
case PARTITION_VERT:
pc_tree->vertical[0].pred_pixel_ready = 1;
- nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, rd_cost,
+ nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost,
subsize, &pc_tree->vertical[0]);
pc_tree->vertical[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->vertical[0].skip_txfm[0] = x->skip_txfm[0];
@@ -3207,26 +3241,20 @@
pc_tree->vertical[0].skip = x->skip;
encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled,
subsize, &pc_tree->vertical[0]);
- if (mi_col + hbs < cm->mi_cols) {
+ if (mi_col + hbs < cm->mi_cols && bsize > BLOCK_8X8) {
pc_tree->vertical[1].pred_pixel_ready = 1;
nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + hbs,
- &this_rdc, subsize, &pc_tree->vertical[1]);
+ dummy_cost, subsize, &pc_tree->vertical[1]);
pc_tree->vertical[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->vertical[1].skip_txfm[0] = x->skip_txfm[0];
pc_tree->vertical[1].skip = x->skip;
encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col + hbs,
output_enabled, subsize, &pc_tree->vertical[1]);
-
- if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
- rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
- rd_cost->rate += this_rdc.rate;
- rd_cost->dist += this_rdc.dist;
- }
}
break;
case PARTITION_HORZ:
pc_tree->horizontal[0].pred_pixel_ready = 1;
- nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, rd_cost,
+ nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost,
subsize, &pc_tree->horizontal[0]);
pc_tree->horizontal[0].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->horizontal[0].skip_txfm[0] = x->skip_txfm[0];
@@ -3234,55 +3262,41 @@
encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col, output_enabled,
subsize, &pc_tree->horizontal[0]);
- if (mi_row + hbs < cm->mi_rows) {
+ if (mi_row + hbs < cm->mi_rows && bsize > BLOCK_8X8) {
pc_tree->horizontal[1].pred_pixel_ready = 1;
nonrd_pick_sb_modes(cpi, tile_data, x, mi_row + hbs, mi_col,
- &this_rdc, subsize, &pc_tree->horizontal[0]);
+ dummy_cost, subsize, &pc_tree->horizontal[1]);
pc_tree->horizontal[1].mic.mbmi = xd->mi[0].src_mi->mbmi;
pc_tree->horizontal[1].skip_txfm[0] = x->skip_txfm[0];
pc_tree->horizontal[1].skip = x->skip;
encode_b_rt(cpi, td, tile_info, tp, mi_row + hbs, mi_col,
output_enabled, subsize, &pc_tree->horizontal[1]);
-
- if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
- rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
- rd_cost->rate += this_rdc.rate;
- rd_cost->dist += this_rdc.dist;
- }
}
break;
case PARTITION_SPLIT:
subsize = get_subsize(bsize, PARTITION_SPLIT);
- nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
- subsize, output_enabled, rd_cost,
- pc_tree->split[0]);
- nonrd_use_partition(cpi, td, tile_data, mi + hbs, tp,
- mi_row, mi_col + hbs, subsize, output_enabled,
- &this_rdc, pc_tree->split[1]);
- if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
- rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
- rd_cost->rate += this_rdc.rate;
- rd_cost->dist += this_rdc.dist;
+ if (bsize == BLOCK_8X8) {
+ nonrd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, dummy_cost,
+ subsize, pc_tree->leaf_split[0]);
+ encode_b_rt(cpi, td, tile_info, tp, mi_row, mi_col,
+ output_enabled, subsize, pc_tree->leaf_split[0]);
+ } else {
+ nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
+ subsize, output_enabled, dummy_cost,
+ pc_tree->split[0]);
+ nonrd_use_partition(cpi, td, tile_data, mi + hbs, tp,
+ mi_row, mi_col + hbs, subsize, output_enabled,
+ dummy_cost, pc_tree->split[1]);
+ nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis, tp,
+ mi_row + hbs, mi_col, subsize, output_enabled,
+ dummy_cost, pc_tree->split[2]);
+ nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis + hbs, tp,
+ mi_row + hbs, mi_col + hbs, subsize, output_enabled,
+ dummy_cost, pc_tree->split[3]);
}
- nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis, tp,
- mi_row + hbs, mi_col, subsize, output_enabled,
- &this_rdc, pc_tree->split[2]);
- if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
- rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
- rd_cost->rate += this_rdc.rate;
- rd_cost->dist += this_rdc.dist;
- }
- nonrd_use_partition(cpi, td, tile_data, mi + hbs * mis + hbs, tp,
- mi_row + hbs, mi_col + hbs, subsize, output_enabled,
- &this_rdc, pc_tree->split[3]);
- if (this_rdc.rate != INT_MAX && this_rdc.dist != INT64_MAX &&
- rd_cost->rate != INT_MAX && rd_cost->dist != INT64_MAX) {
- rd_cost->rate += this_rdc.rate;
- rd_cost->dist += this_rdc.dist;
- }
break;
default:
- assert("Invalid partition type.");
+ assert(0 && "Invalid partition type.");
break;
}
@@ -3320,6 +3334,10 @@
// Set the partition type of the 64X64 block
switch (sf->partition_search_type) {
case VAR_BASED_PARTITION:
+ // TODO(jingning, marpan): The mode decision and encoding process
+ // support both intra and inter sub8x8 block coding for RTC mode.
+ // Tune the thresholds accordingly to use sub8x8 block coding for
+ // coding performance improvement.
choose_partitioning(cpi, tile_info, x, mi_row, mi_col);
nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col,
BLOCK_64X64, 1, &dummy_rdc, td->pc_root);
@@ -3488,7 +3506,7 @@
cm->show_frame;
}
-static void init_tile_data(VP9_COMP *cpi) {
+void vp9_init_tile_data(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
const int tile_cols = 1 << cm->log2_tile_cols;
const int tile_rows = 1 << cm->log2_tile_rows;
@@ -3526,6 +3544,29 @@
}
}
+void vp9_encode_tile(VP9_COMP *cpi, ThreadData *td,
+ int tile_row, int tile_col) {
+ VP9_COMMON *const cm = &cpi->common;
+ const int tile_cols = 1 << cm->log2_tile_cols;
+ TileDataEnc *this_tile =
+ &cpi->tile_data[tile_row * tile_cols + tile_col];
+ const TileInfo * const tile_info = &this_tile->tile_info;
+ TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
+ int mi_row;
+
+ for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
+ mi_row += MI_BLOCK_SIZE) {
+ if (cpi->sf.use_nonrd_pick_mode)
+ encode_nonrd_sb_row(cpi, td, this_tile, mi_row, &tok);
+ else
+ encode_rd_sb_row(cpi, td, this_tile, mi_row, &tok);
+ }
+ cpi->tok_count[tile_row][tile_col] =
+ (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
+ assert(tok - cpi->tile_tok[tile_row][tile_col] <=
+ allocated_tokens(*tile_info));
+}
+
static void encode_tiles(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
const int tile_cols = 1 << cm->log2_tile_cols;
@@ -3532,30 +3573,11 @@
const int tile_rows = 1 << cm->log2_tile_rows;
int tile_col, tile_row;
- init_tile_data(cpi);
+ vp9_init_tile_data(cpi);
- for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
- for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
- const TileInfo * const tile_info =
- &cpi->tile_data[tile_row * tile_cols + tile_col].tile_info;
- TOKENEXTRA *tok = cpi->tile_tok[tile_row][tile_col];
- int mi_row;
- TileDataEnc *this_tile =
- &cpi->tile_data[tile_row * tile_cols + tile_col];
-
- for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
- mi_row += MI_BLOCK_SIZE) {
- if (cpi->sf.use_nonrd_pick_mode)
- encode_nonrd_sb_row(cpi, &cpi->td, this_tile, mi_row, &tok);
- else
- encode_rd_sb_row(cpi, &cpi->td, this_tile, mi_row, &tok);
- }
- cpi->tok_count[tile_row][tile_col] =
- (unsigned int)(tok - cpi->tile_tok[tile_row][tile_col]);
- assert(tok - cpi->tile_tok[tile_row][tile_col] <=
- allocated_tokens(*tile_info));
- }
- }
+ for (tile_row = 0; tile_row < tile_rows; ++tile_row)
+ for (tile_col = 0; tile_col < tile_cols; ++tile_col)
+ vp9_encode_tile(cpi, &cpi->td, tile_row, tile_col);
}
#if CONFIG_FP_MB_STATS
@@ -3604,6 +3626,7 @@
cm->tx_mode = ALLOW_16X16;
}
+
#if CONFIG_VP9_HIGHBITDEPTH
if (cm->use_highbitdepth)
x->fwd_txm4x4 = xd->lossless ? vp9_highbd_fwht4x4 : vp9_highbd_fdct4x4;
@@ -3619,7 +3642,6 @@
if (xd->lossless) {
x->optimize = 0;
cm->lf.filter_level = 0;
- cpi->zbin_mode_boost_enabled = 0;
}
vp9_frame_init_quantizer(cpi);
@@ -3627,12 +3649,15 @@
vp9_initialize_rd_consts(cpi);
vp9_initialize_me_consts(cpi, cm->base_qindex);
init_encode_frame_mb_context(cpi);
- set_prev_mi(cm);
cm->use_prev_frame_mvs = !cm->error_resilient_mode &&
cm->width == cm->last_width &&
cm->height == cm->last_height &&
!cm->intra_only &&
cm->last_show_frame;
+ // Special case: set prev_mi to NULL when the previous mode info
+ // context cannot be used.
+ cm->prev_mi = cm->use_prev_frame_mvs ?
+ cm->prev_mip + cm->mi_stride + 1 : NULL;
x->quant_fp = cpi->sf.use_quant_fp;
vp9_zero(x->skip_txfm);
@@ -3667,7 +3692,11 @@
}
#endif
- encode_tiles(cpi);
+ // If allowed, encoding tiles in parallel with one thread handling one tile.
+ if (MIN(cpi->oxcf.max_threads, 1 << cm->log2_tile_cols) > 1)
+ vp9_encode_tiles_mt(cpi);
+ else
+ encode_tiles(cpi);
vpx_usec_timer_mark(&emr_timer);
cpi->time_encode_sb_row += vpx_usec_timer_elapsed(&emr_timer);
@@ -3716,9 +3745,9 @@
cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
(cm->ref_frame_sign_bias[ALTREF_FRAME] ==
cm->ref_frame_sign_bias[LAST_FRAME])) {
- cm->allow_comp_inter_inter = 0;
+ cpi->allow_comp_inter_inter = 0;
} else {
- cm->allow_comp_inter_inter = 1;
+ cpi->allow_comp_inter_inter = 1;
cm->comp_fixed_ref = ALTREF_FRAME;
cm->comp_var_ref[0] = LAST_FRAME;
cm->comp_var_ref[1] = GOLDEN_FRAME;
@@ -3742,7 +3771,7 @@
const int is_alt_ref = frame_type == ALTREF_FRAME;
/* prediction (compound, single or hybrid) mode selection */
- if (is_alt_ref || !cm->allow_comp_inter_inter)
+ if (is_alt_ref || !cpi->allow_comp_inter_inter)
cm->reference_mode = SINGLE_REFERENCE;
else if (mode_thrs[COMPOUND_REFERENCE] > mode_thrs[SINGLE_REFERENCE] &&
mode_thrs[COMPOUND_REFERENCE] >
@@ -3852,24 +3881,6 @@
++counts->uv_mode[y_mode][uv_mode];
}
-static int get_zbin_mode_boost(const MB_MODE_INFO *mbmi, int enabled) {
- if (enabled) {
- if (is_inter_block(mbmi)) {
- if (mbmi->mode == ZEROMV) {
- return mbmi->ref_frame[0] != LAST_FRAME ? GF_ZEROMV_ZBIN_BOOST
- : LF_ZEROMV_ZBIN_BOOST;
- } else {
- return mbmi->sb_type < BLOCK_8X8 ? SPLIT_MV_ZBIN_BOOST
- : MV_ZBIN_BOOST;
- }
- } else {
- return INTRA_ZBIN_BOOST;
- }
- } else {
- return 0;
- }
-}
-
static void encode_superblock(VP9_COMP *cpi, ThreadData *td,
TOKENEXTRA **t, int output_enabled,
int mi_row, int mi_col, BLOCK_SIZE bsize,
@@ -3905,12 +3916,6 @@
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
- // Experimental code. Special case for gf and arf zeromv modes.
- // Increase zbin size to suppress noise
- cpi->zbin_mode_boost = get_zbin_mode_boost(mbmi,
- cpi->zbin_mode_boost_enabled);
- vp9_update_zbin_extra(cpi, x);
-
if (!is_inter_block(mbmi)) {
int plane;
mbmi->skip = 1;
« no previous file with comments | « source/libvpx/vp9/encoder/vp9_encodeframe.h ('k') | source/libvpx/vp9/encoder/vp9_encodemb.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698