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.c166
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
}
};