| Index: source/libvpx/vpx/src/svc_encodeframe.c
|
| ===================================================================
|
| --- source/libvpx/vpx/src/svc_encodeframe.c (revision 291857)
|
| +++ source/libvpx/vpx/src/svc_encodeframe.c (working copy)
|
| @@ -86,6 +86,7 @@
|
| int layers;
|
| int layer;
|
| int is_keyframe;
|
| + int use_multiple_frame_contexts;
|
|
|
| FrameData *frame_list;
|
| FrameData *frame_temp;
|
| @@ -366,6 +367,7 @@
|
| char *option_name;
|
| char *option_value;
|
| char *input_ptr;
|
| + SvcInternal *const si = get_svc_internal(svc_ctx);
|
| vpx_codec_err_t res = VPX_CODEC_OK;
|
|
|
| if (options == NULL) return VPX_CODEC_OK;
|
| @@ -382,8 +384,10 @@
|
| res = VPX_CODEC_INVALID_PARAM;
|
| break;
|
| }
|
| - if (strcmp("layers", option_name) == 0) {
|
| + if (strcmp("spatial-layers", option_name) == 0) {
|
| svc_ctx->spatial_layers = atoi(option_value);
|
| + } else if (strcmp("temporal-layers", option_name) == 0) {
|
| + svc_ctx->temporal_layers = atoi(option_value);
|
| } else if (strcmp("scale-factors", option_name) == 0) {
|
| res = parse_scale_factors(svc_ctx, option_value);
|
| if (res != VPX_CODEC_OK) break;
|
| @@ -393,6 +397,8 @@
|
| } else if (strcmp("auto-alt-refs", option_name) == 0) {
|
| res = parse_auto_alt_ref(svc_ctx, option_value);
|
| if (res != VPX_CODEC_OK) break;
|
| + } else if (strcmp("multi-frame-contexts", option_name) == 0) {
|
| + si->use_multiple_frame_contexts = atoi(option_value);
|
| } else {
|
| svc_log(svc_ctx, SVC_LOG_ERROR, "invalid option: %s\n", option_name);
|
| res = VPX_CODEC_INVALID_PARAM;
|
| @@ -401,6 +407,12 @@
|
| option_name = strtok_r(NULL, "=", &input_ptr);
|
| }
|
| free(input_string);
|
| +
|
| + if (si->use_multiple_frame_contexts &&
|
| + (svc_ctx->spatial_layers > 3 ||
|
| + svc_ctx->spatial_layers * svc_ctx->temporal_layers > 4))
|
| + res = VPX_CODEC_INVALID_PARAM;
|
| +
|
| return res;
|
| }
|
|
|
| @@ -480,6 +492,16 @@
|
| res = parse_options(svc_ctx, si->options);
|
| if (res != VPX_CODEC_OK) return res;
|
|
|
| + if (svc_ctx->spatial_layers < 1)
|
| + svc_ctx->spatial_layers = 1;
|
| + if (svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS)
|
| + svc_ctx->spatial_layers = VPX_SS_MAX_LAYERS;
|
| +
|
| + if (svc_ctx->temporal_layers < 1)
|
| + svc_ctx->temporal_layers = 1;
|
| + if (svc_ctx->temporal_layers > VPX_TS_MAX_LAYERS)
|
| + svc_ctx->temporal_layers = VPX_TS_MAX_LAYERS;
|
| +
|
| si->layers = svc_ctx->spatial_layers;
|
|
|
| // Assign target bitrate for each layer. We calculate the ratio
|
| @@ -515,9 +537,18 @@
|
| enc_cfg->ss_enable_auto_alt_ref[i] = si->enable_auto_alt_ref[i];
|
| #endif
|
|
|
| + if (svc_ctx->temporal_layers > 1) {
|
| + int i;
|
| + for (i = 0; i < svc_ctx->temporal_layers; ++i) {
|
| + enc_cfg->ts_target_bitrate[i] = enc_cfg->rc_target_bitrate /
|
| + svc_ctx->temporal_layers;
|
| + enc_cfg->ts_rate_decimator[i] = 1 << (svc_ctx->temporal_layers - 1 - i);
|
| + }
|
| + }
|
| +
|
| // modify encoder configuration
|
| enc_cfg->ss_number_layers = si->layers;
|
| - enc_cfg->ts_number_layers = 1; // Temporal layers not used in this encoder.
|
| + enc_cfg->ts_number_layers = svc_ctx->temporal_layers;
|
|
|
| // TODO(ivanmaltz): determine if these values need to be set explicitly for
|
| // svc, or if the normal default/override mechanism can be used
|
| @@ -534,7 +565,8 @@
|
| enc_cfg->rc_buf_initial_sz = 500;
|
| enc_cfg->rc_buf_optimal_sz = 600;
|
| enc_cfg->rc_buf_sz = 1000;
|
| - enc_cfg->g_error_resilient = 1;
|
| + if (enc_cfg->g_error_resilient == 0 && si->use_multiple_frame_contexts == 0)
|
| + enc_cfg->g_error_resilient = 1;
|
|
|
| // Initialize codec
|
| res = vpx_codec_enc_init(codec_ctx, iface, enc_cfg, VPX_CODEC_USE_PSNR);
|
|
|