summaryrefslogtreecommitdiff
path: root/vp9/vp9_cx_iface.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/vp9_cx_iface.c')
-rw-r--r--vp9/vp9_cx_iface.c207
1 files changed, 135 insertions, 72 deletions
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index bd6b07a29..ecfacfaf4 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -13,6 +13,7 @@
#include "./vpx_config.h"
#include "vpx/vpx_encoder.h"
+#include "vpx/vpx_ext_ratectrl.h"
#include "vpx_dsp/psnr.h"
#include "vpx_ports/vpx_once.h"
#include "vpx_ports/static_assert.h"
@@ -355,13 +356,14 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
switch (img->fmt) {
case VPX_IMG_FMT_YV12:
case VPX_IMG_FMT_I420:
- case VPX_IMG_FMT_I42016: break;
+ case VPX_IMG_FMT_I42016:
+ case VPX_IMG_FMT_NV12: break;
case VPX_IMG_FMT_I422:
case VPX_IMG_FMT_I444:
case VPX_IMG_FMT_I440:
if (ctx->cfg.g_profile != (unsigned int)PROFILE_1) {
ERROR(
- "Invalid image format. I422, I444, I440 images are "
+ "Invalid image format. I422, I444, I440, NV12 images are "
"not supported in profile.");
}
break;
@@ -391,6 +393,7 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx,
static int get_image_bps(const vpx_image_t *img) {
switch (img->fmt) {
case VPX_IMG_FMT_YV12:
+ case VPX_IMG_FMT_NV12:
case VPX_IMG_FMT_I420: return 12;
case VPX_IMG_FMT_I422: return 16;
case VPX_IMG_FMT_I444: return 24;
@@ -468,10 +471,11 @@ static vpx_rational64_t get_g_timebase_in_ts(vpx_rational_t g_timebase) {
}
static vpx_codec_err_t set_encoder_config(
- VP9EncoderConfig *oxcf, const vpx_codec_enc_cfg_t *cfg,
+ VP9EncoderConfig *oxcf, vpx_codec_enc_cfg_t *cfg,
const struct vp9_extracfg *extra_cfg) {
const int is_vbr = cfg->rc_end_usage == VPX_VBR;
int sl, tl;
+ unsigned int raw_target_rate;
oxcf->profile = cfg->g_profile;
oxcf->max_threads = (int)cfg->g_threads;
oxcf->width = cfg->g_w;
@@ -498,8 +502,14 @@ static vpx_codec_err_t set_encoder_config(
cfg->g_pass == VPX_RC_FIRST_PASS ? 0 : cfg->g_lag_in_frames;
oxcf->rc_mode = cfg->rc_end_usage;
+ raw_target_rate =
+ (unsigned int)((int64_t)oxcf->width * oxcf->height * oxcf->bit_depth * 3 *
+ oxcf->init_framerate / 1000);
+ // Cap target bitrate to raw rate
+ cfg->rc_target_bitrate = VPXMIN(raw_target_rate, cfg->rc_target_bitrate);
+
// Convert target bandwidth from Kbit/s to Bit/s
- oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate;
+ oxcf->target_bandwidth = 1000 * (int64_t)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->gf_cbr_boost_pct = extra_cfg->gf_cbr_boost_pct;
@@ -624,7 +634,7 @@ static vpx_codec_err_t set_encoder_config(
}
if (get_level_index(oxcf->target_level) >= 0) config_target_level(oxcf);
- // vp9_dump_encoder_config(oxcf);
+ // vp9_dump_encoder_config(oxcf, stderr);
return VPX_CODEC_OK;
}
@@ -1563,6 +1573,7 @@ static vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx,
lc->scaling_factor_num = params->scaling_factor_num[sl];
lc->scaling_factor_den = params->scaling_factor_den[sl];
lc->speed = params->speed_per_layer[sl];
+ lc->loopfilter_ctrl = params->loopfilter_ctrl[sl];
}
}
@@ -1707,6 +1718,52 @@ static vpx_codec_err_t ctrl_set_postencode_drop(vpx_codec_alg_priv_t *ctx,
return VPX_CODEC_OK;
}
+static vpx_codec_err_t ctrl_set_disable_overshoot_maxq_cbr(
+ vpx_codec_alg_priv_t *ctx, va_list args) {
+ VP9_COMP *const cpi = ctx->cpi;
+ const unsigned int data = va_arg(args, unsigned int);
+ cpi->rc.disable_overshoot_maxq_cbr = data;
+ return VPX_CODEC_OK;
+}
+
+static vpx_codec_err_t ctrl_set_disable_loopfilter(vpx_codec_alg_priv_t *ctx,
+ va_list args) {
+ VP9_COMP *const cpi = ctx->cpi;
+ const unsigned int data = va_arg(args, unsigned int);
+ cpi->loopfilter_ctrl = data;
+ return VPX_CODEC_OK;
+}
+
+static vpx_codec_err_t ctrl_set_external_rate_control(vpx_codec_alg_priv_t *ctx,
+ va_list args) {
+ vpx_rc_funcs_t funcs = *CAST(VP9E_SET_EXTERNAL_RATE_CONTROL, args);
+ VP9_COMP *cpi = ctx->cpi;
+ EXT_RATECTRL *ext_ratectrl = &cpi->ext_ratectrl;
+ const VP9EncoderConfig *oxcf = &cpi->oxcf;
+ // TODO(angiebird): Check the possibility of this flag being set at pass == 1
+ if (oxcf->pass == 2) {
+ const FRAME_INFO *frame_info = &cpi->frame_info;
+ vpx_rc_config_t ratectrl_config;
+ vpx_codec_err_t codec_status;
+
+ ratectrl_config.frame_width = frame_info->frame_width;
+ ratectrl_config.frame_height = frame_info->frame_height;
+ ratectrl_config.show_frame_count = cpi->twopass.first_pass_info.num_frames;
+
+ // TODO(angiebird): Double check whether this is the proper way to set up
+ // target_bitrate and frame_rate.
+ ratectrl_config.target_bitrate_kbps = (int)(oxcf->target_bandwidth / 1000);
+ ratectrl_config.frame_rate_num = oxcf->g_timebase.den;
+ ratectrl_config.frame_rate_den = oxcf->g_timebase.num;
+
+ codec_status = vp9_extrc_create(funcs, ratectrl_config, ext_ratectrl);
+ if (codec_status != VPX_CODEC_OK) {
+ return codec_status;
+ }
+ }
+ return VPX_CODEC_OK;
+}
+
static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ VP8_COPY_REFERENCE, ctrl_copy_reference },
@@ -1751,12 +1808,15 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ VP9E_SET_TARGET_LEVEL, ctrl_set_target_level },
{ VP9E_SET_ROW_MT, ctrl_set_row_mt },
{ VP9E_SET_POSTENCODE_DROP, ctrl_set_postencode_drop },
+ { VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, ctrl_set_disable_overshoot_maxq_cbr },
{ VP9E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
{ VP9E_SET_SVC_INTER_LAYER_PRED, ctrl_set_svc_inter_layer_pred },
{ VP9E_SET_SVC_FRAME_DROP_LAYER, ctrl_set_svc_frame_drop_layer },
{ VP9E_SET_SVC_GF_TEMPORAL_REF, ctrl_set_svc_gf_temporal_ref },
{ VP9E_SET_SVC_SPATIAL_LAYER_SYNC, ctrl_set_svc_spatial_layer_sync },
{ VP9E_SET_DELTA_Q_UV, ctrl_set_delta_q_uv },
+ { VP9E_SET_DISABLE_LOOPFILTER, ctrl_set_disable_loopfilter },
+ { VP9E_SET_EXTERNAL_RATE_CONTROL, ctrl_set_external_rate_control },
// Getters
{ VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer },
@@ -1890,7 +1950,7 @@ static vp9_extracfg get_extra_cfg() {
VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height,
vpx_rational_t frame_rate,
- int target_bitrate,
+ int target_bitrate, int encode_speed,
vpx_enc_pass enc_pass) {
/* This function will generate the same VP9EncoderConfig used by the
* vpxenc command given below.
@@ -1901,6 +1961,7 @@ VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height,
* HEIGHT: frame_height
* FPS: frame_rate
* BITRATE: target_bitrate
+ * CPU_USED:encode_speed
*
* INPUT, OUTPUT, LIMIT will not affect VP9EncoderConfig
*
@@ -1912,9 +1973,10 @@ VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height,
* BITRATE=600
* FPS=30/1
* LIMIT=150
+ * CPU_USED=0
* ./vpxenc --limit=$LIMIT --width=$WIDTH --height=$HEIGHT --fps=$FPS
* --lag-in-frames=25 \
- * --codec=vp9 --good --cpu-used=0 --threads=0 --profile=0 \
+ * --codec=vp9 --good --cpu-used=CPU_USED --threads=0 --profile=0 \
* --min-q=0 --max-q=63 --auto-alt-ref=1 --passes=2 --kf-max-dist=150 \
* --kf-min-dist=0 --drop-frame=0 --static-thresh=0 --bias-pct=50 \
* --minsection-pct=0 --maxsection-pct=150 --arnr-maxframes=7 --psnr \
@@ -1937,49 +1999,50 @@ VP9EncoderConfig vp9_get_encoder_config(int frame_width, int frame_height,
oxcf.tile_columns = 0;
oxcf.frame_parallel_decoding_mode = 0;
oxcf.two_pass_vbrmax_section = 150;
+ oxcf.speed = abs(encode_speed);
return oxcf;
}
-#define DUMP_STRUCT_VALUE(struct, value) \
- printf(#value " %" PRId64 "\n", (int64_t)(struct)->value)
+#define DUMP_STRUCT_VALUE(fp, structure, value) \
+ fprintf(fp, #value " %" PRId64 "\n", (int64_t)(structure)->value)
-void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf) {
- DUMP_STRUCT_VALUE(oxcf, profile);
- DUMP_STRUCT_VALUE(oxcf, bit_depth);
- DUMP_STRUCT_VALUE(oxcf, width);
- DUMP_STRUCT_VALUE(oxcf, height);
- DUMP_STRUCT_VALUE(oxcf, input_bit_depth);
- DUMP_STRUCT_VALUE(oxcf, init_framerate);
+void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf, FILE *fp) {
+ DUMP_STRUCT_VALUE(fp, oxcf, profile);
+ DUMP_STRUCT_VALUE(fp, oxcf, bit_depth);
+ DUMP_STRUCT_VALUE(fp, oxcf, width);
+ DUMP_STRUCT_VALUE(fp, oxcf, height);
+ DUMP_STRUCT_VALUE(fp, oxcf, input_bit_depth);
+ DUMP_STRUCT_VALUE(fp, oxcf, init_framerate);
// TODO(angiebird): dump g_timebase
// TODO(angiebird): dump g_timebase_in_ts
- DUMP_STRUCT_VALUE(oxcf, target_bandwidth);
+ DUMP_STRUCT_VALUE(fp, oxcf, target_bandwidth);
- DUMP_STRUCT_VALUE(oxcf, noise_sensitivity);
- DUMP_STRUCT_VALUE(oxcf, sharpness);
- DUMP_STRUCT_VALUE(oxcf, speed);
- DUMP_STRUCT_VALUE(oxcf, rc_max_intra_bitrate_pct);
- DUMP_STRUCT_VALUE(oxcf, rc_max_inter_bitrate_pct);
- DUMP_STRUCT_VALUE(oxcf, gf_cbr_boost_pct);
+ DUMP_STRUCT_VALUE(fp, oxcf, noise_sensitivity);
+ DUMP_STRUCT_VALUE(fp, oxcf, sharpness);
+ DUMP_STRUCT_VALUE(fp, oxcf, speed);
+ DUMP_STRUCT_VALUE(fp, oxcf, rc_max_intra_bitrate_pct);
+ DUMP_STRUCT_VALUE(fp, oxcf, rc_max_inter_bitrate_pct);
+ DUMP_STRUCT_VALUE(fp, oxcf, gf_cbr_boost_pct);
- DUMP_STRUCT_VALUE(oxcf, mode);
- DUMP_STRUCT_VALUE(oxcf, pass);
+ DUMP_STRUCT_VALUE(fp, oxcf, mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, pass);
// Key Framing Operations
- DUMP_STRUCT_VALUE(oxcf, auto_key);
- DUMP_STRUCT_VALUE(oxcf, key_freq);
+ DUMP_STRUCT_VALUE(fp, oxcf, auto_key);
+ DUMP_STRUCT_VALUE(fp, oxcf, key_freq);
- DUMP_STRUCT_VALUE(oxcf, lag_in_frames);
+ DUMP_STRUCT_VALUE(fp, oxcf, lag_in_frames);
// ----------------------------------------------------------------
// DATARATE CONTROL OPTIONS
// vbr, cbr, constrained quality or constant quality
- DUMP_STRUCT_VALUE(oxcf, rc_mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, rc_mode);
// buffer targeting aggressiveness
- DUMP_STRUCT_VALUE(oxcf, under_shoot_pct);
- DUMP_STRUCT_VALUE(oxcf, over_shoot_pct);
+ DUMP_STRUCT_VALUE(fp, oxcf, under_shoot_pct);
+ DUMP_STRUCT_VALUE(fp, oxcf, over_shoot_pct);
// buffering parameters
// TODO(angiebird): dump tarting_buffer_level_ms
@@ -1987,37 +2050,37 @@ void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf) {
// TODO(angiebird): dump maximum_buffer_size_ms
// Frame drop threshold.
- DUMP_STRUCT_VALUE(oxcf, drop_frames_water_mark);
+ DUMP_STRUCT_VALUE(fp, oxcf, drop_frames_water_mark);
// controlling quality
- DUMP_STRUCT_VALUE(oxcf, fixed_q);
- DUMP_STRUCT_VALUE(oxcf, worst_allowed_q);
- DUMP_STRUCT_VALUE(oxcf, best_allowed_q);
- DUMP_STRUCT_VALUE(oxcf, cq_level);
- DUMP_STRUCT_VALUE(oxcf, aq_mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, fixed_q);
+ DUMP_STRUCT_VALUE(fp, oxcf, worst_allowed_q);
+ DUMP_STRUCT_VALUE(fp, oxcf, best_allowed_q);
+ DUMP_STRUCT_VALUE(fp, oxcf, cq_level);
+ DUMP_STRUCT_VALUE(fp, oxcf, aq_mode);
// Special handling of Adaptive Quantization for AltRef frames
- DUMP_STRUCT_VALUE(oxcf, alt_ref_aq);
+ DUMP_STRUCT_VALUE(fp, oxcf, alt_ref_aq);
// Internal frame size scaling.
- DUMP_STRUCT_VALUE(oxcf, resize_mode);
- DUMP_STRUCT_VALUE(oxcf, scaled_frame_width);
- DUMP_STRUCT_VALUE(oxcf, scaled_frame_height);
+ DUMP_STRUCT_VALUE(fp, oxcf, resize_mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, scaled_frame_width);
+ DUMP_STRUCT_VALUE(fp, oxcf, scaled_frame_height);
// Enable feature to reduce the frame quantization every x frames.
- DUMP_STRUCT_VALUE(oxcf, frame_periodic_boost);
+ DUMP_STRUCT_VALUE(fp, oxcf, frame_periodic_boost);
// two pass datarate control
- DUMP_STRUCT_VALUE(oxcf, two_pass_vbrbias);
- DUMP_STRUCT_VALUE(oxcf, two_pass_vbrmin_section);
- DUMP_STRUCT_VALUE(oxcf, two_pass_vbrmax_section);
- DUMP_STRUCT_VALUE(oxcf, vbr_corpus_complexity);
+ DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrbias);
+ DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrmin_section);
+ DUMP_STRUCT_VALUE(fp, oxcf, two_pass_vbrmax_section);
+ DUMP_STRUCT_VALUE(fp, oxcf, vbr_corpus_complexity);
// END DATARATE CONTROL OPTIONS
// ----------------------------------------------------------------
// Spatial and temporal scalability.
- DUMP_STRUCT_VALUE(oxcf, ss_number_layers);
- DUMP_STRUCT_VALUE(oxcf, ts_number_layers);
+ DUMP_STRUCT_VALUE(fp, oxcf, ss_number_layers);
+ DUMP_STRUCT_VALUE(fp, oxcf, ts_number_layers);
// Bitrate allocation for spatial layers.
// TODO(angiebird): dump layer_target_bitrate[VPX_MAX_LAYERS]
@@ -2025,25 +2088,25 @@ void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf) {
// TODO(angiebird): dump ss_enable_auto_arf[VPX_SS_MAX_LAYERS]
// TODO(angiebird): dump ts_rate_decimator[VPX_TS_MAX_LAYERS]
- DUMP_STRUCT_VALUE(oxcf, enable_auto_arf);
- DUMP_STRUCT_VALUE(oxcf, encode_breakout);
- DUMP_STRUCT_VALUE(oxcf, error_resilient_mode);
- DUMP_STRUCT_VALUE(oxcf, frame_parallel_decoding_mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, enable_auto_arf);
+ DUMP_STRUCT_VALUE(fp, oxcf, encode_breakout);
+ DUMP_STRUCT_VALUE(fp, oxcf, error_resilient_mode);
+ DUMP_STRUCT_VALUE(fp, oxcf, frame_parallel_decoding_mode);
- DUMP_STRUCT_VALUE(oxcf, arnr_max_frames);
- DUMP_STRUCT_VALUE(oxcf, arnr_strength);
+ DUMP_STRUCT_VALUE(fp, oxcf, arnr_max_frames);
+ DUMP_STRUCT_VALUE(fp, oxcf, arnr_strength);
- DUMP_STRUCT_VALUE(oxcf, min_gf_interval);
- DUMP_STRUCT_VALUE(oxcf, max_gf_interval);
+ DUMP_STRUCT_VALUE(fp, oxcf, min_gf_interval);
+ DUMP_STRUCT_VALUE(fp, oxcf, max_gf_interval);
- DUMP_STRUCT_VALUE(oxcf, tile_columns);
- DUMP_STRUCT_VALUE(oxcf, tile_rows);
+ DUMP_STRUCT_VALUE(fp, oxcf, tile_columns);
+ DUMP_STRUCT_VALUE(fp, oxcf, tile_rows);
- DUMP_STRUCT_VALUE(oxcf, enable_tpl_model);
+ DUMP_STRUCT_VALUE(fp, oxcf, enable_tpl_model);
- DUMP_STRUCT_VALUE(oxcf, max_threads);
+ DUMP_STRUCT_VALUE(fp, oxcf, max_threads);
- DUMP_STRUCT_VALUE(oxcf, target_level);
+ DUMP_STRUCT_VALUE(fp, oxcf, target_level);
// TODO(angiebird): dump two_pass_stats_in
@@ -2051,19 +2114,19 @@ void vp9_dump_encoder_config(const VP9EncoderConfig *oxcf) {
// TODO(angiebird): dump firstpass_mb_stats_in
#endif
- DUMP_STRUCT_VALUE(oxcf, tuning);
- DUMP_STRUCT_VALUE(oxcf, content);
+ DUMP_STRUCT_VALUE(fp, oxcf, tuning);
+ DUMP_STRUCT_VALUE(fp, oxcf, content);
#if CONFIG_VP9_HIGHBITDEPTH
- DUMP_STRUCT_VALUE(oxcf, use_highbitdepth);
+ DUMP_STRUCT_VALUE(fp, oxcf, use_highbitdepth);
#endif
- DUMP_STRUCT_VALUE(oxcf, color_space);
- DUMP_STRUCT_VALUE(oxcf, color_range);
- DUMP_STRUCT_VALUE(oxcf, render_width);
- DUMP_STRUCT_VALUE(oxcf, render_height);
- DUMP_STRUCT_VALUE(oxcf, temporal_layering_mode);
-
- DUMP_STRUCT_VALUE(oxcf, row_mt);
- DUMP_STRUCT_VALUE(oxcf, motion_vector_unit_test);
+ DUMP_STRUCT_VALUE(fp, oxcf, color_space);
+ DUMP_STRUCT_VALUE(fp, oxcf, color_range);
+ DUMP_STRUCT_VALUE(fp, oxcf, render_width);
+ DUMP_STRUCT_VALUE(fp, oxcf, render_height);
+ DUMP_STRUCT_VALUE(fp, oxcf, temporal_layering_mode);
+
+ DUMP_STRUCT_VALUE(fp, oxcf, row_mt);
+ DUMP_STRUCT_VALUE(fp, oxcf, motion_vector_unit_test);
}
FRAME_INFO vp9_get_frame_info(const VP9EncoderConfig *oxcf) {