summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_bitstream.c12
-rw-r--r--vp9/encoder/vp9_encodeframe.c122
-rw-r--r--vp9/encoder/vp9_onyx_if.c95
-rw-r--r--vp9/encoder/vp9_onyx_int.h7
-rw-r--r--vp9/encoder/vp9_ratectrl.c9
-rw-r--r--vp9/encoder/vp9_rdopt.c164
6 files changed, 289 insertions, 120 deletions
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 83fa42169..146636469 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -321,12 +321,12 @@ static void encode_ref_frame(VP9_COMP *cpi, vp9_writer *bc) {
if (!seg_ref_active) {
// does the feature use compound prediction or not
// (if not specified at the frame/segment level)
- if (cm->comp_pred_mode == HYBRID_PREDICTION) {
+ if (cm->comp_pred_mode == REFERENCE_MODE_SELECT) {
vp9_write(bc, mi->ref_frame[1] > INTRA_FRAME,
vp9_get_pred_prob_comp_inter_inter(cm, xd));
} else {
assert((mi->ref_frame[1] <= INTRA_FRAME) ==
- (cm->comp_pred_mode == SINGLE_PREDICTION_ONLY));
+ (cm->comp_pred_mode == SINGLE_REFERENCE));
}
if (mi->ref_frame[1] > INTRA_FRAME) {
@@ -1359,8 +1359,8 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
if (cm->allow_comp_inter_inter) {
const int comp_pred_mode = cpi->common.comp_pred_mode;
- const int use_compound_pred = comp_pred_mode != SINGLE_PREDICTION_ONLY;
- const int use_hybrid_pred = comp_pred_mode == HYBRID_PREDICTION;
+ const int use_compound_pred = comp_pred_mode != SINGLE_REFERENCE;
+ const int use_hybrid_pred = comp_pred_mode == REFERENCE_MODE_SELECT;
vp9_write_bit(&header_bc, use_compound_pred);
if (use_compound_pred) {
@@ -1372,7 +1372,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
}
}
- if (cm->comp_pred_mode != COMP_PREDICTION_ONLY) {
+ if (cm->comp_pred_mode != COMPOUND_REFERENCE) {
for (i = 0; i < REF_CONTEXTS; i++) {
vp9_cond_prob_diff_update(&header_bc, &fc->single_ref_prob[i][0],
cpi->single_ref_count[i][0]);
@@ -1381,7 +1381,7 @@ static size_t write_compressed_header(VP9_COMP *cpi, uint8_t *data) {
}
}
- if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY)
+ if (cm->comp_pred_mode != SINGLE_REFERENCE)
for (i = 0; i < REF_CONTEXTS; i++)
vp9_cond_prob_diff_update(&header_bc, &fc->comp_ref_prob[i],
cpi->comp_ref_count[i]);
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 33839370a..045c4d4c2 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -360,6 +360,52 @@ void vp9_activity_masking(VP9_COMP *cpi, MACROBLOCK *x) {
adjust_act_zbin(cpi, x);
}
+// Select a segment for the current SB64
+static void select_in_frame_q_segment(VP9_COMP *cpi,
+ int mi_row, int mi_col,
+ int output_enabled, int projected_rate) {
+ VP9_COMMON * const cm = &cpi->common;
+ int target_rate = cpi->rc.sb64_target_rate << 8; // convert to bits << 8
+
+ const int mi_offset = mi_row * cm->mi_cols + mi_col;
+ const int bw = 1 << mi_width_log2(BLOCK_64X64);
+ const int bh = 1 << mi_height_log2(BLOCK_64X64);
+ const int xmis = MIN(cm->mi_cols - mi_col, bw);
+ const int ymis = MIN(cm->mi_rows - mi_row, bh);
+ int complexity_metric = 64;
+ int x, y;
+
+ unsigned char segment;
+
+ if (!output_enabled) {
+ segment = 0;
+ } else {
+ // Rate depends on fraction of a SB64 in frame (xmis * ymis / bw * bh).
+ // It is converted to bits * 256 units
+ target_rate = (cpi->rc.sb64_target_rate * xmis * ymis * 256) / (bw * bh);
+
+ if (projected_rate < (target_rate / 4)) {
+ segment = 2;
+ } else if (projected_rate < (target_rate / 2)) {
+ segment = 1;
+ } else {
+ segment = 0;
+ }
+
+ complexity_metric =
+ clamp((int)((projected_rate * 64) / target_rate), 16, 255);
+ }
+
+ // Fill in the entires in the segment map corresponding to this SB64
+ for (y = 0; y < ymis; y++) {
+ for (x = 0; x < xmis; x++) {
+ cpi->segmentation_map[mi_offset + y * cm->mi_cols + x] = segment;
+ cpi->complexity_map[mi_offset + y * cm->mi_cols + x] =
+ (unsigned char)complexity_metric;
+ }
+ }
+}
+
static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
BLOCK_SIZE bsize, int output_enabled) {
int i, x_idx, y;
@@ -383,6 +429,11 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
assert(mi->mbmi.ref_frame[1] < MAX_REF_FRAMES);
assert(mi->mbmi.sb_type == bsize);
+ // For in frame adaptive Q copy over the chosen segment id into the
+ // mode innfo context for the chosen mode / partition.
+ if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && output_enabled)
+ mi->mbmi.segment_id = xd->mi_8x8[0]->mbmi.segment_id;
+
*mi_addr = *mi;
max_plane = is_inter_block(mbmi) ? MAX_MB_PLANE : 1;
@@ -405,10 +456,12 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
for (y = 0; y < mi_height; y++)
for (x_idx = 0; x_idx < mi_width; x_idx++)
if ((xd->mb_to_right_edge >> (3 + MI_SIZE_LOG2)) + mi_width > x_idx
- && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y)
+ && (xd->mb_to_bottom_edge >> (3 + MI_SIZE_LOG2)) + mi_height > y) {
xd->mi_8x8[x_idx + y * mis] = mi_addr;
+ }
- if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
+ if ((cpi->oxcf.aq_mode == VARIANCE_AQ) ||
+ (cpi->oxcf.aq_mode == COMPLEXITY_AQ)) {
vp9_mb_init_quantizer(cpi, x);
}
@@ -478,9 +531,9 @@ static void update_state(VP9_COMP *cpi, PICK_MODE_CONTEXT *ctx,
++cm->counts.switchable_interp[ctx][mbmi->interp_filter];
}
- cpi->rd_comp_pred_diff[SINGLE_PREDICTION_ONLY] += ctx->single_pred_diff;
- cpi->rd_comp_pred_diff[COMP_PREDICTION_ONLY] += ctx->comp_pred_diff;
- cpi->rd_comp_pred_diff[HYBRID_PREDICTION] += ctx->hybrid_pred_diff;
+ cpi->rd_comp_pred_diff[SINGLE_REFERENCE] += ctx->single_pred_diff;
+ cpi->rd_comp_pred_diff[COMPOUND_REFERENCE] += ctx->comp_pred_diff;
+ cpi->rd_comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
cpi->rd_filter_diff[i] += ctx->best_filter_diff[i];
@@ -557,7 +610,7 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
/* segment ID */
if (seg->enabled) {
- if (!cpi->oxcf.aq_mode == VARIANCE_AQ) {
+ if (cpi->oxcf.aq_mode != VARIANCE_AQ) {
uint8_t *map = seg->update_map ? cpi->segmentation_map
: cm->last_frame_seg_map;
mbmi->segment_id = vp9_get_segment_id(cm, map, bsize, mi_row, mi_col);
@@ -653,6 +706,14 @@ static void pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
vp9_clear_system_state(); // __asm emms;
x->rdmult = round(x->rdmult * rdmult_ratio);
+ } else if (cpi->oxcf.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 == 0) || (mi_row == (cm->mi_rows - 1)) ||
+ (mi_col == 0) || (mi_col == (cm->mi_cols - 1));
+
+ if (!is_edge && (complexity > 128))
+ x->rdmult = x->rdmult + ((x->rdmult * (complexity - 128)) / 256);
}
// Find best coding mode & reconstruct the MB so it is available
@@ -697,7 +758,7 @@ static void update_stats(VP9_COMP *cpi) {
// reference frame allowed for the segment so exclude it from
// the reference frame counts used to work out probabilities.
if (is_inter_block(mbmi) && !seg_ref_active) {
- if (cm->comp_pred_mode == HYBRID_PREDICTION)
+ if (cm->comp_pred_mode == REFERENCE_MODE_SELECT)
cpi->comp_inter_count[vp9_get_pred_context_comp_inter_inter(cm, xd)]
[has_second_ref(mbmi)]++;
@@ -1261,8 +1322,19 @@ static void rd_use_partition(VP9_COMP *cpi,
if ( bsize == BLOCK_64X64)
assert(chosen_rate < INT_MAX && chosen_dist < INT_MAX);
- if (do_recon)
- encode_sb(cpi, tile, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize);
+ 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) {
+ select_in_frame_q_segment(cpi, mi_row, mi_col,
+ output_enabled, chosen_rate);
+ }
+
+ encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
+ }
*rate = chosen_rate;
*dist = chosen_dist;
@@ -1740,8 +1812,17 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
*rate = best_rate;
*dist = best_dist;
- if (best_rate < INT_MAX && best_dist < INT64_MAX && do_recon)
- encode_sb(cpi, tile, tp, mi_row, mi_col, bsize == BLOCK_64X64, bsize);
+ if (best_rate < INT_MAX && best_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 ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) {
+ select_in_frame_q_segment(cpi, mi_row, mi_col, output_enabled, best_rate);
+ }
+ encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize);
+ }
if (bsize == BLOCK_64X64) {
assert(tp_orig < *tp);
assert(best_rate < INT_MAX);
@@ -2234,18 +2315,18 @@ void vp9_encode_frame(VP9_COMP *cpi) {
/* prediction (compound, single or hybrid) mode selection */
if (frame_type == 3 || !cm->allow_comp_inter_inter)
- pred_type = SINGLE_PREDICTION_ONLY;
+ pred_type = SINGLE_REFERENCE;
else if (cpi->rd_prediction_type_threshes[frame_type][1]
> cpi->rd_prediction_type_threshes[frame_type][0]
&& cpi->rd_prediction_type_threshes[frame_type][1]
> cpi->rd_prediction_type_threshes[frame_type][2]
&& check_dual_ref_flags(cpi) && cpi->static_mb_pct == 100)
- pred_type = COMP_PREDICTION_ONLY;
+ pred_type = COMPOUND_REFERENCE;
else if (cpi->rd_prediction_type_threshes[frame_type][0]
> cpi->rd_prediction_type_threshes[frame_type][2])
- pred_type = SINGLE_PREDICTION_ONLY;
+ pred_type = SINGLE_REFERENCE;
else
- pred_type = HYBRID_PREDICTION;
+ pred_type = REFERENCE_MODE_SELECT;
/* filter type selection */
// FIXME(rbultje) for some odd reason, we often select smooth_filter
@@ -2282,7 +2363,7 @@ void vp9_encode_frame(VP9_COMP *cpi) {
cpi->common.mcomp_filter_type = filter_type;
encode_frame_internal(cpi);
- for (i = 0; i < NB_PREDICTION_TYPES; ++i) {
+ for (i = 0; i < REFERENCE_MODES; ++i) {
const int diff = (int) (cpi->rd_comp_pred_diff[i] / cpi->common.MBs);
cpi->rd_prediction_type_threshes[frame_type][i] += diff;
cpi->rd_prediction_type_threshes[frame_type][i] >>= 1;
@@ -2305,7 +2386,7 @@ void vp9_encode_frame(VP9_COMP *cpi) {
cpi->rd_tx_select_threshes[frame_type][i] /= 2;
}
- if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
+ if (cpi->common.comp_pred_mode == REFERENCE_MODE_SELECT) {
int single_count_zero = 0;
int comp_count_zero = 0;
@@ -2315,10 +2396,10 @@ void vp9_encode_frame(VP9_COMP *cpi) {
}
if (comp_count_zero == 0) {
- cpi->common.comp_pred_mode = SINGLE_PREDICTION_ONLY;
+ cpi->common.comp_pred_mode = SINGLE_REFERENCE;
vp9_zero(cpi->comp_inter_count);
} else if (single_count_zero == 0) {
- cpi->common.comp_pred_mode = COMP_PREDICTION_ONLY;
+ cpi->common.comp_pred_mode = COMPOUND_REFERENCE;
vp9_zero(cpi->comp_inter_count);
}
}
@@ -2415,7 +2496,8 @@ static void encode_superblock(VP9_COMP *cpi, TOKENEXTRA **t, int output_enabled,
const int mis = cm->mode_info_stride;
const int mi_width = num_8x8_blocks_wide_lookup[bsize];
const int mi_height = num_8x8_blocks_high_lookup[bsize];
- x->skip_recode = !x->select_txfm_size && mbmi->sb_type >= BLOCK_8X8;
+ x->skip_recode = !x->select_txfm_size && mbmi->sb_type >= BLOCK_8X8 &&
+ (cpi->oxcf.aq_mode != COMPLEXITY_AQ);
x->skip_optimize = ctx->is_coded;
ctx->is_coded = 1;
x->use_lp32x32fdct = cpi->sf.use_lp32x32fdct;
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index b1fa6865e..8b2765104 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -109,6 +109,9 @@ extern unsigned __int64 Sectionbits[500];
extern void vp9_init_quantizer(VP9_COMP *cpi);
+static const double in_frame_q_adj_ratio[MAX_SEGMENTS] =
+ {1.0, 1.5, 2.0, 1.0, 1.0, 1.0, 1.0, 1.0};
+
static INLINE void Scale2Ratio(int mode, int *hr, int *hs) {
switch (mode) {
case NORMAL:
@@ -192,6 +195,8 @@ static void dealloc_compressor_data(VP9_COMP *cpi) {
vpx_free(cpi->coding_context.last_frame_seg_map_copy);
cpi->coding_context.last_frame_seg_map_copy = 0;
+ vpx_free(cpi->complexity_map);
+ cpi->complexity_map = 0;
vpx_free(cpi->active_map);
cpi->active_map = 0;
@@ -243,6 +248,79 @@ int vp9_compute_qdelta(VP9_COMP *cpi, double qstart, double qtarget) {
return target_index - start_index;
}
+// Computes a q delta (in "q index" terms) to get from a starting q value
+// to a value that should equate to thegiven rate ratio.
+
+int vp9_compute_qdelta_by_rate(VP9_COMP *cpi,
+ double base_q_index, double rate_target_ratio) {
+ int i;
+ int base_bits_per_mb;
+ int target_bits_per_mb;
+ int target_index = cpi->rc.worst_quality;
+
+ // Make SURE use of floating point in this function is safe.
+ vp9_clear_system_state();
+
+ // Look up the current projected bits per block for the base index
+ base_bits_per_mb = vp9_bits_per_mb(cpi->common.frame_type,
+ base_q_index, 1.0);
+
+ // Find the target bits per mb based on the base value and given ratio.
+ target_bits_per_mb = rate_target_ratio * base_bits_per_mb;
+
+ // Convert the q target to an index
+ for (i = cpi->rc.best_quality; i < cpi->rc.worst_quality; i++) {
+ target_index = i;
+ if (vp9_bits_per_mb(cpi->common.frame_type,
+ i, 1.0) <= target_bits_per_mb )
+ break;
+ }
+
+ return target_index - base_q_index;
+}
+
+// This function sets up a set of segments with delta Q values around
+// the baseline frame quantizer.
+static void setup_in_frame_q_adj(VP9_COMP *cpi) {
+ VP9_COMMON *cm = &cpi->common;
+ struct segmentation *seg = &cm->seg;
+ // double q_ratio;
+ int segment;
+ int qindex_delta;
+
+ // Make SURE use of floating point in this function is safe.
+ vp9_clear_system_state();
+
+ if (cm->frame_type == KEY_FRAME ||
+ cpi->refresh_alt_ref_frame ||
+ (cpi->refresh_golden_frame && !cpi->is_src_frame_alt_ref)) {
+ // Clear down the segment map
+ vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
+
+ // Clear down the complexity map used for rd
+ vpx_memset(cpi->complexity_map, 0, cm->mi_rows * cm->mi_cols);
+
+ // Enable segmentation
+ vp9_enable_segmentation((VP9_PTR)cpi);
+ vp9_clearall_segfeatures(seg);
+
+ // Select delta coding method
+ seg->abs_delta = SEGMENT_DELTADATA;
+
+ // Segment 0 "Q" feature is disabled so it defaults to the baseline Q
+ vp9_disable_segfeature(seg, 0, SEG_LVL_ALT_Q);
+
+ // Use some of the segments for in frame Q adjustment
+ for (segment = 1; segment < 3; segment++) {
+ qindex_delta =
+ vp9_compute_qdelta_by_rate(cpi, cm->base_qindex,
+ in_frame_q_adj_ratio[segment]);
+ vp9_enable_segfeature(seg, segment, SEG_LVL_ALT_Q);
+ vp9_set_segdata(seg, segment, SEG_LVL_ALT_Q, qindex_delta);
+ }
+ }
+}
+
static void configure_static_seg_features(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
struct segmentation *seg = &cm->seg;
@@ -1446,6 +1524,11 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) {
CHECK_MEM_ERROR(cm, cpi->segmentation_map,
vpx_calloc(cm->mi_rows * cm->mi_cols, 1));
+ // Create a complexity map used for rd adjustment
+ CHECK_MEM_ERROR(cm, cpi->complexity_map,
+ vpx_calloc(cm->mi_rows * cm->mi_cols, 1));
+
+
// And a place holder structure is the coding context
// for use if we want to save and restore it
CHECK_MEM_ERROR(cm, cpi->coding_context.last_frame_seg_map_copy,
@@ -2630,8 +2713,12 @@ static void encode_with_recode_loop(VP9_COMP *cpi,
}
}
+ // Variance adaptive and in frame q adjustment experiments are mutually
+ // exclusive.
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
- vp9_vaq_frame_setup(cpi);
+ vp9_vaq_frame_setup(cpi);
+ } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
+ setup_in_frame_q_adj(cpi);
}
// transform / motion compensation build reconstruction frame
@@ -3615,8 +3702,12 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
VP9BORDERINPIXELS);
// Calculate scaling factors for each of the 3 available references
- for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i)
+ for (i = 0; i < ALLOWED_REFS_PER_FRAME; ++i) {
vp9_setup_scale_factors(cm, i);
+ if (vp9_is_scaled(&cm->active_ref_scale_comm[i]))
+ vp9_extend_frame_borders(&cm->yv12_fb[cm->active_ref_idx[i]],
+ cm->subsampling_x, cm->subsampling_y);
+ }
vp9_setup_interp_filters(&cpi->mb.e_mbd, DEFAULT_INTERP_FILTER, cm);
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index 54af75633..2774d951d 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -293,6 +293,7 @@ typedef struct {
// Rate targetting variables
int this_frame_target;
int projected_frame_size;
+ int sb64_target_rate;
int last_q[2]; // Separate values for Intra/Inter
int last_boosted_qindex; // Last boosted GF/KF/ARF q
@@ -431,8 +432,8 @@ typedef struct VP9_COMP {
int rd_thresh_sub8x8[MAX_SEGMENTS][BLOCK_SIZES][MAX_REFS];
int rd_thresh_freq_sub8x8[BLOCK_SIZES][MAX_REFS];
- int64_t rd_comp_pred_diff[NB_PREDICTION_TYPES];
- int64_t rd_prediction_type_threshes[4][NB_PREDICTION_TYPES];
+ int64_t rd_comp_pred_diff[REFERENCE_MODES];
+ int64_t rd_prediction_type_threshes[4][REFERENCE_MODES];
unsigned int intra_inter_count[INTRA_INTER_CONTEXTS][2];
unsigned int comp_inter_count[COMP_INTER_CONTEXTS][2];
unsigned int single_ref_count[REF_CONTEXTS][2][2];
@@ -516,6 +517,8 @@ typedef struct VP9_COMP {
// segment threashold for encode breakout
int segment_encode_breakout[MAX_SEGMENTS];
+ unsigned char *complexity_map;
+
unsigned char *active_map;
unsigned int active_map_enabled;
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 1293e860f..6e4c56c1a 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -242,6 +242,10 @@ static void calc_iframe_target_size(VP9_COMP *cpi) {
}
cpi->rc.this_frame_target = target;
+
+ // Target rate per SB64 (including partial SB64s.
+ cpi->rc.sb64_target_rate = (cpi->rc.this_frame_target * 64 * 64) /
+ (cpi->common.width * cpi->common.height);
}
@@ -269,6 +273,11 @@ static void calc_pframe_target_size(VP9_COMP *cpi) {
cpi->rc.this_frame_target = cpi->rc.per_frame_bandwidth;
}
+ // Target rate per SB64 (including partial SB64s.
+ cpi->rc.sb64_target_rate = (cpi->rc.this_frame_target * 64 * 64) /
+ (cpi->common.width * cpi->common.height);
+
+
// Check that the total sum of adjustments is not above the maximum allowed.
// That is, having allowed for the KF and GF penalties, we have not pushed
// the current inter-frame target too low. If the adjustment we apply here is
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index fde84298f..9fed2006e 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -588,8 +588,8 @@ static void rate_block(int plane, int block, BLOCK_SIZE plane_bsize,
args->scan, args->nb);
}
-static void block_yrd_txfm(int plane, int block, BLOCK_SIZE plane_bsize,
- TX_SIZE tx_size, void *arg) {
+static void block_rd_txfm(int plane, int block, BLOCK_SIZE plane_bsize,
+ TX_SIZE tx_size, void *arg) {
struct rdcost_block_args *args = arg;
MACROBLOCK *const x = args->x;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -698,7 +698,7 @@ static void txfm_rd_in_plane(MACROBLOCK *x,
rd_stack->nb = so->neighbors;
foreach_transformed_block_in_plane(xd, bsize, plane,
- block_yrd_txfm, rd_stack);
+ block_rd_txfm, rd_stack);
if (rd_stack->skip) {
*rate = INT_MAX;
*distortion = INT64_MAX;
@@ -731,6 +731,32 @@ static void choose_largest_txfm_size(VP9_COMP *cpi, MACROBLOCK *x,
cpi->tx_stepdown_count[0]++;
}
+static TX_SIZE select_tx_size(TX_MODE tx_mode, TX_SIZE max_tx_size,
+ int64_t rd[][2]) {
+ if (max_tx_size == TX_32X32 &&
+ (tx_mode == ALLOW_32X32 ||
+ (tx_mode == TX_MODE_SELECT &&
+ rd[TX_32X32][1] < rd[TX_16X16][1] &&
+ rd[TX_32X32][1] < rd[TX_8X8][1] &&
+ rd[TX_32X32][1] < rd[TX_4X4][1]))) {
+ return TX_32X32;
+ } else if (max_tx_size >= TX_16X16 &&
+ (tx_mode == ALLOW_16X16 ||
+ tx_mode == ALLOW_32X32 ||
+ (tx_mode == TX_MODE_SELECT &&
+ rd[TX_16X16][1] < rd[TX_8X8][1] &&
+ rd[TX_16X16][1] < rd[TX_4X4][1]))) {
+ return TX_16X16;
+ } else if (tx_mode == ALLOW_8X8 ||
+ tx_mode == ALLOW_16X16 ||
+ tx_mode == ALLOW_32X32 ||
+ (tx_mode == TX_MODE_SELECT && rd[TX_8X8][1] < rd[TX_4X4][1])) {
+ return TX_8X8;
+ } else {
+ return TX_4X4;
+ }
+}
+
static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
int (*r)[2], int *rate,
int64_t *d, int64_t *distortion,
@@ -777,27 +803,7 @@ static void choose_txfm_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
}
}
- if (max_tx_size == TX_32X32 &&
- (cm->tx_mode == ALLOW_32X32 ||
- (cm->tx_mode == TX_MODE_SELECT &&
- rd[TX_32X32][1] < rd[TX_16X16][1] && rd[TX_32X32][1] < rd[TX_8X8][1] &&
- rd[TX_32X32][1] < rd[TX_4X4][1]))) {
- mbmi->tx_size = TX_32X32;
- } else if (max_tx_size >= TX_16X16 &&
- (cm->tx_mode == ALLOW_16X16 ||
- cm->tx_mode == ALLOW_32X32 ||
- (cm->tx_mode == TX_MODE_SELECT &&
- rd[TX_16X16][1] < rd[TX_8X8][1] &&
- rd[TX_16X16][1] < rd[TX_4X4][1]))) {
- mbmi->tx_size = TX_16X16;
- } else if (cm->tx_mode == ALLOW_8X8 ||
- cm->tx_mode == ALLOW_16X16 ||
- cm->tx_mode == ALLOW_32X32 ||
- (cm->tx_mode == TX_MODE_SELECT && rd[TX_8X8][1] < rd[TX_4X4][1])) {
- mbmi->tx_size = TX_8X8;
- } else {
- mbmi->tx_size = TX_4X4;
- }
+ mbmi->tx_size = select_tx_size(cm->tx_mode, max_tx_size, rd);
*distortion = d[mbmi->tx_size];
*rate = r[mbmi->tx_size][cm->tx_mode == TX_MODE_SELECT];
@@ -883,29 +889,7 @@ static void choose_txfm_size_from_modelrd(VP9_COMP *cpi, MACROBLOCK *x,
rd[n][1] = (int64_t)(scale_rd[n] * rd[n][1]);
}
- if (max_tx_size == TX_32X32 &&
- (cm->tx_mode == ALLOW_32X32 ||
- (cm->tx_mode == TX_MODE_SELECT &&
- rd[TX_32X32][1] <= rd[TX_16X16][1] &&
- rd[TX_32X32][1] <= rd[TX_8X8][1] &&
- rd[TX_32X32][1] <= rd[TX_4X4][1]))) {
- mbmi->tx_size = TX_32X32;
- } else if (max_tx_size >= TX_16X16 &&
- (cm->tx_mode == ALLOW_16X16 ||
- cm->tx_mode == ALLOW_32X32 ||
- (cm->tx_mode == TX_MODE_SELECT &&
- rd[TX_16X16][1] <= rd[TX_8X8][1] &&
- rd[TX_16X16][1] <= rd[TX_4X4][1]))) {
- mbmi->tx_size = TX_16X16;
- } else if (cm->tx_mode == ALLOW_8X8 ||
- cm->tx_mode == ALLOW_16X16 ||
- cm->tx_mode == ALLOW_32X32 ||
- (cm->tx_mode == TX_MODE_SELECT &&
- rd[TX_8X8][1] <= rd[TX_4X4][1])) {
- mbmi->tx_size = TX_8X8;
- } else {
- mbmi->tx_size = TX_4X4;
- }
+ mbmi->tx_size = select_tx_size(cm->tx_mode, max_tx_size, rd);
// Actually encode using the chosen mode if a model was used, but do not
// update the r, d costs
@@ -2194,7 +2178,7 @@ static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
vp9_prob intra_inter_p = vp9_get_pred_prob_intra_inter(cm, xd);
vp9_prob comp_inter_p = 128;
- if (cm->comp_pred_mode == HYBRID_PREDICTION) {
+ if (cm->comp_pred_mode == REFERENCE_MODE_SELECT) {
comp_inter_p = vp9_get_pred_prob_comp_inter_inter(cm, xd);
*comp_mode_p = comp_inter_p;
} else {
@@ -2203,12 +2187,12 @@ static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
ref_costs_single[INTRA_FRAME] = vp9_cost_bit(intra_inter_p, 0);
- if (cm->comp_pred_mode != COMP_PREDICTION_ONLY) {
+ if (cm->comp_pred_mode != COMPOUND_REFERENCE) {
vp9_prob ref_single_p1 = vp9_get_pred_prob_single_ref_p1(cm, xd);
vp9_prob ref_single_p2 = vp9_get_pred_prob_single_ref_p2(cm, xd);
unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
- if (cm->comp_pred_mode == HYBRID_PREDICTION)
+ if (cm->comp_pred_mode == REFERENCE_MODE_SELECT)
base_cost += vp9_cost_bit(comp_inter_p, 0);
ref_costs_single[LAST_FRAME] = ref_costs_single[GOLDEN_FRAME] =
@@ -2223,11 +2207,11 @@ static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
ref_costs_single[GOLDEN_FRAME] = 512;
ref_costs_single[ALTREF_FRAME] = 512;
}
- if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY) {
+ if (cm->comp_pred_mode != SINGLE_REFERENCE) {
vp9_prob ref_comp_p = vp9_get_pred_prob_comp_ref_p(cm, xd);
unsigned int base_cost = vp9_cost_bit(intra_inter_p, 1);
- if (cm->comp_pred_mode == HYBRID_PREDICTION)
+ if (cm->comp_pred_mode == REFERENCE_MODE_SELECT)
base_cost += vp9_cost_bit(comp_inter_p, 1);
ref_costs_comp[LAST_FRAME] = base_cost + vp9_cost_bit(ref_comp_p, 0);
@@ -2243,7 +2227,7 @@ static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
int mode_index,
int_mv *ref_mv,
int_mv *second_ref_mv,
- int64_t comp_pred_diff[NB_PREDICTION_TYPES],
+ int64_t comp_pred_diff[REFERENCE_MODES],
int64_t tx_size_diff[TX_MODES],
int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]) {
MACROBLOCKD *const xd = &x->e_mbd;
@@ -2257,9 +2241,9 @@ static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
ctx->best_ref_mv.as_int = ref_mv->as_int;
ctx->second_best_ref_mv.as_int = second_ref_mv->as_int;
- ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_PREDICTION_ONLY];
- ctx->comp_pred_diff = (int)comp_pred_diff[COMP_PREDICTION_ONLY];
- ctx->hybrid_pred_diff = (int)comp_pred_diff[HYBRID_PREDICTION];
+ ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
+ ctx->comp_pred_diff = (int)comp_pred_diff[COMPOUND_REFERENCE];
+ ctx->hybrid_pred_diff = (int)comp_pred_diff[REFERENCE_MODE_SELECT];
vpx_memcpy(ctx->tx_rd_diff, tx_size_diff, sizeof(ctx->tx_rd_diff));
vpx_memcpy(ctx->best_filter_diff, best_filter_diff,
@@ -2782,9 +2766,9 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
if (!(*mode_excluded)) {
if (is_comp_pred) {
- *mode_excluded = (cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY);
+ *mode_excluded = (cpi->common.comp_pred_mode == SINGLE_REFERENCE);
} else {
- *mode_excluded = (cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY);
+ *mode_excluded = (cpi->common.comp_pred_mode == COMPOUND_REFERENCE);
}
}
@@ -3149,8 +3133,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
int64_t best_rd = best_rd_so_far;
int64_t best_tx_rd[TX_MODES];
int64_t best_tx_diff[TX_MODES];
- int64_t best_pred_diff[NB_PREDICTION_TYPES];
- int64_t best_pred_rd[NB_PREDICTION_TYPES];
+ int64_t best_pred_diff[REFERENCE_MODES];
+ int64_t best_pred_rd[REFERENCE_MODES];
int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
MB_MODE_INFO best_mbmode = { 0 };
@@ -3186,7 +3170,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp,
&comp_mode_p);
- for (i = 0; i < NB_PREDICTION_TYPES; ++i)
+ for (i = 0; i < REFERENCE_MODES; ++i)
best_pred_rd[i] = INT64_MAX;
for (i = 0; i < TX_MODES; i++)
best_tx_rd[i] = INT64_MAX;
@@ -3363,12 +3347,12 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
mode_excluded = mode_excluded
? mode_excluded
- : cm->comp_pred_mode == SINGLE_PREDICTION_ONLY;
+ : cm->comp_pred_mode == SINGLE_REFERENCE;
} else {
if (ref_frame != INTRA_FRAME && second_ref_frame != INTRA_FRAME) {
mode_excluded =
mode_excluded ?
- mode_excluded : cm->comp_pred_mode == COMP_PREDICTION_ONLY;
+ mode_excluded : cm->comp_pred_mode == COMPOUND_REFERENCE;
}
}
@@ -3491,7 +3475,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
continue;
}
- if (cm->comp_pred_mode == HYBRID_PREDICTION) {
+ if (cm->comp_pred_mode == REFERENCE_MODE_SELECT) {
rate2 += compmode_cost;
}
@@ -3576,7 +3560,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
}
if (!disable_skip && ref_frame == INTRA_FRAME) {
- for (i = 0; i < NB_PREDICTION_TYPES; ++i)
+ for (i = 0; i < REFERENCE_MODES; ++i)
best_pred_rd[i] = MIN(best_pred_rd[i], this_rd);
for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
best_filter_rd[i] = MIN(best_filter_rd[i], this_rd);
@@ -3638,7 +3622,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
if (!disable_skip && ref_frame != INTRA_FRAME) {
int single_rd, hybrid_rd, single_rate, hybrid_rate;
- if (cm->comp_pred_mode == HYBRID_PREDICTION) {
+ if (cm->comp_pred_mode == REFERENCE_MODE_SELECT) {
single_rate = rate2 - compmode_cost;
hybrid_rate = rate2;
} else {
@@ -3650,14 +3634,14 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
if (second_ref_frame <= INTRA_FRAME &&
- single_rd < best_pred_rd[SINGLE_PREDICTION_ONLY]) {
- best_pred_rd[SINGLE_PREDICTION_ONLY] = single_rd;
+ single_rd < best_pred_rd[SINGLE_REFERENCE]) {
+ best_pred_rd[SINGLE_REFERENCE] = single_rd;
} else if (second_ref_frame > INTRA_FRAME &&
- single_rd < best_pred_rd[COMP_PREDICTION_ONLY]) {
- best_pred_rd[COMP_PREDICTION_ONLY] = single_rd;
+ single_rd < best_pred_rd[COMPOUND_REFERENCE]) {
+ best_pred_rd[COMPOUND_REFERENCE] = single_rd;
}
- if (hybrid_rd < best_pred_rd[HYBRID_PREDICTION])
- best_pred_rd[HYBRID_PREDICTION] = hybrid_rd;
+ if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
+ best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
}
/* keep record of best filter type */
@@ -3779,7 +3763,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
*mbmi = best_mbmode;
x->skip |= best_skip2;
- for (i = 0; i < NB_PREDICTION_TYPES; ++i) {
+ for (i = 0; i < REFERENCE_MODES; ++i) {
if (best_pred_rd[i] == INT64_MAX)
best_pred_diff[i] = INT_MIN;
else
@@ -3850,8 +3834,8 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
int64_t best_yrd = best_rd_so_far; // FIXME(rbultje) more precise
int64_t best_tx_rd[TX_MODES];
int64_t best_tx_diff[TX_MODES];
- int64_t best_pred_diff[NB_PREDICTION_TYPES];
- int64_t best_pred_rd[NB_PREDICTION_TYPES];
+ int64_t best_pred_diff[REFERENCE_MODES];
+ int64_t best_pred_rd[REFERENCE_MODES];
int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
MB_MODE_INFO best_mbmode = { 0 };
@@ -3886,7 +3870,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
estimate_ref_frame_costs(cpi, segment_id, ref_costs_single, ref_costs_comp,
&comp_mode_p);
- for (i = 0; i < NB_PREDICTION_TYPES; ++i)
+ for (i = 0; i < REFERENCE_MODES; ++i)
best_pred_rd[i] = INT64_MAX;
for (i = 0; i < TX_MODES; i++)
best_tx_rd[i] = INT64_MAX;
@@ -4030,12 +4014,12 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
mode_excluded = mode_excluded
? mode_excluded
- : cm->comp_pred_mode == SINGLE_PREDICTION_ONLY;
+ : cm->comp_pred_mode == SINGLE_REFERENCE;
} else {
if (ref_frame != INTRA_FRAME && second_ref_frame != INTRA_FRAME) {
mode_excluded =
mode_excluded ?
- mode_excluded : cm->comp_pred_mode == COMP_PREDICTION_ONLY;
+ mode_excluded : cm->comp_pred_mode == COMPOUND_REFERENCE;
}
}
@@ -4241,9 +4225,9 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
if (!mode_excluded) {
if (comp_pred)
- mode_excluded = cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY;
+ mode_excluded = cpi->common.comp_pred_mode == SINGLE_REFERENCE;
else
- mode_excluded = cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY;
+ mode_excluded = cpi->common.comp_pred_mode == COMPOUND_REFERENCE;
}
compmode_cost = vp9_cost_bit(comp_mode_p, comp_pred);
@@ -4271,7 +4255,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
}
}
- if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
+ if (cpi->common.comp_pred_mode == REFERENCE_MODE_SELECT) {
rate2 += compmode_cost;
}
@@ -4332,7 +4316,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
}
if (!disable_skip && ref_frame == INTRA_FRAME) {
- for (i = 0; i < NB_PREDICTION_TYPES; ++i)
+ for (i = 0; i < REFERENCE_MODES; ++i)
best_pred_rd[i] = MIN(best_pred_rd[i], this_rd);
for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++)
best_filter_rd[i] = MIN(best_filter_rd[i], this_rd);
@@ -4389,7 +4373,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
if (!disable_skip && ref_frame != INTRA_FRAME) {
int single_rd, hybrid_rd, single_rate, hybrid_rate;
- if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
+ if (cpi->common.comp_pred_mode == REFERENCE_MODE_SELECT) {
single_rate = rate2 - compmode_cost;
hybrid_rate = rate2;
} else {
@@ -4401,14 +4385,14 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
if (second_ref_frame <= INTRA_FRAME &&
- single_rd < best_pred_rd[SINGLE_PREDICTION_ONLY]) {
- best_pred_rd[SINGLE_PREDICTION_ONLY] = single_rd;
+ single_rd < best_pred_rd[SINGLE_REFERENCE]) {
+ best_pred_rd[SINGLE_REFERENCE] = single_rd;
} else if (second_ref_frame > INTRA_FRAME &&
- single_rd < best_pred_rd[COMP_PREDICTION_ONLY]) {
- best_pred_rd[COMP_PREDICTION_ONLY] = single_rd;
+ single_rd < best_pred_rd[COMPOUND_REFERENCE]) {
+ best_pred_rd[COMPOUND_REFERENCE] = single_rd;
}
- if (hybrid_rd < best_pred_rd[HYBRID_PREDICTION])
- best_pred_rd[HYBRID_PREDICTION] = hybrid_rd;
+ if (hybrid_rd < best_pred_rd[REFERENCE_MODE_SELECT])
+ best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
}
/* keep record of best filter type */
@@ -4524,7 +4508,7 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
mbmi->mv[1].as_int = xd->mi_8x8[0]->bmi[3].as_mv[1].as_int;
}
- for (i = 0; i < NB_PREDICTION_TYPES; ++i) {
+ for (i = 0; i < REFERENCE_MODES; ++i) {
if (best_pred_rd[i] == INT64_MAX)
best_pred_diff[i] = INT_MIN;
else