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); |