vp9_svc_layercontext.c 27.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
/*
 *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <math.h>

13
#include "vp9/encoder/vp9_aq_cyclicrefresh.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
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_FB_IDX 7
20
#define SMALL_FRAME_WIDTH  32
21
#define SMALL_FRAME_HEIGHT 16
22

23
void vp9_init_layer_context(VP9_COMP *const cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
24
  SVC *const svc = &cpi->svc;
25
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
26
27
  int mi_rows = cpi->common.mi_rows;
  int mi_cols = cpi->common.mi_cols;
28
  int sl, tl;
29
  int alt_ref_idx = svc->number_spatial_layers;
30

Dmitry Kovalev's avatar
Dmitry Kovalev committed
31
32
  svc->spatial_layer_id = 0;
  svc->temporal_layer_id = 0;
33
  svc->first_spatial_layer_to_encode = 0;
34
  svc->rc_drop_superframe = 0;
35

36
  if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) {
37
    if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img,
38
39
40
                                 SMALL_FRAME_WIDTH, SMALL_FRAME_HEIGHT,
                                 cpi->common.subsampling_x,
                                 cpi->common.subsampling_y,
41
42
43
#if CONFIG_VP9_HIGHBITDEPTH
                                 cpi->common.use_highbitdepth,
#endif
44
45
46
                                 VP9_ENC_BORDER_IN_PIXELS,
                                 cpi->common.byte_alignment,
                                 NULL, NULL, NULL))
47
48
49
      vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
                         "Failed to allocate empty frame for multiple frame "
                         "contexts");
50

51
52
    memset(cpi->svc.empty_frame.img.buffer_alloc, 0x80,
           cpi->svc.empty_frame.img.buffer_alloc_sz);
53
54
  }

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
  for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
    for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
      int layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers);
      LAYER_CONTEXT *const lc = &svc->layer_context[layer];
      RATE_CONTROL *const lrc = &lc->rc;
      int i;
      lc->current_video_frame_in_layer = 0;
      lc->layer_size = 0;
      lc->frames_from_key_frame = 0;
      lc->last_frame_type = FRAME_TYPES;
      lrc->ni_av_qi = oxcf->worst_allowed_q;
      lrc->total_actual_bits = 0;
      lrc->total_target_vs_actual = 0;
      lrc->ni_tot_qi = 0;
      lrc->tot_q = 0.0;
      lrc->avg_q = 0.0;
      lrc->ni_frames = 0;
      lrc->decimation_count = 0;
      lrc->decimation_factor = 0;

      for (i = 0; i < RATE_FACTOR_LEVELS; ++i) {
        lrc->rate_correction_factors[i] = 1.0;
      }
78

79
80
81
82
83
84
85
86
87
88
      if (cpi->oxcf.rc_mode == VPX_CBR) {
        lc->target_bandwidth = oxcf->layer_target_bitrate[layer];
        lrc->last_q[INTER_FRAME] = oxcf->worst_allowed_q;
        lrc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q;
        lrc->avg_frame_qindex[KEY_FRAME] = oxcf->worst_allowed_q;
      } else {
        lc->target_bandwidth = oxcf->layer_target_bitrate[layer];
        lrc->last_q[KEY_FRAME] = oxcf->best_allowed_q;
        lrc->last_q[INTER_FRAME] = oxcf->best_allowed_q;
        lrc->avg_frame_qindex[KEY_FRAME] = (oxcf->worst_allowed_q +
89
                                            oxcf->best_allowed_q) / 2;
90
91
92
93
94
95
96
97
        lrc->avg_frame_qindex[INTER_FRAME] = (oxcf->worst_allowed_q +
                                              oxcf->best_allowed_q) / 2;
        if (oxcf->ss_enable_auto_arf[sl])
          lc->alt_ref_idx = alt_ref_idx++;
        else
          lc->alt_ref_idx = INVALID_IDX;
        lc->gold_ref_idx = INVALID_IDX;
      }
98

99
100
101
      lrc->buffer_level = oxcf->starting_buffer_level_ms *
                              lc->target_bandwidth / 1000;
      lrc->bits_off_target = lrc->buffer_level;
102
103
104
105
106
107
108

      // Initialize the cyclic refresh parameters. If spatial layers are used
      // (i.e., ss_number_layers > 1), these need to be updated per spatial
      // layer.
      // Cyclic refresh is only applied on base temporal layer.
      if (oxcf->ss_number_layers > 1 &&
          tl == 0) {
109
110
        size_t last_coded_q_map_size;
        size_t consec_zero_mv_size;
111
112
113
        lc->sb_index = 0;
        lc->map = vpx_malloc(mi_rows * mi_cols * sizeof(signed char));
        memset(lc->map, 0, mi_rows * mi_cols);
114
        last_coded_q_map_size = mi_rows * mi_cols * sizeof(uint8_t);
115
116
117
        lc->last_coded_q_map = vpx_malloc(last_coded_q_map_size);
        assert(MAXQ <= 255);
        memset(lc->last_coded_q_map, MAXQ, last_coded_q_map_size);
118
119
120
        consec_zero_mv_size = mi_rows * mi_cols * sizeof(uint8_t);
        lc->consec_zero_mv = vpx_malloc(consec_zero_mv_size);
        memset(lc->consec_zero_mv, 0, consec_zero_mv_size);
121
       }
122
    }
123
  }
124
125

  // Still have extra buffer for base layer golden frame
126
127
  if (!(svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR)
      && alt_ref_idx < REF_FRAMES)
128
    svc->layer_context[0].gold_ref_idx = alt_ref_idx;
129
130
131
132
133
}

// Update the layer context from a change_config() call.
void vp9_update_layer_context_change_config(VP9_COMP *const cpi,
                                            const int target_bandwidth) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
134
  SVC *const svc = &cpi->svc;
135
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
136
  const RATE_CONTROL *const rc = &cpi->rc;
137
  int sl, tl, layer = 0, spatial_layer_target;
138
  float bitrate_alloc = 1.0;
139

140
141
142
143
144
145
146
  if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) {
    for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
      for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
        layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers);
        svc->layer_context[layer].target_bandwidth =
            oxcf->layer_target_bitrate[layer];
      }
147

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
      layer = LAYER_IDS_TO_IDX(sl, ((oxcf->ts_number_layers - 1) < 0 ?
          0 : (oxcf->ts_number_layers - 1)), oxcf->ts_number_layers);
      spatial_layer_target =
          svc->layer_context[layer].target_bandwidth =
              oxcf->layer_target_bitrate[layer];

      for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
        LAYER_CONTEXT *const lc =
            &svc->layer_context[sl * oxcf->ts_number_layers + tl];
        RATE_CONTROL *const lrc = &lc->rc;

        lc->spatial_layer_target_bandwidth = spatial_layer_target;
        bitrate_alloc = (float)lc->target_bandwidth / spatial_layer_target;
        lrc->starting_buffer_level =
            (int64_t)(rc->starting_buffer_level * bitrate_alloc);
        lrc->optimal_buffer_level =
            (int64_t)(rc->optimal_buffer_level * bitrate_alloc);
        lrc->maximum_buffer_size =
            (int64_t)(rc->maximum_buffer_size * bitrate_alloc);
        lrc->bits_off_target =
168
169
            VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size);
        lrc->buffer_level = VPXMIN(lrc->buffer_level, lrc->maximum_buffer_size);
Marco's avatar
Marco committed
170
        lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[tl];
171
172
173
174
175
        lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
        lrc->max_frame_bandwidth = rc->max_frame_bandwidth;
        lrc->worst_quality = rc->worst_quality;
        lrc->best_quality = rc->best_quality;
      }
176
    }
177
178
179
  } else {
    int layer_end;

180
    if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) {
181
      layer_end = svc->number_temporal_layers;
182
    } else {
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
      layer_end = svc->number_spatial_layers;
    }

    for (layer = 0; layer < layer_end; ++layer) {
      LAYER_CONTEXT *const lc = &svc->layer_context[layer];
      RATE_CONTROL *const lrc = &lc->rc;

      lc->target_bandwidth = oxcf->layer_target_bitrate[layer];

      bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth;
      // Update buffer-related quantities.
      lrc->starting_buffer_level =
          (int64_t)(rc->starting_buffer_level * bitrate_alloc);
      lrc->optimal_buffer_level =
          (int64_t)(rc->optimal_buffer_level * bitrate_alloc);
      lrc->maximum_buffer_size =
          (int64_t)(rc->maximum_buffer_size * bitrate_alloc);
200
201
202
      lrc->bits_off_target = VPXMIN(lrc->bits_off_target,
                                    lrc->maximum_buffer_size);
      lrc->buffer_level = VPXMIN(lrc->buffer_level, lrc->maximum_buffer_size);
203
204
205
206
207
208
209
210
211
212
213
      // Update framerate-related quantities.
      if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) {
        lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[layer];
      } else {
        lc->framerate = cpi->framerate;
      }
      lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
      lrc->max_frame_bandwidth = rc->max_frame_bandwidth;
      // Update qp-related quantities.
      lrc->worst_quality = rc->worst_quality;
      lrc->best_quality = rc->best_quality;
214
    }
215
216
217
  }
}

218
static LAYER_CONTEXT *get_layer_context(VP9_COMP *const cpi) {
219
220
221
222
223
224
225
226
  if (is_one_pass_cbr_svc(cpi))
    return &cpi->svc.layer_context[cpi->svc.spatial_layer_id *
        cpi->svc.number_temporal_layers + cpi->svc.temporal_layer_id];
  else
    return (cpi->svc.number_temporal_layers > 1 &&
            cpi->oxcf.rc_mode == VPX_CBR) ?
             &cpi->svc.layer_context[cpi->svc.temporal_layer_id] :
             &cpi->svc.layer_context[cpi->svc.spatial_layer_id];
227
228
}

229
void vp9_update_temporal_layer_framerate(VP9_COMP *const cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
230
  SVC *const svc = &cpi->svc;
231
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
232
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
233
  RATE_CONTROL *const lrc = &lc->rc;
234
235
236
237
  // Index into spatial+temporal arrays.
  const int st_idx = svc->spatial_layer_id * svc->number_temporal_layers +
      svc->temporal_layer_id;
  const int tl = svc->temporal_layer_id;
238

239
  lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[tl];
240
  lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
241
242
  lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth;
  // Update the average layer frame size (non-cumulative per-frame-bw).
243
  if (tl == 0) {
244
    lc->avg_frame_size = lrc->avg_frame_bandwidth;
245
  } else {
246
    const double prev_layer_framerate =
247
248
249
        cpi->framerate / oxcf->ts_rate_decimator[tl - 1];
    const int prev_layer_target_bandwidth =
        oxcf->layer_target_bitrate[st_idx - 1];
250
251
252
253
254
255
    lc->avg_frame_size =
        (int)((lc->target_bandwidth - prev_layer_target_bandwidth) /
              (lc->framerate - prev_layer_framerate));
  }
}

256
void vp9_update_spatial_layer_framerate(VP9_COMP *const cpi, double framerate) {
257
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
258
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
259
260
261
  RATE_CONTROL *const lrc = &lc->rc;

  lc->framerate = framerate;
262
263
  lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
  lrc->min_frame_bandwidth = (int)(lrc->avg_frame_bandwidth *
264
                                   oxcf->two_pass_vbrmin_section / 100);
265
  lrc->max_frame_bandwidth = (int)(((int64_t)lrc->avg_frame_bandwidth *
266
                                   oxcf->two_pass_vbrmax_section) / 100);
paulwilkins's avatar
paulwilkins committed
267
  vp9_rc_set_gf_interval_range(cpi, lrc);
268
269
}

270
void vp9_restore_layer_context(VP9_COMP *const cpi) {
271
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
272
273
274
  const int old_frame_since_key = cpi->rc.frames_since_key;
  const int old_frame_to_key = cpi->rc.frames_to_key;

275
  cpi->rc = lc->rc;
276
  cpi->twopass = lc->twopass;
277
  cpi->oxcf.target_bandwidth = lc->target_bandwidth;
278
  cpi->alt_ref_source = lc->alt_ref_source;
279
280
  // Reset the frames_since_key and frames_to_key counters to their values
  // before the layer restore. Keep these defined for the stream (not layer).
281
  if (cpi->svc.number_temporal_layers > 1 ||
282
      (cpi->svc.number_spatial_layers > 1 && !is_two_pass_svc(cpi))) {
283
284
285
    cpi->rc.frames_since_key = old_frame_since_key;
    cpi->rc.frames_to_key = old_frame_to_key;
  }
286
287
288
289
290
291
292
293
294

  // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers,
  // for the base temporal layer.
  if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ &&
      cpi->svc.number_spatial_layers > 1 &&
      cpi->svc.temporal_layer_id == 0) {
    CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
    signed char *temp = cr->map;
    uint8_t *temp2 = cr->last_coded_q_map;
295
    uint8_t *temp3 = cr->consec_zero_mv;
296
297
298
299
    cr->map = lc->map;
    lc->map = temp;
    cr->last_coded_q_map = lc->last_coded_q_map;
    lc->last_coded_q_map = temp2;
300
301
    cr->consec_zero_mv = lc->consec_zero_mv;
    lc->consec_zero_mv = temp3;
302
303
    cr->sb_index = lc->sb_index;
  }
304
305
306
}

void vp9_save_layer_context(VP9_COMP *const cpi) {
307
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
308
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
309

310
  lc->rc = cpi->rc;
311
  lc->twopass = cpi->twopass;
312
  lc->target_bandwidth = (int)oxcf->target_bandwidth;
313
  lc->alt_ref_source = cpi->alt_ref_source;
314
315
316
317
318
319
320
321
322

  // For spatial-svc, allow cyclic-refresh to be applied on the spatial layers,
  // for the base temporal layer.
  if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ &&
      cpi->svc.number_spatial_layers > 1 &&
      cpi->svc.temporal_layer_id == 0) {
    CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
    signed char *temp = lc->map;
    uint8_t *temp2 = lc->last_coded_q_map;
323
    uint8_t *temp3 = lc->consec_zero_mv;
324
325
326
327
    lc->map = cr->map;
    cr->map = temp;
    lc->last_coded_q_map = cr->last_coded_q_map;
    cr->last_coded_q_map = temp2;
328
329
    lc->consec_zero_mv = cr->consec_zero_mv;
    cr->consec_zero_mv = temp3;
330
331
    lc->sb_index = cr->sb_index;
  }
332
}
333
334

void vp9_init_second_pass_spatial_svc(VP9_COMP *cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
335
  SVC *const svc = &cpi->svc;
336
337
  int i;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
338
  for (i = 0; i < svc->number_spatial_layers; ++i) {
Paul Wilkins's avatar
Paul Wilkins committed
339
    TWO_PASS *const twopass = &svc->layer_context[i].twopass;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
340
341

    svc->spatial_layer_id = i;
342
343
344
345
346
    vp9_init_second_pass(cpi);

    twopass->total_stats.spatial_layer_id = i;
    twopass->total_left_stats.spatial_layer_id = i;
  }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
347
  svc->spatial_layer_id = 0;
348
}
349

350
351
void vp9_inc_frame_in_layer(VP9_COMP *const cpi) {
  LAYER_CONTEXT *const lc =
352
353
      &cpi->svc.layer_context[cpi->svc.spatial_layer_id *
                              cpi->svc.number_temporal_layers];
354
  ++lc->current_video_frame_in_layer;
355
  ++lc->frames_from_key_frame;
356
}
357

358
int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) {
359
  return is_two_pass_svc(cpi) &&
360
         cpi->svc.spatial_layer_id > 0 &&
361
362
363
         cpi->svc.layer_context[cpi->svc.spatial_layer_id *
                                cpi->svc.number_temporal_layers +
                                cpi->svc.temporal_layer_id].is_key_frame;
364
}
365

366
367
368
369
static void get_layer_resolution(const int width_org, const int height_org,
                                 const int num, const int den,
                                 int *width_out, int *height_out) {
  int w, h;
370

371
372
  if (width_out == NULL || height_out == NULL || den == 0)
    return;
373

374
375
  w = width_org * num / den;
  h = height_org * num / den;
376

377
378
379
  // make height and width even to make chrome player happy
  w += w % 2;
  h += h % 2;
380

381
382
  *width_out = w;
  *height_out = h;
383
384
}

385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
// The function sets proper ref_frame_flags, buffer indices, and buffer update
// variables for temporal layering mode 3 - that does 0-2-1-2 temporal layering
// scheme.
static void set_flags_and_fb_idx_for_temporal_mode3(VP9_COMP *const cpi) {
  int frame_num_within_temporal_struct = 0;
  int spatial_id, temporal_id;
  spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
  frame_num_within_temporal_struct =
      cpi->svc.layer_context[cpi->svc.spatial_layer_id *
      cpi->svc.number_temporal_layers].current_video_frame_in_layer % 4;
  temporal_id = cpi->svc.temporal_layer_id =
      (frame_num_within_temporal_struct & 1) ? 2 :
      (frame_num_within_temporal_struct >> 1);
  cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame =
      cpi->ext_refresh_alt_ref_frame = 0;
  if (!temporal_id) {
    cpi->ext_refresh_frame_flags_pending = 1;
    cpi->ext_refresh_last_frame = 1;
    if (!spatial_id) {
      cpi->ref_frame_flags = VP9_LAST_FLAG;
    } else if (cpi->svc.layer_context[temporal_id].is_key_frame) {
      // base layer is a key frame.
      cpi->ref_frame_flags = VP9_GOLD_FLAG;
    } else {
      cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
    }
  } else if (temporal_id == 1) {
    cpi->ext_refresh_frame_flags_pending = 1;
    cpi->ext_refresh_alt_ref_frame = 1;
    if (!spatial_id) {
      cpi->ref_frame_flags = VP9_LAST_FLAG;
    } else {
      cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
    }
  } else {
    if (frame_num_within_temporal_struct == 1) {
      // the first tl2 picture
      if (!spatial_id) {
        cpi->ext_refresh_frame_flags_pending = 1;
        cpi->ext_refresh_alt_ref_frame = 1;
        cpi->ref_frame_flags = VP9_LAST_FLAG;
      } else if (spatial_id < cpi->svc.number_spatial_layers - 1) {
        cpi->ext_refresh_frame_flags_pending = 1;
        cpi->ext_refresh_alt_ref_frame = 1;
        cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
      } else {  // Top layer
        cpi->ext_refresh_frame_flags_pending = 0;
        cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
      }
    } else {
      //  The second tl2 picture
      if (!spatial_id) {
        cpi->ext_refresh_frame_flags_pending = 1;
        cpi->ref_frame_flags = VP9_LAST_FLAG;
        cpi->ext_refresh_last_frame = 1;
      } else if (spatial_id < cpi->svc.number_spatial_layers - 1) {
        cpi->ext_refresh_frame_flags_pending = 1;
        cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
        cpi->ext_refresh_last_frame = 1;
      } else {  // top layer
        cpi->ext_refresh_frame_flags_pending = 0;
        cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
      }
    }
  }
  if (temporal_id == 0) {
    cpi->lst_fb_idx = spatial_id;
    if (spatial_id)
      cpi->gld_fb_idx = spatial_id - 1;
    else
      cpi->gld_fb_idx = 0;
    cpi->alt_fb_idx = 0;
  } else if (temporal_id == 1) {
    cpi->lst_fb_idx = spatial_id;
    cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
    cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
  } else if (frame_num_within_temporal_struct == 1) {
    cpi->lst_fb_idx = spatial_id;
    cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
    cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
  } else {
    cpi->lst_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
    cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
    cpi->alt_fb_idx = 0;
  }
}

// The function sets proper ref_frame_flags, buffer indices, and buffer update
// variables for temporal layering mode 2 - that does 0-1-0-1 temporal layering
// scheme.
static void set_flags_and_fb_idx_for_temporal_mode2(VP9_COMP *const cpi) {
  int spatial_id, temporal_id;
  spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
  temporal_id = cpi->svc.temporal_layer_id =
      cpi->svc.layer_context[cpi->svc.spatial_layer_id *
      cpi->svc.number_temporal_layers].current_video_frame_in_layer & 1;
  cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame =
                                cpi->ext_refresh_alt_ref_frame = 0;
  if (!temporal_id) {
    cpi->ext_refresh_frame_flags_pending = 1;
    cpi->ext_refresh_last_frame = 1;
    if (!spatial_id) {
      cpi->ref_frame_flags = VP9_LAST_FLAG;
    } else if (cpi->svc.layer_context[temporal_id].is_key_frame) {
      // base layer is a key frame.
      cpi->ref_frame_flags = VP9_GOLD_FLAG;
    } else {
      cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
    }
  } else if (temporal_id == 1) {
    cpi->ext_refresh_frame_flags_pending = 1;
    cpi->ext_refresh_alt_ref_frame = 1;
    if (!spatial_id) {
      cpi->ref_frame_flags = VP9_LAST_FLAG;
    } else {
      cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
    }
  }

  if (temporal_id == 0) {
    cpi->lst_fb_idx = spatial_id;
    if (spatial_id)
      cpi->gld_fb_idx = spatial_id - 1;
    else
      cpi->gld_fb_idx = 0;
    cpi->alt_fb_idx = 0;
  } else if (temporal_id == 1) {
    cpi->lst_fb_idx = spatial_id;
    cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
    cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
  }
}

// The function sets proper ref_frame_flags, buffer indices, and buffer update
// variables for temporal layering mode 0 - that has no temporal layering.
static void set_flags_and_fb_idx_for_temporal_mode_noLayering(
    VP9_COMP *const cpi) {
  int spatial_id;
  spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
  cpi->ext_refresh_last_frame =
      cpi->ext_refresh_golden_frame = cpi->ext_refresh_alt_ref_frame = 0;
  cpi->ext_refresh_frame_flags_pending = 1;
  cpi->ext_refresh_last_frame = 1;
  if (!spatial_id) {
    cpi->ref_frame_flags = VP9_LAST_FLAG;
  } else if (cpi->svc.layer_context[0].is_key_frame) {
    cpi->ref_frame_flags = VP9_GOLD_FLAG;
  } else {
    cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
  }
  cpi->lst_fb_idx = spatial_id;
  if (spatial_id)
    cpi->gld_fb_idx = spatial_id - 1;
  else
    cpi->gld_fb_idx = 0;
}

int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) {
  int width = 0, height = 0;
  LAYER_CONTEXT *lc = NULL;

  if (cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) {
    set_flags_and_fb_idx_for_temporal_mode3(cpi);
  } else if (cpi->svc.temporal_layering_mode ==
           VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) {
    set_flags_and_fb_idx_for_temporal_mode_noLayering(cpi);
  } else if (cpi->svc.temporal_layering_mode ==
           VP9E_TEMPORAL_LAYERING_MODE_0101) {
    set_flags_and_fb_idx_for_temporal_mode2(cpi);
  } else if (cpi->svc.temporal_layering_mode ==
      VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
    // In the BYPASS/flexible mode, the encoder is relying on the application
    // to specify, for each spatial layer, the flags and buffer indices for the
    // layering.
    // Note that the check (cpi->ext_refresh_frame_flags_pending == 0) is
    // needed to support the case where the frame flags may be passed in via
    // vpx_codec_encode(), which can be used for the temporal-only svc case.
    if (cpi->ext_refresh_frame_flags_pending == 0) {
      int sl;
      cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
      sl = cpi->svc.spatial_layer_id;
      vp9_apply_encoding_flags(cpi, cpi->svc.ext_frame_flags[sl]);
      cpi->lst_fb_idx = cpi->svc.ext_lst_fb_idx[sl];
      cpi->gld_fb_idx = cpi->svc.ext_gld_fb_idx[sl];
      cpi->alt_fb_idx = cpi->svc.ext_alt_fb_idx[sl];
    }
571
572
  }

573
574
575
  if (cpi->svc.spatial_layer_id == cpi->svc.first_spatial_layer_to_encode)
    cpi->svc.rc_drop_superframe = 0;

576
577
578
579
  lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id *
                               cpi->svc.number_temporal_layers +
                               cpi->svc.temporal_layer_id];

580
581
582
583
584
585
586
587
  // Setting the worst/best_quality via the encoder control: SET_SVC_PARAMETERS,
  // only for non-BYPASS mode for now.
  if (cpi->svc.temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
    RATE_CONTROL *const lrc = &lc->rc;
    lrc->worst_quality = vp9_quantizer_to_qindex(lc->max_q);
    lrc->best_quality =  vp9_quantizer_to_qindex(lc->min_q);
  }

588
589
590
591
592
593
594
595
596
597
598
  get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height,
                       lc->scaling_factor_num, lc->scaling_factor_den,
                       &width, &height);

  if (vp9_set_size_literal(cpi, width, height) != 0)
    return VPX_CODEC_INVALID_PARAM;

  return 0;
}

#if CONFIG_SPATIAL_SVC
599
600
int vp9_svc_start_frame(VP9_COMP *const cpi) {
  int width = 0, height = 0;
601
  LAYER_CONTEXT *lc;
602
  struct lookahead_entry *buf;
603
  int count = 1 << (cpi->svc.number_temporal_layers - 1);
604

605
  cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
606
  lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id];
607

608
609
610
611
612
613
  cpi->svc.temporal_layer_id = 0;
  while ((lc->current_video_frame_in_layer % count) != 0) {
    ++cpi->svc.temporal_layer_id;
    count >>= 1;
  }

614
615
  cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;

616
617
618
619
620
621
622
  cpi->lst_fb_idx = cpi->svc.spatial_layer_id;

  if (cpi->svc.spatial_layer_id == 0)
    cpi->gld_fb_idx = (lc->gold_ref_idx >= 0) ?
                      lc->gold_ref_idx : cpi->lst_fb_idx;
  else
    cpi->gld_fb_idx = cpi->svc.spatial_layer_id - 1;
623
624

  if (lc->current_video_frame_in_layer == 0) {
625
    if (cpi->svc.spatial_layer_id >= 2) {
626
      cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2;
627
    } else {
628
      cpi->alt_fb_idx = cpi->lst_fb_idx;
629
630
      cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_ALT_FLAG);
    }
631
  } else {
632
    if (cpi->oxcf.ss_enable_auto_arf[cpi->svc.spatial_layer_id]) {
633
634
635
636
637
638
639
640
641
642
643
      cpi->alt_fb_idx = lc->alt_ref_idx;
      if (!lc->has_alt_frame)
        cpi->ref_frame_flags &= (~VP9_ALT_FLAG);
    } else {
      // Find a proper alt_fb_idx for layers that don't have alt ref frame
      if (cpi->svc.spatial_layer_id == 0) {
        cpi->alt_fb_idx = cpi->lst_fb_idx;
      } else {
        LAYER_CONTEXT *lc_lower =
            &cpi->svc.layer_context[cpi->svc.spatial_layer_id - 1];

644
        if (cpi->oxcf.ss_enable_auto_arf[cpi->svc.spatial_layer_id - 1] &&
645
646
647
            lc_lower->alt_ref_source != NULL)
          cpi->alt_fb_idx = lc_lower->alt_ref_idx;
        else if (cpi->svc.spatial_layer_id >= 2)
648
          cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2;
649
650
651
652
653
        else
          cpi->alt_fb_idx = cpi->lst_fb_idx;
      }
    }
  }
654

655
656
657
  get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height,
                       lc->scaling_factor_num, lc->scaling_factor_den,
                       &width, &height);
658
659
660
661
662

  // Workaround for multiple frame contexts. In some frames we can't use prev_mi
  // since its previous frame could be changed during decoding time. The idea is
  // we put a empty invisible frame in front of them, then we will not use
  // prev_mi when encoding these frames.
663
664

  buf = vp9_lookahead_peek(cpi->lookahead, 0);
665
  if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2 &&
666
      cpi->svc.encode_empty_frame_state == NEED_TO_ENCODE &&
667
668
      lc->rc.frames_to_key != 0 &&
      !(buf != NULL && (buf->flags & VPX_EFLAG_FORCE_KF))) {
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
    if ((cpi->svc.number_temporal_layers > 1 &&
         cpi->svc.temporal_layer_id < cpi->svc.number_temporal_layers - 1) ||
        (cpi->svc.number_spatial_layers > 1 &&
         cpi->svc.spatial_layer_id == 0)) {
      struct lookahead_entry *buf = vp9_lookahead_peek(cpi->lookahead, 0);

      if (buf != NULL) {
        cpi->svc.empty_frame.ts_start = buf->ts_start;
        cpi->svc.empty_frame.ts_end = buf->ts_end;
        cpi->svc.encode_empty_frame_state = ENCODING;
        cpi->common.show_frame = 0;
        cpi->ref_frame_flags = 0;
        cpi->common.frame_type = INTER_FRAME;
        cpi->lst_fb_idx =
            cpi->gld_fb_idx = cpi->alt_fb_idx = SMALL_FRAME_FB_IDX;

685
686
        if (cpi->svc.encode_intra_empty_frame != 0)
          cpi->common.intra_only = 1;
687

688
689
        width = SMALL_FRAME_WIDTH;
        height = SMALL_FRAME_HEIGHT;
690
691
692
693
      }
    }
  }

694
695
  cpi->oxcf.worst_allowed_q = vp9_quantizer_to_qindex(lc->max_q);
  cpi->oxcf.best_allowed_q = vp9_quantizer_to_qindex(lc->min_q);
696
697

  vp9_change_config(cpi, &cpi->oxcf);
698
699
700
701

  if (vp9_set_size_literal(cpi, width, height) != 0)
    return VPX_CODEC_INVALID_PARAM;

702
703
  vp9_set_high_precision_mv(cpi, 1);

704
  cpi->alt_ref_source = get_layer_context(cpi)->alt_ref_source;
705
706
707
708

  return 0;
}

709
710
#endif

711
712
713
714
715
struct lookahead_entry *vp9_svc_lookahead_pop(VP9_COMP *const cpi,
                                              struct lookahead_ctx *ctx,
                                              int drain) {
  struct lookahead_entry *buf = NULL;
  if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) {
716
    buf = vp9_lookahead_peek(ctx, 0);
717
    if (buf != NULL) {
718
      // Only remove the buffer when pop the highest layer.
719
720
721
722
723
724
725
      if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) {
        vp9_lookahead_pop(ctx, drain);
      }
    }
  }
  return buf;
}
726
727
728
729
730
731
732
733
734
735
736
737
738

void vp9_free_svc_cyclic_refresh(VP9_COMP *const cpi) {
  int sl, tl;
  SVC *const svc = &cpi->svc;
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
  for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
    for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
      int layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers);
      LAYER_CONTEXT *const lc = &svc->layer_context[layer];
        if (lc->map)
          vpx_free(lc->map);
        if (lc->last_coded_q_map)
          vpx_free(lc->last_coded_q_map);
739
740
        if (lc->consec_zero_mv)
          vpx_free(lc->consec_zero_mv);
741
742
743
    }
  }
}