Enable encode_breakout in real time encoding
In real time encoding, we enable encode_breakout to make encoding fast. A speed feature "use_encode_breakout" is defined to set encode_breakout thresholds for different speeds. However, currently, static_thresh is an encoder option. The encode_ breakout can be turned off if user sets static_thresh=0 specifically. The rtc set borg test result: (need to set --static_thresh=1) speed -5, psnr loss -3.543%; speed -4, psnr loss -2.358%; speed -3, psnr loss -0.771%. Encoding speed test: speed -5, 11% - 60% speedup; speed -4, 5.5% - 28% speedup; speed -3, 0.8% - 7% speedup. Change-Id: Icde592ffbe77eac7446f872a2e9eb2051733677b
This commit is contained in:
@@ -613,7 +613,7 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
|
|||||||
x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
|
x->encode_breakout = cpi->segment_encode_breakout[mbmi->segment_id];
|
||||||
} else {
|
} else {
|
||||||
mbmi->segment_id = 0;
|
mbmi->segment_id = 0;
|
||||||
x->encode_breakout = cpi->oxcf.encode_breakout;
|
x->encode_breakout = cpi->encode_breakout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2328,11 +2328,11 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
|
|||||||
|
|
||||||
if (twopass->gf_zeromotion_pct > 995) {
|
if (twopass->gf_zeromotion_pct > 995) {
|
||||||
// As long as max_thresh for encode breakout is small enough, it is ok
|
// As long as max_thresh for encode breakout is small enough, it is ok
|
||||||
// to enable it for no-show frame, i.e. set enable_encode_breakout to 2.
|
// to enable it for show frame, i.e. set allow_encode_breakout to 2.
|
||||||
if (!cm->show_frame)
|
if (!cm->show_frame)
|
||||||
cpi->enable_encode_breakout = 0;
|
cpi->allow_encode_breakout = ENCODE_BREAKOUT_DISABLED;
|
||||||
else
|
else
|
||||||
cpi->enable_encode_breakout = 2;
|
cpi->allow_encode_breakout = ENCODE_BREAKOUT_LIMITED;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
|
rc->frames_till_gf_update_due = rc->baseline_gf_interval;
|
||||||
|
|||||||
@@ -744,6 +744,8 @@ static void set_rt_speed_feature(VP9_COMMON *cm,
|
|||||||
sf->static_segmentation = 0;
|
sf->static_segmentation = 0;
|
||||||
sf->adaptive_rd_thresh = 1;
|
sf->adaptive_rd_thresh = 1;
|
||||||
sf->recode_loop = ((speed < 1) ? ALLOW_RECODE : ALLOW_RECODE_KFMAXBW);
|
sf->recode_loop = ((speed < 1) ? ALLOW_RECODE : ALLOW_RECODE_KFMAXBW);
|
||||||
|
sf->encode_breakout_thresh = 1;
|
||||||
|
|
||||||
if (speed == 1) {
|
if (speed == 1) {
|
||||||
sf->use_square_partition_only = !frame_is_intra_only(cm);
|
sf->use_square_partition_only = !frame_is_intra_only(cm);
|
||||||
sf->less_rectangular_check = 1;
|
sf->less_rectangular_check = 1;
|
||||||
@@ -765,6 +767,7 @@ static void set_rt_speed_feature(VP9_COMMON *cm,
|
|||||||
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
|
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
|
||||||
sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
|
sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
|
||||||
sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
|
sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
|
||||||
|
sf->encode_breakout_thresh = 8;
|
||||||
}
|
}
|
||||||
if (speed >= 2) {
|
if (speed >= 2) {
|
||||||
sf->use_square_partition_only = !frame_is_intra_only(cm);
|
sf->use_square_partition_only = !frame_is_intra_only(cm);
|
||||||
@@ -804,6 +807,7 @@ static void set_rt_speed_feature(VP9_COMMON *cm,
|
|||||||
sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
|
sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
|
||||||
sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
|
sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
|
||||||
sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
|
sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
|
||||||
|
sf->encode_breakout_thresh = 200;
|
||||||
}
|
}
|
||||||
if (speed >= 3) {
|
if (speed >= 3) {
|
||||||
sf->use_square_partition_only = 1;
|
sf->use_square_partition_only = 1;
|
||||||
@@ -826,11 +830,13 @@ static void set_rt_speed_feature(VP9_COMMON *cm,
|
|||||||
sf->use_fast_coef_updates = 2;
|
sf->use_fast_coef_updates = 2;
|
||||||
sf->adaptive_rd_thresh = 4;
|
sf->adaptive_rd_thresh = 4;
|
||||||
sf->mode_skip_start = 6;
|
sf->mode_skip_start = 6;
|
||||||
|
sf->encode_breakout_thresh = 400;
|
||||||
}
|
}
|
||||||
if (speed >= 4) {
|
if (speed >= 4) {
|
||||||
sf->optimize_coefficients = 0;
|
sf->optimize_coefficients = 0;
|
||||||
sf->disable_split_mask = DISABLE_ALL_SPLIT;
|
sf->disable_split_mask = DISABLE_ALL_SPLIT;
|
||||||
sf->use_fast_lpf_pick = 2;
|
sf->use_fast_lpf_pick = 2;
|
||||||
|
sf->encode_breakout_thresh = 700;
|
||||||
}
|
}
|
||||||
if (speed >= 5) {
|
if (speed >= 5) {
|
||||||
int i;
|
int i;
|
||||||
@@ -843,10 +849,12 @@ static void set_rt_speed_feature(VP9_COMMON *cm,
|
|||||||
sf->intra_uv_mode_mask[i] = INTRA_DC_ONLY;
|
sf->intra_uv_mode_mask[i] = INTRA_DC_ONLY;
|
||||||
}
|
}
|
||||||
sf->frame_parameter_update = 0;
|
sf->frame_parameter_update = 0;
|
||||||
|
sf->encode_breakout_thresh = 1000;
|
||||||
}
|
}
|
||||||
if (speed >= 6) {
|
if (speed >= 6) {
|
||||||
sf->always_this_block_size = BLOCK_16X16;
|
sf->always_this_block_size = BLOCK_16X16;
|
||||||
sf->use_pick_mode = 1;
|
sf->use_pick_mode = 1;
|
||||||
|
sf->encode_breakout_thresh = 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -906,6 +914,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
|
|||||||
sf->using_small_partition_info = 0;
|
sf->using_small_partition_info = 0;
|
||||||
sf->mode_skip_start = MAX_MODES; // Mode index at which mode skip mask set
|
sf->mode_skip_start = MAX_MODES; // Mode index at which mode skip mask set
|
||||||
sf->use_pick_mode = 0;
|
sf->use_pick_mode = 0;
|
||||||
|
sf->encode_breakout_thresh = 0;
|
||||||
|
|
||||||
switch (cpi->oxcf.mode) {
|
switch (cpi->oxcf.mode) {
|
||||||
case MODE_BESTQUALITY:
|
case MODE_BESTQUALITY:
|
||||||
@@ -949,6 +958,10 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cpi->mb.optimize = cpi->sf.optimize_coefficients == 1 && cpi->pass != 1;
|
cpi->mb.optimize = cpi->sf.optimize_coefficients == 1 && cpi->pass != 1;
|
||||||
|
|
||||||
|
if (cpi->encode_breakout && cpi->oxcf.mode == MODE_REALTIME &&
|
||||||
|
sf->encode_breakout_thresh > cpi->encode_breakout)
|
||||||
|
cpi->encode_breakout = sf->encode_breakout_thresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
|
static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
|
||||||
@@ -1408,6 +1421,7 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
|
|||||||
for (i = 0; i < MAX_SEGMENTS; i++)
|
for (i = 0; i < MAX_SEGMENTS; i++)
|
||||||
cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
|
cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
|
||||||
}
|
}
|
||||||
|
cpi->encode_breakout = cpi->oxcf.encode_breakout;
|
||||||
|
|
||||||
// local file playback mode == really big buffer
|
// local file playback mode == really big buffer
|
||||||
if (cpi->oxcf.end_usage == USAGE_LOCAL_FILE_PLAYBACK) {
|
if (cpi->oxcf.end_usage == USAGE_LOCAL_FILE_PLAYBACK) {
|
||||||
@@ -1848,7 +1862,7 @@ VP9_PTR vp9_create_compressor(VP9_CONFIG *oxcf) {
|
|||||||
|
|
||||||
cpi->output_pkt_list = oxcf->output_pkt_list;
|
cpi->output_pkt_list = oxcf->output_pkt_list;
|
||||||
|
|
||||||
cpi->enable_encode_breakout = 1;
|
cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED;
|
||||||
|
|
||||||
if (cpi->pass == 1) {
|
if (cpi->pass == 1) {
|
||||||
vp9_init_first_pass(cpi);
|
vp9_init_first_pass(cpi);
|
||||||
@@ -3398,7 +3412,7 @@ static void Pass1Encode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
|
|||||||
|
|
||||||
static void Pass2Encode(VP9_COMP *cpi, size_t *size,
|
static void Pass2Encode(VP9_COMP *cpi, size_t *size,
|
||||||
uint8_t *dest, unsigned int *frame_flags) {
|
uint8_t *dest, unsigned int *frame_flags) {
|
||||||
cpi->enable_encode_breakout = 1;
|
cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED;
|
||||||
|
|
||||||
vp9_rc_get_second_pass_params(cpi);
|
vp9_rc_get_second_pass_params(cpi);
|
||||||
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
|
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
|
||||||
|
|||||||
@@ -208,6 +208,15 @@ typedef enum {
|
|||||||
ALLOW_RECODE = 3,
|
ALLOW_RECODE = 3,
|
||||||
} RECODE_LOOP_TYPE;
|
} RECODE_LOOP_TYPE;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// encode_breakout is disabled.
|
||||||
|
ENCODE_BREAKOUT_DISABLED = 0,
|
||||||
|
// encode_breakout is enabled.
|
||||||
|
ENCODE_BREAKOUT_ENABLED = 1,
|
||||||
|
// encode_breakout is enabled with small max_thresh limit.
|
||||||
|
ENCODE_BREAKOUT_LIMITED = 2
|
||||||
|
} ENCODE_BREAKOUT_TYPE;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Frame level coding parameter update
|
// Frame level coding parameter update
|
||||||
int frame_parameter_update;
|
int frame_parameter_update;
|
||||||
@@ -392,6 +401,10 @@ typedef struct {
|
|||||||
|
|
||||||
// This flag controls the use of non-RD mode decision.
|
// This flag controls the use of non-RD mode decision.
|
||||||
int use_pick_mode;
|
int use_pick_mode;
|
||||||
|
|
||||||
|
// This variable sets the encode_breakout threshold. Currently, it is only
|
||||||
|
// enabled in real time mode.
|
||||||
|
int encode_breakout_thresh;
|
||||||
} SPEED_FEATURES;
|
} SPEED_FEATURES;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -546,6 +559,13 @@ typedef struct VP9_COMP {
|
|||||||
unsigned int max_mv_magnitude;
|
unsigned int max_mv_magnitude;
|
||||||
int mv_step_param;
|
int mv_step_param;
|
||||||
|
|
||||||
|
// Default value is 1. From first pass stats, encode_breakout may be disabled.
|
||||||
|
ENCODE_BREAKOUT_TYPE allow_encode_breakout;
|
||||||
|
|
||||||
|
// Get threshold from external input. In real time mode, it can be
|
||||||
|
// overwritten according to encoding speed.
|
||||||
|
int encode_breakout;
|
||||||
|
|
||||||
unsigned char *segmentation_map;
|
unsigned char *segmentation_map;
|
||||||
|
|
||||||
// segment threashold for encode breakout
|
// segment threashold for encode breakout
|
||||||
@@ -636,9 +656,6 @@ typedef struct VP9_COMP {
|
|||||||
LAYER_CONTEXT layer_context[VPX_TS_MAX_LAYERS];
|
LAYER_CONTEXT layer_context[VPX_TS_MAX_LAYERS];
|
||||||
} svc;
|
} svc;
|
||||||
|
|
||||||
int enable_encode_breakout; // Default value is 1. From first pass stats,
|
|
||||||
// encode_breakout may be disabled.
|
|
||||||
|
|
||||||
#if CONFIG_MULTIPLE_ARF
|
#if CONFIG_MULTIPLE_ARF
|
||||||
// ARF tracking variables.
|
// ARF tracking variables.
|
||||||
int multi_arf_enabled;
|
int multi_arf_enabled;
|
||||||
|
|||||||
@@ -2907,33 +2907,26 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
|||||||
if (cm->interp_filter == SWITCHABLE)
|
if (cm->interp_filter == SWITCHABLE)
|
||||||
*rate2 += get_switchable_rate(x);
|
*rate2 += get_switchable_rate(x);
|
||||||
|
|
||||||
if (!is_comp_pred && cpi->enable_encode_breakout) {
|
if (!is_comp_pred) {
|
||||||
if (cpi->active_map_enabled && x->active_ptr[0] == 0)
|
if (cpi->active_map_enabled && x->active_ptr[0] == 0)
|
||||||
x->skip = 1;
|
x->skip = 1;
|
||||||
else if (x->encode_breakout) {
|
else if (cpi->allow_encode_breakout && x->encode_breakout) {
|
||||||
const BLOCK_SIZE y_size = get_plane_block_size(bsize, &xd->plane[0]);
|
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]);
|
const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]);
|
||||||
unsigned int var, sse;
|
unsigned int var, sse;
|
||||||
// Skipping threshold for ac.
|
// Skipping threshold for ac.
|
||||||
unsigned int thresh_ac;
|
unsigned int thresh_ac;
|
||||||
// The encode_breakout input
|
// Set a maximum for threshold to avoid big PSNR loss in low bitrate case.
|
||||||
unsigned int encode_breakout = x->encode_breakout << 4;
|
|
||||||
unsigned int max_thresh = 36000;
|
|
||||||
|
|
||||||
// Use extreme low threshold for static frames to limit skipping.
|
// Use extreme low threshold for static frames to limit skipping.
|
||||||
if (cpi->enable_encode_breakout == 2)
|
const unsigned int max_thresh = (cpi->allow_encode_breakout ==
|
||||||
max_thresh = 128;
|
ENCODE_BREAKOUT_LIMITED) ? 128 : 36000;
|
||||||
|
// The encode_breakout input
|
||||||
|
const unsigned int min_thresh = ((x->encode_breakout << 4) > max_thresh) ?
|
||||||
|
max_thresh : (x->encode_breakout << 4);
|
||||||
|
|
||||||
// Calculate threshold according to dequant value.
|
// Calculate threshold according to dequant value.
|
||||||
thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9;
|
thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9;
|
||||||
|
thresh_ac = clamp(thresh_ac, min_thresh, max_thresh);
|
||||||
// Use encode_breakout input if it is bigger than internal threshold.
|
|
||||||
if (thresh_ac < encode_breakout)
|
|
||||||
thresh_ac = encode_breakout;
|
|
||||||
|
|
||||||
// Set a maximum for threshold to avoid big PSNR loss in low bitrate case.
|
|
||||||
if (thresh_ac > max_thresh)
|
|
||||||
thresh_ac = max_thresh;
|
|
||||||
|
|
||||||
var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride,
|
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.buf,
|
||||||
|
|||||||
Reference in New Issue
Block a user