diff options
Diffstat (limited to 'libvpx/vp9/vp9_cx_iface.c')
-rw-r--r-- | libvpx/vp9/vp9_cx_iface.c | 638 |
1 files changed, 402 insertions, 236 deletions
diff --git a/libvpx/vp9/vp9_cx_iface.c b/libvpx/vp9/vp9_cx_iface.c index 152e1f46e..bf8eec717 100644 --- a/libvpx/vp9/vp9_cx_iface.c +++ b/libvpx/vp9/vp9_cx_iface.c @@ -11,10 +11,11 @@ #include <stdlib.h> #include <string.h> +#include "./vpx_config.h" #include "vpx/vpx_codec.h" #include "vpx/internal/vpx_codec_internal.h" #include "./vpx_version.h" -#include "vp9/encoder/vp9_onyx_int.h" +#include "vp9/encoder/vp9_encoder.h" #include "vpx/vp8cx.h" #include "vp9/encoder/vp9_firstpass.h" #include "vp9/vp9_iface_common.h" @@ -39,10 +40,11 @@ struct vp9_extracfg { AQ_MODE aq_mode; unsigned int frame_periodic_boost; BIT_DEPTH bit_depth; + vp9e_tune_content content; }; struct extraconfig_map { - int usage; + unsigned int usage; struct vp9_extracfg cfg; }; @@ -69,6 +71,7 @@ static const struct extraconfig_map extracfg_map[] = { NO_AQ, // aq_mode 0, // frame_periodic_delta_q BITS_8, // Bit depth + VP9E_CONTENT_DEFAULT // content } } }; @@ -77,7 +80,7 @@ struct vpx_codec_alg_priv { vpx_codec_priv_t base; vpx_codec_enc_cfg_t cfg; struct vp9_extracfg extra_cfg; - VP9_CONFIG oxcf; + VP9EncoderConfig oxcf; VP9_COMP *cpi; unsigned char *cx_data; size_t cx_data_sz; @@ -88,8 +91,8 @@ struct vpx_codec_alg_priv { size_t pending_frame_magnitude; vpx_image_t preview_img; vp8_postproc_cfg_t preview_ppcfg; - vpx_codec_pkt_list_decl(64) pkt_list; - unsigned int fixed_kf_cntr; + vpx_codec_pkt_list_decl(256) pkt_list; + unsigned int fixed_kf_cntr; }; static VP9_REFFRAME ref_frame_to_vp9_reframe(vpx_ref_frame_type_t frame) { @@ -168,7 +171,25 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, RANGE_CHECK_HI(cfg, rc_resize_down_thresh, 100); RANGE_CHECK(cfg, g_pass, VPX_RC_ONE_PASS, VPX_RC_LAST_PASS); + if (cfg->rc_resize_allowed == 1) { + RANGE_CHECK(cfg, rc_scaled_width, 1, cfg->g_w); + RANGE_CHECK(cfg, rc_scaled_height, 1, cfg->g_h); + } + RANGE_CHECK(cfg, ss_number_layers, 1, VPX_SS_MAX_LAYERS); + +#if CONFIG_SPATIAL_SVC + if (cfg->ss_number_layers > 1) { + unsigned int i, alt_ref_sum = 0; + for (i = 0; i < cfg->ss_number_layers; ++i) { + if (cfg->ss_enable_auto_alt_ref[i]) + ++alt_ref_sum; + } + if (alt_ref_sum > REF_FRAMES - cfg->ss_number_layers) + ERROR("Not enough ref buffers for svc alt ref frames"); + } +#endif + RANGE_CHECK(cfg, ts_number_layers, 1, VPX_TS_MAX_LAYERS); if (cfg->ts_number_layers > 1) { unsigned int i; @@ -182,7 +203,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, ERROR("ts_rate_decimator factors are not powers of 2"); } - // VP8 does not support a lower bound on the keyframe interval in + // VP9 does not support a lower bound on the keyframe interval in // automatic keyframe placement mode. if (cfg->kf_mode != VPX_KF_DISABLED && cfg->kf_min_dist != cfg->kf_max_dist && @@ -200,14 +221,16 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, RANGE_CHECK_HI(extra_cfg, arnr_strength, 6); RANGE_CHECK(extra_cfg, arnr_type, 1, 3); RANGE_CHECK(extra_cfg, cq_level, 0, 63); + RANGE_CHECK(extra_cfg, content, + VP9E_CONTENT_DEFAULT, VP9E_CONTENT_INVALID - 1); // TODO(yaowu): remove this when ssim tuning is implemented for vp9 if (extra_cfg->tuning == VP8_TUNE_SSIM) ERROR("Option --tune=ssim is not currently supported in VP9."); if (cfg->g_pass == VPX_RC_LAST_PASS) { - size_t packet_sz = sizeof(FIRSTPASS_STATS); - int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz); + const size_t packet_sz = sizeof(FIRSTPASS_STATS); + const int n_packets = (int)(cfg->rc_twopass_stats_in.sz / packet_sz); const FIRSTPASS_STATS *stats; if (cfg->rc_twopass_stats_in.buf == NULL) @@ -240,7 +263,8 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, layer_id = (int)stats->spatial_layer_id; if (layer_id >= cfg->ss_number_layers - ||(int)(stats->count + 0.5) != n_packets_per_layer[layer_id] - 1) + ||(unsigned int)(stats->count + 0.5) != + n_packets_per_layer[layer_id] - 1) ERROR("rc_twopass_stats_in missing EOS stats packet"); } } else { @@ -254,6 +278,7 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, ERROR("rc_twopass_stats_in missing EOS stats packet"); } } + if (cfg->g_profile <= (unsigned int)PROFILE_1 && extra_cfg->bit_depth > BITS_8) ERROR("High bit-depth not supported in profile < 2"); @@ -276,6 +301,7 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx, default: ERROR("Invalid image format. Only YV12, I420, I422, I444 images are " "supported."); + break; } if (img->d_w != ctx->cfg.g_w || img->d_h != ctx->cfg.g_h) @@ -284,9 +310,19 @@ static vpx_codec_err_t validate_img(vpx_codec_alg_priv_t *ctx, return VPX_CODEC_OK; } +static int get_image_bps(const vpx_image_t *img) { + switch (img->fmt) { + case VPX_IMG_FMT_YV12: + case VPX_IMG_FMT_I420: return 12; + case VPX_IMG_FMT_I422: return 16; + case VPX_IMG_FMT_I444: return 24; + default: assert(0 && "Invalid image format"); break; + } + return 0; +} static vpx_codec_err_t set_encoder_config( - VP9_CONFIG *oxcf, + VP9EncoderConfig *oxcf, const vpx_codec_enc_cfg_t *cfg, const struct vp9_extracfg *extra_cfg) { oxcf->profile = cfg->g_profile; @@ -300,41 +336,44 @@ static vpx_codec_err_t set_encoder_config( switch (cfg->g_pass) { case VPX_RC_ONE_PASS: - oxcf->mode = MODE_GOODQUALITY; + oxcf->mode = ONE_PASS_GOOD; + oxcf->pass = 0; break; case VPX_RC_FIRST_PASS: - oxcf->mode = MODE_FIRSTPASS; + oxcf->mode = TWO_PASS_FIRST; + oxcf->pass = 1; break; case VPX_RC_LAST_PASS: - oxcf->mode = MODE_SECONDPASS_BEST; + oxcf->mode = TWO_PASS_SECOND_BEST; + oxcf->pass = 2; break; } oxcf->lag_in_frames = cfg->g_pass == VPX_RC_FIRST_PASS ? 0 : cfg->g_lag_in_frames; + oxcf->rc_mode = cfg->rc_end_usage; - oxcf->end_usage = USAGE_LOCAL_FILE_PLAYBACK; - if (cfg->rc_end_usage == VPX_CQ) - oxcf->end_usage = USAGE_CONSTRAINED_QUALITY; - else if (cfg->rc_end_usage == VPX_Q) - oxcf->end_usage = USAGE_CONSTANT_QUALITY; - else if (cfg->rc_end_usage == VPX_CBR) - oxcf->end_usage = USAGE_STREAM_FROM_SERVER; - - oxcf->target_bandwidth = cfg->rc_target_bitrate; + // 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->best_allowed_q = q_trans[cfg->rc_min_quantizer]; - oxcf->worst_allowed_q = q_trans[cfg->rc_max_quantizer]; - oxcf->cq_level = q_trans[extra_cfg->cq_level]; + oxcf->best_allowed_q = + extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_min_quantizer); + oxcf->worst_allowed_q = + extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_max_quantizer); + oxcf->cq_level = vp9_quantizer_to_qindex(extra_cfg->cq_level); oxcf->fixed_q = -1; oxcf->under_shoot_pct = cfg->rc_undershoot_pct; oxcf->over_shoot_pct = cfg->rc_overshoot_pct; - oxcf->maximum_buffer_size = cfg->rc_buf_sz; - oxcf->starting_buffer_level = cfg->rc_buf_initial_sz; - oxcf->optimal_buffer_level = cfg->rc_buf_optimal_sz; + oxcf->allow_spatial_resampling = cfg->rc_resize_allowed; + oxcf->scaled_frame_width = cfg->rc_scaled_width; + oxcf->scaled_frame_height = cfg->rc_scaled_height; + + oxcf->maximum_buffer_size_ms = cfg->rc_buf_sz; + oxcf->starting_buffer_level_ms = cfg->rc_buf_initial_sz; + oxcf->optimal_buffer_level_ms = cfg->rc_buf_optimal_sz; oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh; @@ -347,7 +386,7 @@ static vpx_codec_err_t set_encoder_config( oxcf->key_freq = cfg->kf_max_dist; - oxcf->cpu_used = extra_cfg->cpu_used; + oxcf->speed = abs(extra_cfg->cpu_used); oxcf->encode_breakout = extra_cfg->static_thresh; oxcf->play_alternate = extra_cfg->enable_auto_alt_ref; oxcf->noise_sensitivity = extra_cfg->noise_sensitivity; @@ -356,17 +395,20 @@ static vpx_codec_err_t set_encoder_config( oxcf->two_pass_stats_in = cfg->rc_twopass_stats_in; oxcf->output_pkt_list = extra_cfg->pkt_list; +#if CONFIG_FP_MB_STATS + oxcf->firstpass_mb_stats_in = cfg->rc_firstpass_mb_stats_in; +#endif + oxcf->arnr_max_frames = extra_cfg->arnr_max_frames; oxcf->arnr_strength = extra_cfg->arnr_strength; oxcf->arnr_type = extra_cfg->arnr_type; oxcf->tuning = extra_cfg->tuning; + oxcf->content = extra_cfg->content; oxcf->tile_columns = extra_cfg->tile_columns; oxcf->tile_rows = extra_cfg->tile_rows; - oxcf->lossless = extra_cfg->lossless; - oxcf->error_resilient_mode = cfg->g_error_resilient; oxcf->frame_parallel_decoding_mode = extra_cfg->frame_parallel_decoding_mode; @@ -377,7 +419,13 @@ static vpx_codec_err_t set_encoder_config( oxcf->ss_number_layers = cfg->ss_number_layers; if (oxcf->ss_number_layers > 1) { - vp9_copy(oxcf->ss_target_bitrate, cfg->ss_target_bitrate); + int i; + for (i = 0; i < VPX_SS_MAX_LAYERS; ++i) { + oxcf->ss_target_bitrate[i] = 1000 * cfg->ss_target_bitrate[i]; +#if CONFIG_SPATIAL_SVC + oxcf->ss_play_alternate[i] = cfg->ss_enable_auto_alt_ref[i]; +#endif + } } else if (oxcf->ss_number_layers == 1) { oxcf->ss_target_bitrate[0] = (int)oxcf->target_bandwidth; } @@ -385,8 +433,11 @@ static vpx_codec_err_t set_encoder_config( oxcf->ts_number_layers = cfg->ts_number_layers; if (oxcf->ts_number_layers > 1) { - vp9_copy(oxcf->ts_target_bitrate, cfg->ts_target_bitrate); - vp9_copy(oxcf->ts_rate_decimator, cfg->ts_rate_decimator); + int i; + for (i = 0; i < VPX_TS_MAX_LAYERS; ++i) { + oxcf->ts_target_bitrate[i] = 1000 * cfg->ts_target_bitrate[i]; + oxcf->ts_rate_decimator[i] = cfg->ts_rate_decimator[i]; + } } else if (oxcf->ts_number_layers == 1) { oxcf->ts_target_bitrate[0] = (int)oxcf->target_bandwidth; oxcf->ts_rate_decimator[0] = 1; @@ -410,6 +461,9 @@ static vpx_codec_err_t set_encoder_config( printf("fixed_q: %d\n", oxcf->fixed_q); printf("worst_allowed_q: %d\n", oxcf->worst_allowed_q); printf("best_allowed_q: %d\n", oxcf->best_allowed_q); + printf("allow_spatial_resampling: %d\n", oxcf->allow_spatial_resampling); + printf("scaled_frame_width: %d\n", oxcf->scaled_frame_width); + printf("scaled_frame_height: %d\n", oxcf->scaled_frame_height); printf("two_pass_vbrbias: %d\n", oxcf->two_pass_vbrbias); printf("two_pass_vbrmin_section: %d\n", oxcf->two_pass_vbrmin_section); printf("two_pass_vbrmax_section: %d\n", oxcf->two_pass_vbrmax_section); @@ -449,79 +503,168 @@ static vpx_codec_err_t encoder_set_config(vpx_codec_alg_priv_t *ctx, return res; } +static vpx_codec_err_t ctrl_get_quantizer(vpx_codec_alg_priv_t *ctx, + va_list args) { + int *const arg = va_arg(args, int *); + if (arg == NULL) + return VPX_CODEC_INVALID_PARAM; + *arg = vp9_get_quantizer(ctx->cpi); + return VPX_CODEC_OK; +} + +static vpx_codec_err_t ctrl_get_quantizer64(vpx_codec_alg_priv_t *ctx, + va_list args) { + int *const arg = va_arg(args, int *); + if (arg == NULL) + return VPX_CODEC_INVALID_PARAM; + *arg = vp9_qindex_to_quantizer(vp9_get_quantizer(ctx->cpi)); + return VPX_CODEC_OK; +} + +static vpx_codec_err_t update_extra_cfg(vpx_codec_alg_priv_t *ctx, + const struct vp9_extracfg *extra_cfg) { + const vpx_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg); + if (res == VPX_CODEC_OK) { + ctx->extra_cfg = *extra_cfg; + set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); + vp9_change_config(ctx->cpi, &ctx->oxcf); + } + return res; +} + +static vpx_codec_err_t ctrl_set_cpuused(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.cpu_used = CAST(VP8E_SET_CPUUSED, args); + return update_extra_cfg(ctx, &extra_cfg); +} -int vp9_reverse_trans(int q); +static vpx_codec_err_t ctrl_set_enable_auto_alt_ref(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.enable_auto_alt_ref = CAST(VP8E_SET_ENABLEAUTOALTREF, args); + return update_extra_cfg(ctx, &extra_cfg); +} +static vpx_codec_err_t ctrl_set_noise_sensitivity(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.noise_sensitivity = CAST(VP8E_SET_NOISE_SENSITIVITY, args); + return update_extra_cfg(ctx, &extra_cfg); +} -static vpx_codec_err_t ctrl_get_param(vpx_codec_alg_priv_t *ctx, int ctrl_id, - va_list args) { - void *arg = va_arg(args, void *); +static vpx_codec_err_t ctrl_set_sharpness(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.sharpness = CAST(VP8E_SET_SHARPNESS, args); + return update_extra_cfg(ctx, &extra_cfg); +} -#define MAP(id, var) case id: *(RECAST(id, arg)) = var; break +static vpx_codec_err_t ctrl_set_static_thresh(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.static_thresh = CAST(VP8E_SET_STATIC_THRESHOLD, args); + return update_extra_cfg(ctx, &extra_cfg); +} - if (arg == NULL) - return VPX_CODEC_INVALID_PARAM; +static vpx_codec_err_t ctrl_set_tile_columns(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.tile_columns = CAST(VP9E_SET_TILE_COLUMNS, args); + return update_extra_cfg(ctx, &extra_cfg); +} - switch (ctrl_id) { - MAP(VP8E_GET_LAST_QUANTIZER, vp9_get_quantizer(ctx->cpi)); - MAP(VP8E_GET_LAST_QUANTIZER_64, - vp9_reverse_trans(vp9_get_quantizer(ctx->cpi))); - } +static vpx_codec_err_t ctrl_set_tile_rows(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.tile_rows = CAST(VP9E_SET_TILE_ROWS, args); + return update_extra_cfg(ctx, &extra_cfg); +} - return VPX_CODEC_OK; -#undef MAP +static vpx_codec_err_t ctrl_set_arnr_max_frames(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.arnr_max_frames = CAST(VP8E_SET_ARNR_MAXFRAMES, args); + return update_extra_cfg(ctx, &extra_cfg); } +static vpx_codec_err_t ctrl_set_arnr_strength(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.arnr_strength = CAST(VP8E_SET_ARNR_STRENGTH, args); + return update_extra_cfg(ctx, &extra_cfg); +} -static vpx_codec_err_t ctrl_set_param(vpx_codec_alg_priv_t *ctx, int ctrl_id, - va_list args) { - vpx_codec_err_t res = VPX_CODEC_OK; +static vpx_codec_err_t ctrl_set_arnr_type(vpx_codec_alg_priv_t *ctx, + va_list args) { struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.arnr_type = CAST(VP8E_SET_ARNR_TYPE, args); + return update_extra_cfg(ctx, &extra_cfg); +} -#define MAP(id, var) case id: var = CAST(id, args); break; - - switch (ctrl_id) { - MAP(VP8E_SET_CPUUSED, extra_cfg.cpu_used); - MAP(VP8E_SET_ENABLEAUTOALTREF, extra_cfg.enable_auto_alt_ref); - MAP(VP8E_SET_NOISE_SENSITIVITY, extra_cfg.noise_sensitivity); - MAP(VP8E_SET_SHARPNESS, extra_cfg.sharpness); - MAP(VP8E_SET_STATIC_THRESHOLD, extra_cfg.static_thresh); - MAP(VP9E_SET_TILE_COLUMNS, extra_cfg.tile_columns); - MAP(VP9E_SET_TILE_ROWS, extra_cfg.tile_rows); - MAP(VP8E_SET_ARNR_MAXFRAMES, extra_cfg.arnr_max_frames); - MAP(VP8E_SET_ARNR_STRENGTH, extra_cfg.arnr_strength); - MAP(VP8E_SET_ARNR_TYPE, extra_cfg.arnr_type); - MAP(VP8E_SET_TUNING, extra_cfg.tuning); - MAP(VP8E_SET_CQ_LEVEL, extra_cfg.cq_level); - MAP(VP8E_SET_MAX_INTRA_BITRATE_PCT, extra_cfg.rc_max_intra_bitrate_pct); - MAP(VP9E_SET_LOSSLESS, extra_cfg.lossless); - MAP(VP9E_SET_FRAME_PARALLEL_DECODING, - extra_cfg.frame_parallel_decoding_mode); - MAP(VP9E_SET_AQ_MODE, extra_cfg.aq_mode); - MAP(VP9E_SET_FRAME_PERIODIC_BOOST, extra_cfg.frame_periodic_boost); - } +static vpx_codec_err_t ctrl_set_tuning(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.tuning = CAST(VP8E_SET_TUNING, args); + return update_extra_cfg(ctx, &extra_cfg); +} - res = validate_config(ctx, &ctx->cfg, &extra_cfg); +static vpx_codec_err_t ctrl_set_cq_level(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.cq_level = CAST(VP8E_SET_CQ_LEVEL, args); + return update_extra_cfg(ctx, &extra_cfg); +} - if (res == VPX_CODEC_OK) { - ctx->extra_cfg = extra_cfg; - set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); - vp9_change_config(ctx->cpi, &ctx->oxcf); - } +static vpx_codec_err_t ctrl_set_rc_max_intra_bitrate_pct( + vpx_codec_alg_priv_t *ctx, va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.rc_max_intra_bitrate_pct = + CAST(VP8E_SET_MAX_INTRA_BITRATE_PCT, args); + return update_extra_cfg(ctx, &extra_cfg); +} - return res; -#undef MAP +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; + extra_cfg.lossless = CAST(VP9E_SET_LOSSLESS, args); + return update_extra_cfg(ctx, &extra_cfg); } -static vpx_codec_err_t encoder_common_init(vpx_codec_ctx_t *ctx) { +static vpx_codec_err_t ctrl_set_frame_parallel_decoding_mode( + vpx_codec_alg_priv_t *ctx, va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.frame_parallel_decoding_mode = + CAST(VP9E_SET_FRAME_PARALLEL_DECODING, args); + return update_extra_cfg(ctx, &extra_cfg); +} + +static vpx_codec_err_t ctrl_set_aq_mode(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.aq_mode = CAST(VP9E_SET_AQ_MODE, args); + return update_extra_cfg(ctx, &extra_cfg); +} + +static vpx_codec_err_t ctrl_set_frame_periodic_boost(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.frame_periodic_boost = CAST(VP9E_SET_FRAME_PERIODIC_BOOST, args); + return update_extra_cfg(ctx, &extra_cfg); +} + +static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx, + vpx_codec_priv_enc_mr_cfg_t *data) { vpx_codec_err_t res = VPX_CODEC_OK; + (void)data; if (ctx->priv == NULL) { int i; vpx_codec_enc_cfg_t *cfg; struct vpx_codec_alg_priv *priv = calloc(1, sizeof(*priv)); - if (priv == NULL) return VPX_CODEC_MEM_ERROR; + if (priv == NULL) + return VPX_CODEC_MEM_ERROR; ctx->priv = &priv->base; ctx->priv->sz = sizeof(*ctx->priv); @@ -531,8 +674,7 @@ static vpx_codec_err_t encoder_common_init(vpx_codec_ctx_t *ctx) { ctx->priv->enc.total_encoders = 1; if (ctx->config.enc) { - // Update the reference to the config structure to an - // internal copy. + // Update the reference to the config structure to an internal copy. ctx->priv->alg_priv->cfg = *ctx->config.enc; ctx->config.enc = &ctx->priv->alg_priv->cfg; } @@ -549,15 +691,6 @@ static vpx_codec_err_t encoder_common_init(vpx_codec_ctx_t *ctx) { priv->extra_cfg = extracfg_map[i].cfg; priv->extra_cfg.pkt_list = &priv->pkt_list.head; - // Maximum buffer size approximated based on having multiple ARF. - priv->cx_data_sz = priv->cfg.g_w * priv->cfg.g_h * 3 / 2 * 8; - - if (priv->cx_data_sz < 4096) priv->cx_data_sz = 4096; - - priv->cx_data = (unsigned char *)malloc(priv->cx_data_sz); - if (priv->cx_data == NULL) - return VPX_CODEC_MEM_ERROR; - vp9_initialize_enc(); res = validate_config(priv, &priv->cfg, &priv->extra_cfg); @@ -565,8 +698,8 @@ static vpx_codec_err_t encoder_common_init(vpx_codec_ctx_t *ctx) { if (res == VPX_CODEC_OK) { VP9_COMP *cpi; set_encoder_config(&ctx->priv->alg_priv->oxcf, - &ctx->priv->alg_priv->cfg, - &ctx->priv->alg_priv->extra_cfg); + &ctx->priv->alg_priv->cfg, + &ctx->priv->alg_priv->extra_cfg); cpi = vp9_create_compressor(&ctx->priv->alg_priv->oxcf); if (cpi == NULL) res = VPX_CODEC_MEM_ERROR; @@ -578,12 +711,6 @@ static vpx_codec_err_t encoder_common_init(vpx_codec_ctx_t *ctx) { return res; } - -static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx, - vpx_codec_priv_enc_mr_cfg_t *data) { - return encoder_common_init(ctx); -} - static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) { free(ctx->cx_data); vp9_remove_compressor(ctx->cpi); @@ -595,7 +722,7 @@ static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, unsigned long duration, unsigned long deadline) { // Use best quality mode if no deadline is given. - MODE new_qc = MODE_BESTQUALITY; + MODE new_qc = ONE_PASS_BEST; if (deadline) { // Convert duration parameter from stream timebase to microseconds @@ -605,14 +732,14 @@ static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, // If the deadline is more that the duration this frame is to be shown, // use good quality mode. Otherwise use realtime mode. - new_qc = (deadline > duration_us) ? MODE_GOODQUALITY : MODE_REALTIME; + new_qc = (deadline > duration_us) ? ONE_PASS_GOOD : REALTIME; } if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS) - new_qc = MODE_FIRSTPASS; + new_qc = TWO_PASS_FIRST; else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS) - new_qc = (new_qc == MODE_BESTQUALITY) ? MODE_SECONDPASS_BEST - : MODE_SECONDPASS; + new_qc = (new_qc == ONE_PASS_BEST) ? TWO_PASS_SECOND_BEST + : TWO_PASS_SECOND_GOOD; if (ctx->oxcf.mode != new_qc) { ctx->oxcf.mode = new_qc; @@ -620,7 +747,8 @@ static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, } } - +// Turn on to test if supplemental superframe data breaks decoding +// #define TEST_SUPPLEMENTAL_SUPERFRAME_DATA static int write_superframe_index(vpx_codec_alg_priv_t *ctx) { uint8_t marker = 0xc0; unsigned int mask; @@ -646,6 +774,20 @@ static int write_superframe_index(vpx_codec_alg_priv_t *ctx) { if (ctx->pending_cx_data_sz + index_sz < ctx->cx_data_sz) { uint8_t *x = ctx->pending_cx_data + ctx->pending_cx_data_sz; int i, j; +#ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA + uint8_t marker_test = 0xc0; + int mag_test = 2; // 1 - 4 + int frames_test = 4; // 1 - 8 + int index_sz_test = 2 + mag_test * frames_test; + marker_test |= frames_test - 1; + marker_test |= (mag_test - 1) << 3; + *x++ = marker_test; + for (i = 0; i < mag_test * frames_test; ++i) + *x++ = 0; // fill up with arbitrary data + *x++ = marker_test; + ctx->pending_cx_data_sz += index_sz_test; + printf("Added supplemental superframe data\n"); +#endif *x++ = marker; for (i = 0; i < ctx->pending_frame_count; i++) { @@ -658,10 +800,27 @@ static int write_superframe_index(vpx_codec_alg_priv_t *ctx) { } *x++ = marker; ctx->pending_cx_data_sz += index_sz; +#ifdef TEST_SUPPLEMENTAL_SUPERFRAME_DATA + index_sz += index_sz_test; +#endif } return index_sz; } +// vp9 uses 10,000,000 ticks/second as time stamp +#define TICKS_PER_SEC 10000000LL + +static int64_t timebase_units_to_ticks(const vpx_rational_t *timebase, + int64_t n) { + return n * TICKS_PER_SEC * timebase->num / timebase->den; +} + +static int64_t ticks_to_timebase_units(const vpx_rational_t *timebase, + int64_t n) { + const int64_t round = TICKS_PER_SEC * timebase->num / 2 - 1; + return (n * timebase->den + round) / timebase->num / TICKS_PER_SEC; +} + static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, const vpx_image_t *img, vpx_codec_pts_t pts, @@ -669,9 +828,26 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, vpx_enc_frame_flags_t flags, unsigned long deadline) { vpx_codec_err_t res = VPX_CODEC_OK; + const vpx_rational_t *const timebase = &ctx->cfg.g_timebase; - if (img) + if (img != NULL) { res = validate_img(ctx, img); + // TODO(jzern) the checks related to cpi's validity should be treated as a + // failure condition, encoder setup is done fully in init() currently. + if (res == VPX_CODEC_OK && ctx->cpi != NULL && ctx->cx_data == NULL) { + // There's no codec control for multiple alt-refs so check the encoder + // instance for its status to determine the compressed data size. + ctx->cx_data_sz = ctx->cfg.g_w * ctx->cfg.g_h * + get_image_bps(img) / 8 * + (ctx->cpi->multi_arf_allowed ? 8 : 2); + if (ctx->cx_data_sz < 4096) ctx->cx_data_sz = 4096; + + ctx->cx_data = (unsigned char *)malloc(ctx->cx_data_sz); + if (ctx->cx_data == NULL) { + return VPX_CODEC_MEM_ERROR; + } + } + } pick_quickcompress_mode(ctx, duration, deadline); vpx_codec_pkt_list_init(&ctx->pkt_list); @@ -683,42 +859,7 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, return VPX_CODEC_INVALID_PARAM; } - if (flags & (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF | - VP8_EFLAG_NO_REF_ARF)) { - int ref = 7; - - if (flags & VP8_EFLAG_NO_REF_LAST) - ref ^= VP9_LAST_FLAG; - - if (flags & VP8_EFLAG_NO_REF_GF) - ref ^= VP9_GOLD_FLAG; - - if (flags & VP8_EFLAG_NO_REF_ARF) - ref ^= VP9_ALT_FLAG; - - vp9_use_as_reference(ctx->cpi, ref); - } - - if (flags & (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | - VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_FORCE_GF | - VP8_EFLAG_FORCE_ARF)) { - int upd = 7; - - if (flags & VP8_EFLAG_NO_UPD_LAST) - upd ^= VP9_LAST_FLAG; - - if (flags & VP8_EFLAG_NO_UPD_GF) - upd ^= VP9_GOLD_FLAG; - - if (flags & VP8_EFLAG_NO_UPD_ARF) - upd ^= VP9_ALT_FLAG; - - vp9_update_reference(ctx->cpi, upd); - } - - if (flags & VP8_EFLAG_NO_UPD_ENTROPY) { - vp9_update_entropy(ctx->cpi, 0); - } + vp9_apply_encoding_flags(ctx->cpi, flags); // Handle fixed keyframe intervals if (ctx->cfg.kf_mode == VPX_KF_AUTO && @@ -731,9 +872,11 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, // Initialize the encoder instance on the first frame. if (res == VPX_CODEC_OK && ctx->cpi != NULL) { - unsigned int lib_flags; + unsigned int lib_flags = 0; YV12_BUFFER_CONFIG sd; - int64_t dst_time_stamp, dst_end_time_stamp; + int64_t dst_time_stamp = timebase_units_to_ticks(timebase, pts); + int64_t dst_end_time_stamp = + timebase_units_to_ticks(timebase, pts + duration); size_t size, cx_data_sz; unsigned char *cx_data; @@ -741,19 +884,12 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, if (ctx->base.init_flags & VPX_CODEC_USE_PSNR) ((VP9_COMP *)ctx->cpi)->b_calculate_psnr = 1; - // Convert API flags to internal codec lib flags - lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0; - - /* vp9 use 10,000,000 ticks/second as time stamp */ - dst_time_stamp = (pts * 10000000 * ctx->cfg.g_timebase.num) - / ctx->cfg.g_timebase.den; - dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num / - ctx->cfg.g_timebase.den; - if (img != NULL) { res = image2yuvconfig(img, &sd); - if (vp9_receive_raw_frame(ctx->cpi, lib_flags, + // Store the original flags in to the frame buffer. Will extract the + // key frame flag when we actually encode this frame. + if (vp9_receive_raw_frame(ctx->cpi, flags, &sd, dst_time_stamp, dst_end_time_stamp)) { VP9_COMP *cpi = (VP9_COMP *)ctx->cpi; res = update_error_state(ctx, &cpi->common.error); @@ -762,7 +898,6 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, cx_data = ctx->cx_data; cx_data_sz = ctx->cx_data_sz; - lib_flags = 0; /* Any pending invisible frames? */ if (ctx->pending_cx_data) { @@ -785,12 +920,21 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, cx_data, &dst_time_stamp, &dst_end_time_stamp, !img)) { if (size) { - vpx_codec_pts_t round, delta; - vpx_codec_cx_pkt_t pkt; VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi; + vpx_codec_cx_pkt_t pkt; + +#if CONFIG_SPATIAL_SVC + if (is_spatial_svc(cpi)) + cpi->svc.layer_context[cpi->svc.spatial_layer_id].layer_size += size; +#endif // Pack invisible frames with the next visible frame - if (cpi->common.show_frame == 0) { + if (cpi->common.show_frame == 0 +#if CONFIG_SPATIAL_SVC + || (is_spatial_svc(cpi) && + cpi->svc.spatial_layer_id < cpi->svc.number_spatial_layers - 1) +#endif + ) { if (ctx->pending_cx_data == 0) ctx->pending_cx_data = cx_data; ctx->pending_cx_data_sz += size; @@ -802,18 +946,19 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, } // Add the frame packet to the list of returned packets. - round = (vpx_codec_pts_t)1000000 * ctx->cfg.g_timebase.num / 2 - 1; - delta = (dst_end_time_stamp - dst_time_stamp); pkt.kind = VPX_CODEC_CX_FRAME_PKT; - pkt.data.frame.pts = - (dst_time_stamp * ctx->cfg.g_timebase.den + round) - / ctx->cfg.g_timebase.num / 10000000; - pkt.data.frame.duration = (unsigned long) - ((delta * ctx->cfg.g_timebase.den + round) - / ctx->cfg.g_timebase.num / 10000000); + pkt.data.frame.pts = ticks_to_timebase_units(timebase, dst_time_stamp); + pkt.data.frame.duration = + (unsigned long)ticks_to_timebase_units(timebase, + dst_end_time_stamp - dst_time_stamp); pkt.data.frame.flags = lib_flags << 16; - if (lib_flags & FRAMEFLAGS_KEY) + if (lib_flags & FRAMEFLAGS_KEY +#if CONFIG_SPATIAL_SVC + || (is_spatial_svc(cpi) && + cpi->svc.layer_context[0].is_key_frame) +#endif + ) pkt.data.frame.flags |= VPX_FRAME_IS_KEY; if (cpi->common.show_frame == 0) { @@ -823,9 +968,8 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, // prior PTS so that if a decoder uses pts to schedule when // to do this, we start right after last frame was decoded. // Invisible frames have no duration. - pkt.data.frame.pts = ((cpi->last_time_stamp_seen - * ctx->cfg.g_timebase.den + round) - / ctx->cfg.g_timebase.num / 10000000) + 1; + pkt.data.frame.pts = + ticks_to_timebase_units(timebase, cpi->last_time_stamp_seen) + 1; pkt.data.frame.duration = 0; } @@ -851,6 +995,18 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt); cx_data += size; cx_data_sz -= size; +#if CONFIG_SPATIAL_SVC + if (is_spatial_svc(cpi)) { + vpx_codec_cx_pkt_t pkt = {0}; + int i; + pkt.kind = VPX_CODEC_SPATIAL_SVC_LAYER_SIZES; + for (i = 0; i < cpi->svc.number_spatial_layers; ++i) { + pkt.data.layer_sizes[i] = cpi->svc.layer_context[i].layer_size; + cpi->svc.layer_context[i].layer_size = 0; + } + vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt); + } +#endif } } } @@ -858,14 +1014,13 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, return res; } - -static const vpx_codec_cx_pkt_t *encoder_get_cxdata(vpx_codec_alg_priv_t *ctx, +static const vpx_codec_cx_pkt_t *encoder_get_cxdata(vpx_codec_alg_priv_t *ctx, vpx_codec_iter_t *iter) { return vpx_codec_pkt_list_get(&ctx->pkt_list.head, iter); } static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { + va_list args) { vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *); if (frame != NULL) { @@ -881,7 +1036,7 @@ static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, } static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { + va_list args) { vpx_ref_frame_t *const frame = va_arg(args, vpx_ref_frame_t *); if (frame != NULL) { @@ -897,13 +1052,13 @@ static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx, } static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { - vp9_ref_frame_t *frame = va_arg(args, vp9_ref_frame_t *); + va_list args) { + vp9_ref_frame_t *const frame = va_arg(args, vp9_ref_frame_t *); if (frame != NULL) { - YV12_BUFFER_CONFIG* fb; + YV12_BUFFER_CONFIG *fb = get_ref_frame(&ctx->cpi->common, frame->idx); + if (fb == NULL) return VPX_CODEC_ERROR; - vp9_get_reference_enc(ctx->cpi, frame->idx, &fb); yuvconfig2image(&frame->img, fb, NULL); return VPX_CODEC_OK; } else { @@ -912,11 +1067,9 @@ static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, } static vpx_codec_err_t ctrl_set_previewpp(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { + va_list args) { #if CONFIG_VP9_POSTPROC vp8_postproc_cfg_t *config = va_arg(args, vp8_postproc_cfg_t *); - (void)ctr_id; - if (config != NULL) { ctx->preview_ppcfg = *config; return VPX_CODEC_OK; @@ -925,7 +1078,6 @@ static vpx_codec_err_t ctrl_set_previewpp(vpx_codec_alg_priv_t *ctx, } #else (void)ctx; - (void)ctr_id; (void)args; return VPX_CODEC_INCAPABLE; #endif @@ -934,7 +1086,8 @@ static vpx_codec_err_t ctrl_set_previewpp(vpx_codec_alg_priv_t *ctx, static vpx_image_t *encoder_get_preview(vpx_codec_alg_priv_t *ctx) { YV12_BUFFER_CONFIG sd; - vp9_ppflags_t flags = {0}; + vp9_ppflags_t flags; + vp9_zero(flags); if (ctx->preview_ppcfg.post_proc_flag) { flags.post_proc_flag = ctx->preview_ppcfg.post_proc_flag; @@ -951,39 +1104,46 @@ static vpx_image_t *encoder_get_preview(vpx_codec_alg_priv_t *ctx) { } static vpx_codec_err_t ctrl_update_entropy(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { + va_list args) { const int update = va_arg(args, int); + vp9_update_entropy(ctx->cpi, update); return VPX_CODEC_OK; } static vpx_codec_err_t ctrl_update_reference(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { + va_list args) { const int ref_frame_flags = va_arg(args, int); + vp9_update_reference(ctx->cpi, ref_frame_flags); return VPX_CODEC_OK; } static vpx_codec_err_t ctrl_use_reference(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { + va_list args) { const int reference_flag = va_arg(args, int); + vp9_use_as_reference(ctx->cpi, reference_flag); return VPX_CODEC_OK; } static vpx_codec_err_t ctrl_set_roi_map(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { + va_list args) { + (void)ctx; + (void)args; + // TODO(yaowu): Need to re-implement and test for VP9. return VPX_CODEC_INVALID_PARAM; } static vpx_codec_err_t ctrl_set_active_map(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { + va_list args) { vpx_active_map_t *const map = va_arg(args, vpx_active_map_t *); if (map) { - if (!vp9_set_active_map(ctx->cpi, map->active_map, map->rows, map->cols)) + if (!vp9_set_active_map(ctx->cpi, map->active_map, + (int)map->rows, (int)map->cols)) return VPX_CODEC_OK; else return VPX_CODEC_INVALID_PARAM; @@ -993,7 +1153,7 @@ static vpx_codec_err_t ctrl_set_active_map(vpx_codec_alg_priv_t *ctx, } static vpx_codec_err_t ctrl_set_scale_mode(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { + va_list args) { vpx_scaling_mode_t *const mode = va_arg(args, vpx_scaling_mode_t *); if (mode) { @@ -1006,10 +1166,10 @@ static vpx_codec_err_t ctrl_set_scale_mode(vpx_codec_alg_priv_t *ctx, } } -static vpx_codec_err_t ctrl_set_svc(vpx_codec_alg_priv_t *ctx, int ctr_id, - va_list args) { +static vpx_codec_err_t ctrl_set_svc(vpx_codec_alg_priv_t *ctx, va_list args) { int data = va_arg(args, int); const vpx_codec_enc_cfg_t *cfg = &ctx->cfg; + vp9_set_svc(ctx->cpi, data); // CBR or two pass mode for SVC with both temporal and spatial layers // not yet supported. @@ -1025,11 +1185,11 @@ static vpx_codec_err_t ctrl_set_svc(vpx_codec_alg_priv_t *ctx, int ctr_id, } static vpx_codec_err_t ctrl_set_svc_layer_id(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { vpx_svc_layer_id_t *const data = va_arg(args, vpx_svc_layer_id_t *); VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi; SVC *const svc = &cpi->svc; + svc->spatial_layer_id = data->spatial_layer_id; svc->temporal_layer_id = data->temporal_layer_id; // Checks on valid layer_id input. @@ -1045,32 +1205,34 @@ static vpx_codec_err_t ctrl_set_svc_layer_id(vpx_codec_alg_priv_t *ctx, } static vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx, - int ctr_id, va_list args) { + va_list args) { VP9_COMP *const cpi = ctx->cpi; vpx_svc_parameters_t *const params = va_arg(args, vpx_svc_parameters_t *); - if (params == NULL) + if (params == NULL || params->spatial_layer < 0 || + params->spatial_layer >= cpi->svc.number_spatial_layers) return VPX_CODEC_INVALID_PARAM; - cpi->svc.spatial_layer_id = params->spatial_layer; - cpi->svc.temporal_layer_id = params->temporal_layer; - - cpi->lst_fb_idx = params->lst_fb_idx; - cpi->gld_fb_idx = params->gld_fb_idx; - cpi->alt_fb_idx = params->alt_fb_idx; - - if (vp9_set_size_literal(ctx->cpi, params->width, params->height) != 0) - return VPX_CODEC_INVALID_PARAM; - - ctx->cfg.rc_max_quantizer = params->max_quantizer; - ctx->cfg.rc_min_quantizer = params->min_quantizer; + if (params->spatial_layer == 0) { + int i; + for (i = 0; i < cpi->svc.number_spatial_layers; ++i) { + cpi->svc.layer_context[i].svc_params_received.spatial_layer = -1; + } + } - set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); - vp9_change_config(ctx->cpi, &ctx->oxcf); + cpi->svc.layer_context[params->spatial_layer].svc_params_received = + *params; return VPX_CODEC_OK; } +static vpx_codec_err_t ctrl_set_tune_content(vpx_codec_alg_priv_t *ctx, + va_list args) { + struct vp9_extracfg extra_cfg = ctx->extra_cfg; + extra_cfg.content = CAST(VP9E_SET_TUNE_CONTENT, args); + return update_extra_cfg(ctx, &extra_cfg); +} + static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { {VP8_COPY_REFERENCE, ctrl_copy_reference}, {VP8E_UPD_ENTROPY, ctrl_update_entropy}, @@ -1083,30 +1245,31 @@ static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { {VP8E_SET_ROI_MAP, ctrl_set_roi_map}, {VP8E_SET_ACTIVEMAP, ctrl_set_active_map}, {VP8E_SET_SCALEMODE, ctrl_set_scale_mode}, - {VP8E_SET_CPUUSED, ctrl_set_param}, - {VP8E_SET_NOISE_SENSITIVITY, ctrl_set_param}, - {VP8E_SET_ENABLEAUTOALTREF, ctrl_set_param}, - {VP8E_SET_SHARPNESS, ctrl_set_param}, - {VP8E_SET_STATIC_THRESHOLD, ctrl_set_param}, - {VP9E_SET_TILE_COLUMNS, ctrl_set_param}, - {VP9E_SET_TILE_ROWS, ctrl_set_param}, - {VP8E_SET_ARNR_MAXFRAMES, ctrl_set_param}, - {VP8E_SET_ARNR_STRENGTH, ctrl_set_param}, - {VP8E_SET_ARNR_TYPE, ctrl_set_param}, - {VP8E_SET_TUNING, ctrl_set_param}, - {VP8E_SET_CQ_LEVEL, ctrl_set_param}, - {VP8E_SET_MAX_INTRA_BITRATE_PCT, ctrl_set_param}, - {VP9E_SET_LOSSLESS, ctrl_set_param}, - {VP9E_SET_FRAME_PARALLEL_DECODING, ctrl_set_param}, - {VP9E_SET_AQ_MODE, ctrl_set_param}, - {VP9E_SET_FRAME_PERIODIC_BOOST, ctrl_set_param}, + {VP8E_SET_CPUUSED, ctrl_set_cpuused}, + {VP8E_SET_NOISE_SENSITIVITY, ctrl_set_noise_sensitivity}, + {VP8E_SET_ENABLEAUTOALTREF, ctrl_set_enable_auto_alt_ref}, + {VP8E_SET_SHARPNESS, ctrl_set_sharpness}, + {VP8E_SET_STATIC_THRESHOLD, ctrl_set_static_thresh}, + {VP9E_SET_TILE_COLUMNS, ctrl_set_tile_columns}, + {VP9E_SET_TILE_ROWS, ctrl_set_tile_rows}, + {VP8E_SET_ARNR_MAXFRAMES, ctrl_set_arnr_max_frames}, + {VP8E_SET_ARNR_STRENGTH, ctrl_set_arnr_strength}, + {VP8E_SET_ARNR_TYPE, ctrl_set_arnr_type}, + {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}, + {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}, + {VP9E_SET_FRAME_PERIODIC_BOOST, ctrl_set_frame_periodic_boost}, {VP9E_SET_SVC, ctrl_set_svc}, {VP9E_SET_SVC_PARAMETERS, ctrl_set_svc_parameters}, {VP9E_SET_SVC_LAYER_ID, ctrl_set_svc_layer_id}, + {VP9E_SET_TUNE_CONTENT, ctrl_set_tune_content}, // Getters - {VP8E_GET_LAST_QUANTIZER, ctrl_get_param}, - {VP8E_GET_LAST_QUANTIZER_64, ctrl_get_param}, + {VP8E_GET_LAST_QUANTIZER, ctrl_get_quantizer}, + {VP8E_GET_LAST_QUANTIZER_64, ctrl_get_quantizer64}, {VP9_GET_REFERENCE, ctrl_get_reference}, { -1, NULL}, @@ -1132,12 +1295,15 @@ static vpx_codec_enc_cfg_map_t encoder_usage_cfg_map[] = { 0, // rc_dropframe_thresh 0, // rc_resize_allowed + 1, // rc_scaled_width + 1, // rc_scaled_height 60, // rc_resize_down_thresold 30, // rc_resize_up_thresold VPX_VBR, // rc_end_usage #if VPX_ENCODER_ABI_VERSION > (1 + VPX_CODEC_ABI_VERSION) - {0}, // rc_twopass_stats_in + {NULL, 0}, // rc_twopass_stats_in + {NULL, 0}, // rc_firstpass_mb_stats_in #endif 256, // rc_target_bandwidth 0, // rc_min_quantizer @@ -1159,6 +1325,7 @@ static vpx_codec_enc_cfg_map_t encoder_usage_cfg_map[] = { 9999, // kf_max_dist VPX_SS_DEFAULT_LAYERS, // ss_number_layers + {0}, {0}, // ss_target_bitrate 1, // ts_number_layers {0}, // ts_target_bitrate @@ -1170,7 +1337,6 @@ static vpx_codec_enc_cfg_map_t encoder_usage_cfg_map[] = { #endif } }, - { -1, {NOT_IMPLEMENTED}} }; #ifndef VERSION_STRING @@ -1183,21 +1349,21 @@ CODEC_INTERFACE(vpx_codec_vp9_cx) = { encoder_init, // vpx_codec_init_fn_t encoder_destroy, // vpx_codec_destroy_fn_t encoder_ctrl_maps, // vpx_codec_ctrl_fn_map_t - NOT_IMPLEMENTED, // vpx_codec_get_mmap_fn_t - NOT_IMPLEMENTED, // vpx_codec_set_mmap_fn_t { // NOLINT NOT_IMPLEMENTED, // vpx_codec_peek_si_fn_t NOT_IMPLEMENTED, // vpx_codec_get_si_fn_t NOT_IMPLEMENTED, // vpx_codec_decode_fn_t NOT_IMPLEMENTED, // vpx_codec_frame_get_fn_t + NOT_IMPLEMENTED // vpx_codec_set_fb_fn_t }, { // NOLINT + 1, // 1 cfg map encoder_usage_cfg_map, // vpx_codec_enc_cfg_map_t encoder_encode, // vpx_codec_encode_fn_t encoder_get_cxdata, // vpx_codec_get_cx_data_fn_t encoder_set_config, // vpx_codec_enc_config_set_fn_t NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t encoder_get_preview, // vpx_codec_get_preview_frame_fn_t - NOT_IMPLEMENTED , // vpx_codec_enc_mr_get_mem_loc_fn_t + NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t } }; |