Index: source/libvpx/vp9/encoder/vp9_svc_layercontext.c |
=================================================================== |
--- source/libvpx/vp9/encoder/vp9_svc_layercontext.c (revision 284462) |
+++ source/libvpx/vp9/encoder/vp9_svc_layercontext.c (working copy) |
@@ -19,6 +19,7 @@ |
const VP9EncoderConfig *const oxcf = &cpi->oxcf; |
int layer; |
int layer_end; |
+ int alt_ref_idx = svc->number_spatial_layers; |
svc->spatial_layer_id = 0; |
svc->temporal_layer_id = 0; |
@@ -34,7 +35,6 @@ |
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; |
lrc->total_actual_bits = 0; |
lrc->total_target_vs_actual = 0; |
@@ -48,14 +48,24 @@ |
for (i = 0; i < RATE_FACTOR_LEVELS; ++i) { |
lrc->rate_correction_factors[i] = 1.0; |
} |
+ lc->layer_size = 0; |
if (svc->number_temporal_layers > 1) { |
lc->target_bandwidth = oxcf->ts_target_bitrate[layer]; |
lrc->last_q[INTER_FRAME] = oxcf->worst_allowed_q; |
+ lrc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q; |
} else { |
lc->target_bandwidth = oxcf->ss_target_bitrate[layer]; |
lrc->last_q[KEY_FRAME] = oxcf->best_allowed_q; |
lrc->last_q[INTER_FRAME] = oxcf->best_allowed_q; |
+ lrc->avg_frame_qindex[KEY_FRAME] = (oxcf->worst_allowed_q + |
+ oxcf->best_allowed_q) / 2; |
+ lrc->avg_frame_qindex[INTER_FRAME] = (oxcf->worst_allowed_q + |
+ oxcf->best_allowed_q) / 2; |
+ if (oxcf->ss_play_alternate[layer]) |
+ lc->alt_ref_idx = alt_ref_idx++; |
+ else |
+ lc->alt_ref_idx = -1; |
} |
lrc->buffer_level = vp9_rescale((int)(oxcf->starting_buffer_level_ms), |
@@ -153,7 +163,7 @@ |
oxcf->two_pass_vbrmin_section / 100); |
lrc->max_frame_bandwidth = (int)(((int64_t)lrc->avg_frame_bandwidth * |
oxcf->two_pass_vbrmax_section) / 100); |
- vp9_rc_set_gf_max_interval(oxcf, lrc); |
+ vp9_rc_set_gf_max_interval(cpi, lrc); |
} |
void vp9_restore_layer_context(VP9_COMP *const cpi) { |
@@ -164,6 +174,7 @@ |
cpi->rc = lc->rc; |
cpi->twopass = lc->twopass; |
cpi->oxcf.target_bandwidth = lc->target_bandwidth; |
+ cpi->alt_ref_source = lc->alt_ref_source; |
// Reset the frames_since_key and frames_to_key counters to their values |
// before the layer restore. Keep these defined for the stream (not layer). |
if (cpi->svc.number_temporal_layers > 1) { |
@@ -179,6 +190,7 @@ |
lc->rc = cpi->rc; |
lc->twopass = cpi->twopass; |
lc->target_bandwidth = (int)oxcf->target_bandwidth; |
+ lc->alt_ref_source = cpi->alt_ref_source; |
} |
void vp9_init_second_pass_spatial_svc(VP9_COMP *cpi) { |
@@ -239,7 +251,7 @@ |
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; |
+ LAYER_CONTEXT *lc; |
// Find the next layer to be encoded |
for (layer_id = 0; layer_id < cpi->svc.number_spatial_layers; ++layer_id) { |
@@ -251,13 +263,47 @@ |
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; |
+ cpi->lst_fb_idx = cpi->svc.spatial_layer_id; |
+ |
+ if (cpi->svc.spatial_layer_id < 1) |
+ cpi->gld_fb_idx = cpi->lst_fb_idx; |
+ else |
+ cpi->gld_fb_idx = cpi->svc.spatial_layer_id - 1; |
+ |
+ lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id]; |
+ |
+ if (lc->current_video_frame_in_layer == 0) { |
+ if (cpi->svc.spatial_layer_id >= 2) |
+ cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2; |
+ else |
+ cpi->alt_fb_idx = cpi->lst_fb_idx; |
+ } else { |
+ if (cpi->oxcf.ss_play_alternate[cpi->svc.spatial_layer_id]) { |
+ cpi->alt_fb_idx = lc->alt_ref_idx; |
+ if (!lc->has_alt_frame) |
+ cpi->ref_frame_flags &= (~VP9_ALT_FLAG); |
+ } else { |
+ // Find a proper alt_fb_idx for layers that don't have alt ref frame |
+ if (cpi->svc.spatial_layer_id == 0) { |
+ cpi->alt_fb_idx = cpi->lst_fb_idx; |
+ } else { |
+ LAYER_CONTEXT *lc_lower = |
+ &cpi->svc.layer_context[cpi->svc.spatial_layer_id - 1]; |
+ |
+ if (cpi->oxcf.ss_play_alternate[cpi->svc.spatial_layer_id - 1] && |
+ lc_lower->alt_ref_source != NULL) |
+ cpi->alt_fb_idx = lc_lower->alt_ref_idx; |
+ else if (cpi->svc.spatial_layer_id >= 2) |
+ cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2; |
+ else |
+ cpi->alt_fb_idx = cpi->lst_fb_idx; |
+ } |
+ } |
+ } |
+ |
if (vp9_set_size_literal(cpi, layer_param->width, layer_param->height) != 0) |
return VPX_CODEC_INVALID_PARAM; |
@@ -270,9 +316,7 @@ |
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); |
+ cpi->alt_ref_source = get_layer_context(&cpi->svc)->alt_ref_source; |
return 0; |
} |