vp9_svc_layercontext.c 14.8 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>

Dmitry Kovalev's avatar
Dmitry Kovalev committed
13
#include "vp9/encoder/vp9_encoder.h"
14
#include "vp9/encoder/vp9_svc_layercontext.h"
15
#include "vp9/encoder/vp9_extend.h"
16

17
18
#define SMALL_FRAME_FB_IDX 7

19
void vp9_init_layer_context(VP9_COMP *const cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
20
  SVC *const svc = &cpi->svc;
21
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
22
  int layer;
23
  int layer_end;
24
  int alt_ref_idx = svc->number_spatial_layers;
25

Dmitry Kovalev's avatar
Dmitry Kovalev committed
26
27
  svc->spatial_layer_id = 0;
  svc->temporal_layer_id = 0;
28

29
  if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
30
    layer_end = svc->number_temporal_layers;
31
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
32
    layer_end = svc->number_spatial_layers;
33
34
35
36
37
38
39
40
41

    if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) {
      if (vp9_realloc_frame_buffer(&cpi->svc.empty_frame.img,
                                   cpi->common.width, cpi->common.height,
                                   cpi->common.subsampling_x,
                                   cpi->common.subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
                                 cpi->common.use_highbitdepth,
#endif
42
43
44
                                 VP9_ENC_BORDER_IN_PIXELS,
                                 cpi->common.byte_alignment,
                                 NULL, NULL, NULL))
45
46
47
48
49
50
51
52
53
        vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
                           "Failed to allocate empty frame for multiple frame "
                           "contexts");

      vpx_memset(cpi->svc.empty_frame.img.buffer_alloc, 0x80,
                 cpi->svc.empty_frame.img.buffer_alloc_sz);
      cpi->svc.empty_frame_width = cpi->common.width;
      cpi->svc.empty_frame_height = cpi->common.height;
    }
54
55
56
  }

  for (layer = 0; layer < layer_end; ++layer) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
57
    LAYER_CONTEXT *const lc = &svc->layer_context[layer];
58
    RATE_CONTROL *const lrc = &lc->rc;
59
    int i;
60
    lc->current_video_frame_in_layer = 0;
61
    lc->layer_size = 0;
62
    lc->frames_from_key_frame = 0;
63
    lc->last_frame_type = FRAME_TYPES;
64
    lrc->ni_av_qi = oxcf->worst_allowed_q;
65
66
67
68
69
70
71
72
    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;
73
74
75
76

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
98
99
    lrc->buffer_level = oxcf->starting_buffer_level_ms *
                            lc->target_bandwidth / 1000;
100
101
    lrc->bits_off_target = lrc->buffer_level;
  }
102
103

  // Still have extra buffer for base layer golden frame
104
105
  if (!(svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR)
      && alt_ref_idx < REF_FRAMES)
106
    svc->layer_context[0].gold_ref_idx = alt_ref_idx;
107
108
109
110
111
}

// 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
112
  SVC *const svc = &cpi->svc;
113
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
114
  const RATE_CONTROL *const rc = &cpi->rc;
115
  int layer;
116
  int layer_end;
117
  float bitrate_alloc = 1.0;
118

119
  if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
120
    layer_end = svc->number_temporal_layers;
121
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
122
    layer_end = svc->number_spatial_layers;
123
124
125
  }

  for (layer = 0; layer < layer_end; ++layer) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
126
    LAYER_CONTEXT *const lc = &svc->layer_context[layer];
127
    RATE_CONTROL *const lrc = &lc->rc;
128

129
    if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) {
130
      lc->target_bandwidth = oxcf->ts_target_bitrate[layer];
131
    } else {
132
      lc->target_bandwidth = oxcf->ss_target_bitrate[layer];
133
    }
134
    bitrate_alloc = (float)lc->target_bandwidth / target_bandwidth;
135
    // Update buffer-related quantities.
136
137
138
139
140
141
    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);
142
143
    lrc->bits_off_target = MIN(lrc->bits_off_target, lrc->maximum_buffer_size);
    lrc->buffer_level = MIN(lrc->buffer_level, lrc->maximum_buffer_size);
144
    // Update framerate-related quantities.
145
    if (svc->number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) {
146
      lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[layer];
147
    } else {
148
      lc->framerate = cpi->framerate;
149
    }
