configure: add --extra-cxxflags option
[platform/upstream/libvpx.git] / vp9 / encoder / vp9_svc_layercontext.c
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_encoder.h"
14 #include "vp9/encoder/vp9_svc_layercontext.h"
15 #include "vp9/encoder/vp9_extend.h"
16 #include "vpx_dsp/vpx_dsp_common.h"
17
18 #define SMALL_FRAME_FB_IDX 7
19 #define SMALL_FRAME_WIDTH  32
20 #define SMALL_FRAME_HEIGHT 16
21
22 void vp9_init_layer_context(VP9_COMP *const cpi) {
23   SVC *const svc = &cpi->svc;
24   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
25   int sl, tl;
26   int alt_ref_idx = svc->number_spatial_layers;
27
28   svc->spatial_layer_id = 0;
29   svc->temporal_layer_id = 0;
30
31   if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) {
32     if (vpx_realloc_frame_buffer(&cpi->svc.empty_frame.img,
33                                  SMALL_FRAME_WIDTH, SMALL_FRAME_HEIGHT,
34                                  cpi->common.subsampling_x,
35                                  cpi->common.subsampling_y,
36 #if CONFIG_VP9_HIGHBITDEPTH
37                                  cpi->common.use_highbitdepth,
38 #endif
39                                  VP9_ENC_BORDER_IN_PIXELS,
40                                  cpi->common.byte_alignment,
41                                  NULL, NULL, NULL))
42       vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
43                          "Failed to allocate empty frame for multiple frame "
44                          "contexts");
45
46     memset(cpi->svc.empty_frame.img.buffer_alloc, 0x80,
47            cpi->svc.empty_frame.img.buffer_alloc_sz);
48   }
49
50   for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
51     for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
52       int layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers);
53       LAYER_CONTEXT *const lc = &svc->layer_context[layer];
54       RATE_CONTROL *const lrc = &lc->rc;
55       int i;
56       lc->current_video_frame_in_layer = 0;
57       lc->layer_size = 0;
58       lc->frames_from_key_frame = 0;
59       lc->last_frame_type = FRAME_TYPES;
60       lrc->ni_av_qi = oxcf->worst_allowed_q;
61       lrc->total_actual_bits = 0;
62       lrc->total_target_vs_actual = 0;
63       lrc->ni_tot_qi = 0;
64       lrc->tot_q = 0.0;
65       lrc->avg_q = 0.0;
66       lrc->ni_frames = 0;
67       lrc->decimation_count = 0;
68       lrc->decimation_factor = 0;
69
70       for (i = 0; i < RATE_FACTOR_LEVELS; ++i) {
71         lrc->rate_correction_factors[i] = 1.0;
72       }
73
74       if (cpi->oxcf.rc_mode == VPX_CBR) {
75         lc->target_bandwidth = oxcf->layer_target_bitrate[layer];
76         lrc->last_q[INTER_FRAME] = oxcf->worst_allowed_q;
77         lrc->avg_frame_qindex[INTER_FRAME] = oxcf->worst_allowed_q;
78         lrc->avg_frame_qindex[KEY_FRAME] = oxcf->worst_allowed_q;
79       } else {
80         lc->target_bandwidth = oxcf->layer_target_bitrate[layer];
81         lrc->last_q[KEY_FRAME] = oxcf->best_allowed_q;
82         lrc->last_q[INTER_FRAME] = oxcf->best_allowed_q;
83         lrc->avg_frame_qindex[KEY_FRAME] = (oxcf->worst_allowed_q +
84                                             oxcf->best_allowed_q) / 2;
85         lrc->avg_frame_qindex[INTER_FRAME] = (oxcf->worst_allowed_q +
86                                               oxcf->best_allowed_q) / 2;
87         if (oxcf->ss_enable_auto_arf[sl])
88           lc->alt_ref_idx = alt_ref_idx++;
89         else
90           lc->alt_ref_idx = INVALID_IDX;
91         lc->gold_ref_idx = INVALID_IDX;
92       }
93
94       lrc->buffer_level = oxcf->starting_buffer_level_ms *
95                               lc->target_bandwidth / 1000;
96       lrc->bits_off_target = lrc->buffer_level;
97     }
98   }
99
100   // Still have extra buffer for base layer golden frame
101   if (!(svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR)
102       && alt_ref_idx < REF_FRAMES)
103     svc->layer_context[0].gold_ref_idx = alt_ref_idx;
104 }
105
106 // Update the layer context from a change_config() call.
107 void vp9_update_layer_context_change_config(VP9_COMP *const cpi,
108                                             const int target_bandwidth) {
109   SVC *const svc = &cpi->svc;
110   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
111   const RATE_CONTROL *const rc = &cpi->rc;
112   int sl, tl, layer = 0, spatial_layer_target;
113   float bitrate_alloc = 1.0;
114
115   if (svc->temporal_layering_mode != VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) {
116     for (sl = 0; sl < oxcf->ss_number_layers; ++sl) {
117       for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
118         layer = LAYER_IDS_TO_IDX(sl, tl, oxcf->ts_number_layers);
119         svc->layer_context[layer].target_bandwidth =
120             oxcf->layer_target_bitrate[layer];
121       }
122
123       layer = LAYER_IDS_TO_IDX(sl, ((oxcf->ts_number_layers - 1) < 0 ?
124           0 : (oxcf->ts_number_layers - 1)), oxcf->ts_number_layers);
125       spatial_layer_target =
126           svc->layer_context[layer].target_bandwidth =
127               oxcf->layer_target_bitrate[layer];
128
129       for (tl = 0; tl < oxcf->ts_number_layers; ++tl) {
130         LAYER_CONTEXT *const lc =
131             &svc->layer_context[sl * oxcf->ts_number_layers + tl];
132         RATE_CONTROL *const lrc = &lc->rc;
133
134         lc->spatial_layer_target_bandwidth = spatial_layer_target;
135         bitrate_alloc = (float)lc->target_bandwidth / spatial_layer_target;
136         lrc->starting_buffer_level =
137             (int64_t)(rc->starting_buffer_level * bitrate_alloc);
138         lrc->optimal_buffer_level =
139             (int64_t)(rc->optimal_buffer_level * bitrate_alloc);
140         lrc->maximum_buffer_size =
141             (int64_t)(rc->maximum_buffer_size * bitrate_alloc);
142         lrc->bits_off_target =
143             VPXMIN(lrc->bits_off_target, lrc->maximum_buffer_size);
144         lrc->buffer_level = VPXMIN(lrc->buffer_level, lrc->maximum_buffer_size);
145         lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[tl];
146         lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
147         lrc->max_frame_bandwidth = rc->max_frame_bandwidth;
148         lrc->worst_quality = rc->worst_quality;
149         lrc->best_quality = rc->best_quality;
150       }
151     }
152   } else {
153     int layer_end;
154
155     if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) {
156       layer_end = svc->number_temporal_layers;
157     } else {
158       layer_end = svc->number_spatial_layers;
159     }
160
161     for (layer = 0; layer < layer_end; ++layer) {
162       LAYER_CONTEXT *const lc = &svc->layer_context[layer];
163       RATE_CONTROL *const lrc = &lc->rc;
164
165       lc->target_bandwidth = oxcf->layer_target_bitrate[layer];
166
167       bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth;
168       // Update buffer-related quantities.
169       lrc->starting_buffer_level =
170           (int64_t)(rc->starting_buffer_level * bitrate_alloc);
171       lrc->optimal_buffer_level =
172           (int64_t)(rc->optimal_buffer_level * bitrate_alloc);
173       lrc->maximum_buffer_size =
174           (int64_t)(rc->maximum_buffer_size * bitrate_alloc);
175       lrc->bits_off_target = VPXMIN(lrc->bits_off_target,
176                                     lrc->maximum_buffer_size);
177       lrc->buffer_level = VPXMIN(lrc->buffer_level, lrc->maximum_buffer_size);
178       // Update framerate-related quantities.
179       if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) {
180         lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[layer];
181       } else {
182         lc->framerate = cpi->framerate;
183       }
184       lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
185       lrc->max_frame_bandwidth = rc->max_frame_bandwidth;
186       // Update qp-related quantities.
187       lrc->worst_quality = rc->worst_quality;
188       lrc->best_quality = rc->best_quality;
189     }
190   }
191 }
192
193 static LAYER_CONTEXT *get_layer_context(VP9_COMP *const cpi) {
194   if (is_one_pass_cbr_svc(cpi))
195     return &cpi->svc.layer_context[cpi->svc.spatial_layer_id *
196         cpi->svc.number_temporal_layers + cpi->svc.temporal_layer_id];
197   else
198     return (cpi->svc.number_temporal_layers > 1 &&
199             cpi->oxcf.rc_mode == VPX_CBR) ?
200              &cpi->svc.layer_context[cpi->svc.temporal_layer_id] :
201              &cpi->svc.layer_context[cpi->svc.spatial_layer_id];
202 }
203
204 void vp9_update_temporal_layer_framerate(VP9_COMP *const cpi) {
205   SVC *const svc = &cpi->svc;
206   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
207   LAYER_CONTEXT *const lc = get_layer_context(cpi);
208   RATE_CONTROL *const lrc = &lc->rc;
209   // Index into spatial+temporal arrays.
210   const int st_idx = svc->spatial_layer_id * svc->number_temporal_layers +
211       svc->temporal_layer_id;
212   const int tl = svc->temporal_layer_id;
213
214   lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[tl];
215   lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
216   lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth;
217   // Update the average layer frame size (non-cumulative per-frame-bw).
218   if (tl == 0) {
219     lc->avg_frame_size = lrc->avg_frame_bandwidth;
220   } else {
221     const double prev_layer_framerate =
222         cpi->framerate / oxcf->ts_rate_decimator[tl - 1];
223     const int prev_layer_target_bandwidth =
224         oxcf->layer_target_bitrate[st_idx - 1];
225     lc->avg_frame_size =
226         (int)((lc->target_bandwidth - prev_layer_target_bandwidth) /
227               (lc->framerate - prev_layer_framerate));
228   }
229 }
230
231 void vp9_update_spatial_layer_framerate(VP9_COMP *const cpi, double framerate) {
232   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
233   LAYER_CONTEXT *const lc = get_layer_context(cpi);
234   RATE_CONTROL *const lrc = &lc->rc;
235
236   lc->framerate = framerate;
237   lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
238   lrc->min_frame_bandwidth = (int)(lrc->avg_frame_bandwidth *
239                                    oxcf->two_pass_vbrmin_section / 100);
240   lrc->max_frame_bandwidth = (int)(((int64_t)lrc->avg_frame_bandwidth *
241                                    oxcf->two_pass_vbrmax_section) / 100);
242   vp9_rc_set_gf_interval_range(cpi, lrc);
243 }
244
245 void vp9_restore_layer_context(VP9_COMP *const cpi) {
246   LAYER_CONTEXT *const lc = get_layer_context(cpi);
247   const int old_frame_since_key = cpi->rc.frames_since_key;
248   const int old_frame_to_key = cpi->rc.frames_to_key;
249
250   cpi->rc = lc->rc;
251   cpi->twopass = lc->twopass;
252   cpi->oxcf.target_bandwidth = lc->target_bandwidth;
253   cpi->alt_ref_source = lc->alt_ref_source;
254   // Reset the frames_since_key and frames_to_key counters to their values
255   // before the layer restore. Keep these defined for the stream (not layer).
256   if (cpi->svc.number_temporal_layers > 1) {
257     cpi->rc.frames_since_key = old_frame_since_key;
258     cpi->rc.frames_to_key = old_frame_to_key;
259   }
260 }
261
262 void vp9_save_layer_context(VP9_COMP *const cpi) {
263   const VP9EncoderConfig *const oxcf = &cpi->oxcf;
264   LAYER_CONTEXT *const lc = get_layer_context(cpi);
265
266   lc->rc = cpi->rc;
267   lc->twopass = cpi->twopass;
268   lc->target_bandwidth = (int)oxcf->target_bandwidth;
269   lc->alt_ref_source = cpi->alt_ref_source;
270 }
271
272 void vp9_init_second_pass_spatial_svc(VP9_COMP *cpi) {
273   SVC *const svc = &cpi->svc;
274   int i;
275
276   for (i = 0; i < svc->number_spatial_layers; ++i) {
277     TWO_PASS *const twopass = &svc->layer_context[i].twopass;
278
279     svc->spatial_layer_id = i;
280     vp9_init_second_pass(cpi);
281
282     twopass->total_stats.spatial_layer_id = i;
283     twopass->total_left_stats.spatial_layer_id = i;
284   }
285   svc->spatial_layer_id = 0;
286 }
287
288 void vp9_inc_frame_in_layer(VP9_COMP *const cpi) {
289   LAYER_CONTEXT *const lc =
290       &cpi->svc.layer_context[cpi->svc.spatial_layer_id *
291                               cpi->svc.number_temporal_layers];
292   ++lc->current_video_frame_in_layer;
293   ++lc->frames_from_key_frame;
294 }
295
296 int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) {
297   return is_two_pass_svc(cpi) &&
298          cpi->svc.spatial_layer_id > 0 &&
299          cpi->svc.layer_context[cpi->svc.spatial_layer_id *
300                                 cpi->svc.number_temporal_layers +
301                                 cpi->svc.temporal_layer_id].is_key_frame;
302 }
303
304 static void get_layer_resolution(const int width_org, const int height_org,
305                                  const int num, const int den,
306                                  int *width_out, int *height_out) {
307   int w, h;
308
309   if (width_out == NULL || height_out == NULL || den == 0)
310     return;
311
312   w = width_org * num / den;
313   h = height_org * num / den;
314
315   // make height and width even to make chrome player happy
316   w += w % 2;
317   h += h % 2;
318
319   *width_out = w;
320   *height_out = h;
321 }
322
323 // The function sets proper ref_frame_flags, buffer indices, and buffer update
324 // variables for temporal layering mode 3 - that does 0-2-1-2 temporal layering
325 // scheme.
326 static void set_flags_and_fb_idx_for_temporal_mode3(VP9_COMP *const cpi) {
327   int frame_num_within_temporal_struct = 0;
328   int spatial_id, temporal_id;
329   spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
330   frame_num_within_temporal_struct =
331       cpi->svc.layer_context[cpi->svc.spatial_layer_id *
332       cpi->svc.number_temporal_layers].current_video_frame_in_layer % 4;
333   temporal_id = cpi->svc.temporal_layer_id =
334       (frame_num_within_temporal_struct & 1) ? 2 :
335       (frame_num_within_temporal_struct >> 1);
336   cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame =
337       cpi->ext_refresh_alt_ref_frame = 0;
338   if (!temporal_id) {
339     cpi->ext_refresh_frame_flags_pending = 1;
340     cpi->ext_refresh_last_frame = 1;
341     if (!spatial_id) {
342       cpi->ref_frame_flags = VP9_LAST_FLAG;
343     } else if (cpi->svc.layer_context[temporal_id].is_key_frame) {
344       // base layer is a key frame.
345       cpi->ref_frame_flags = VP9_GOLD_FLAG;
346     } else {
347       cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
348     }
349   } else if (temporal_id == 1) {
350     cpi->ext_refresh_frame_flags_pending = 1;
351     cpi->ext_refresh_alt_ref_frame = 1;
352     if (!spatial_id) {
353       cpi->ref_frame_flags = VP9_LAST_FLAG;
354     } else {
355       cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
356     }
357   } else {
358     if (frame_num_within_temporal_struct == 1) {
359       // the first tl2 picture
360       if (!spatial_id) {
361         cpi->ext_refresh_frame_flags_pending = 1;
362         cpi->ext_refresh_alt_ref_frame = 1;
363         cpi->ref_frame_flags = VP9_LAST_FLAG;
364       } else if (spatial_id < cpi->svc.number_spatial_layers - 1) {
365         cpi->ext_refresh_frame_flags_pending = 1;
366         cpi->ext_refresh_alt_ref_frame = 1;
367         cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
368       } else {  // Top layer
369         cpi->ext_refresh_frame_flags_pending = 0;
370         cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
371       }
372     } else {
373       //  The second tl2 picture
374       if (!spatial_id) {
375         cpi->ext_refresh_frame_flags_pending = 1;
376         cpi->ref_frame_flags = VP9_LAST_FLAG;
377         cpi->ext_refresh_last_frame = 1;
378       } else if (spatial_id < cpi->svc.number_spatial_layers - 1) {
379         cpi->ext_refresh_frame_flags_pending = 1;
380         cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
381         cpi->ext_refresh_last_frame = 1;
382       } else {  // top layer
383         cpi->ext_refresh_frame_flags_pending = 0;
384         cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
385       }
386     }
387   }
388   if (temporal_id == 0) {
389     cpi->lst_fb_idx = spatial_id;
390     if (spatial_id)
391       cpi->gld_fb_idx = spatial_id - 1;
392     else
393       cpi->gld_fb_idx = 0;
394     cpi->alt_fb_idx = 0;
395   } else if (temporal_id == 1) {
396     cpi->lst_fb_idx = spatial_id;
397     cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
398     cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
399   } else if (frame_num_within_temporal_struct == 1) {
400     cpi->lst_fb_idx = spatial_id;
401     cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
402     cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
403   } else {
404     cpi->lst_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
405     cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
406     cpi->alt_fb_idx = 0;
407   }
408 }
409
410 // The function sets proper ref_frame_flags, buffer indices, and buffer update
411 // variables for temporal layering mode 2 - that does 0-1-0-1 temporal layering
412 // scheme.
413 static void set_flags_and_fb_idx_for_temporal_mode2(VP9_COMP *const cpi) {
414   int spatial_id, temporal_id;
415   spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
416   temporal_id = cpi->svc.temporal_layer_id =
417       cpi->svc.layer_context[cpi->svc.spatial_layer_id *
418       cpi->svc.number_temporal_layers].current_video_frame_in_layer & 1;
419   cpi->ext_refresh_last_frame = cpi->ext_refresh_golden_frame =
420                                 cpi->ext_refresh_alt_ref_frame = 0;
421   if (!temporal_id) {
422     cpi->ext_refresh_frame_flags_pending = 1;
423     cpi->ext_refresh_last_frame = 1;
424     if (!spatial_id) {
425       cpi->ref_frame_flags = VP9_LAST_FLAG;
426     } else if (cpi->svc.layer_context[temporal_id].is_key_frame) {
427       // base layer is a key frame.
428       cpi->ref_frame_flags = VP9_GOLD_FLAG;
429     } else {
430       cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
431     }
432   } else if (temporal_id == 1) {
433     cpi->ext_refresh_frame_flags_pending = 1;
434     cpi->ext_refresh_alt_ref_frame = 1;
435     if (!spatial_id) {
436       cpi->ref_frame_flags = VP9_LAST_FLAG;
437     } else {
438       cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
439     }
440   }
441
442   if (temporal_id == 0) {
443     cpi->lst_fb_idx = spatial_id;
444     if (spatial_id)
445       cpi->gld_fb_idx = spatial_id - 1;
446     else
447       cpi->gld_fb_idx = 0;
448     cpi->alt_fb_idx = 0;
449   } else if (temporal_id == 1) {
450     cpi->lst_fb_idx = spatial_id;
451     cpi->gld_fb_idx = cpi->svc.number_spatial_layers + spatial_id - 1;
452     cpi->alt_fb_idx = cpi->svc.number_spatial_layers + spatial_id;
453   }
454 }
455
456 // The function sets proper ref_frame_flags, buffer indices, and buffer update
457 // variables for temporal layering mode 0 - that has no temporal layering.
458 static void set_flags_and_fb_idx_for_temporal_mode_noLayering(
459     VP9_COMP *const cpi) {
460   int spatial_id;
461   spatial_id = cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
462   cpi->ext_refresh_last_frame =
463       cpi->ext_refresh_golden_frame = cpi->ext_refresh_alt_ref_frame = 0;
464   cpi->ext_refresh_frame_flags_pending = 1;
465   cpi->ext_refresh_last_frame = 1;
466   if (!spatial_id) {
467     cpi->ref_frame_flags = VP9_LAST_FLAG;
468   } else if (cpi->svc.layer_context[0].is_key_frame) {
469     cpi->ref_frame_flags = VP9_GOLD_FLAG;
470   } else {
471     cpi->ref_frame_flags = VP9_LAST_FLAG | VP9_GOLD_FLAG;
472   }
473   cpi->lst_fb_idx = spatial_id;
474   if (spatial_id)
475     cpi->gld_fb_idx = spatial_id - 1;
476   else
477     cpi->gld_fb_idx = 0;
478 }
479
480 int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) {
481   int width = 0, height = 0;
482   LAYER_CONTEXT *lc = NULL;
483
484   if (cpi->svc.temporal_layering_mode == VP9E_TEMPORAL_LAYERING_MODE_0212) {
485     set_flags_and_fb_idx_for_temporal_mode3(cpi);
486   } else if (cpi->svc.temporal_layering_mode ==
487            VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING) {
488     set_flags_and_fb_idx_for_temporal_mode_noLayering(cpi);
489   } else if (cpi->svc.temporal_layering_mode ==
490            VP9E_TEMPORAL_LAYERING_MODE_0101) {
491     set_flags_and_fb_idx_for_temporal_mode2(cpi);
492   } else if (cpi->svc.temporal_layering_mode ==
493       VP9E_TEMPORAL_LAYERING_MODE_BYPASS) {
494     // VP9E_TEMPORAL_LAYERING_MODE_BYPASS :
495     // if the code goes here, it means the encoder will be relying on the
496     // flags from outside for layering.
497     // However, since when spatial+temporal layering is used, the buffer indices
498     // cannot be derived automatically, the bypass mode will only work when the
499     // number of spatial layers equals 1.
500     assert(cpi->svc.number_spatial_layers == 1);
501   }
502
503   lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id *
504                                cpi->svc.number_temporal_layers +
505                                cpi->svc.temporal_layer_id];
506
507   get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height,
508                        lc->scaling_factor_num, lc->scaling_factor_den,
509                        &width, &height);
510
511   if (vp9_set_size_literal(cpi, width, height) != 0)
512     return VPX_CODEC_INVALID_PARAM;
513
514   return 0;
515 }
516
517 #if CONFIG_SPATIAL_SVC
518 int vp9_svc_start_frame(VP9_COMP *const cpi) {
519   int width = 0, height = 0;
520   LAYER_CONTEXT *lc;
521   struct lookahead_entry *buf;
522   int count = 1 << (cpi->svc.number_temporal_layers - 1);
523
524   cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
525   lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id];
526
527   cpi->svc.temporal_layer_id = 0;
528   while ((lc->current_video_frame_in_layer % count) != 0) {
529     ++cpi->svc.temporal_layer_id;
530     count >>= 1;
531   }
532
533   cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
534
535   cpi->lst_fb_idx = cpi->svc.spatial_layer_id;
536
537   if (cpi->svc.spatial_layer_id == 0)
538     cpi->gld_fb_idx = (lc->gold_ref_idx >= 0) ?
539                       lc->gold_ref_idx : cpi->lst_fb_idx;
540   else
541     cpi->gld_fb_idx = cpi->svc.spatial_layer_id - 1;
542
543   if (lc->current_video_frame_in_layer == 0) {
544     if (cpi->svc.spatial_layer_id >= 2) {
545       cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2;
546     } else {
547       cpi->alt_fb_idx = cpi->lst_fb_idx;
548       cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_ALT_FLAG);
549     }
550   } else {
551     if (cpi->oxcf.ss_enable_auto_arf[cpi->svc.spatial_layer_id]) {
552       cpi->alt_fb_idx = lc->alt_ref_idx;
553       if (!lc->has_alt_frame)
554         cpi->ref_frame_flags &= (~VP9_ALT_FLAG);
555     } else {
556       // Find a proper alt_fb_idx for layers that don't have alt ref frame
557       if (cpi->svc.spatial_layer_id == 0) {
558         cpi->alt_fb_idx = cpi->lst_fb_idx;
559       } else {
560         LAYER_CONTEXT *lc_lower =
561             &cpi->svc.layer_context[cpi->svc.spatial_layer_id - 1];
562
563         if (cpi->oxcf.ss_enable_auto_arf[cpi->svc.spatial_layer_id - 1] &&
564             lc_lower->alt_ref_source != NULL)
565           cpi->alt_fb_idx = lc_lower->alt_ref_idx;
566         else if (cpi->svc.spatial_layer_id >= 2)
567           cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2;
568         else
569           cpi->alt_fb_idx = cpi->lst_fb_idx;
570       }
571     }
572   }
573
574   get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height,
575                        lc->scaling_factor_num, lc->scaling_factor_den,
576                        &width, &height);
577
578   // Workaround for multiple frame contexts. In some frames we can't use prev_mi
579   // since its previous frame could be changed during decoding time. The idea is
580   // we put a empty invisible frame in front of them, then we will not use
581   // prev_mi when encoding these frames.
582
583   buf = vp9_lookahead_peek(cpi->lookahead, 0);
584   if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2 &&
585       cpi->svc.encode_empty_frame_state == NEED_TO_ENCODE &&
586       lc->rc.frames_to_key != 0 &&
587       !(buf != NULL && (buf->flags & VPX_EFLAG_FORCE_KF))) {
588     if ((cpi->svc.number_temporal_layers > 1 &&
589          cpi->svc.temporal_layer_id < cpi->svc.number_temporal_layers - 1) ||
590         (cpi->svc.number_spatial_layers > 1 &&
591          cpi->svc.spatial_layer_id == 0)) {
592       struct lookahead_entry *buf = vp9_lookahead_peek(cpi->lookahead, 0);
593
594       if (buf != NULL) {
595         cpi->svc.empty_frame.ts_start = buf->ts_start;
596         cpi->svc.empty_frame.ts_end = buf->ts_end;
597         cpi->svc.encode_empty_frame_state = ENCODING;
598         cpi->common.show_frame = 0;
599         cpi->ref_frame_flags = 0;
600         cpi->common.frame_type = INTER_FRAME;
601         cpi->lst_fb_idx =
602             cpi->gld_fb_idx = cpi->alt_fb_idx = SMALL_FRAME_FB_IDX;
603
604         if (cpi->svc.encode_intra_empty_frame != 0)
605           cpi->common.intra_only = 1;
606
607         width = SMALL_FRAME_WIDTH;
608         height = SMALL_FRAME_HEIGHT;
609       }
610     }
611   }
612
613   cpi->oxcf.worst_allowed_q = vp9_quantizer_to_qindex(lc->max_q);
614   cpi->oxcf.best_allowed_q = vp9_quantizer_to_qindex(lc->min_q);
615
616   vp9_change_config(cpi, &cpi->oxcf);
617
618   if (vp9_set_size_literal(cpi, width, height) != 0)
619     return VPX_CODEC_INVALID_PARAM;
620
621   vp9_set_high_precision_mv(cpi, 1);
622
623   cpi->alt_ref_source = get_layer_context(cpi)->alt_ref_source;
624
625   return 0;
626 }
627
628 #endif
629
630 struct lookahead_entry *vp9_svc_lookahead_pop(VP9_COMP *const cpi,
631                                               struct lookahead_ctx *ctx,
632                                               int drain) {
633   struct lookahead_entry *buf = NULL;
634   if (ctx->sz && (drain || ctx->sz == ctx->max_sz - MAX_PRE_FRAMES)) {
635     buf = vp9_lookahead_peek(ctx, 0);
636     if (buf != NULL) {
637       // Only remove the buffer when pop the highest layer.
638       if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) {
639         vp9_lookahead_pop(ctx, drain);
640       }
641     }
642   }
643   return buf;
644 }