Coverage Report

Created: 2022-08-24 06:17

/src/aom/av1/encoder/svc_layercontext.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  Copyright (c) 2019, Alliance for Open Media. 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 "av1/encoder/encoder.h"
14
#include "av1/encoder/encoder_alloc.h"
15
16
0
static void swap_ptr(void *a, void *b) {
17
0
  void **a_p = (void **)a;
18
0
  void **b_p = (void **)b;
19
0
  void *c = *a_p;
20
0
  *a_p = *b_p;
21
0
  *b_p = c;
22
0
}
23
24
0
void av1_init_layer_context(AV1_COMP *const cpi) {
25
0
  AV1_COMMON *const cm = &cpi->common;
26
0
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
27
0
  SVC *const svc = &cpi->svc;
28
0
  int mi_rows = cpi->common.mi_params.mi_rows;
29
0
  int mi_cols = cpi->common.mi_params.mi_cols;
30
0
  svc->base_framerate = 30.0;
31
0
  svc->current_superframe = 0;
32
0
  svc->force_zero_mode_spatial_ref = 1;
33
0
  svc->num_encoded_top_layer = 0;
34
0
  svc->use_flexible_mode = 0;
35
36
0
  for (int sl = 0; sl < svc->number_spatial_layers; ++sl) {
37
0
    for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
38
0
      int layer = LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
39
0
      LAYER_CONTEXT *const lc = &svc->layer_context[layer];
40
0
      RATE_CONTROL *const lrc = &lc->rc;
41
0
      PRIMARY_RATE_CONTROL *const lp_rc = &lc->p_rc;
42
0
      lrc->ni_av_qi = oxcf->rc_cfg.worst_allowed_q;
43
0
      lp_rc->total_actual_bits = 0;
44
0
      lrc->ni_tot_qi = 0;
45
0
      lp_rc->tot_q = 0.0;
46
0
      lp_rc->avg_q = 0.0;
47
0
      lp_rc->ni_frames = 0;
48
0
      lrc->decimation_count = 0;
49
0
      lrc->decimation_factor = 0;
50
0
      lrc->worst_quality = av1_quantizer_to_qindex(lc->max_q);
51
0
      lrc->best_quality = av1_quantizer_to_qindex(lc->min_q);
52
0
      lrc->rtc_external_ratectrl = 0;
53
0
      for (int i = 0; i < RATE_FACTOR_LEVELS; ++i) {
54
0
        lp_rc->rate_correction_factors[i] = 1.0;
55
0
      }
56
0
      lc->target_bandwidth = lc->layer_target_bitrate;
57
0
      lp_rc->last_q[INTER_FRAME] = lrc->worst_quality;
58
0
      lp_rc->avg_frame_qindex[INTER_FRAME] = lrc->worst_quality;
59
0
      lp_rc->avg_frame_qindex[KEY_FRAME] = lrc->worst_quality;
60
0
      lp_rc->buffer_level =
61
0
          oxcf->rc_cfg.starting_buffer_level_ms * lc->target_bandwidth / 1000;
62
0
      lp_rc->bits_off_target = lp_rc->buffer_level;
63
      // Initialize the cyclic refresh parameters. If spatial layers are used
64
      // (i.e., ss_number_layers > 1), these need to be updated per spatial
65
      // layer. Cyclic refresh is only applied on base temporal layer.
66
0
      if (svc->number_spatial_layers > 1 && tl == 0) {
67
0
        lc->sb_index = 0;
68
0
        lc->actual_num_seg1_blocks = 0;
69
0
        lc->actual_num_seg2_blocks = 0;
70
0
        lc->counter_encode_maxq_scene_change = 0;
71
0
        if (lc->map) aom_free(lc->map);
72
0
        CHECK_MEM_ERROR(cm, lc->map,
73
0
                        aom_malloc(mi_rows * mi_cols * sizeof(*lc->map)));
74
0
        memset(lc->map, 0, mi_rows * mi_cols);
75
0
      }
76
0
    }
77
0
    svc->downsample_filter_type[sl] = BILINEAR;
78
0
    svc->downsample_filter_phase[sl] = 8;
79
0
  }