150
    lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
151
152
153
154
155
156
157
    lrc->max_frame_bandwidth = rc->max_frame_bandwidth;
    // Update qp-related quantities.
    lrc->worst_quality = rc->worst_quality;
    lrc->best_quality = rc->best_quality;
  }
}

158
159
160
161
static LAYER_CONTEXT *get_layer_context(VP9_COMP *const cpi) {
  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];
162
163
}

164
void vp9_update_temporal_layer_framerate(VP9_COMP *const cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
165
  SVC *const svc = &cpi->svc;
166
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
167
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
168
  RATE_CONTROL *const lrc = &lc->rc;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
169
  const int layer = svc->temporal_layer_id;
170

171
  lc->framerate = cpi->framerate / oxcf->ts_rate_decimator[layer];
172
  lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
173
174
  lrc->max_frame_bandwidth = cpi->rc.max_frame_bandwidth;
  // Update the average layer frame size (non-cumulative per-frame-bw).
175
  if (layer == 0) {
176
    lc->avg_frame_size = lrc->avg_frame_bandwidth;
177
  } else {
178
    const double prev_layer_framerate =
179
        cpi->framerate / oxcf->ts_rate_decimator[layer - 1];
180
    const int prev_layer_target_bandwidth = oxcf->ts_target_bitrate[layer - 1];
181
182
183
184
185
186
    lc->avg_frame_size =
        (int)((lc->target_bandwidth - prev_layer_target_bandwidth) /
              (lc->framerate - prev_layer_framerate));
  }
}

187
void vp9_update_spatial_layer_framerate(VP9_COMP *const cpi, double framerate) {
188
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
189
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
190
191
192
  RATE_CONTROL *const lrc = &lc->rc;

  lc->framerate = framerate;
193
194
  lrc->avg_frame_bandwidth = (int)(lc->target_bandwidth / lc->framerate);
  lrc->min_frame_bandwidth = (int)(lrc->avg_frame_bandwidth *
195
                                   oxcf->two_pass_vbrmin_section / 100);
196
  lrc->max_frame_bandwidth = (int)(((int64_t)lrc->avg_frame_bandwidth *
197
                                   oxcf->two_pass_vbrmax_section) / 100);
198
  vp9_rc_set_gf_max_interval(cpi, lrc);
199
200
}

201
void vp9_restore_layer_context(VP9_COMP *const cpi) {
202
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
203
204
205
  const int old_frame_since_key = cpi->rc.frames_since_key;
  const int old_frame_to_key = cpi->rc.frames_to_key;

206
  cpi->rc = lc->rc;
207
  cpi->twopass = lc->twopass;
208
  cpi->oxcf.target_bandwidth = lc->target_bandwidth;
209
  cpi->alt_ref_source = lc->alt_ref_source;
210
211
  // 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).
212
213
214
215
  if (cpi->svc.number_temporal_layers > 1) {
    cpi->rc.frames_since_key = old_frame_since_key;
    cpi->rc.frames_to_key = old_frame_to_key;
  }
216
217
218
}

void vp9_save_layer_context(VP9_COMP *const cpi) {
219
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
220
  LAYER_CONTEXT *const lc = get_layer_context(cpi);
221

222
  lc->rc = cpi->rc;
223
  lc->twopass = cpi->twopass;
224
  lc->target_bandwidth = (int)oxcf->target_bandwidth;
225
  lc->alt_ref_source = cpi->alt_ref_source;
226
}
227
228

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
232
  for (i = 0; i < svc->number_spatial_layers; ++i) {
Paul Wilkins's avatar
Paul Wilkins committed
233
    TWO_PASS *const twopass = &svc->layer_context[i].twopass;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
234
235

    svc->spatial_layer_id = i;
236
237
238
239
240
    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
241
  svc->spatial_layer_id = 0;
242
}
243

244
245
246
247
248
void vp9_inc_frame_in_layer(VP9_COMP *const cpi) {
  LAYER_CONTEXT *const lc =
      (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];
249
  ++lc->current_video_frame_in_layer;
250
  ++lc->frames_from_key_frame;
251
}
252

253
int vp9_is_upper_layer_key_frame(const VP9_COMP *const cpi) {
254
  return is_two_pass_svc(cpi) &&
255
256
         cpi->svc.spatial_layer_id > 0 &&
         cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame;
257
}
258

