193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org/* 293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org * Copyright (c) 2014 The WebM project authors. All Rights Reserved. 393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org * 493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org * Use of this source code is governed by a BSD-style license 593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org * that can be found in the LICENSE file in the root of the source 693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org * tree. An additional intellectual property rights grant can be found 793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org * in the file PATENTS. All contributing project authors may 893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org * be found in the AUTHORS file in the root of the source tree. 993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org */ 1093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include <math.h> 1293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 13693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com#include "vp9/encoder/vp9_encoder.h" 1493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org#include "vp9/encoder/vp9_svc_layercontext.h" 15e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org#include "vp9/encoder/vp9_extend.h" 1693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 1793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_init_layer_context(VP9_COMP *const cpi) { 1893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org SVC *const svc = &cpi->svc; 19693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com const VP9EncoderConfig *const oxcf = &cpi->oxcf; 2093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org int layer; 2193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org int layer_end; 2287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int alt_ref_idx = svc->number_spatial_layers; 2393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 2493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org svc->spatial_layer_id = 0; 2593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org svc->temporal_layer_id = 0; 2693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 27d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) { 2893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org layer_end = svc->number_temporal_layers; 2993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else { 3093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org layer_end = svc->number_spatial_layers; 3193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 3293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 3393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org for (layer = 0; layer < layer_end; ++layer) { 3493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org LAYER_CONTEXT *const lc = &svc->layer_context[layer]; 3593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org RATE_CONTROL *const lrc = &lc->rc; 36e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org int i; 3793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lc->current_video_frame_in_layer = 0; 3841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org lc->layer_size = 0; 39d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org lc->frames_from_key_frame = 0; 40d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org lc->last_frame_type = FRAME_TYPES; 41693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com lrc->ni_av_qi = oxcf->worst_allowed_q; 4293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->total_actual_bits = 0; 4393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->total_target_vs_actual = 0; 4493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->ni_tot_qi = 0; 4593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->tot_q = 0.0; 4693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->avg_q = 0.0; 4793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->ni_frames = 0; 4893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->decimation_count = 0; 4993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->decimation_factor = 0; 50e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 51e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org for (i = 0; i < RATE_FACTOR_LEVELS; ++i) { 52e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org lrc->rate_correction_factors[i] = 1.0; 53e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org } 5493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 55d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) { 5688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org lc->target_bandwidth = oxcf->ts_target_bitrate[layer]; 57693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com lrc->last_q[INTER_FRAME] = oxcf->worst_allowed_q; 58ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org lrc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q; 5993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else { 6088b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org lc->target_bandwidth = oxcf->ss_target_bitrate[layer]; 6188b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org lrc->last_q[KEY_FRAME] = oxcf->best_allowed_q; 6288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org lrc->last_q[INTER_FRAME] = oxcf->best_allowed_q; 63ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org lrc->avg_frame_qindex[KEY_FRAME] = (oxcf->worst_allowed_q + 64ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org oxcf->best_allowed_q) / 2; 65ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org lrc->avg_frame_qindex[INTER_FRAME] = (oxcf->worst_allowed_q + 66ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org oxcf->best_allowed_q) / 2; 67ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org if (oxcf->ss_play_alternate[layer]) 68ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org lc->alt_ref_idx = alt_ref_idx++; 69ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org else 70ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org lc->alt_ref_idx = -1; 7141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org lc->gold_ref_idx = -1; 7293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 7393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 74ace65784417788374f0b19ce5a8abd06c9ccd007johannkoenig@chromium.org lrc->buffer_level = oxcf->starting_buffer_level_ms * 75ace65784417788374f0b19ce5a8abd06c9ccd007johannkoenig@chromium.org lc->target_bandwidth / 1000; 7693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->bits_off_target = lrc->buffer_level; 7793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 7841294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org 7941294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org // Still have extra buffer for base layer golden frame 80d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (!(svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) 81d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org && alt_ref_idx < REF_FRAMES) 8241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org svc->layer_context[0].gold_ref_idx = alt_ref_idx; 8393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 8493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 8593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// Update the layer context from a change_config() call. 8693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_update_layer_context_change_config(VP9_COMP *const cpi, 8793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const int target_bandwidth) { 8893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org SVC *const svc = &cpi->svc; 89693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com const VP9EncoderConfig *const oxcf = &cpi->oxcf; 9093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const RATE_CONTROL *const rc = &cpi->rc; 9193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org int layer; 9293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org int layer_end; 9393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org float bitrate_alloc = 1.0; 9493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 95d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) { 9693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org layer_end = svc->number_temporal_layers; 9793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else { 9893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org layer_end = svc->number_spatial_layers; 9993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 10093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 10193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org for (layer = 0; layer < layer_end; ++layer) { 10293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org LAYER_CONTEXT *const lc = &svc->layer_context[layer]; 10393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org RATE_CONTROL *const lrc = &lc->rc; 10493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 105d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) { 10688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org lc->target_bandwidth = oxcf->ts_target_bitrate[layer]; 10793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else { 10888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org lc->target_bandwidth = oxcf->ss_target_bitrate[layer]; 10993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 11093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth; 11193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // Update buffer-related quantities. 11288b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org lrc->starting_buffer_level = 11388b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org (int64_t)(rc->starting_buffer_level * bitrate_alloc); 11488b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org lrc->optimal_buffer_level = 11588b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org (int64_t)(rc->optimal_buffer_level * bitrate_alloc); 11688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org lrc->maximum_buffer_size = 11788b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org (int64_t)(rc->maximum_buffer_size * bitrate_alloc); 11888b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org lrc->bits_off_target = MIN(lrc->bits_off_target, lrc->maximum_buffer_size); 11988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org lrc->buffer_level = MIN(lrc->buffer_level, lrc->maximum_buffer_size); 12093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // Update framerate-related quantities. 121d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) { 12241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[layer]; 12393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else { 12441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org lc->framerate = cpi->framerate; 12593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 126693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate); 12793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->max_frame_bandwidth = rc->max_frame_bandwidth; 12893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // Update qp-related quantities. 12993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->worst_quality = rc->worst_quality; 13093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->best_quality = rc->best_quality; 13193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 13293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 13393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 134d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.orgstatic LAYER_CONTEXT *get_layer_context(VP9_COMP *const cpi) { 135d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org return (cpi->svc.number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) ? 136d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org &cpi->svc.layer_context[cpi->svc.temporal_layer_id] : 137d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org &cpi->svc.layer_context[cpi->svc.spatial_layer_id]; 13893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 13993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 14093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_update_temporal_layer_framerate(VP9_COMP *const cpi) { 14193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org SVC *const svc = &cpi->svc; 142693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com const VP9EncoderConfig *const oxcf = &cpi->oxcf; 143d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org LAYER_CONTEXT *const lc = get_layer_context(cpi); 14493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org RATE_CONTROL *const lrc = &lc->rc; 14593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const int layer = svc->temporal_layer_id; 14693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 14741294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[layer]; 148693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate); 14993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth; 15093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // Update the average layer frame size (non-cumulative per-frame-bw). 15193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (layer == 0) { 152693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com lc->avg_frame_size = lrc->avg_frame_bandwidth; 15393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } else { 15493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const double prev_layer_framerate = 15541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org cpi->framerate / oxcf->ts_rate_decimator[layer - 1]; 15688b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org const int prev_layer_target_bandwidth = oxcf->ts_target_bitrate[layer - 1]; 15793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lc->avg_frame_size = 15893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org (int)((lc->target_bandwidth - prev_layer_target_bandwidth) / 15993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org (lc->framerate - prev_layer_framerate)); 16093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 16193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 16293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 16393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_update_spatial_layer_framerate(VP9_COMP *const cpi, double framerate) { 164693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com const VP9EncoderConfig *const oxcf = &cpi->oxcf; 165d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org LAYER_CONTEXT *const lc = get_layer_context(cpi); 16693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org RATE_CONTROL *const lrc = &lc->rc; 16793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 16893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lc->framerate = framerate; 169693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate); 170693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com lrc->min_frame_bandwidth = (int)(lrc->avg_frame_bandwidth * 17193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org oxcf->two_pass_vbrmin_section / 100); 172693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com lrc->max_frame_bandwidth = (int)(((int64_t)lrc->avg_frame_bandwidth * 17393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org oxcf->two_pass_vbrmax_section) / 100); 174ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org vp9_rc_set_gf_max_interval(cpi, lrc); 17593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 17693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 17793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_restore_layer_context(VP9_COMP *const cpi) { 178d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org LAYER_CONTEXT *const lc = get_layer_context(cpi); 17993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const int old_frame_since_key = cpi->rc.frames_since_key; 18093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org const int old_frame_to_key = cpi->rc.frames_to_key; 18193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 18293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org cpi->rc = lc->rc; 18393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org cpi->twopass = lc->twopass; 18493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org cpi->oxcf.target_bandwidth = lc->target_bandwidth; 185ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org cpi->alt_ref_source = lc->alt_ref_source; 18693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // Reset the frames_since_key and frames_to_key counters to their values 18793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org // before the layer restore. Keep these defined for the stream (not layer). 18893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org if (cpi->svc.number_temporal_layers > 1) { 18993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org cpi->rc.frames_since_key = old_frame_since_key; 19093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org cpi->rc.frames_to_key = old_frame_to_key; 19193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 19293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 19393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 19493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_save_layer_context(VP9_COMP *const cpi) { 195693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com const VP9EncoderConfig *const oxcf = &cpi->oxcf; 196d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org LAYER_CONTEXT *const lc = get_layer_context(cpi); 19793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 19893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lc->rc = cpi->rc; 19993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lc->twopass = cpi->twopass; 20093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org lc->target_bandwidth = (int)oxcf->target_bandwidth; 201ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org lc->alt_ref_source = cpi->alt_ref_source; 20293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 20393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 20493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_init_second_pass_spatial_svc(VP9_COMP *cpi) { 20593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org SVC *const svc = &cpi->svc; 20693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org int i; 20793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 20893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org for (i = 0; i < svc->number_spatial_layers; ++i) { 20988b47b29cc274dd19cddc37c1ce1834d97df282efgalligan@chromium.org TWO_PASS *const twopass = &svc->layer_context[i].twopass; 21093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 21193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org svc->spatial_layer_id = i; 21293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org vp9_init_second_pass(cpi); 21393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org 21493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org twopass->total_stats.spatial_layer_id = i; 21593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org twopass->total_left_stats.spatial_layer_id = i; 21693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org } 21793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org svc->spatial_layer_id = 0; 21893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org} 219693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com 220d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.orgvoid vp9_inc_frame_in_layer(VP9_COMP *const cpi) { 221d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org LAYER_CONTEXT *const lc = 222d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org (cpi->svc.number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) ? 223d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org &cpi->svc.layer_context[cpi->svc.temporal_layer_id] : 224d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org &cpi->svc.layer_context[cpi->svc.spatial_layer_id]; 225693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com ++lc->current_video_frame_in_layer; 226d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org ++lc->frames_from_key_frame; 227693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com} 2289a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org 229810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgint vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) { 230d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org return is_two_pass_svc(cpi) && 2319a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org cpi->svc.spatial_layer_id > 0 && 2329a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame; 2339a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org} 234e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 2353983288b51bb3c8f48a2d5f77523ef3ff1e94cd2johannkoenig@chromium.org#if CONFIG_SPATIAL_SVC 23687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgstatic void get_layer_resolution(const int width_org, const int height_org, 23787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org const int num, const int den, 23887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int *width_out, int *height_out) { 23987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int w, h; 240e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 24187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (width_out == NULL || height_out == NULL || den == 0) 24287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org return; 243e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 24487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org w = width_org * num / den; 24587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org h = height_org * num / den; 246e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 24787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org // make height and width even to make chrome player happy 24887997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org w += w % 2; 24987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org h += h % 2; 250e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 25187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org *width_out = w; 25287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org *height_out = h; 253e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org} 254e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 25587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.orgint vp9_svc_start_frame(VP9_COMP *const cpi) { 25687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org int width = 0, height = 0; 257ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org LAYER_CONTEXT *lc; 258d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org int count = 1 << (cpi->svc.number_temporal_layers - 1); 259e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 26087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode; 26141294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id]; 262ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 263d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org cpi->svc.temporal_layer_id = 0; 264d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org while ((lc->current_video_frame_in_layer % count) != 0) { 265d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org ++cpi->svc.temporal_layer_id; 266d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org count >>= 1; 267d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org } 268d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org 26987997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG; 27087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 27187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->lst_fb_idx = cpi->svc.spatial_layer_id; 27287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org 27387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (cpi->svc.spatial_layer_id == 0) 27487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->gld_fb_idx = (lc->gold_ref_idx >= 0) ? 27587997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org lc->gold_ref_idx : cpi->lst_fb_idx; 27687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org else 27787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->gld_fb_idx = cpi->svc.spatial_layer_id - 1; 278ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 279ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org if (lc->current_video_frame_in_layer == 0) { 28041294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org if (cpi->svc.spatial_layer_id >= 2) { 28187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2; 28241294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } else { 283ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org cpi->alt_fb_idx = cpi->lst_fb_idx; 28441294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_ALT_FLAG); 28541294d96d7dbf9bc215b09832a8336c5fb158f0bjohannkoenig@chromium.org } 286ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } else { 287ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org if (cpi->oxcf.ss_play_alternate[cpi->svc.spatial_layer_id]) { 288ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org cpi->alt_fb_idx = lc->alt_ref_idx; 289ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org if (!lc->has_alt_frame) 290ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org cpi->ref_frame_flags &= (~VP9_ALT_FLAG); 291ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } else { 292ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org // Find a proper alt_fb_idx for layers that don't have alt ref frame 293ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org if (cpi->svc.spatial_layer_id == 0) { 294ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org cpi->alt_fb_idx = cpi->lst_fb_idx; 295ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } else { 296ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org LAYER_CONTEXT *lc_lower = 297ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org &cpi->svc.layer_context[cpi->svc.spatial_layer_id - 1]; 298ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org 299ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org if (cpi->oxcf.ss_play_alternate[cpi->svc.spatial_layer_id - 1] && 300ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org lc_lower->alt_ref_source != NULL) 301ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org cpi->alt_fb_idx = lc_lower->alt_ref_idx; 302ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org else if (cpi->svc.spatial_layer_id >= 2) 30387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2; 304ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org else 305ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org cpi->alt_fb_idx = cpi->lst_fb_idx; 306ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } 307ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } 308ac4e313c19203132648a2a271703b6ee76fe4284johannkoenig@chromium.org } 309e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 31087997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height, 31187997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org lc->scaling_factor_num, lc->scaling_factor_den, 31287997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org &width, &height); 31387997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org if (vp9_set_size_literal(cpi, width, height) != 0) 314e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org return VPX_CODEC_INVALID_PARAM; 315e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 31687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->oxcf.worst_allowed_q = vp9_quantizer_to_qindex(lc->max_q); 31787997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org cpi->oxcf.best_allowed_q = vp9_quantizer_to_qindex(lc->min_q); 318e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 319e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org vp9_change_config(cpi, &cpi->oxcf); 320e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 321e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org vp9_set_high_precision_mv(cpi, 1); 322e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 323d95585fb0ec024f6abd96f7b02e0df58019d46afjohannkoenig@chromium.org cpi->alt_ref_source = get_layer_context(cpi)->alt_ref_source; 324e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 325e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org return 0; 326e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org} 327e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 328e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.orgstruct lookahead_entry *vp9_svc_lookahead_pop(VP9_COMP *const cpi, 329e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org struct lookahead_ctx *ctx, 330e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org int drain) { 331e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org struct lookahead_entry *buf = NULL; 332e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 333e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) { 33487997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org buf = vp9_lookahead_peek(ctx, 0); 335e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org if (buf != NULL) { 33687997d490ae52aa962a985c95b3cddf7f8832641johannkoenig@chromium.org // Only remove the buffer when pop the highest layer. 337e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) { 338e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org vp9_lookahead_pop(ctx, drain); 339e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org } 340e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org } 341e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org } 342e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org 343e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org return buf; 344e2064011d36b2008099446503f28e64d445060ecjohannkoenig@chromium.org} 3453983288b51bb3c8f48a2d5f77523ef3ff1e94cd2johannkoenig@chromium.org#endif 346