80
0
  if (svc->number_spatial_layers == 3) {
81
0
    svc->downsample_filter_type[0] = EIGHTTAP_SMOOTH;
82
0
  }
83
0
  svc->ref_frame_comp[0] = 0;
84
0
  svc->ref_frame_comp[1] = 0;
85
0
  svc->ref_frame_comp[2] = 0;
86
0
}
87
88
// Update the layer context from a change_config() call.
89
void av1_update_layer_context_change_config(AV1_COMP *const cpi,
90
0
                                            const int64_t target_bandwidth) {
91
0
  const RATE_CONTROL *const rc = &cpi->rc;
92
0
  const PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
93
0
  SVC *const svc = &cpi->svc;
94
0
  int layer = 0;
95
0
  int64_t spatial_layer_target = 0;
96
0
  float bitrate_alloc = 1.0;
97
0
  for (int sl = 0; sl < svc->number_spatial_layers; ++sl) {
98
0
    for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
99
0
      layer = LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
100
0
      LAYER_CONTEXT *const lc = &svc->layer_context[layer];
101
0
      svc->layer_context[layer].target_bandwidth = lc->layer_target_bitrate;
102
0
    }
103
0
    spatial_layer_target = svc->layer_context[layer].target_bandwidth;
104
0
    for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
105
0
      LAYER_CONTEXT *const lc =
106
0
          &svc->layer_context[sl * svc->number_temporal_layers + tl];
107
0
      RATE_CONTROL *const lrc = &lc->rc;
108
0
      PRIMARY_RATE_CONTROL *const lp_rc = &lc->p_rc;
109
0
      lc->spatial_layer_target_bandwidth = spatial_layer_target;
110
0
      bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth;
111
0
      lp_rc->starting_buffer_level =
112
0
          (int64_t)(p_rc->starting_buffer_level * bitrate_alloc);
113
0
      lp_rc->optimal_buffer_level =
114
0
          (int64_t)(p_rc->optimal_buffer_level * bitrate_alloc);
115
0
      lp_rc->maximum_buffer_size =
116
0
          (int64_t)(p_rc->maximum_buffer_size * bitrate_alloc);
117
0
      lp_rc->bits_off_target =
118
0
          AOMMIN(lp_rc->bits_off_target, lp_rc->maximum_buffer_size);
119
0
      lp_rc->buffer_level =
120
0
          AOMMIN(lp_rc->buffer_level, lp_rc->maximum_buffer_size);
121
0
      lc->framerate = cpi->framerate / lc->framerate_factor;
122
0
      lrc->avg_frame_bandwidth =
123
0
          (int)round(lc->target_bandwidth / lc->framerate);
124
0
      lrc->max_frame_bandwidth = rc->max_frame_bandwidth;
125
0
      lrc->rtc_external_ratectrl = rc->rtc_external_ratectrl;
126
0
      lrc->worst_quality = av1_quantizer_to_qindex(lc->max_q);
127
0
      lrc->best_quality = av1_quantizer_to_qindex(lc->min_q);
128
0
    }
129
0
  }
130
0
}
131
132
/*!\brief Return layer context for current layer.
133
 *
134
 * \ingroup rate_control
135
 * \param[in]       cpi   Top level encoder structure
136
 *
137
 * \return LAYER_CONTEXT for current layer.
138
 */
