diff options
Diffstat (limited to 'vp9/vp9_cx_iface.c')
-rw-r--r-- | vp9/vp9_cx_iface.c | 118 |
1 files changed, 61 insertions, 57 deletions
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index d3097e526..09e6b6781 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -152,10 +152,6 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, RANGE_CHECK_HI(cfg, rc_max_quantizer, 63); RANGE_CHECK_HI(cfg, rc_min_quantizer, cfg->rc_max_quantizer); RANGE_CHECK_BOOL(extra_cfg, lossless); - if (extra_cfg->lossless) { - RANGE_CHECK_HI(cfg, rc_max_quantizer, 0); - RANGE_CHECK_HI(cfg, rc_min_quantizer, 0); - } RANGE_CHECK(extra_cfg, aq_mode, 0, AQ_MODE_COUNT - 1); RANGE_CHECK_HI(cfg, g_threads, 64); @@ -225,14 +221,43 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx, if (cfg->rc_twopass_stats_in.sz % packet_sz) ERROR("rc_twopass_stats_in.sz indicates truncated packet."); - if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz) - ERROR("rc_twopass_stats_in requires at least two packets."); + if (cfg->ss_number_layers > 1) { + int i; + unsigned int n_packets_per_layer[VPX_SS_MAX_LAYERS] = {0}; + + stats = cfg->rc_twopass_stats_in.buf; + for (i = 0; i < n_packets; ++i) { + const int layer_id = (int)stats[i].spatial_layer_id; + if (layer_id >= 0 && layer_id < (int)cfg->ss_number_layers) { + ++n_packets_per_layer[layer_id]; + } + } + + for (i = 0; i < (int)cfg->ss_number_layers; ++i) { + unsigned int layer_id; + if (n_packets_per_layer[i] < 2) { + ERROR("rc_twopass_stats_in requires at least two packets for each " + "layer."); + } + + stats = (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + + n_packets - cfg->ss_number_layers + i; + 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) + ERROR("rc_twopass_stats_in missing EOS stats packet"); + } + } else { + if (cfg->rc_twopass_stats_in.sz < 2 * packet_sz) + ERROR("rc_twopass_stats_in requires at least two packets."); - stats = - (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1; + stats = + (const FIRSTPASS_STATS *)cfg->rc_twopass_stats_in.buf + n_packets - 1; - if ((int)(stats->count + 0.5) != n_packets - 1) - ERROR("rc_twopass_stats_in missing EOS stats packet"); + if ((int)(stats->count + 0.5) != n_packets - 1) + ERROR("rc_twopass_stats_in missing EOS stats packet"); + } } return VPX_CODEC_OK; @@ -807,48 +832,25 @@ static vpx_codec_err_t vp9e_encode(vpx_codec_alg_priv_t *ctx, if (cpi->droppable) pkt.data.frame.flags |= VPX_FRAME_IS_DROPPABLE; - /*if (cpi->output_partition) - { - int i; - const int num_partitions = 1; - - pkt.data.frame.flags |= VPX_FRAME_IS_FRAGMENT; - - for (i = 0; i < num_partitions; ++i) - { - pkt.data.frame.buf = cx_data; - pkt.data.frame.sz = cpi->partition_sz[i]; - pkt.data.frame.partition_id = i; - // don't set the fragment bit for the last partition - if (i == (num_partitions - 1)) - pkt.data.frame.flags &= ~VPX_FRAME_IS_FRAGMENT; - vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt); - cx_data += cpi->partition_sz[i]; - cx_data_sz -= cpi->partition_sz[i]; - } - } - else*/ - { - if (ctx->pending_cx_data) { - ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; - ctx->pending_frame_magnitude |= size; - ctx->pending_cx_data_sz += size; - size += write_superframe_index(ctx); - pkt.data.frame.buf = ctx->pending_cx_data; - pkt.data.frame.sz = ctx->pending_cx_data_sz; - ctx->pending_cx_data = NULL; - ctx->pending_cx_data_sz = 0; - ctx->pending_frame_count = 0; - ctx->pending_frame_magnitude = 0; - } else { - pkt.data.frame.buf = cx_data; - pkt.data.frame.sz = size; - } - pkt.data.frame.partition_id = -1; - vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt); - cx_data += size; - cx_data_sz -= size; + if (ctx->pending_cx_data) { + ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; + ctx->pending_frame_magnitude |= size; + ctx->pending_cx_data_sz += size; + size += write_superframe_index(ctx); + pkt.data.frame.buf = ctx->pending_cx_data; + pkt.data.frame.sz = ctx->pending_cx_data_sz; + ctx->pending_cx_data = NULL; + ctx->pending_cx_data_sz = 0; + ctx->pending_frame_count = 0; + ctx->pending_frame_magnitude = 0; + } else { + pkt.data.frame.buf = cx_data; + pkt.data.frame.sz = size; } + pkt.data.frame.partition_id = -1; + vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt); + cx_data += size; + cx_data_sz -= size; } } } @@ -963,8 +965,8 @@ static vpx_codec_err_t vp9e_update_entropy(vpx_codec_alg_priv_t *ctx, static vpx_codec_err_t vp9e_update_reference(vpx_codec_alg_priv_t *ctx, int ctr_id, va_list args) { - const int update = va_arg(args, int); - vp9_update_reference(ctx->cpi, update); + const int ref_frame_flags = va_arg(args, int); + vp9_update_reference(ctx->cpi, ref_frame_flags); return VPX_CODEC_OK; } @@ -1017,9 +1019,12 @@ static vpx_codec_err_t vp9e_set_svc(vpx_codec_alg_priv_t *ctx, int ctr_id, va_list args) { int data = va_arg(args, int); vp9_set_svc(ctx->cpi, data); - // CBR mode for SVC with both temporal and spatial layers not yet supported. + // CBR or two pass mode for SVC with both temporal and spatial layers + // not yet supported. if (data == 1 && - ctx->cfg.rc_end_usage == VPX_CBR && + (ctx->cfg.rc_end_usage == VPX_CBR || + ctx->cfg.g_pass == VPX_RC_FIRST_PASS || + ctx->cfg.g_pass == VPX_RC_LAST_PASS) && ctx->cfg.ss_number_layers > 1 && ctx->cfg.ts_number_layers > 1) { return VPX_CODEC_INVALID_PARAM; @@ -1176,8 +1181,7 @@ static vpx_codec_enc_cfg_map_t vp9e_usage_cfg_map[] = { CODEC_INTERFACE(vpx_codec_vp9_cx) = { "WebM Project VP9 Encoder" VERSION_STRING, VPX_CODEC_INTERNAL_ABI_VERSION, - VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR | - VPX_CODEC_CAP_OUTPUT_PARTITION, + VPX_CODEC_CAP_ENCODER | VPX_CODEC_CAP_PSNR, /* vpx_codec_caps_t caps; */ vp9e_init, /* vpx_codec_init_fn_t init; */ vp9e_destroy, /* vpx_codec_destroy_fn_t destroy; */ |