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"
1593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
1693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_init_layer_context(VP9_COMP *const cpi) {
1793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  SVC *const svc = &cpi->svc;
18693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
1993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int layer;
2093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int layer_end;
2193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
2293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  svc->spatial_layer_id = 0;
2393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  svc->temporal_layer_id = 0;
2493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
2593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (svc->number_temporal_layers > 1) {
2693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    layer_end = svc->number_temporal_layers;
2793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  } else {
2893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    layer_end = svc->number_spatial_layers;
2993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
3093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
3193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  for (layer = 0; layer < layer_end; ++layer) {
3293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    LAYER_CONTEXT *const lc = &svc->layer_context[layer];
3393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    RATE_CONTROL *const lrc = &lc->rc;
3493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lc->current_video_frame_in_layer = 0;
35693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    lrc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q;
36693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    lrc->ni_av_qi = oxcf->worst_allowed_q;
3793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->total_actual_bits = 0;
3893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->total_target_vs_actual = 0;
3993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->ni_tot_qi = 0;
4093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->tot_q = 0.0;
4193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->avg_q = 0.0;
4293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->ni_frames = 0;
4393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->decimation_count = 0;
4493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->decimation_factor = 0;
4593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->rate_correction_factor = 1.0;
4693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->key_frame_rate_correction_factor = 1.0;
4793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
4893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    if (svc->number_temporal_layers > 1) {
4993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      lc->target_bandwidth = oxcf->ts_target_bitrate[layer] * 1000;
50693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      lrc->last_q[INTER_FRAME] = oxcf->worst_allowed_q;
5193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    } else {
5293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      lc->target_bandwidth = oxcf->ss_target_bitrate[layer] * 1000;
53693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      lrc->last_q[0] = oxcf->best_allowed_q;
54693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      lrc->last_q[1] = oxcf->best_allowed_q;
55693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      lrc->last_q[2] = oxcf->best_allowed_q;
5693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    }
5793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
5893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->buffer_level = vp9_rescale((int)(oxcf->starting_buffer_level),
5993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                    lc->target_bandwidth, 1000);
6093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->bits_off_target = lrc->buffer_level;
6193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
6293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}
6393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
6493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org// Update the layer context from a change_config() call.
6593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_update_layer_context_change_config(VP9_COMP *const cpi,
6693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                            const int target_bandwidth) {
6793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  SVC *const svc = &cpi->svc;
68693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
6993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const RATE_CONTROL *const rc = &cpi->rc;
7093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int layer;
7193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int layer_end;
7293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  float bitrate_alloc = 1.0;
7393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
7493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (svc->number_temporal_layers > 1) {
7593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    layer_end = svc->number_temporal_layers;
7693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  } else {
7793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    layer_end = svc->number_spatial_layers;
7893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
7993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
8093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  for (layer = 0; layer < layer_end; ++layer) {
8193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    LAYER_CONTEXT *const lc = &svc->layer_context[layer];
8293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    RATE_CONTROL *const lrc = &lc->rc;
8393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
8493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    if (svc->number_temporal_layers > 1) {
8593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      lc->target_bandwidth = oxcf->ts_target_bitrate[layer] * 1000;
8693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    } else {
8793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      lc->target_bandwidth = oxcf->ss_target_bitrate[layer] * 1000;
8893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    }
8993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth;
9093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // Update buffer-related quantities.
9193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lc->starting_buffer_level =
9293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        (int64_t)(oxcf->starting_buffer_level * bitrate_alloc);
9393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lc->optimal_buffer_level =
9493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        (int64_t)(oxcf->optimal_buffer_level * bitrate_alloc);
9593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lc->maximum_buffer_size =
9693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        (int64_t)(oxcf->maximum_buffer_size * bitrate_alloc);
9793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->bits_off_target = MIN(lrc->bits_off_target, lc->maximum_buffer_size);
9893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->buffer_level = MIN(lrc->buffer_level, lc->maximum_buffer_size);
9993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // Update framerate-related quantities.
10093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    if (svc->number_temporal_layers > 1) {
10193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      lc->framerate = oxcf->framerate / oxcf->ts_rate_decimator[layer];
10293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    } else {
10393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      lc->framerate = oxcf->framerate;
10493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    }
105693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
10693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->max_frame_bandwidth = rc->max_frame_bandwidth;
10793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    // Update qp-related quantities.
10893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->worst_quality = rc->worst_quality;
10993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->best_quality = rc->best_quality;
11093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
11193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}
11293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
11393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgstatic LAYER_CONTEXT *get_layer_context(SVC *svc) {
11493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  return svc->number_temporal_layers > 1 ?
11593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org         &svc->layer_context[svc->temporal_layer_id] :
11693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org         &svc->layer_context[svc->spatial_layer_id];
11793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}
11893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
11993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_update_temporal_layer_framerate(VP9_COMP *const cpi) {
12093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  SVC *const svc = &cpi->svc;
121693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
12293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  LAYER_CONTEXT *const lc = get_layer_context(svc);
12393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RATE_CONTROL *const lrc = &lc->rc;
12493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const int layer = svc->temporal_layer_id;
12593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
12693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  lc->framerate = oxcf->framerate / oxcf->ts_rate_decimator[layer];
127693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
12893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth;
12993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Update the average layer frame size (non-cumulative per-frame-bw).
13093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (layer == 0) {
131693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com    lc->avg_frame_size = lrc->avg_frame_bandwidth;
13293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  } else {
13393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    const double prev_layer_framerate =
13493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        oxcf->framerate / oxcf->ts_rate_decimator[layer - 1];
13593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    const int prev_layer_target_bandwidth =
13693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        oxcf->ts_target_bitrate[layer - 1] * 1000;
13793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lc->avg_frame_size =
13893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org        (int)((lc->target_bandwidth - prev_layer_target_bandwidth) /
13993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org              (lc->framerate - prev_layer_framerate));
14093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
14193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}
14293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
14393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_update_spatial_layer_framerate(VP9_COMP *const cpi, double framerate) {
144693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
14593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  LAYER_CONTEXT *const lc = get_layer_context(&cpi->svc);
14693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  RATE_CONTROL *const lrc = &lc->rc;
14793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
14893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  lc->framerate = framerate;
149693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
150693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  lrc->min_frame_bandwidth = (int)(lrc->avg_frame_bandwidth *
15193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                   oxcf->two_pass_vbrmin_section / 100);
152693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  lrc->max_frame_bandwidth = (int)(((int64_t)lrc->avg_frame_bandwidth *
15393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org                                   oxcf->two_pass_vbrmax_section) / 100);
15493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  lrc->max_gf_interval = 16;
15593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
15677496404dc182c2f4a5f86ebabffe1d1ceb81e7ejohannkoenig@chromium.org  lrc->static_scene_max_gf_interval = cpi->oxcf.key_freq >> 1;
15793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
15893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (oxcf->play_alternate && oxcf->lag_in_frames) {
15993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    if (lrc->max_gf_interval > oxcf->lag_in_frames - 1)
16093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      lrc->max_gf_interval = oxcf->lag_in_frames - 1;
16193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
16293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    if (lrc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1)
16393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org      lrc->static_scene_max_gf_interval = oxcf->lag_in_frames - 1;
16493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
16593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
16693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (lrc->max_gf_interval > lrc->static_scene_max_gf_interval)
16793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    lrc->max_gf_interval = lrc->static_scene_max_gf_interval;
16893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}
16993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
17093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_restore_layer_context(VP9_COMP *const cpi) {
17193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  LAYER_CONTEXT *const lc = get_layer_context(&cpi->svc);
17293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const int old_frame_since_key = cpi->rc.frames_since_key;
17393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  const int old_frame_to_key = cpi->rc.frames_to_key;
17493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
17593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  cpi->rc = lc->rc;
17693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  cpi->twopass = lc->twopass;
17793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  cpi->oxcf.target_bandwidth = lc->target_bandwidth;
17893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  cpi->oxcf.starting_buffer_level = lc->starting_buffer_level;
17993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  cpi->oxcf.optimal_buffer_level = lc->optimal_buffer_level;
18093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  cpi->oxcf.maximum_buffer_size = lc->maximum_buffer_size;
18193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // Reset the frames_since_key and frames_to_key counters to their values
18293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  // before the layer restore. Keep these defined for the stream (not layer).
18393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  if (cpi->svc.number_temporal_layers > 1) {
18493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    cpi->rc.frames_since_key = old_frame_since_key;
18593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    cpi->rc.frames_to_key = old_frame_to_key;
18693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
18793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}
18893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
18993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_save_layer_context(VP9_COMP *const cpi) {
190693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
19193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  LAYER_CONTEXT *const lc = get_layer_context(&cpi->svc);
19293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
19393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  lc->rc = cpi->rc;
19493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  lc->twopass = cpi->twopass;
19593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  lc->target_bandwidth = (int)oxcf->target_bandwidth;
19693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  lc->starting_buffer_level = oxcf->starting_buffer_level;
19793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  lc->optimal_buffer_level = oxcf->optimal_buffer_level;
19893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  lc->maximum_buffer_size = oxcf->maximum_buffer_size;
19993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}
20093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
20193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.orgvoid vp9_init_second_pass_spatial_svc(VP9_COMP *cpi) {
20293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  SVC *const svc = &cpi->svc;
20393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  int i;
20493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
20593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  for (i = 0; i < svc->number_spatial_layers; ++i) {
20693a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    struct twopass_rc *const twopass = &svc->layer_context[i].twopass;
20793a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
20893a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    svc->spatial_layer_id = i;
20993a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    vp9_init_second_pass(cpi);
21093a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org
21193a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    twopass->total_stats.spatial_layer_id = i;
21293a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org    twopass->total_left_stats.spatial_layer_id = i;
21393a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  }
21493a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org  svc->spatial_layer_id = 0;
21593a74791c8e808ea76001ee07693aa2a5fdd3500johannkoenig@chromium.org}
216693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com
217693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.comvoid vp9_inc_frame_in_layer(SVC *svc) {
218693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  LAYER_CONTEXT *const lc = (svc->number_temporal_layers > 1)
219693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      ? &svc->layer_context[svc->temporal_layer_id]
220693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com      : &svc->layer_context[svc->spatial_layer_id];
221693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com  ++lc->current_video_frame_in_layer;
222693441efe611de7ca09c00f4e79776f604b689f4joeyparrish@google.com}
2239a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org
224810cf1767dc8df4783e02ba8a712072f50ddc99efgalligan@chromium.orgint vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) {
2259a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org  return cpi->use_svc &&
2269a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org         cpi->svc.number_temporal_layers == 1 &&
2279a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org         cpi->svc.spatial_layer_id > 0 &&
2289a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org         cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame;
2299a5fccadbf86bd614db22afaff64c794c1e16215fgalligan@chromium.org}
230