139
0
static LAYER_CONTEXT *get_layer_context(AV1_COMP *const cpi) {
140
0
  return &cpi->svc.layer_context[cpi->svc.spatial_layer_id *
141
0
                                     cpi->svc.number_temporal_layers +
142
0
                                 cpi->svc.temporal_layer_id];
143
0
}
144
145
0
void av1_update_temporal_layer_framerate(AV1_COMP *const cpi) {
146
0
  SVC *const svc = &cpi->svc;
147
0
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
148
0
  RATE_CONTROL *const lrc = &lc->rc;
149
0
  const int tl = svc->temporal_layer_id;
150
0
  lc->framerate = cpi->framerate / lc->framerate_factor;
151
0
  lrc->avg_frame_bandwidth = (int)round(lc->target_bandwidth / lc->framerate);
152
0
  lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth;
153
  // Update the average layer frame size (non-cumulative per-frame-bw).
154
0
  if (tl == 0) {
155
0
    lc->avg_frame_size = lrc->avg_frame_bandwidth;
156
0
  } else {
157
0
    int prev_layer = svc->spatial_layer_id * svc->number_temporal_layers +
158
0
                     svc->temporal_layer_id - 1;
159
0
    LAYER_CONTEXT *const lcprev = &svc->layer_context[prev_layer];
160
0
    const double prev_layer_framerate =
161
0
        cpi->framerate / lcprev->framerate_factor;
162
0
    const int64_t prev_layer_target_bandwidth = lcprev->layer_target_bitrate;
163
0
    lc->avg_frame_size =
164
0
        (int)round((lc->target_bandwidth - prev_layer_target_bandwidth) /
165
0
                   (lc->framerate - prev_layer_framerate));
166
0
  }
167
0
}
168
169
0
void av1_restore_layer_context(AV1_COMP *const cpi) {
170
0
  SVC *const svc = &cpi->svc;
171
0
  const AV1_COMMON *const cm = &cpi->common;
172
0
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
173
0
  const int old_frame_since_key = cpi->rc.frames_since_key;
174
0
  const int old_frame_to_key = cpi->rc.frames_to_key;
175
  // Restore layer rate control.
176
0
  cpi->rc = lc->rc;
177
0
  cpi->ppi->p_rc = lc->p_rc;
178
0
  cpi->oxcf.rc_cfg.target_bandwidth = lc->target_bandwidth;
179
0
  cpi->gf_frame_index = 0;
180
0
  cpi->mv_search_params.max_mv_magnitude = lc->max_mv_magnitude;
181
0
  if (cpi->mv_search_params.max_mv_magnitude == 0)
182
0
    cpi->mv_search_params.max_mv_magnitude = AOMMAX(cm->width, cm->height);
183
  // Reset the frames_since_key and frames_to_key counters to their values
184
  // before the layer restore. Keep these defined for the stream (not layer).
185
0
  cpi->rc.frames_since_key = old_frame_since_key;
186
0
  cpi->rc.frames_to_key = old_frame_to_key;
187
  // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers,
188
  // for the base temporal layer.
189
0
  if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ &&
190
0
      svc->number_spatial_layers > 1 && svc->temporal_layer_id == 0) {
191
0
    CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
192
0
    swap_ptr(&cr->map, &lc->map);
193
0
    cr->sb_index = lc->sb_index;
194
0
    cr->actual_num_seg1_blocks = lc->actual_num_seg1_blocks;
195
0
    cr->actual_num_seg2_blocks = lc->actual_num_seg2_blocks;
196
0
  }
197
0
  svc->skip_mvsearch_last = 0;
198
0
  svc->skip_mvsearch_gf = 0;
199
  // For each reference (LAST/GOLDEN) set the skip_mvsearch_last/gf frame flags.
200
  // This is to skip searching mv for that reference if it was last
201
  // refreshed (i.e., buffer slot holding that reference was refreshed) on the
202
  // previous spatial layer(s) at the same time (current_superframe).
203
0
  if (svc->set_ref_frame_config && svc->force_zero_mode_spatial_ref) {
204
0
    int ref_frame_idx = svc->ref_idx[LAST_FRAME - 1];
205
0
    if (svc->buffer_time_index[ref_frame_idx] == svc->current_superframe &&
206
0
        svc->buffer_spatial_layer[ref_frame_idx] <= svc->spatial_layer_id - 1)
207
0
      svc->skip_mvsearch_last = 1;
208
0
    ref_frame_idx = svc->ref_idx[GOLDEN_FRAME - 1];
209
0
    if (svc->buffer_time_index[ref_frame_idx] == svc->current_superframe &&
210
0
        svc->buffer_spatial_layer[ref_frame_idx] <= svc->spatial_layer_id - 1)
211
0
      svc->skip_mvsearch_gf = 1;
212
0
  }