259
#if CONFIG_SPATIAL_SVC
260
261
262
263
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;
264

265
266
  if (width_out == NULL || height_out == NULL || den == 0)
    return;
267

268
269
  w = width_org * num / den;
  h = height_org * num / den;
270

271
272
273
  // make height and width even to make chrome player happy
  w += w % 2;
  h += h % 2;
274

275
276
  *width_out = w;
  *height_out = h;
277
278
}

279
280
int vp9_svc_start_frame(VP9_COMP *const cpi) {
  int width = 0, height = 0;
281
  LAYER_CONTEXT *lc;
282
  int count = 1 << (cpi->svc.number_temporal_layers - 1);
283

284
  cpi->svc.spatial_layer_id = cpi->svc.spatial_layer_to_encode;
285
  lc = &cpi->svc.layer_context[cpi->svc.spatial_layer_id];
286

287
288
289
290
291
292
  cpi->svc.temporal_layer_id = 0;
  while ((lc->current_video_frame_in_layer % count) != 0) {
    ++cpi->svc.temporal_layer_id;
    count >>= 1;
  }

293
294
  cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;

295
296
297
298
299
300
301
  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;
302
303

  if (lc->current_video_frame_in_layer == 0) {
304
    if (cpi->svc.spatial_layer_id >= 2) {
305
      cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2;
306
    } else {
307
      cpi->alt_fb_idx = cpi->lst_fb_idx;
308
309
      cpi->ref_frame_flags &= (~VP9_LAST_FLAG & ~VP9_ALT_FLAG);
    }
310
  } else {
311
    if (cpi->oxcf.ss_enable_auto_arf[cpi->svc.spatial_layer_id]) {
312
313
314
315
316
317
318
319
320
321
322
      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];

323
        if (cpi->oxcf.ss_enable_auto_arf[cpi->svc.spatial_layer_id - 1] &&
324
325
326
            lc_lower->alt_ref_source != NULL)
          cpi->alt_fb_idx = lc_lower->alt_ref_idx;
        else if (cpi->svc.spatial_layer_id >= 2)
327
          cpi->alt_fb_idx = cpi->svc.spatial_layer_id - 2;
328
329
330
331
332
        else
          cpi->alt_fb_idx = cpi->lst_fb_idx;
      }
    }
  }
333

334
335
336
  get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height,
                       lc->scaling_factor_num, lc->scaling_factor_den,
                       &width, &height);
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377

  // 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.
  if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2 &&
      cpi->svc.encode_empty_frame_state == NEED_TO_ENCODE) {
    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;

        // Gradually make the empty frame smaller to save bits. Make it half of
        // its previous size because of the scaling factor restriction.
        cpi->svc.empty_frame_width >>= 1;
        cpi->svc.empty_frame_width = (cpi->svc.empty_frame_width + 1) & ~1;
        if (cpi->svc.empty_frame_width < 16)
          cpi->svc.empty_frame_width = 16;

        cpi->svc.empty_frame_height >>= 1;
        cpi->svc.empty_frame_height = (cpi->svc.empty_frame_height + 1) & ~1;
        if (cpi->svc.empty_frame_height < 16)
          cpi->svc.empty_frame_height = 16;

        width = cpi->svc.empty_frame_width;
        height = cpi->svc.empty_frame_height;
      }
    }
  }

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

381
382
  cpi->oxcf.worst_allowed_q = vp9_quantizer_to_qindex(lc->max_q);
  cpi->oxcf.best_allowed_q = vp9_quantizer_to_qindex(lc->min_q);
383
384
385
386

  vp9_change_config(cpi, &cpi->oxcf);
  vp9_set_high_precision_mv(cpi, 1);

387
  cpi->alt_ref_source = get_layer_context(cpi)->alt_ref_source;
388
389
390
391
392
393
394
395
396
397

  return 0;
}

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)) {
398
    buf = vp9_lookahead_peek(ctx, 0);
399
    if (buf != NULL) {
400
      // Only remove the buffer when pop the highest layer.
401
402
403
404
405
406
407
408
      if (cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1) {
        vp9_lookahead_pop(ctx, drain);
      }
    }
  }

  return buf;
}
409
#endif