From: Yunqing Wang Date: Tue, 4 Feb 2014 19:09:34 +0000 (-0800) Subject: Enable encode_breakout in real time encoding X-Git-Tag: v1.4.0~2423^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=507fd5220b50be735c462308778efed9709404a6;p=platform%2Fupstream%2Flibvpx.git 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 --- diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index dfb69ca..0022ef3 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -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]; } else { mbmi->segment_id = 0; - x->encode_breakout = cpi->oxcf.encode_breakout; + x->encode_breakout = cpi->encode_breakout; } } diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c index dc35044..45bd47c 100644 --- a/vp9/encoder/vp9_firstpass.c +++ b/vp9/encoder/vp9_firstpass.c @@ -2328,11 +2328,11 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) { if (twopass->gf_zeromotion_pct > 995) { // 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) - cpi->enable_encode_breakout = 0; + cpi->allow_encode_breakout = ENCODE_BREAKOUT_DISABLED; else - cpi->enable_encode_breakout = 2; + cpi->allow_encode_breakout = ENCODE_BREAKOUT_LIMITED; } rc->frames_till_gf_update_due = rc->baseline_gf_interval; diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 932e850..ec7e4b9 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -744,6 +744,8 @@ static void set_rt_speed_feature(VP9_COMMON *cm, sf->static_segmentation = 0; sf->adaptive_rd_thresh = 1; sf->recode_loop = ((speed < 1) ? ALLOW_RECODE : ALLOW_RECODE_KFMAXBW); + sf->encode_breakout_thresh = 1; + if (speed == 1) { sf->use_square_partition_only = !frame_is_intra_only(cm); 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_uv_mode_mask[TX_32X32] = INTRA_DC_H_V; sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V; + sf->encode_breakout_thresh = 8; } if (speed >= 2) { 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_uv_mode_mask[TX_32X32] = INTRA_DC_H_V; sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V; + sf->encode_breakout_thresh = 200; } if (speed >= 3) { 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->adaptive_rd_thresh = 4; sf->mode_skip_start = 6; + sf->encode_breakout_thresh = 400; } if (speed >= 4) { sf->optimize_coefficients = 0; sf->disable_split_mask = DISABLE_ALL_SPLIT; sf->use_fast_lpf_pick = 2; + sf->encode_breakout_thresh = 700; } if (speed >= 5) { 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->frame_parameter_update = 0; + sf->encode_breakout_thresh = 1000; } if (speed >= 6) { sf->always_this_block_size = BLOCK_16X16; 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->mode_skip_start = MAX_MODES; // Mode index at which mode skip mask set sf->use_pick_mode = 0; + sf->encode_breakout_thresh = 0; switch (cpi->oxcf.mode) { 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; + + 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) { @@ -1408,6 +1421,7 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) { for (i = 0; i < MAX_SEGMENTS; i++) cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout; } + cpi->encode_breakout = cpi->oxcf.encode_breakout; // local file playback mode == really big buffer 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->enable_encode_breakout = 1; + cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED; if (cpi->pass == 1) { 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, 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); encode_frame_to_data_rate(cpi, size, dest, frame_flags); diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 243ca11..88a0419 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -208,6 +208,15 @@ typedef enum { ALLOW_RECODE = 3, } 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 { // Frame level coding parameter update int frame_parameter_update; @@ -392,6 +401,10 @@ typedef struct { // This flag controls the use of non-RD mode decision. 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; typedef struct { @@ -546,6 +559,13 @@ typedef struct VP9_COMP { unsigned int max_mv_magnitude; 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; // segment threashold for encode breakout @@ -636,9 +656,6 @@ typedef struct VP9_COMP { LAYER_CONTEXT layer_context[VPX_TS_MAX_LAYERS]; } svc; - int enable_encode_breakout; // Default value is 1. From first pass stats, - // encode_breakout may be disabled. - #if CONFIG_MULTIPLE_ARF // ARF tracking variables. int multi_arf_enabled; diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 4408353..f859cce 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -2907,33 +2907,26 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, if (cm->interp_filter == SWITCHABLE) *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) 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 uv_size = get_plane_block_size(bsize, &xd->plane[1]); unsigned int var, sse; // Skipping threshold for ac. unsigned int thresh_ac; - // The encode_breakout input - unsigned int encode_breakout = x->encode_breakout << 4; - unsigned int max_thresh = 36000; - + // Set a maximum for threshold to avoid big PSNR loss in low bitrate case. // Use extreme low threshold for static frames to limit skipping. - if (cpi->enable_encode_breakout == 2) - max_thresh = 128; + const unsigned int max_thresh = (cpi->allow_encode_breakout == + 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. thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9; - - // 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; + thresh_ac = clamp(thresh_ac, min_thresh, max_thresh); var = cpi->fn_ptr[y_size].vf(x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].dst.buf,