213
0
}
214
215
0
void av1_save_layer_context(AV1_COMP *const cpi) {
216
0
  SVC *const svc = &cpi->svc;
217
0
  const AV1_COMMON *const cm = &cpi->common;
218
0
  LAYER_CONTEXT *lc = get_layer_context(cpi);
219
0
  lc->rc = cpi->rc;
220
0
  lc->p_rc = cpi->ppi->p_rc;
221
0
  lc->target_bandwidth = (int)cpi->oxcf.rc_cfg.target_bandwidth;
222
0
  lc->group_index = cpi->gf_frame_index;
223
0
  lc->max_mv_magnitude = cpi->mv_search_params.max_mv_magnitude;
224
0
  if (svc->spatial_layer_id == 0) svc->base_framerate = cpi->framerate;
225
  // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers,
226
  // for the base temporal layer.
227
0
  if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ &&
228
0
      cpi->svc.number_spatial_layers > 1 && svc->temporal_layer_id == 0) {
229
0
    CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
230
0
    signed char *temp = lc->map;
231
0
    lc->map = cr->map;
232
0
    cr->map = temp;
233
0
    lc->sb_index = cr->sb_index;
234
0
    lc->actual_num_seg1_blocks = cr->actual_num_seg1_blocks;
235
0
    lc->actual_num_seg2_blocks = cr->actual_num_seg2_blocks;
236
0
  }
237
  // For any buffer slot that is refreshed, update it with
238
  // the spatial_layer_id and the current_superframe.
239
0
  if (cpi->common.current_frame.frame_type == KEY_FRAME) {
240
    // All slots are refreshed on KEY.
241
0
    for (unsigned int i = 0; i < REF_FRAMES; i++) {
242
0
      svc->buffer_time_index[i] = svc->current_superframe;
243
0
      svc->buffer_spatial_layer[i] = svc->spatial_layer_id;
244
0
    }
245
0
  } else if (cpi->svc.set_ref_frame_config) {
246
0
    for (unsigned int i = 0; i < INTER_REFS_PER_FRAME; i++) {
247
0
      int ref_frame_map_idx = svc->ref_idx[i];
248
0
      if (cpi->svc.refresh[ref_frame_map_idx]) {
249
0
        svc->buffer_time_index[ref_frame_map_idx] = svc->current_superframe;
250
0
        svc->buffer_spatial_layer[ref_frame_map_idx] = svc->spatial_layer_id;
251
0
      }
252
0
    }
253
0
  }
254
0
  for (unsigned int i = 0; i < REF_FRAMES; i++) {
255
0
    if (frame_is_intra_only(cm) ||
256
0
        cm->current_frame.refresh_frame_flags & (1 << i)) {
257
0
      svc->spatial_layer_fb[i] = svc->spatial_layer_id;
258
0
      svc->temporal_layer_fb[i] = svc->temporal_layer_id;
259
0
    }
260
0
  }
261
0
  if (svc->spatial_layer_id == svc->number_spatial_layers - 1)
262
0
    svc->current_superframe++;
263
0
}
264
265
0
int av1_svc_primary_ref_frame(const AV1_COMP *const cpi) {
266
0
  const SVC *const svc = &cpi->svc;
267
0
  const AV1_COMMON *const cm = &cpi->common;
268
0
  int wanted_fb = -1;
269
0
  int primary_ref_frame = PRIMARY_REF_NONE;
270
0
  for (unsigned int i = 0; i < REF_FRAMES; i++) {
271
0
    if (svc->spatial_layer_fb[i] == svc->spatial_layer_id &&
272
0
        svc->temporal_layer_fb[i] == svc->temporal_layer_id) {
273
0
      wanted_fb = i;
274
0
      break;
275
0
    }
276
0
  }
277
0
  if (wanted_fb != -1) {
278
0
    for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
279
0
      if (get_ref_frame_map_idx(cm, ref_frame) == wanted_fb) {
280
0
        primary_ref_frame = ref_frame - LAST_FRAME;
281
0
        break;
282
0
      }
283
0
    }
284
0
  }
285
0
  return primary_ref_frame;
286
0
}
287
288
0
void av1_free_svc_cyclic_refresh(AV1_COMP *const cpi) {
289
0
  SVC *const svc = &cpi->svc;
290
0
  for (int sl = 0; sl < svc->number_spatial_layers; ++sl) {
291
0
    for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
292
0
      int layer = LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
293
0
      LAYER_CONTEXT *const lc = &svc->layer_context[layer];
294
0
      if (lc->map) aom_free(lc->map);
295
0
    }
296
0
  }
