diff options
Diffstat (limited to 'vp9/vp9_cx_iface.c')
-rw-r--r-- | vp9/vp9_cx_iface.c | 166 |
1 files changed, 69 insertions, 97 deletions
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index cdbb69b2d..5ff02d882 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -21,7 +21,6 @@ #include "vp9/vp9_iface_common.h" struct vp9_extracfg { - struct vpx_codec_pkt_list *pkt_list; int cpu_used; // available cpu percentage in 1/16 unsigned int enable_auto_alt_ref; unsigned int noise_sensitivity; @@ -43,37 +42,26 @@ struct vp9_extracfg { vp9e_tune_content content; }; -struct extraconfig_map { - unsigned int usage; - struct vp9_extracfg cfg; -}; - -static const struct extraconfig_map extracfg_map[] = { - { - 0, - { // NOLINT - NULL, - 0, // cpu_used - 1, // enable_auto_alt_ref - 0, // noise_sensitivity - 0, // sharpness - 0, // static_thresh - 0, // tile_columns - 0, // tile_rows - 7, // arnr_max_frames - 5, // arnr_strength - 3, // arnr_type - VP8_TUNE_PSNR, // tuning - 10, // cq_level - 0, // rc_max_intra_bitrate_pct - 0, // lossless - 0, // frame_parallel_decoding_mode - NO_AQ, // aq_mode - 0, // frame_periodic_delta_q - BITS_8, // Bit depth - VP9E_CONTENT_DEFAULT // content - } - } +static struct vp9_extracfg default_extra_cfg = { + 0, // cpu_used + 1, // enable_auto_alt_ref + 0, // noise_sensitivity + 0, // sharpness + 0, // static_thresh + 0, // tile_columns + 0, // tile_rows + 7, // arnr_max_frames + 5, // arnr_strength + 3, // arnr_type + VP8_TUNE_PSNR, // tuning + 10, // cq_level + 0, // rc_max_intra_bitrate_pct + 0, // lossless + 0, // frame_parallel_decoding_mode + NO_AQ, // aq_mode + 0, // frame_periodic_delta_q + BITS_8, // Bit depth + VP9E_CONTENT_DEFAULT // content }; struct vpx_codec_alg_priv { @@ -188,6 +176,8 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, if (alt_ref_sum > REF_FRAMES - cfg->ss_number_layers) ERROR("Not enough ref buffers for svc alt ref frames"); } + if (cfg->ss_number_layers > 3 && cfg->g_error_resilient == 0) + ERROR("Multiple frame contexts are not supported for more than 3 layers"); #endif RANGE_CHECK(cfg, ts_number_layers, 1, VPX_TS_MAX_LAYERS); @@ -325,6 +315,7 @@ static vpx_codec_err_t set_encoder_config( VP9EncoderConfig *oxcf, const vpx_codec_enc_cfg_t *cfg, const struct vp9_extracfg *extra_cfg) { + const int is_vbr = cfg->rc_end_usage == VPX_VBR; oxcf->profile = cfg->g_profile; oxcf->width = cfg->g_w; oxcf->height = cfg->g_h; @@ -334,17 +325,16 @@ static vpx_codec_err_t set_encoder_config( if (oxcf->init_framerate > 180) oxcf->init_framerate = 30; + oxcf->mode = GOOD; + switch (cfg->g_pass) { case VPX_RC_ONE_PASS: - oxcf->mode = ONE_PASS_GOOD; oxcf->pass = 0; break; case VPX_RC_FIRST_PASS: - oxcf->mode = TWO_PASS_FIRST; oxcf->pass = 1; break; case VPX_RC_LAST_PASS: - oxcf->mode = TWO_PASS_SECOND_BEST; oxcf->pass = 2; break; } @@ -371,9 +361,9 @@ static vpx_codec_err_t set_encoder_config( 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->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz; + oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz; + oxcf->optimal_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_optimal_sz; oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh; @@ -393,7 +383,6 @@ static vpx_codec_err_t set_encoder_config( oxcf->sharpness = extra_cfg->sharpness; 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; @@ -659,8 +648,6 @@ static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx, (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) @@ -668,7 +655,6 @@ static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx, ctx->priv = &priv->base; ctx->priv->sz = sizeof(*ctx->priv); - ctx->priv->iface = ctx->iface; ctx->priv->alg_priv = priv; ctx->priv->init_flags = ctx->init_flags; ctx->priv->enc.total_encoders = 1; @@ -679,17 +665,7 @@ static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx, ctx->config.enc = &ctx->priv->alg_priv->cfg; } - cfg = &ctx->priv->alg_priv->cfg; - - // Select the extra vp6 configuration table based on the current - // usage value. If the current usage value isn't found, use the - // values for usage case 0. - for (i = 0; - extracfg_map[i].usage && extracfg_map[i].usage != cfg->g_usage; - ++i) {} - - priv->extra_cfg = extracfg_map[i].cfg; - priv->extra_cfg.pkt_list = &priv->pkt_list.head; + priv->extra_cfg = default_extra_cfg; vp9_initialize_enc(); @@ -701,10 +677,12 @@ static vpx_codec_err_t encoder_init(vpx_codec_ctx_t *ctx, &ctx->priv->alg_priv->cfg, &ctx->priv->alg_priv->extra_cfg); cpi = vp9_create_compressor(&ctx->priv->alg_priv->oxcf); - if (cpi == NULL) + if (cpi == NULL) { res = VPX_CODEC_MEM_ERROR; - else + } else { + cpi->output_pkt_list = &priv->pkt_list.head; ctx->priv->alg_priv->cpi = cpi; + } } } @@ -718,31 +696,36 @@ static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) { return VPX_CODEC_OK; } -static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, +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 = ONE_PASS_BEST; - - if (deadline) { - // Convert duration parameter from stream timebase to microseconds - const uint64_t duration_us = (uint64_t)duration * 1000000 * - (uint64_t)ctx->cfg.g_timebase.num / - (uint64_t)ctx->cfg.g_timebase.den; - - // 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) ? ONE_PASS_GOOD : REALTIME; - } + MODE new_mode = BEST; - if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS) - new_qc = TWO_PASS_FIRST; - else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS) - new_qc = (new_qc == ONE_PASS_BEST) ? TWO_PASS_SECOND_BEST - : TWO_PASS_SECOND_GOOD; + switch (ctx->cfg.g_pass) { + case VPX_RC_ONE_PASS: + if (deadline > 0) { + const vpx_codec_enc_cfg_t *const cfg = &ctx->cfg; + + // Convert duration parameter from stream timebase to microseconds. + const uint64_t duration_us = (uint64_t)duration * 1000000 * + (uint64_t)cfg->g_timebase.num /(uint64_t)cfg->g_timebase.den; + + // If the deadline is more that the duration this frame is to be shown, + // use good quality mode. Otherwise use realtime mode. + new_mode = (deadline > duration_us) ? GOOD : REALTIME; + } else { + new_mode = BEST; + } + break; + case VPX_RC_FIRST_PASS: + break; + case VPX_RC_LAST_PASS: + new_mode = deadline > 0 ? GOOD : BEST; + break; + } - if (ctx->oxcf.mode != new_qc) { - ctx->oxcf.mode = new_qc; + if (ctx->oxcf.mode != new_mode) { + ctx->oxcf.mode = new_mode; vp9_change_config(ctx->cpi, &ctx->oxcf); } } @@ -929,7 +912,7 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, #endif // Pack invisible frames with the next visible frame - if (cpi->common.show_frame == 0 + if (!cpi->common.show_frame #if CONFIG_SPATIAL_SVC || (is_spatial_svc(cpi) && cpi->svc.spatial_layer_id < cpi->svc.number_spatial_layers - 1) @@ -961,18 +944,6 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, ) pkt.data.frame.flags |= VPX_FRAME_IS_KEY; - if (cpi->common.show_frame == 0) { - pkt.data.frame.flags |= VPX_FRAME_IS_INVISIBLE; - - // This timestamp should be as close as possible to the - // 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 = - ticks_to_timebase_units(timebase, cpi->last_time_stamp_seen) + 1; - pkt.data.frame.duration = 0; - } - if (cpi->droppable) pkt.data.frame.flags |= VPX_FRAME_IS_DROPPABLE; @@ -997,8 +968,9 @@ static vpx_codec_err_t encoder_encode(vpx_codec_alg_priv_t *ctx, cx_data_sz -= size; #if CONFIG_SPATIAL_SVC if (is_spatial_svc(cpi)) { - vpx_codec_cx_pkt_t pkt = {0}; + vpx_codec_cx_pkt_t pkt; int i; + vp9_zero(pkt); 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; @@ -1350,11 +1322,11 @@ CODEC_INTERFACE(vpx_codec_vp9_cx) = { encoder_destroy, // vpx_codec_destroy_fn_t encoder_ctrl_maps, // vpx_codec_ctrl_fn_map_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 + NULL, // vpx_codec_peek_si_fn_t + NULL, // vpx_codec_get_si_fn_t + NULL, // vpx_codec_decode_fn_t + NULL, // vpx_codec_frame_get_fn_t + NULL // vpx_codec_set_fb_fn_t }, { // NOLINT 1, // 1 cfg map @@ -1362,8 +1334,8 @@ CODEC_INTERFACE(vpx_codec_vp9_cx) = { 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 + NULL, // 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 + NULL // vpx_codec_enc_mr_get_mem_loc_fn_t } }; |