| Index: source/libvpx/vp9/encoder/vp9_svc_layercontext.c
|
| ===================================================================
|
| --- source/libvpx/vp9/encoder/vp9_svc_layercontext.c (revision 281795)
|
| +++ source/libvpx/vp9/encoder/vp9_svc_layercontext.c (working copy)
|
| @@ -12,6 +12,7 @@
|
|
|
| #include "vp9/encoder/vp9_encoder.h"
|
| #include "vp9/encoder/vp9_svc_layercontext.h"
|
| +#include "vp9/encoder/vp9_extend.h"
|
|
|
| void vp9_init_layer_context(VP9_COMP *const cpi) {
|
| SVC *const svc = &cpi->svc;
|
| @@ -31,6 +32,7 @@
|
| for (layer = 0; layer < layer_end; ++layer) {
|
| LAYER_CONTEXT *const lc = &svc->layer_context[layer];
|
| RATE_CONTROL *const lrc = &lc->rc;
|
| + int i;
|
| lc->current_video_frame_in_layer = 0;
|
| lrc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q;
|
| lrc->ni_av_qi = oxcf->worst_allowed_q;
|
| @@ -42,9 +44,11 @@
|
| lrc->ni_frames = 0;
|
| lrc->decimation_count = 0;
|
| lrc->decimation_factor = 0;
|
| - lrc->rate_correction_factor = 1.0;
|
| - lrc->key_frame_rate_correction_factor = 1.0;
|
|
|
| + for (i = 0; i < RATE_FACTOR_LEVELS; ++i) {
|
| + lrc->rate_correction_factors[i] = 1.0;
|
| + }
|
| +
|
| if (svc->number_temporal_layers > 1) {
|
| lc->target_bandwidth = oxcf->ts_target_bitrate[layer];
|
| lrc->last_q[INTER_FRAME] = oxcf->worst_allowed_q;
|
| @@ -206,3 +210,101 @@
|
| cpi->svc.spatial_layer_id > 0 &&
|
| cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame;
|
| }
|
| +
|
| +int vp9_svc_lookahead_push(const VP9_COMP *const cpi, struct lookahead_ctx *ctx,
|
| + YV12_BUFFER_CONFIG *src, int64_t ts_start,
|
| + int64_t ts_end, unsigned int flags) {
|
| + struct lookahead_entry *buf;
|
| + int i, index;
|
| +
|
| + if (vp9_lookahead_push(ctx, src, ts_start, ts_end, flags))
|
| + return 1;
|
| +
|
| + index = ctx->write_idx - 1;
|
| + if (index < 0)
|
| + index += ctx->max_sz;
|
| +
|
| + buf = ctx->buf + index;
|
| +
|
| + if (buf == NULL)
|
| + return 1;
|
| +
|
| + // Store svc parameters for each layer
|
| + for (i = 0; i < cpi->svc.number_spatial_layers; ++i)
|
| + buf->svc_params[i] = cpi->svc.layer_context[i].svc_params_received;
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +static int copy_svc_params(VP9_COMP *const cpi, struct lookahead_entry *buf) {
|
| + int layer_id;
|
| + vpx_svc_parameters_t *layer_param;
|
| + vpx_enc_frame_flags_t flags;
|
| +
|
| + // Find the next layer to be encoded
|
| + for (layer_id = 0; layer_id < cpi->svc.number_spatial_layers; ++layer_id) {
|
| + if (buf->svc_params[layer_id].spatial_layer >=0)
|
| + break;
|
| + }
|
| +
|
| + if (layer_id == cpi->svc.number_spatial_layers)
|
| + return 1;
|
| +
|
| + layer_param = &buf->svc_params[layer_id];
|
| + buf->flags = flags = layer_param->flags;
|
| + cpi->svc.spatial_layer_id = layer_param->spatial_layer;
|
| + cpi->svc.temporal_layer_id = layer_param->temporal_layer;
|
| + cpi->lst_fb_idx = layer_param->lst_fb_idx;
|
| + cpi->gld_fb_idx = layer_param->gld_fb_idx;
|
| + cpi->alt_fb_idx = layer_param->alt_fb_idx;
|
| +
|
| + if (vp9_set_size_literal(cpi, layer_param->width, layer_param->height) != 0)
|
| + return VPX_CODEC_INVALID_PARAM;
|
| +
|
| + cpi->oxcf.worst_allowed_q =
|
| + vp9_quantizer_to_qindex(layer_param->max_quantizer);
|
| + cpi->oxcf.best_allowed_q =
|
| + vp9_quantizer_to_qindex(layer_param->min_quantizer);
|
| +
|
| + vp9_change_config(cpi, &cpi->oxcf);
|
| +
|
| + vp9_set_high_precision_mv(cpi, 1);
|
| +
|
| + // Retrieve the encoding flags for each layer and apply it to encoder.
|
| + // It includes reference frame flags and update frame flags.
|
| + vp9_apply_encoding_flags(cpi, flags);
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +struct lookahead_entry *vp9_svc_lookahead_peek(VP9_COMP *const cpi,
|
| + struct lookahead_ctx *ctx,
|
| + int index, int copy_params) {
|
| + struct lookahead_entry *buf = vp9_lookahead_peek(ctx, index);
|
| +
|
| + if (buf != NULL && copy_params != 0) {
|
| + if (copy_svc_params(cpi, buf) != 0)
|
| + return NULL;
|
| + }
|
| + return buf;
|
| +}
|
| +
|
| +struct lookahead_entry *vp9_svc_lookahead_pop(VP9_COMP *const cpi,
|
| + struct lookahead_ctx *ctx,
|
| + int drain) {
|
| + struct lookahead_entry *buf = NULL;
|
| +
|
| + if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) {
|
| + buf = vp9_svc_lookahead_peek(cpi, ctx, 0, 1);
|
| + if (buf != NULL) {
|
| + // Only remove the buffer when pop the highest layer. Simply set the
|
| + // spatial_layer to -1 for lower layers.
|
| + buf->svc_params[cpi->svc.spatial_layer_id].spatial_layer = -1;
|
| + if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) {
|
| + vp9_lookahead_pop(ctx, drain);
|
| + }
|
| + }
|
| + }
|
| +
|
| + return buf;
|
| +}
|
|
|