297
0
}
298
299
0
void av1_svc_reset_temporal_layers(AV1_COMP *const cpi, int is_key) {
300
0
  SVC *const svc = &cpi->svc;
301
0
  LAYER_CONTEXT *lc = NULL;
302
0
  for (int sl = 0; sl < svc->number_spatial_layers; ++sl) {
303
0
    for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
304
0
      lc = &cpi->svc.layer_context[sl * svc->number_temporal_layers + tl];
305
0
      if (is_key) lc->frames_from_key_frame = 0;
306
0
    }
307
0
  }
308
0
  av1_update_temporal_layer_framerate(cpi);
309
0
  av1_restore_layer_context(cpi);
310
0
}
311
312
void av1_get_layer_resolution(const int width_org, const int height_org,
313
                              const int num, const int den, int *width_out,
314
0
                              int *height_out) {
315
0
  int w, h;
316
0
  if (width_out == NULL || height_out == NULL || den == 0) return;
317
0
  w = width_org * num / den;
318
0
  h = height_org * num / den;
319
  // Make height and width even.
320
0
  w += w % 2;
321
0
  h += h % 2;
322
0
  *width_out = w;
323
0
  *height_out = h;
324
0
}
325
326
0
void av1_one_pass_cbr_svc_start_layer(AV1_COMP *const cpi) {
327
0
  SVC *const svc = &cpi->svc;
328
0
  LAYER_CONTEXT *lc = NULL;
329
0
  int width = 0, height = 0;
330
0
  lc = &svc->layer_context[svc->spatial_layer_id * svc->number_temporal_layers +
331
0
                           svc->temporal_layer_id];
332
0
  av1_get_layer_resolution(cpi->oxcf.frm_dim_cfg.width,
333
0
                           cpi->oxcf.frm_dim_cfg.height, lc->scaling_factor_num,
334
0
                           lc->scaling_factor_den, &width, &height);
335
  // Use Eightap_smooth for low resolutions.
336
0
  if (width * height <= 320 * 240)
337
0
    svc->downsample_filter_type[svc->spatial_layer_id] = EIGHTTAP_SMOOTH;
338
339
0
  cpi->common.width = width;
340
0
  cpi->common.height = height;
341
0
  alloc_mb_mode_info_buffers(cpi);
342
0
  av1_update_frame_size(cpi);
343
0
  if (svc->spatial_layer_id == 0) svc->high_source_sad_superframe = 0;
344
0
}
345
346
enum {
347
  SVC_LAST_FRAME = 0,
348
  SVC_LAST2_FRAME,
349
  SVC_LAST3_FRAME,
350
  SVC_GOLDEN_FRAME,
351
  SVC_BWDREF_FRAME,
352
  SVC_ALTREF2_FRAME,
353
  SVC_ALTREF_FRAME
354
};
355
356
// For fixed svc mode: fixed pattern is set based on the number of
357
// spatial and temporal layers, and the ksvc_fixed_mode.
358
0
void av1_set_svc_fixed_mode(AV1_COMP *const cpi) {
359
0
  SVC *const svc = &cpi->svc;
360
0
  int i;
361
0
  assert(svc->use_flexible_mode == 0);
362
  // Fixed SVC mode only supports at most 3 spatial or temporal layers.
363
0
  assert(svc->number_spatial_layers >= 1 && svc->number_spatial_layers <= 3 &&
364
0
         svc->number_temporal_layers >= 1 && svc->number_temporal_layers <= 3);
365
0
  svc->set_ref_frame_config = 1;
366
0
  int superframe_cnt = svc->current_superframe;
367
  // Set the reference map buffer idx for the 7 references:
368
  // LAST_FRAME (0), LAST2_FRAME(1), LAST3_FRAME(2), GOLDEN_FRAME(3),
369
  // BWDREF_FRAME(4), ALTREF2_FRAME(5), ALTREF_FRAME(6).
370
0
  for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = i;
371
0
  for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->reference[i] = 0;
372
0
  for (i = 0; i < REF_FRAMES; i++) svc->refresh[i] = 0;
373
  // Always reference LAST, and reference GOLDEN on SL > 0.
374
  // For KSVC: GOLDEN reference will be removed on INTER_FRAMES later
375
  // when frame_type is set.
376
0
  svc->reference[SVC_LAST_FRAME] = 1;
377
0
  if (svc->spatial_layer_id > 0) svc->reference[SVC_GOLDEN_FRAME] = 1;
378
0
  if (svc->temporal_layer_id == 0) {
379
    // Base temporal layer.
380
0
    if (svc->spatial_layer_id == 0) {
381
      // Set all buffer_idx to 0. Update slot 0 (LAST).
382
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 0;
383
0
      svc->refresh[0] = 1;
384
0
    } else if (svc->spatial_layer_id == 1) {
385
      // Set buffer_idx for LAST to slot 1, GOLDEN (and all other refs) to
386
      // slot 0. Update slot 1 (LAST).
387
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 0;
388
0
      svc->ref_idx[SVC_LAST_FRAME] = 1;
389
0
      svc->refresh[1] = 1;
390
0
    } else if (svc->spatial_layer_id == 2) {
391
      // Set buffer_idx for LAST to slot 2, GOLDEN (and all other refs) to
392
      // slot 1. Update slot 2 (LAST).
393
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 1;
394
0
      svc->ref_idx[SVC_LAST_FRAME] = 2;
395
0
      svc->refresh[2] = 1;
396
0
    }
397
0
  } else if (svc->temporal_layer_id == 2 && (superframe_cnt - 1) % 4 == 0) {
398
    // First top temporal enhancement layer.
399
0
    if (svc->spatial_layer_id == 0) {
400
      // Reference LAST (slot 0).
401
      // Set GOLDEN to slot 3 and update slot 3.
402
      // Set all other buffer_idx to slot 0.
403
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 0;
404
0
      if (svc->spatial_layer_id < svc->number_spatial_layers - 1) {
405
0
        svc->ref_idx[SVC_GOLDEN_FRAME] = 3;
406
0
        svc->refresh[3] = 1;
407
0
      }
408
0
    } else if (svc->spatial_layer_id == 1) {
409
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1,
410
      // GOLDEN (and all other refs) to slot 3.
411
      // Set LAST2 to slot 4 and Update slot 4.
412
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 3;
413
0
      svc->ref_idx[SVC_LAST_FRAME] = 1;
414
0
      if (svc->spatial_layer_id < svc->number_spatial_layers - 1) {
415
0
        svc->ref_idx[SVC_LAST2_FRAME] = 4;
416
0
        svc->refresh[4] = 1;
417
0
      }
418
0
    } else if (svc->spatial_layer_id == 2) {
419
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2,
420
      // GOLDEN (and all other refs) to slot 4.
421
      // No update.
422
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 4;
423
0
      svc->ref_idx[SVC_LAST_FRAME] = 2;
424
0
    }
425
0
  } else if (svc->temporal_layer_id == 1) {
426
    // Middle temporal enhancement layer.
427
0
    if (svc->spatial_layer_id == 0) {
428
      // Reference LAST.
429
      // Set all buffer_idx to 0.
430
      // Set GOLDEN to slot 5 and update slot 5.
431
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 0;
432
0
      if (svc->temporal_layer_id < svc->number_temporal_layers - 1) {
433
0
        svc->ref_idx[SVC_GOLDEN_FRAME] = 5;
434
0
        svc->refresh[5] = 1;
435
0
      }
436
0
    } else if (svc->spatial_layer_id == 1) {
437
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1,
438
      // GOLDEN (and all other refs) to slot 5.
439
      // Set LAST3 to slot 6 and update slot 6.
440
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 5;
441
0
      svc->ref_idx[SVC_LAST_FRAME] = 1;
442
0
      if (svc->temporal_layer_id < svc->number_temporal_layers - 1) {
443
0
        svc->ref_idx[SVC_LAST3_FRAME] = 6;
444
0
        svc->refresh[6] = 1;
445
0
      }
446
0
    } else if (svc->spatial_layer_id == 2) {
447
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2,
448
      // GOLDEN (and all other refs) to slot 6.
449
      // Set LAST3 to slot 7 and update slot 7.
450
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 6;
451
0
      svc->ref_idx[SVC_LAST_FRAME] = 2;
452
0
      if (svc->temporal_layer_id < svc->number_temporal_layers - 1) {
453
0
        svc->ref_idx[SVC_LAST3_FRAME] = 7;
454
0
        svc->refresh[7] = 1;
455
0
      }
456
0
    }
457
0
  } else if (svc->temporal_layer_id == 2 && (superframe_cnt - 3) % 4 == 0) {
458
    // Second top temporal enhancement layer.
459
0
    if (svc->spatial_layer_id == 0) {
460
      // Set LAST to slot 5 and reference LAST.
461
      // Set GOLDEN to slot 3 and update slot 3.
462
      // Set all other buffer_idx to 0.
463
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 0;
464
0
      svc->ref_idx[SVC_LAST_FRAME] = 5;
465
0
      if (svc->spatial_layer_id < svc->number_spatial_layers - 1) {
466
0
        svc->ref_idx[SVC_GOLDEN_FRAME] = 3;
467
0
        svc->refresh[3] = 1;
468
0
      }
469
0
    } else if (svc->spatial_layer_id == 1) {
470
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 6,
471
      // GOLDEN to slot 3. Set LAST2 to slot 4 and update slot 4.
472
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 0;
473
0
      svc->ref_idx[SVC_LAST_FRAME] = 6;
474
0
      svc->ref_idx[SVC_GOLDEN_FRAME] = 3;
475
0
      if (svc->spatial_layer_id < svc->number_spatial_layers - 1) {
476
0
        svc->ref_idx[SVC_LAST2_FRAME] = 4;
477
0
        svc->refresh[4] = 1;
478
0
      }
479
0
    } else if (svc->spatial_layer_id == 2) {
480
      // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 7,
481
      // GOLDEN to slot 4. No update.
482
0
      for (i = 0; i < INTER_REFS_PER_FRAME; i++) svc->ref_idx[i] = 0;
483
0
      svc->ref_idx[SVC_LAST_FRAME] = 7;
484
0
      svc->ref_idx[SVC_GOLDEN_FRAME] = 4;
485
0
    }
486
0
  }
487
0
}
488
489
0
void av1_svc_check_reset_layer_rc_flag(AV1_COMP *const cpi) {
490
0
  SVC *const svc = &cpi->svc;
491
0
  for (int sl = 0; sl < svc->number_spatial_layers; ++sl) {
492
    // Check for reset based on avg_frame_bandwidth for spatial layer sl.
493
0
    int layer = LAYER_IDS_TO_IDX(sl, svc->number_temporal_layers - 1,
494
0
                                 svc->number_temporal_layers);
495
0
    LAYER_CONTEXT *lc = &svc->layer_context[layer];
496
0
    RATE_CONTROL *lrc = &lc->rc;
497
0
    if (lrc->avg_frame_bandwidth > (3 * lrc->prev_avg_frame_bandwidth >> 1) ||
498
0
        lrc->avg_frame_bandwidth < (lrc->prev_avg_frame_bandwidth >> 1)) {
499
      // Reset for all temporal layers with spatial layer sl.
500
0
      for (int tl = 0; tl < svc->number_temporal_layers; ++tl) {
501
0
        int layer2 = LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
502
0
        LAYER_CONTEXT *lc2 = &svc->layer_context[layer2];
503
0
        RATE_CONTROL *lrc2 = &lc2->rc;
504
0
        PRIMARY_RATE_CONTROL *lp_rc2 = &lc2->p_rc;
505
0
        PRIMARY_RATE_CONTROL *const lp_rc = &lc2->p_rc;
506
0
        lrc2->rc_1_frame = 0;
507
0
        lrc2->rc_2_frame = 0;
508
0
        lp_rc2->bits_off_target = lp_rc->optimal_buffer_level;
509
0
        lp_rc2->buffer_level = lp_rc->optimal_buffer_level;
510
0
      }
511
0
    }
512
0
  }
513
0
}