From 636099f7b6db3a9586887fd2db6e720dae847dec Mon Sep 17 00:00:00 2001 From: Yaowu Xu Date: Fri, 24 Oct 2014 09:31:16 -0700 Subject: [PATCH] Add a new control of max bitrate for inter frame Change-Id: I205de3611622cff7f751ea8baf9f82784581730a --- vp9/encoder/vp9_encoder.h | 3 +++ vp9/encoder/vp9_ratectrl.c | 11 +++++++++++ vp9/vp9_cx_iface.c | 12 ++++++++++++ vpx/vp8cx.h | 15 +++++++++++++++ vpxenc.c | 5 ++++- 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h index 1e6047464..2a7d9f40f 100644 --- a/vp9/encoder/vp9_encoder.h +++ b/vp9/encoder/vp9_encoder.h @@ -122,7 +122,10 @@ typedef struct VP9EncoderConfig { int noise_sensitivity; // pre processing blur: recommendation 0 int sharpness; // sharpening output: recommendation 0: int speed; + // maximum allowed bitrate for any intra frame in % of bitrate target. unsigned int rc_max_intra_bitrate_pct; + // maximum allowed bitrate for any inter frame in % of bitrate target. + unsigned int rc_max_inter_bitrate_pct; MODE mode; int pass; diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c index 65bca669a..f3e900f0c 100644 --- a/vp9/encoder/vp9_ratectrl.c +++ b/vp9/encoder/vp9_ratectrl.c @@ -196,6 +196,7 @@ static int estimate_bits_at_q(FRAME_TYPE frame_type, int q, int mbs, int vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) { const RATE_CONTROL *rc = &cpi->rc; + const VP9EncoderConfig *oxcf = &cpi->oxcf; const int min_frame_target = MAX(rc->min_frame_bandwidth, rc->avg_frame_bandwidth >> 5); if (target < min_frame_target) @@ -210,6 +211,11 @@ int vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) { // Clip the frame target to the maximum allowed value. if (target > rc->max_frame_bandwidth) target = rc->max_frame_bandwidth; + if (oxcf->rc_max_inter_bitrate_pct) { + const int max_rate = rc->avg_frame_bandwidth * + oxcf->rc_max_inter_bitrate_pct / 100; + target = MIN(target, max_rate); + } return target; } @@ -1347,6 +1353,11 @@ static int calc_pframe_target_size_one_pass_cbr(const VP9_COMP *cpi) { const int pct_high = (int)MIN(-diff / one_pct_bits, oxcf->over_shoot_pct); target += (target * pct_high) / 200; } + if (oxcf->rc_max_inter_bitrate_pct) { + const int max_rate = rc->avg_frame_bandwidth * + oxcf->rc_max_inter_bitrate_pct / 100; + target = MIN(target, max_rate); + } return MAX(min_frame_target, target); } diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index adae18b48..3684bf032 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -33,6 +33,7 @@ struct vp9_extracfg { vp8e_tuning tuning; unsigned int cq_level; // constrained quality level unsigned int rc_max_intra_bitrate_pct; + unsigned int rc_max_inter_bitrate_pct; unsigned int lossless; unsigned int frame_parallel_decoding_mode; AQ_MODE aq_mode; @@ -54,6 +55,7 @@ static struct vp9_extracfg default_extra_cfg = { VP8_TUNE_PSNR, // tuning 10, // cq_level 0, // rc_max_intra_bitrate_pct + 0, // rc_max_inter_bitrate_pct 0, // lossless 0, // frame_parallel_decoding_mode NO_AQ, // aq_mode @@ -380,6 +382,7 @@ static vpx_codec_err_t set_encoder_config( // Convert target bandwidth from Kbit/s to Bit/s oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate; oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct; + oxcf->rc_max_inter_bitrate_pct = extra_cfg->rc_max_inter_bitrate_pct; oxcf->best_allowed_q = extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_min_quantizer); @@ -649,6 +652,14 @@ static vpx_codec_err_t ctrl_set_rc_max_intra_bitrate_pct( return update_extra_cfg(ctx, &extra_cfg); } +static vpx_codec_err_t ctrl_set_rc_max_inter_bitrate_pct( + vpx_codec_alg_priv_t *ctx, va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.rc_max_inter_bitrate_pct = + CAST(VP8E_SET_MAX_INTER_BITRATE_PCT, args); + return update_extra_cfg(ctx, &extra_cfg); +} + static vpx_codec_err_t ctrl_set_lossless(vpx_codec_alg_priv_t *ctx, va_list args) { struct vp9_extracfg extra_cfg = ctx->extra_cfg; @@ -1266,6 +1277,7 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { {VP8E_SET_TUNING, ctrl_set_tuning}, {VP8E_SET_CQ_LEVEL, ctrl_set_cq_level}, {VP8E_SET_MAX_INTRA_BITRATE_PCT, ctrl_set_rc_max_intra_bitrate_pct}, + {VP8E_SET_MAX_INTER_BITRATE_PCT, ctrl_set_rc_max_inter_bitrate_pct}, {VP9E_SET_LOSSLESS, ctrl_set_lossless}, {VP9E_SET_FRAME_PARALLEL_DECODING, ctrl_set_frame_parallel_decoding_mode}, {VP9E_SET_AQ_MODE, ctrl_set_aq_mode}, diff --git a/vpx/vp8cx.h b/vpx/vp8cx.h index 77d9d6a1c..406a0d276 100644 --- a/vpx/vp8cx.h +++ b/vpx/vp8cx.h @@ -194,6 +194,20 @@ enum vp8e_enc_control_id { */ VP8E_SET_MAX_INTRA_BITRATE_PCT, + /*!\brief Max data rate for Inter frames + * + * This value controls additional clamping on the maximum size of an + * inter frame. It is expressed as a percentage of the average + * per-frame bitrate, with the special (and default) value 0 meaning + * unlimited, or no additional clamping beyond the codec's built-in + * algorithm. + * + * For example, to allow no more than 4.5 frames worth of bitrate + * to an inter frame, set this to 450. + * + */ + VP8E_SET_MAX_INTER_BITRATE_PCT, + /* TODO(jkoleszar): Move to vp9cx.h */ VP9E_SET_LOSSLESS, @@ -360,6 +374,7 @@ VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER, int *) VPX_CTRL_USE_TYPE(VP8E_GET_LAST_QUANTIZER_64, int *) VPX_CTRL_USE_TYPE(VP8E_SET_MAX_INTRA_BITRATE_PCT, unsigned int) +VPX_CTRL_USE_TYPE(VP8E_SET_MAX_INTER_BITRATE_PCT, unsigned int) VPX_CTRL_USE_TYPE(VP9E_SET_LOSSLESS, unsigned int) diff --git a/vpxenc.c b/vpxenc.c index 0a0c0718b..e88dcebd8 100644 --- a/vpxenc.c +++ b/vpxenc.c @@ -349,6 +349,8 @@ static const arg_def_t cq_level = ARG_DEF( NULL, "cq-level", 1, "Constant/Constrained Quality level"); static const arg_def_t max_intra_rate_pct = ARG_DEF( NULL, "max-intra-rate", 1, "Max I-frame bitrate (pct)"); +static const arg_def_t max_inter_rate_pct = ARG_DEF( + NULL, "max-inter-rate", 1, "Max P-frame bitrate (pct)"); #if CONFIG_VP8_ENCODER static const arg_def_t token_parts = ARG_DEF( @@ -414,7 +416,7 @@ static const arg_def_t tune_content = ARG_DEF_ENUM( static const arg_def_t *vp9_args[] = { &cpu_used, &auto_altref, &sharpness, &static_thresh, &tile_cols, &tile_rows, &arnr_maxframes, &arnr_strength, &arnr_type, - &tune_ssim, &cq_level, &max_intra_rate_pct, &lossless, + &tune_ssim, &cq_level, &max_intra_rate_pct, &max_inter_rate_pct, &lossless, &frame_parallel_decoding, &aq_mode, &frame_periodic_boost, &noise_sens, &tune_content, #if CONFIG_VP9 && CONFIG_VP9_HIGHBITDEPTH @@ -428,6 +430,7 @@ static const int vp9_arg_ctrl_map[] = { VP9E_SET_TILE_COLUMNS, VP9E_SET_TILE_ROWS, VP8E_SET_ARNR_MAXFRAMES, VP8E_SET_ARNR_STRENGTH, VP8E_SET_ARNR_TYPE, VP8E_SET_TUNING, VP8E_SET_CQ_LEVEL, VP8E_SET_MAX_INTRA_BITRATE_PCT, + VP8E_SET_MAX_INTER_BITRATE_PCT, VP9E_SET_LOSSLESS, VP9E_SET_FRAME_PARALLEL_DECODING, VP9E_SET_AQ_MODE, VP9E_SET_FRAME_PERIODIC_BOOST, VP9E_SET_NOISE_SENSITIVITY, VP9E_SET_TUNE_CONTENT, -- 2.40.0