LCOV - code coverage report
Current view: top level - media/libvpx/libvpx/vp9/encoder - vp9_svc_layercontext.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 472 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
       3             :  *
       4             :  *  Use of this source code is governed by a BSD-style license
       5             :  *  that can be found in the LICENSE file in the root of the source
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include <math.h>
      12             : 
      13             : #include "vp9/encoder/vp9_aq_cyclicrefresh.h"
      14             : #include "vp9/encoder/vp9_encoder.h"
      15             : #include "vp9/encoder/vp9_svc_layercontext.h"
      16             : #include "vp9/encoder/vp9_extend.h"
      17             : #include "vpx_dsp/vpx_dsp_common.h"
      18             : 
      19             : #define SMALL_FRAME_WIDTH 32
      20             : #define SMALL_FRAME_HEIGHT 16
      21             : 
      22           0 : void vp9_init_layer_context(VP9_COMP *const cpi) {
      23           0 :   SVC *const svc = &cpi->svc;
      24           0 :   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
      25           0 :   int mi_rows = cpi->common.mi_rows;
      26           0 :   int mi_cols = cpi->common.mi_cols;
      27             :   int sl, tl, i;
      28           0 :   int alt_ref_idx = svc->number_spatial_layers;
      29             : 
      30           0 :   svc->spatial_layer_id = 0;
      31           0 :   svc->temporal_layer_id = 0;
      32           0 :   svc->first_spatial_layer_to_encode = 0;
      33           0 :   svc->rc_drop_superframe = 0;
      34           0 :   svc->force_zero_mode_spatial_ref = 0;
      35           0 :   svc->use_base_mv = 0;
      36           0 :   svc->scaled_temp_is_alloc = 0;
      37           0 :   svc->scaled_one_half = 0;
      38           0 :   svc->current_superframe = 0;
      39           0 :   for (i = 0; i < REF_FRAMES; ++i) svc->ref_frame_index[i] = -1;
      40           0 :   for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
      41           0 :     cpi->svc.ext_frame_flags[sl] = 0;
      42           0 :     cpi->svc.ext_lst_fb_idx[sl] = 0;
      43           0 :     cpi->svc.ext_gld_fb_idx[sl] = 1;
      44           0 :     cpi->svc.ext_alt_fb_idx[sl] = 2;
      45             :   }
      46             : 
      47           0 :   if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) {
      48           0 :     if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img, SMALL_FRAME_WIDTH,
      49             :                                  SMALL_FRAME_HEIGHT, cpi->common.subsampling_x,
      50             :                                  cpi->common.subsampling_y,
      51             : #if CONFIG_VP9_HIGHBITDEPTH
      52             :                                  cpi->common.use_highbitdepth,
      53             : #endif
      54             :                                  VP9_ENC_BORDER_IN_PIXELS,
      55             :                                  cpi->common.byte_alignment, NULL, NULL, NULL))
      56           0 :       vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
      57             :                          "Failed to allocate empty frame for multiple frame "
      58             :                          "contexts");
      59             : 
      60           0 :     memset(cpi->svc.empty_frame.img.buffer_alloc, 0x80,
      61           0 :            cpi->svc.empty_frame.img.buffer_alloc_sz);
      62             :   }
      63             : 
      64           0 :   for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
      65           0 :     for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
      66           0 :       int layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers);
      67           0 :       LAYER_CONTEXT *const lc = &svc->layer_context[layer];
      68           0 :       RATE_CONTROL *const lrc = &lc->rc;
      69             :       int i;
      70           0 :       lc->current_video_frame_in_layer = 0;
      71           0 :       lc->layer_size = 0;
      72           0 :       lc->frames_from_key_frame = 0;
      73           0 :       lc->last_frame_type = FRAME_TYPES;
      74           0 :       lrc->ni_av_qi = oxcf->worst_allowed_q;
      75           0 :       lrc->total_actual_bits = 0;
      76           0 :       lrc->total_target_vs_actual = 0;
      77           0 :       lrc->ni_tot_qi = 0;
      78           0 :       lrc->tot_q = 0.0;
      79           0 :       lrc->avg_q = 0.0;
      80           0 :       lrc->ni_frames = 0;
      81           0 :       lrc->decimation_count = 0;
      82           0 :       lrc->decimation_factor = 0;
      83             : 
      84           0 :       for (i = 0; i < RATE_FACTOR_LEVELS; ++i) {
      85           0 :         lrc->rate_correction_factors[i] = 1.0;
      86             :       }
      87             : 
      88           0 :       if (cpi->oxcf.rc_mode == VPX_CBR) {
      89           0 :         lc->target_bandwidth = oxcf->layer_target_bitrate[layer];
      90           0 :         lrc->last_q[INTER_FRAME] = oxcf->worst_allowed_q;
      91           0 :         lrc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q;
      92           0 :         lrc->avg_frame_qindex[KEY_FRAME] = oxcf->worst_allowed_q;
      93             :       } else {
      94           0 :         lc->target_bandwidth = oxcf->layer_target_bitrate[layer];
      95           0 :         lrc->last_q[KEY_FRAME] = oxcf->best_allowed_q;
      96           0 :         lrc->last_q[INTER_FRAME] = oxcf->best_allowed_q;
      97           0 :         lrc->avg_frame_qindex[KEY_FRAME] =
      98           0 :             (oxcf->worst_allowed_q + oxcf->best_allowed_q) / 2;
      99           0 :         lrc->avg_frame_qindex[INTER_FRAME] =
     100           0 :             (oxcf->worst_allowed_q + oxcf->best_allowed_q) / 2;
     101           0 :         if (oxcf->ss_enable_auto_arf[sl])
     102           0 :           lc->alt_ref_idx = alt_ref_idx++;
     103             :         else
     104           0 :           lc->alt_ref_idx = INVALID_IDX;
     105           0 :         lc->gold_ref_idx = INVALID_IDX;
     106             :       }
     107             : 
     108           0 :       lrc->buffer_level =
     109           0 :           oxcf->starting_buffer_level_ms * lc->target_bandwidth / 1000;
     110           0 :       lrc->bits_off_target = lrc->buffer_level;
     111             : 
     112             :       // Initialize the cyclic refresh parameters. If spatial layers are used
     113             :       // (i.e., ss_number_layers > 1), these need to be updated per spatial
     114             :       // layer.
     115             :       // Cyclic refresh is only applied on base temporal layer.
     116           0 :       if (oxcf->ss_number_layers > 1 && tl == 0) {
     117             :         size_t last_coded_q_map_size;
     118             :         size_t consec_zero_mv_size;
     119           0 :         VP9_COMMON *const cm = &cpi->common;
     120           0 :         lc->sb_index = 0;
     121           0 :         CHECK_MEM_ERROR(cm, lc->map,
     122             :                         vpx_malloc(mi_rows * mi_cols * sizeof(*lc->map)));
     123           0 :         memset(lc->map, 0, mi_rows * mi_cols);
     124           0 :         last_coded_q_map_size =
     125           0 :             mi_rows * mi_cols * sizeof(*lc->last_coded_q_map);
     126           0 :         CHECK_MEM_ERROR(cm, lc->last_coded_q_map,
     127             :                         vpx_malloc(last_coded_q_map_size));
     128             :         assert(MAXQ <= 255);
     129           0 :         memset(lc->last_coded_q_map, MAXQ, last_coded_q_map_size);
     130           0 :         consec_zero_mv_size = mi_rows * mi_cols * sizeof(*lc->consec_zero_mv);
     131           0 :         CHECK_MEM_ERROR(cm, lc->consec_zero_mv,
     132             :                         vpx_malloc(consec_zero_mv_size));
     133           0 :         memset(lc->consec_zero_mv, 0, consec_zero_mv_size);
     134             :       }
     135             :     }
     136             :   }
     137             : 
     138             :   // Still have extra buffer for base layer golden frame
     139           0 :   if (!(svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) &&
     140             :       alt_ref_idx < REF_FRAMES)
     141           0 :     svc->layer_context[0].gold_ref_idx = alt_ref_idx;
     142           0 : }
     143             : 
     144             : // Update the layer context from a change_config() call.
     145           0 : void vp9_update_layer_context_change_config(VP9_COMP *const cpi,
     146             :                                             const int target_bandwidth) {
     147           0 :   SVC *const svc = &cpi->svc;
     148           0 :   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
     149           0 :   const RATE_CONTROL *const rc = &cpi->rc;
     150           0 :   int sl, tl, layer = 0, spatial_layer_target;
     151           0 :   float bitrate_alloc = 1.0;
     152             : 
     153           0 :   if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) {
     154           0 :     for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
     155           0 :       for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
     156           0 :         layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers);
     157           0 :         svc->layer_context[layer].target_bandwidth =
     158           0 :             oxcf->layer_target_bitrate[layer];
     159             :       }
     160             : 
     161           0 :       layer = LAYER_IDS_TO_IDX(
     162             :           sl,
     163             :           ((oxcf->ts_number_layers - 1) < 0 ? 0 : (oxcf->ts_number_layers - 1)),
     164             :           oxcf->ts_number_layers);
     165           0 :       spatial_layer_target = svc->layer_context[layer].target_bandwidth =
     166           0 :           oxcf->layer_target_bitrate[layer];
     167             : 
     168           0 :       for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
     169           0 :         LAYER_CONTEXT *const lc =
     170           0 :             &svc->layer_context[sl * oxcf->ts_number_layers + tl];
     171           0 :         RATE_CONTROL *const lrc = &lc->rc;
     172             : 
     173           0 :         lc->spatial_layer_target_bandwidth = spatial_layer_target;
     174           0 :         bitrate_alloc = (float)lc->target_bandwidth / spatial_layer_target;
     175           0 :         lrc->starting_buffer_level =
     176           0 :             (int64_t)(rc->starting_buffer_level * bitrate_alloc);
     177           0 :         lrc->optimal_buffer_level =
     178           0 :             (int64_t)(rc->optimal_buffer_level * bitrate_alloc);
     179           0 :         lrc->maximum_buffer_size =
     180           0 :             (int64_t)(rc->maximum_buffer_size * bitrate_alloc);
     181           0 :         lrc->bits_off_target =
     182           0 :             VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size);
     183           0 :         lrc->buffer_level = VPXMIN(lrc->buffer_level, lrc->maximum_buffer_size);
     184           0 :         lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[tl];
     185           0 :         lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
     186           0 :         lrc->max_frame_bandwidth = rc->max_frame_bandwidth;
     187           0 :         lrc->worst_quality = rc->worst_quality;
     188           0 :         lrc->best_quality = rc->best_quality;
     189             :       }
     190             :     }
     191             :   } else {
     192             :     int layer_end;
     193             : 
     194           0 :     if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) {
     195           0 :       layer_end = svc->number_temporal_layers;
     196             :     } else {
     197           0 :       layer_end = svc->number_spatial_layers;
     198             :     }
     199             : 
     200           0 :     for (layer = 0; layer < layer_end; ++layer) {
     201           0 :       LAYER_CONTEXT *const lc = &svc->layer_context[layer];
     202           0 :       RATE_CONTROL *const lrc = &lc->rc;
     203             : 
     204           0 :       lc->target_bandwidth = oxcf->layer_target_bitrate[layer];
     205             : 
     206           0 :       bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth;
     207             :       // Update buffer-related quantities.
     208           0 :       lrc->starting_buffer_level =
     209           0 :           (int64_t)(rc->starting_buffer_level * bitrate_alloc);
     210           0 :       lrc->optimal_buffer_level =
     211           0 :           (int64_t)(rc->optimal_buffer_level * bitrate_alloc);
     212           0 :       lrc->maximum_buffer_size =
     213           0 :           (int64_t)(rc->maximum_buffer_size * bitrate_alloc);
     214           0 :       lrc->bits_off_target =
     215           0 :           VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size);
     216           0 :       lrc->buffer_level = VPXMIN(lrc->buffer_level, lrc->maximum_buffer_size);
     217             :       // Update framerate-related quantities.
     218           0 :       if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) {
     219           0 :         lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[layer];
     220             :       } else {
     221           0 :         lc->framerate = cpi->framerate;
     222             :       }
     223           0 :       lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
     224           0 :       lrc->max_frame_bandwidth = rc->max_frame_bandwidth;
     225             :       // Update qp-related quantities.
     226           0 :       lrc->worst_quality = rc->worst_quality;
     227           0 :       lrc->best_quality = rc->best_quality;
     228             :     }
     229             :   }
     230           0 : }
     231             : 
     232           0 : static LAYER_CONTEXT *get_layer_context(VP9_COMP *const cpi) {
     233           0 :   if (is_one_pass_cbr_svc(cpi))
     234           0 :     return &cpi->svc.layer_context[cpi->svc.spatial_layer_id *
     235           0 :                                        cpi->svc.number_temporal_layers +
     236           0 :                                    cpi->svc.temporal_layer_id];
     237             :   else
     238           0 :     return (cpi->svc.number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR)
     239           0 :                ? &cpi->svc.layer_context[cpi->svc.temporal_layer_id]
     240           0 :                : &cpi->svc.layer_context[cpi->svc.spatial_layer_id];
     241             : }
     242             : 
     243           0 : void vp9_update_temporal_layer_framerate(VP9_COMP *const cpi) {
     244           0 :   SVC *const svc = &cpi->svc;
     245           0 :   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
     246           0 :   LAYER_CONTEXT *const lc = get_layer_context(cpi);
     247           0 :   RATE_CONTROL *const lrc = &lc->rc;
     248             :   // Index into spatial+temporal arrays.
     249           0 :   const int st_idx = svc->spatial_layer_id * svc->number_temporal_layers +
     250           0 :                      svc->temporal_layer_id;
     251           0 :   const int tl = svc->temporal_layer_id;
     252             : 
     253           0 :   lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[tl];
     254           0 :   lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
     255           0 :   lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth;
     256             :   // Update the average layer frame size (non-cumulative per-frame-bw).
     257           0 :   if (tl == 0) {
     258           0 :     lc->avg_frame_size = lrc->avg_frame_bandwidth;
     259             :   } else {
     260           0 :     const double prev_layer_framerate =
     261           0 :         cpi->framerate / oxcf->ts_rate_decimator[tl - 1];
     262           0 :     const int prev_layer_target_bandwidth =
     263           0 :         oxcf->layer_target_bitrate[st_idx - 1];
     264           0 :     lc->avg_frame_size =
     265           0 :         (int)((lc->target_bandwidth - prev_layer_target_bandwidth) /
     266           0 :               (lc->framerate - prev_layer_framerate));
     267             :   }
     268           0 : }
     269             : 
     270           0 : void vp9_update_spatial_layer_framerate(VP9_COMP *const cpi, double framerate) {
     271           0 :   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
     272           0 :   LAYER_CONTEXT *const lc = get_layer_context(cpi);
     273           0 :   RATE_CONTROL *const lrc = &lc->rc;
     274             : 
     275           0 :   lc->framerate = framerate;
     276           0 :   lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
     277           0 :   lrc->min_frame_bandwidth =
     278           0 :       (int)(lrc->avg_frame_bandwidth * oxcf->two_pass_vbrmin_section / 100);
     279           0 :   lrc->max_frame_bandwidth = (int)(((int64_t)lrc->avg_frame_bandwidth *
     280           0 :                                     oxcf->two_pass_vbrmax_section) /
     281             :                                    100);
     282           0 :   vp9_rc_set_gf_interval_range(cpi, lrc);
     283           0 : }
     284             : 
     285           0 : void vp9_restore_layer_context(VP9_COMP *const cpi) {
     286           0 :   LAYER_CONTEXT *const lc = get_layer_context(cpi);
     287           0 :   const int old_frame_since_key = cpi->rc.frames_since_key;
     288           0 :   const int old_frame_to_key = cpi->rc.frames_to_key;
     289             : 
     290           0 :   cpi->rc = lc->rc;
     291           0 :   cpi->twopass = lc->twopass;
     292           0 :   cpi->oxcf.target_bandwidth = lc->target_bandwidth;
     293           0 :   cpi->alt_ref_source = lc->alt_ref_source;
     294             :   // Check if it is one_pass_cbr_svc mode and lc->speed > 0 (real-time mode
     295             :   // does not use speed = 0).
     296           0 :   if (is_one_pass_cbr_svc(cpi) && lc->speed > 0) {
     297           0 :     cpi->oxcf.speed = lc->speed;
     298             :   }
     299             :   // Reset the frames_since_key and frames_to_key counters to their values
     300             :   // before the layer restore. Keep these defined for the stream (not layer).
     301           0 :   if (cpi->svc.number_temporal_layers > 1 ||
     302           0 :       (cpi->svc.number_spatial_layers > 1 && !is_two_pass_svc(cpi))) {
     303           0 :     cpi->rc.frames_since_key = old_frame_since_key;
     304           0 :     cpi->rc.frames_to_key = old_frame_to_key;
     305             :   }
     306             : 
     307             :   // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers,
     308             :   // for the base temporal layer.
     309           0 :   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ &&
     310           0 :       cpi->svc.number_spatial_layers > 1 && cpi->svc.temporal_layer_id == 0) {
     311           0 :     CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
     312           0 :     signed char *temp = cr->map;
     313           0 :     uint8_t *temp2 = cr->last_coded_q_map;
     314           0 :     uint8_t *temp3 = cpi->consec_zero_mv;
     315           0 :     cr->map = lc->map;
     316           0 :     lc->map = temp;
     317           0 :     cr->last_coded_q_map = lc->last_coded_q_map;
     318           0 :     lc->last_coded_q_map = temp2;
     319           0 :     cpi->consec_zero_mv = lc->consec_zero_mv;
     320           0 :     lc->consec_zero_mv = temp3;
     321           0 :     cr->sb_index = lc->sb_index;
     322             :   }
     323           0 : }
     324             : 
     325           0 : void vp9_save_layer_context(VP9_COMP *const cpi) {
     326           0 :   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
     327           0 :   LAYER_CONTEXT *const lc = get_layer_context(cpi);
     328             : 
     329           0 :   lc->rc = cpi->rc;
     330           0 :   lc->twopass = cpi->twopass;
     331           0 :   lc->target_bandwidth = (int)oxcf->target_bandwidth;
     332           0 :   lc->alt_ref_source = cpi->alt_ref_source;
     333             : 
     334             :   // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers,
     335             :   // for the base temporal layer.
     336           0 :   if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ &&
     337           0 :       cpi->svc.number_spatial_layers > 1 && cpi->svc.temporal_layer_id == 0) {
     338           0 :     CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
     339           0 :     signed char *temp = lc->map;
     340           0 :     uint8_t *temp2 = lc->last_coded_q_map;
     341           0 :     uint8_t *temp3 = lc->consec_zero_mv;
     342           0 :     lc->map = cr->map;
     343           0 :     cr->map = temp;
     344           0 :     lc->last_coded_q_map = cr->last_coded_q_map;
     345           0 :     cr->last_coded_q_map = temp2;
     346           0 :     lc->consec_zero_mv = cpi->consec_zero_mv;
     347           0 :     cpi->consec_zero_mv = temp3;
     348           0 :     lc->sb_index = cr->sb_index;
     349             :   }
     350           0 : }
     351             : 
     352           0 : void vp9_init_second_pass_spatial_svc(VP9_COMP *cpi) {
     353           0 :   SVC *const svc = &cpi->svc;
     354             :   int i;
     355             : 
     356           0 :   for (i = 0; i < svc->number_spatial_layers; ++i) {
     357           0 :     TWO_PASS *const twopass = &svc->layer_context[i].twopass;
     358             : 
     359           0 :     svc->spatial_layer_id = i;
     360           0 :     vp9_init_second_pass(cpi);
     361             : 
     362           0 :     twopass->total_stats.spatial_layer_id = i;
     363           0 :     twopass->total_left_stats.spatial_layer_id = i;
     364             :   }
     365           0 :   svc->spatial_layer_id = 0;
     366           0 : }
     367             : 
     368           0 : void vp9_inc_frame_in_layer(VP9_COMP *const cpi) {
     369           0 :   LAYER_CONTEXT *const lc =
     370           0 :       &cpi->svc.layer_context[cpi->svc.spatial_layer_id *
     371           0 :                               cpi->svc.number_temporal_layers];
     372           0 :   ++lc->current_video_frame_in_layer;
     373           0 :   ++lc->frames_from_key_frame;
     374           0 :   if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)
     375           0 :     ++cpi->svc.current_superframe;
     376           0 : }
     377             : 
     378           0 : int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) {
     379           0 :   return is_two_pass_svc(cpi) && cpi->svc.spatial_layer_id > 0 &&
     380             :          cpi->svc
     381           0 :              .layer_context[cpi->svc.spatial_layer_id *
     382           0 :                                 cpi->svc.number_temporal_layers +
     383           0 :                             cpi->svc.temporal_layer_id]
     384           0 :              .is_key_frame;
     385             : }
     386             : 
     387           0 : static void get_layer_resolution(const int width_org, const int height_org,
     388             :                                  const int num, const int den, int *width_out,
     389             :                                  int *height_out) {
     390             :   int w, h;
     391             : 
     392           0 :   if (width_out == NULL || height_out == NULL || den == 0) return;
     393             : 
     394           0 :   w = width_org * num / den;
     395           0 :   h = height_org * num / den;
     396             : 
     397             :   // make height and width even to make chrome player happy
     398           0 :   w += w % 2;
     399           0 :   h += h % 2;
     400             : 
     401           0 :   *width_out = w;
     402           0 :   *height_out = h;
     403             : }
     404             : 
     405             : // The function sets proper ref_frame_flags, buffer indices, and buffer update
     406             : // variables for temporal layering mode 3 - that does 0-2-1-2 temporal layering
     407             : // scheme.
     408           0 : static void set_flags_and_fb_idx_for_temporal_mode3(VP9_COMP *const cpi) {
     409           0 :   int frame_num_within_temporal_struct = 0;
     410             :   int spatial_id, temporal_id;
     411           0 :   spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
     412           0 :   frame_num_within_temporal_struct =
     413             :       cpi->svc
     414           0 :           .layer_context[cpi->svc.spatial_layer_id *
     415           0 :                          cpi->svc.number_temporal_layers]
     416           0 :           .current_video_frame_in_layer %
     417             :       4;
     418           0 :   temporal_id = cpi->svc.temporal_layer_id =
     419           0 :       (frame_num_within_temporal_struct & 1)
     420             :           ? 2
     421           0 :           : (frame_num_within_temporal_struct >> 1);
     422           0 :   cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame =
     423           0 :       cpi->ext_refresh_alt_ref_frame = 0;
     424           0 :   if (!temporal_id) {
     425           0 :     cpi->ext_refresh_frame_flags_pending = 1;
     426           0 :     cpi->ext_refresh_last_frame = 1;
     427           0 :     if (!spatial_id) {
     428           0 :       cpi->ref_frame_flags = VP9_LAST_FLAG;
     429           0 :     } else if (cpi->svc.layer_context[temporal_id].is_key_frame) {
     430             :       // base layer is a key frame.
     431           0 :       cpi->ref_frame_flags = VP9_LAST_FLAG;
     432           0 :       cpi->ext_refresh_last_frame = 0;
     433           0 :       cpi->ext_refresh_golden_frame = 1;
     434             :     } else {
     435           0 :       cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
     436             :     }
     437           0 :   } else if (temporal_id == 1) {
     438           0 :     cpi->ext_refresh_frame_flags_pending = 1;
     439           0 :     cpi->ext_refresh_alt_ref_frame = 1;
     440           0 :     if (!spatial_id) {
     441           0 :       cpi->ref_frame_flags = VP9_LAST_FLAG;
     442             :     } else {
     443           0 :       cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
     444             :     }
     445             :   } else {
     446           0 :     if (frame_num_within_temporal_struct == 1) {
     447             :       // the first tl2 picture
     448           0 :       if (spatial_id == cpi->svc.number_spatial_layers - 1) {  // top layer
     449           0 :         cpi->ext_refresh_frame_flags_pending = 1;
     450           0 :         if (!spatial_id)
     451           0 :           cpi->ref_frame_flags = VP9_LAST_FLAG;
     452             :         else
     453           0 :           cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
     454           0 :       } else if (!spatial_id) {
     455           0 :         cpi->ext_refresh_frame_flags_pending = 1;
     456           0 :         cpi->ext_refresh_alt_ref_frame = 1;
     457           0 :         cpi->ref_frame_flags = VP9_LAST_FLAG;
     458           0 :       } else if (spatial_id < cpi->svc.number_spatial_layers - 1) {
     459           0 :         cpi->ext_refresh_frame_flags_pending = 1;
     460           0 :         cpi->ext_refresh_alt_ref_frame = 1;
     461           0 :         cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
     462             :       }
     463             :     } else {
     464             :       //  The second tl2 picture
     465           0 :       if (spatial_id == cpi->svc.number_spatial_layers - 1) {  // top layer
     466           0 :         cpi->ext_refresh_frame_flags_pending = 1;
     467           0 :         if (!spatial_id)
     468           0 :           cpi->ref_frame_flags = VP9_LAST_FLAG;
     469             :         else
     470           0 :           cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
     471           0 :       } else if (!spatial_id) {
     472           0 :         cpi->ext_refresh_frame_flags_pending = 1;
     473           0 :         cpi->ref_frame_flags = VP9_LAST_FLAG;
     474           0 :         cpi->ext_refresh_alt_ref_frame = 1;
     475             :       } else {  // top layer
     476           0 :         cpi->ext_refresh_frame_flags_pending = 1;
     477           0 :         cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
     478           0 :         cpi->ext_refresh_alt_ref_frame = 1;
     479             :       }
     480             :     }
     481             :   }
     482           0 :   if (temporal_id == 0) {
     483           0 :     cpi->lst_fb_idx = spatial_id;
     484           0 :     if (spatial_id) {
     485           0 :       if (cpi->svc.layer_context[temporal_id].is_key_frame) {
     486           0 :         cpi->lst_fb_idx = spatial_id - 1;
     487           0 :         cpi->gld_fb_idx = spatial_id;
     488             :       } else {
     489           0 :         cpi->gld_fb_idx = spatial_id - 1;
     490             :       }
     491             :     } else {
     492           0 :       cpi->gld_fb_idx = 0;
     493             :     }
     494           0 :     cpi->alt_fb_idx = 0;
     495           0 :   } else if (temporal_id == 1) {
     496           0 :     cpi->lst_fb_idx = spatial_id;
     497           0 :     cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
     498           0 :     cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
     499           0 :   } else if (frame_num_within_temporal_struct == 1) {
     500           0 :     cpi->lst_fb_idx = spatial_id;
     501           0 :     cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
     502           0 :     cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
     503             :   } else {
     504           0 :     cpi->lst_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
     505           0 :     cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
     506           0 :     cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
     507             :   }
     508           0 : }
     509             : 
     510             : // The function sets proper ref_frame_flags, buffer indices, and buffer update
     511             : // variables for temporal layering mode 2 - that does 0-1-0-1 temporal layering
     512             : // scheme.
     513           0 : static void set_flags_and_fb_idx_for_temporal_mode2(VP9_COMP *const cpi) {
     514             :   int spatial_id, temporal_id;
     515           0 :   spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
     516           0 :   temporal_id = cpi->svc.temporal_layer_id =
     517             :       cpi->svc
     518           0 :           .layer_context[cpi->svc.spatial_layer_id *
     519           0 :                          cpi->svc.number_temporal_layers]
     520           0 :           .current_video_frame_in_layer &
     521             :       1;
     522           0 :   cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame =
     523           0 :       cpi->ext_refresh_alt_ref_frame = 0;
     524           0 :   if (!temporal_id) {
     525           0 :     cpi->ext_refresh_frame_flags_pending = 1;
     526           0 :     cpi->ext_refresh_last_frame = 1;
     527           0 :     if (!spatial_id) {
     528           0 :       cpi->ref_frame_flags = VP9_LAST_FLAG;
     529           0 :     } else if (cpi->svc.layer_context[temporal_id].is_key_frame) {
     530             :       // base layer is a key frame.
     531           0 :       cpi->ref_frame_flags = VP9_LAST_FLAG;
     532           0 :       cpi->ext_refresh_last_frame = 0;
     533           0 :       cpi->ext_refresh_golden_frame = 1;
     534             :     } else {
     535           0 :       cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
     536             :     }
     537           0 :   } else if (temporal_id == 1) {
     538           0 :     cpi->ext_refresh_frame_flags_pending = 1;
     539           0 :     cpi->ext_refresh_alt_ref_frame = 1;
     540           0 :     if (!spatial_id) {
     541           0 :       cpi->ref_frame_flags = VP9_LAST_FLAG;
     542             :     } else {
     543           0 :       cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
     544             :     }
     545             :   }
     546             : 
     547           0 :   if (temporal_id == 0) {
     548           0 :     cpi->lst_fb_idx = spatial_id;
     549           0 :     if (spatial_id) {
     550           0 :       if (cpi->svc.layer_context[temporal_id].is_key_frame) {
     551           0 :         cpi->lst_fb_idx = spatial_id - 1;
     552           0 :         cpi->gld_fb_idx = spatial_id;
     553             :       } else {
     554           0 :         cpi->gld_fb_idx = spatial_id - 1;
     555             :       }
     556             :     } else {
     557           0 :       cpi->gld_fb_idx = 0;
     558             :     }
     559           0 :     cpi->alt_fb_idx = 0;
     560           0 :   } else if (temporal_id == 1) {
     561           0 :     cpi->lst_fb_idx = spatial_id;
     562           0 :     cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
     563           0 :     cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
     564             :   }
     565           0 : }
     566             : 
     567             : // The function sets proper ref_frame_flags, buffer indices, and buffer update
     568             : // variables for temporal layering mode 0 - that has no temporal layering.
     569           0 : static void set_flags_and_fb_idx_for_temporal_mode_noLayering(
     570             :     VP9_COMP *const cpi) {
     571             :   int spatial_id;
     572           0 :   spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
     573           0 :   cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame =
     574           0 :       cpi->ext_refresh_alt_ref_frame = 0;
     575           0 :   cpi->ext_refresh_frame_flags_pending = 1;
     576           0 :   cpi->ext_refresh_last_frame = 1;
     577           0 :   if (!spatial_id) {
     578           0 :     cpi->ref_frame_flags = VP9_LAST_FLAG;
     579           0 :   } else if (cpi->svc.layer_context[0].is_key_frame) {
     580           0 :     cpi->ref_frame_flags = VP9_LAST_FLAG;
     581           0 :     cpi->ext_refresh_last_frame = 0;
     582           0 :     cpi->ext_refresh_golden_frame = 1;
     583             :   } else {
     584           0 :     cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
     585             :   }
     586           0 :   cpi->lst_fb_idx = spatial_id;
     587           0 :   if (spatial_id) {
     588           0 :     if (cpi->svc.layer_context[0].is_key_frame) {
     589           0 :       cpi->lst_fb_idx = spatial_id - 1;
     590           0 :       cpi->gld_fb_idx = spatial_id;
     591             :     } else {
     592           0 :       cpi->gld_fb_idx = spatial_id - 1;
     593             :     }
     594             :   } else {
     595           0 :     cpi->gld_fb_idx = 0;
     596             :   }
     597           0 : }
     598             : 
     599           0 : int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) {
     600           0 :   int width = 0, height = 0;
     601           0 :   LAYER_CONTEXT *lc = NULL;
     602           0 :   if (cpi->svc.number_spatial_layers > 1) cpi->svc.use_base_mv = 1;
     603           0 :   cpi->svc.force_zero_mode_spatial_ref = 1;
     604             : 
     605           0 :   if (cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) {
     606           0 :     set_flags_and_fb_idx_for_temporal_mode3(cpi);
     607           0 :   } else if (cpi->svc.temporal_layering_mode ==
     608             :              VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) {
     609           0 :     set_flags_and_fb_idx_for_temporal_mode_noLayering(cpi);
     610           0 :   } else if (cpi->svc.temporal_layering_mode ==
     611             :              VP9E_TEMPORAL_LAYERING_MODE_0101) {
     612           0 :     set_flags_and_fb_idx_for_temporal_mode2(cpi);
     613           0 :   } else if (cpi->svc.temporal_layering_mode ==
     614             :              VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
     615             :     // In the BYPASS/flexible mode, the encoder is relying on the application
     616             :     // to specify, for each spatial layer, the flags and buffer indices for the
     617             :     // layering.
     618             :     // Note that the check (cpi->ext_refresh_frame_flags_pending == 0) is
     619             :     // needed to support the case where the frame flags may be passed in via
     620             :     // vpx_codec_encode(), which can be used for the temporal-only svc case.
     621             :     // TODO(marpan): Consider adding an enc_config parameter to better handle
     622             :     // this case.
     623           0 :     if (cpi->ext_refresh_frame_flags_pending == 0) {
     624             :       int sl;
     625           0 :       cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
     626           0 :       sl = cpi->svc.spatial_layer_id;
     627           0 :       vp9_apply_encoding_flags(cpi, cpi->svc.ext_frame_flags[sl]);
     628           0 :       cpi->lst_fb_idx = cpi->svc.ext_lst_fb_idx[sl];
     629           0 :       cpi->gld_fb_idx = cpi->svc.ext_gld_fb_idx[sl];
     630           0 :       cpi->alt_fb_idx = cpi->svc.ext_alt_fb_idx[sl];
     631             :     }
     632             :   }
     633             : 
     634           0 :   if (cpi->svc.spatial_layer_id == cpi->svc.first_spatial_layer_to_encode)
     635           0 :     cpi->svc.rc_drop_superframe = 0;
     636             : 
     637           0 :   lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id *
     638           0 :                                    cpi->svc.number_temporal_layers +
     639           0 :                                cpi->svc.temporal_layer_id];
     640             : 
     641             :   // Setting the worst/best_quality via the encoder control: SET_SVC_PARAMETERS,
     642             :   // only for non-BYPASS mode for now.
     643           0 :   if (cpi->svc.temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
     644           0 :     RATE_CONTROL *const lrc = &lc->rc;
     645           0 :     lrc->worst_quality = vp9_quantizer_to_qindex(lc->max_q);
     646           0 :     lrc->best_quality = vp9_quantizer_to_qindex(lc->min_q);
     647             :   }
     648             : 
     649           0 :   get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height,
     650             :                        lc->scaling_factor_num, lc->scaling_factor_den, &width,
     651             :                        &height);
     652             : 
     653             :   // The usage of use_base_mv assumes down-scale of 2x2. For now, turn off use
     654             :   // of base motion vectors if spatial scale factors for any layers are not 2.
     655             :   // TODO(marpan): Fix this to allow for use_base_mv for scale factors != 2.
     656           0 :   if (cpi->svc.number_spatial_layers > 1) {
     657             :     int sl;
     658           0 :     for (sl = 0; sl < cpi->svc.number_spatial_layers - 1; ++sl) {
     659           0 :       lc = &cpi->svc.layer_context[sl * cpi->svc.number_temporal_layers +
     660           0 :                                    cpi->svc.temporal_layer_id];
     661           0 :       if (lc->scaling_factor_num != lc->scaling_factor_den >> 1) {
     662           0 :         cpi->svc.use_base_mv = 0;
     663           0 :         break;
     664             :       }
     665             :     }
     666             :   }
     667             : 
     668           0 :   if (vp9_set_size_literal(cpi, width, height) != 0)
     669           0 :     return VPX_CODEC_INVALID_PARAM;
     670             : 
     671           0 :   return 0;
     672             : }
     673             : 
     674             : #if CONFIG_SPATIAL_SVC
     675             : #define SMALL_FRAME_FB_IDX 7
     676             : 
     677             : int vp9_svc_start_frame(VP9_COMP *const cpi) {
     678             :   int width = 0, height = 0;
     679             :   LAYER_CONTEXT *lc;
     680             :   struct lookahead_entry *buf;
     681             :   int count = 1 << (cpi->svc.number_temporal_layers - 1);
     682             : 
     683             :   cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
     684             :   lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id];
     685             : 
     686             :   cpi->svc.temporal_layer_id = 0;
     687             :   while ((lc->current_video_frame_in_layer % count) != 0) {
     688             :     ++cpi->svc.temporal_layer_id;
     689             :     count >>= 1;
     690             :   }
     691             : 
     692             :   cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
     693             : 
     694             :   cpi->lst_fb_idx = cpi->svc.spatial_layer_id;
     695             : 
     696             :   if (cpi->svc.spatial_layer_id == 0)
     697             :     cpi->gld_fb_idx =
     698             :         (lc->gold_ref_idx >= 0) ? lc->gold_ref_idx : cpi->lst_fb_idx;
     699             :   else
     700             :     cpi->gld_fb_idx = cpi->svc.spatial_layer_id - 1;
     701             : 
     702             :   if (lc->current_video_frame_in_layer == 0) {
     703             :     if (cpi->svc.spatial_layer_id >= 2) {
     704             :       cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2;
     705             :     } else {
     706             :       cpi->alt_fb_idx = cpi->lst_fb_idx;
     707             :       cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_ALT_FLAG);
     708             :     }
     709             :   } else {
     710             :     if (cpi->oxcf.ss_enable_auto_arf[cpi->svc.spatial_layer_id]) {
     711             :       cpi->alt_fb_idx = lc->alt_ref_idx;
     712             :       if (!lc->has_alt_frame) cpi->ref_frame_flags &= (~VP9_ALT_FLAG);
     713             :     } else {
     714             :       // Find a proper alt_fb_idx for layers that don't have alt ref frame
     715             :       if (cpi->svc.spatial_layer_id == 0) {
     716             :         cpi->alt_fb_idx = cpi->lst_fb_idx;
     717             :       } else {
     718             :         LAYER_CONTEXT *lc_lower =
     719             :             &cpi->svc.layer_context[cpi->svc.spatial_layer_id - 1];
     720             : 
     721             :         if (cpi->oxcf.ss_enable_auto_arf[cpi->svc.spatial_layer_id - 1] &&
     722             :             lc_lower->alt_ref_source != NULL)
     723             :           cpi->alt_fb_idx = lc_lower->alt_ref_idx;
     724             :         else if (cpi->svc.spatial_layer_id >= 2)
     725             :           cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2;
     726             :         else
     727             :           cpi->alt_fb_idx = cpi->lst_fb_idx;
     728             :       }
     729             :     }
     730             :   }
     731             : 
     732             :   get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height,
     733             :                        lc->scaling_factor_num, lc->scaling_factor_den, &width,
     734             :                        &height);
     735             : 
     736             :   // Workaround for multiple frame contexts. In some frames we can't use prev_mi
     737             :   // since its previous frame could be changed during decoding time. The idea is
     738             :   // we put a empty invisible frame in front of them, then we will not use
     739             :   // prev_mi when encoding these frames.
     740             : 
     741             :   buf = vp9_lookahead_peek(cpi->lookahead, 0);
     742             :   if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2 &&
     743             :       cpi->svc.encode_empty_frame_state == NEED_TO_ENCODE &&
     744             :       lc->rc.frames_to_key != 0 &&
     745             :       !(buf != NULL && (buf->flags & VPX_EFLAG_FORCE_KF))) {
     746             :     if ((cpi->svc.number_temporal_layers > 1 &&
     747             :          cpi->svc.temporal_layer_id < cpi->svc.number_temporal_layers - 1) ||
     748             :         (cpi->svc.number_spatial_layers > 1 &&
     749             :          cpi->svc.spatial_layer_id == 0)) {
     750             :       struct lookahead_entry *buf = vp9_lookahead_peek(cpi->lookahead, 0);
     751             : 
     752             :       if (buf != NULL) {
     753             :         cpi->svc.empty_frame.ts_start = buf->ts_start;
     754             :         cpi->svc.empty_frame.ts_end = buf->ts_end;
     755             :         cpi->svc.encode_empty_frame_state = ENCODING;
     756             :         cpi->common.show_frame = 0;
     757             :         cpi->ref_frame_flags = 0;
     758             :         cpi->common.frame_type = INTER_FRAME;
     759             :         cpi->lst_fb_idx = cpi->gld_fb_idx = cpi->alt_fb_idx =
     760             :             SMALL_FRAME_FB_IDX;
     761             : 
     762             :         if (cpi->svc.encode_intra_empty_frame != 0) cpi->common.intra_only = 1;
     763             : 
     764             :         width = SMALL_FRAME_WIDTH;
     765             :         height = SMALL_FRAME_HEIGHT;
     766             :       }
     767             :     }
     768             :   }
     769             : 
     770             :   cpi->oxcf.worst_allowed_q = vp9_quantizer_to_qindex(lc->max_q);
     771             :   cpi->oxcf.best_allowed_q = vp9_quantizer_to_qindex(lc->min_q);
     772             : 
     773             :   vp9_change_config(cpi, &cpi->oxcf);
     774             : 
     775             :   if (vp9_set_size_literal(cpi, width, height) != 0)
     776             :     return VPX_CODEC_INVALID_PARAM;
     777             : 
     778             :   vp9_set_high_precision_mv(cpi, 1);
     779             : 
     780             :   cpi->alt_ref_source = get_layer_context(cpi)->alt_ref_source;
     781             : 
     782             :   return 0;
     783             : }
     784             : 
     785             : #undef SMALL_FRAME_FB_IDX
     786             : #endif  // CONFIG_SPATIAL_SVC
     787             : 
     788           0 : struct lookahead_entry *vp9_svc_lookahead_pop(VP9_COMP *const cpi,
     789             :                                               struct lookahead_ctx *ctx,
     790             :                                               int drain) {
     791           0 :   struct lookahead_entry *buf = NULL;
     792           0 :   if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) {
     793           0 :     buf = vp9_lookahead_peek(ctx, 0);
     794           0 :     if (buf != NULL) {
     795             :       // Only remove the buffer when pop the highest layer.
     796           0 :       if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) {
     797           0 :         vp9_lookahead_pop(ctx, drain);
     798             :       }
     799             :     }
     800             :   }
     801           0 :   return buf;
     802             : }
     803             : 
     804           0 : void vp9_free_svc_cyclic_refresh(VP9_COMP *const cpi) {
     805             :   int sl, tl;
     806           0 :   SVC *const svc = &cpi->svc;
     807           0 :   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
     808           0 :   for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
     809           0 :     for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
     810           0 :       int layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers);
     811           0 :       LAYER_CONTEXT *const lc = &svc->layer_context[layer];
     812           0 :       if (lc->map) vpx_free(lc->map);
     813           0 :       if (lc->last_coded_q_map) vpx_free(lc->last_coded_q_map);
     814           0 :       if (lc->consec_zero_mv) vpx_free(lc->consec_zero_mv);
     815             :     }
     816             :   }
     817           0 : }
     818             : 
     819             : // Reset on key frame: reset counters, references and buffer updates.
     820           0 : void vp9_svc_reset_key_frame(VP9_COMP *const cpi) {
     821             :   int sl, tl;
     822           0 :   SVC *const svc = &cpi->svc;
     823           0 :   LAYER_CONTEXT *lc = NULL;
     824           0 :   for (sl = 0; sl < svc->number_spatial_layers; ++sl) {
     825           0 :     for (tl = 0; tl < svc->number_temporal_layers; ++tl) {
     826           0 :       lc = &cpi->svc.layer_context[sl * svc->number_temporal_layers + tl];
     827           0 :       lc->current_video_frame_in_layer = 0;
     828           0 :       lc->frames_from_key_frame = 0;
     829             :     }
     830             :   }
     831           0 :   if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) {
     832           0 :     set_flags_and_fb_idx_for_temporal_mode3(cpi);
     833           0 :   } else if (svc->temporal_layering_mode ==
     834             :              VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) {
     835           0 :     set_flags_and_fb_idx_for_temporal_mode_noLayering(cpi);
     836           0 :   } else if (svc->temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0101) {
     837           0 :     set_flags_and_fb_idx_for_temporal_mode2(cpi);
     838             :   }
     839           0 :   vp9_update_temporal_layer_framerate(cpi);
     840           0 :   vp9_restore_layer_context(cpi);
     841           0 : }

Generated by: LCOV version 1.13