Change speed and rd features for formatting bars.
Change speed features / behavior for split mode when there is an internal active edge (e.g. formatting bars). Remove some threshold constraints in rd code near the active edge of the image. Add some plumbing for left and right active edge detection. Patch set 5. Limit rd pass through for sub 8x8 to internal active edges. This takes away any speed penalty for most clips but keeps the enhanced edge coding for the more critical case of internal image edges Change-Id: If644e4762874de4fe9cbb0a66211953fa74c13a5
This commit is contained in:
parent
892128f6ca
commit
a126b6ce7d
@ -2123,38 +2123,6 @@ static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
|
||||
BLOCK_64X64
|
||||
};
|
||||
|
||||
// Checks to see if a macro block is at the edge of the active image.
|
||||
// In most cases this is the "real" edge unless there are formatting
|
||||
// bars embedded in the stream.
|
||||
static int active_edge_sb(VP9_COMP *cpi,
|
||||
int mi_row, int mi_col) {
|
||||
int is_active_edge = 0;
|
||||
int top_edge = 0;
|
||||
int bottom_edge = cpi->common.mi_rows;
|
||||
int left_edge = 0;
|
||||
int right_edge = cpi->common.mi_cols;
|
||||
|
||||
// For two pass account for any formatting bars detected.
|
||||
if (cpi->oxcf.pass == 2) {
|
||||
TWO_PASS *twopass = &cpi->twopass;
|
||||
|
||||
// The inactive region is specified in MBs not mi units.
|
||||
// The image edge is in the following MB row.
|
||||
top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
|
||||
|
||||
bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
|
||||
bottom_edge = MAX(top_edge, bottom_edge);
|
||||
}
|
||||
|
||||
if (((top_edge >= mi_row) && (top_edge < (mi_row + MI_BLOCK_SIZE))) ||
|
||||
((bottom_edge >= mi_row) && (bottom_edge < (mi_row + MI_BLOCK_SIZE))) ||
|
||||
((left_edge >= mi_col) && (left_edge < (mi_col + MI_BLOCK_SIZE))) ||
|
||||
((right_edge >= mi_col) && (right_edge < (mi_col + MI_BLOCK_SIZE)))) {
|
||||
is_active_edge = 1;
|
||||
}
|
||||
|
||||
return is_active_edge;
|
||||
}
|
||||
|
||||
// Look at all the mode_info entries for blocks that are part of this
|
||||
// partition and find the min and max values for sb_type.
|
||||
@ -2253,7 +2221,7 @@ static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile,
|
||||
// Test for blocks at the edge of the active image.
|
||||
// This may be the actual edge of the image or where there are formatting
|
||||
// bars.
|
||||
if (active_edge_sb(cpi, mi_row, mi_col)) {
|
||||
if (vp9_active_edge_sb(cpi, mi_row, mi_col)) {
|
||||
min_size = BLOCK_4X4;
|
||||
} else {
|
||||
min_size = MIN(cpi->sf.rd_auto_partition_min_limit,
|
||||
|
@ -126,6 +126,7 @@ static void output_stats(FIRSTPASS_STATS *stats,
|
||||
stats->pcnt_neutral,
|
||||
stats->intra_skip_pct,
|
||||
stats->inactive_zone_rows,
|
||||
stats->inactive_zone_cols,
|
||||
stats->MVr,
|
||||
stats->mvr_abs,
|
||||
stats->MVc,
|
||||
@ -164,6 +165,7 @@ static void zero_stats(FIRSTPASS_STATS *section) {
|
||||
section->pcnt_neutral = 0.0;
|
||||
section->intra_skip_pct = 0.0;
|
||||
section->inactive_zone_rows = 0.0;
|
||||
section->inactive_zone_cols = 0.0;
|
||||
section->MVr = 0.0;
|
||||
section->mvr_abs = 0.0;
|
||||
section->MVc = 0.0;
|
||||
@ -191,6 +193,7 @@ static void accumulate_stats(FIRSTPASS_STATS *section,
|
||||
section->pcnt_neutral += frame->pcnt_neutral;
|
||||
section->intra_skip_pct += frame->intra_skip_pct;
|
||||
section->inactive_zone_rows += frame->inactive_zone_rows;
|
||||
section->inactive_zone_cols += frame->inactive_zone_cols;
|
||||
section->MVr += frame->MVr;
|
||||
section->mvr_abs += frame->mvr_abs;
|
||||
section->MVc += frame->MVc;
|
||||
@ -216,6 +219,7 @@ static void subtract_stats(FIRSTPASS_STATS *section,
|
||||
section->pcnt_neutral -= frame->pcnt_neutral;
|
||||
section->intra_skip_pct -= frame->intra_skip_pct;
|
||||
section->inactive_zone_rows -= frame->inactive_zone_rows;
|
||||
section->inactive_zone_cols -= frame->inactive_zone_cols;
|
||||
section->MVr -= frame->MVr;
|
||||
section->mvr_abs -= frame->mvr_abs;
|
||||
section->MVc -= frame->MVc;
|
||||
@ -1050,6 +1054,7 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
|
||||
fps.pcnt_neutral = (double)neutral_count / num_mbs;
|
||||
fps.intra_skip_pct = (double)intra_skip_count / num_mbs;
|
||||
fps.inactive_zone_rows = (double)image_data_start_row;
|
||||
fps.inactive_zone_cols = (double)0; // TODO(paulwilkins): fix
|
||||
|
||||
if (mvcount > 0) {
|
||||
fps.MVr = (double)sum_mvr / mvcount;
|
||||
|
@ -53,6 +53,7 @@ typedef struct {
|
||||
double pcnt_neutral;
|
||||
double intra_skip_pct;
|
||||
double inactive_zone_rows; // Image mask rows top and bottom.
|
||||
double inactive_zone_cols; // Image mask columns at left and right edges.
|
||||
double MVr;
|
||||
double mvr_abs;
|
||||
double MVc;
|
||||
|
@ -2898,6 +2898,47 @@ static void rd_variance_adjustment(VP9_COMP *cpi,
|
||||
*this_rd += (*this_rd * var_factor) / 100;
|
||||
}
|
||||
|
||||
|
||||
// Do we have an internal image edge (e.g. formatting bars).
|
||||
int vp9_internal_image_edge(VP9_COMP *cpi) {
|
||||
return (cpi->oxcf.pass == 2) &&
|
||||
((cpi->twopass.this_frame_stats.inactive_zone_rows > 0) ||
|
||||
(cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
|
||||
}
|
||||
|
||||
// Checks to see if a macro block is at the edge of the active image.
|
||||
// In most cases this is the "real" edge unless there are formatting
|
||||
// bars embedded in the stream.
|
||||
int vp9_active_edge_sb(VP9_COMP *cpi,
|
||||
int mi_row, int mi_col) {
|
||||
int is_active_edge = 0;
|
||||
int top_edge = 0;
|
||||
int bottom_edge = cpi->common.mi_rows;
|
||||
int left_edge = 0;
|
||||
int right_edge = cpi->common.mi_cols;
|
||||
|
||||
// For two pass account for any formatting bars detected.
|
||||
if (cpi->oxcf.pass == 2) {
|
||||
TWO_PASS *twopass = &cpi->twopass;
|
||||
|
||||
// The inactive region is specified in MBs not mi units.
|
||||
// The image edge is in the following MB row.
|
||||
top_edge += (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
|
||||
|
||||
bottom_edge -= (int)(twopass->this_frame_stats.inactive_zone_rows * 2);
|
||||
bottom_edge = MAX(top_edge, bottom_edge);
|
||||
}
|
||||
|
||||
if (((top_edge >= mi_row) && (top_edge < (mi_row + MI_BLOCK_SIZE))) ||
|
||||
((bottom_edge >= mi_row) && (bottom_edge < (mi_row + MI_BLOCK_SIZE))) ||
|
||||
((left_edge >= mi_col) && (left_edge < (mi_col + MI_BLOCK_SIZE))) ||
|
||||
((right_edge >= mi_col) && (right_edge < (mi_col + MI_BLOCK_SIZE)))) {
|
||||
is_active_edge = 1;
|
||||
}
|
||||
|
||||
return is_active_edge;
|
||||
}
|
||||
|
||||
void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
|
||||
TileDataEnc *tile_data,
|
||||
MACROBLOCK *x,
|
||||
@ -3751,13 +3792,15 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi,
|
||||
int skip_uv;
|
||||
PREDICTION_MODE mode_uv = DC_PRED;
|
||||
const int intra_cost_penalty = vp9_get_intra_cost_penalty(
|
||||
cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
|
||||
cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
|
||||
int_mv seg_mvs[4][MAX_REF_FRAMES];
|
||||
b_mode_info best_bmodes[4];
|
||||
int best_skip2 = 0;
|
||||
int ref_frame_skip_mask[2] = { 0 };
|
||||
int64_t mask_filter = 0;
|
||||
int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS];
|
||||
int internal_active_edge =
|
||||
vp9_active_edge_sb(cpi, mi_row, mi_col) && vp9_internal_image_edge(cpi);
|
||||
|
||||
x->skip_encode = sf->skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
|
||||
memset(x->zcoeff_blk[TX_4X4], 0, 4);
|
||||
@ -3843,7 +3886,8 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi,
|
||||
continue;
|
||||
|
||||
// Test best rd so far against threshold for trying this mode.
|
||||
if (rd_less_than_thresh(best_rd,
|
||||
if (!internal_active_edge &&
|
||||
rd_less_than_thresh(best_rd,
|
||||
rd_opt->threshes[segment_id][bsize][ref_index],
|
||||
tile_data->thresh_freq_fact[bsize][ref_index]))
|
||||
continue;
|
||||
|
@ -54,6 +54,9 @@ void vp9_rd_pick_inter_mode_sb_seg_skip(struct VP9_COMP *cpi,
|
||||
PICK_MODE_CONTEXT *ctx,
|
||||
int64_t best_rd_so_far);
|
||||
|
||||
int vp9_internal_image_edge(struct VP9_COMP *cpi);
|
||||
int vp9_active_edge_sb(struct VP9_COMP *cpi, int mi_row, int mi_col);
|
||||
|
||||
void vp9_rd_pick_inter_mode_sub8x8(struct VP9_COMP *cpi,
|
||||
struct TileDataEnc *tile_data,
|
||||
struct macroblock *x,
|
||||
@ -61,6 +64,7 @@ void vp9_rd_pick_inter_mode_sub8x8(struct VP9_COMP *cpi,
|
||||
struct RD_COST *rd_cost,
|
||||
BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
|
||||
int64_t best_rd_so_far);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
#include "vp9/encoder/vp9_encoder.h"
|
||||
#include "vp9/encoder/vp9_speed_features.h"
|
||||
#include "vp9/encoder/vp9_rdopt.h"
|
||||
|
||||
|
||||
// Intra only frames, golden frames (except alt ref overlays) and
|
||||
// alt ref frames tend to be coded at a higher than ambient quality
|
||||
@ -90,7 +92,8 @@ static void set_good_speed_feature_framesize_dependent(VP9_COMP *cpi,
|
||||
// If this is a two pass clip that fits the criteria for animated or
|
||||
// graphics content then reset disable_split_mask for speeds 1-4.
|
||||
if ((speed >= 1) && (cpi->oxcf.pass == 2) &&
|
||||
(cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION)) {
|
||||
((cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ||
|
||||
(vp9_internal_image_edge(cpi)))) {
|
||||
sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user