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; |
+} |