Coverage Report

Created: 2022-08-24 06:17

/src/aom/av1/encoder/rc_utils.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2020, Alliance for Open Media. All rights reserved
3
 *
4
 * This source code is subject to the terms of the BSD 2 Clause License and
5
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6
 * was not distributed with this source code in the LICENSE file, you can
7
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8
 * Media Patent License 1.0 was not distributed with this source code in the
9
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10
 */
11
12
#ifndef AOM_AV1_ENCODER_RC_UTILS_H_
13
#define AOM_AV1_ENCODER_RC_UTILS_H_
14
15
#include "av1/encoder/encoder.h"
16
#include "aom_dsp/psnr.h"
17
18
#ifdef __cplusplus
19
extern "C" {
20
#endif
21
22
0
static AOM_INLINE void check_reset_rc_flag(AV1_COMP *cpi) {
23
0
  RATE_CONTROL *rc = &cpi->rc;
24
0
  PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
25
0
  if (cpi->common.current_frame.frame_number >
26
0
      (unsigned int)cpi->svc.number_spatial_layers) {
27
0
    if (cpi->ppi->use_svc) {
28
0
      av1_svc_check_reset_layer_rc_flag(cpi);
29
0
    } else {
30
0
      if (rc->avg_frame_bandwidth > (3 * rc->prev_avg_frame_bandwidth >> 1) ||
31
0
          rc->avg_frame_bandwidth < (rc->prev_avg_frame_bandwidth >> 1)) {
32
0
        rc->rc_1_frame = 0;
33
0
        rc->rc_2_frame = 0;
34
0
        p_rc->bits_off_target = p_rc->optimal_buffer_level;
35
0
        p_rc->buffer_level = p_rc->optimal_buffer_level;
36
0
      }
37
0
    }
38
0
  }
39
0
}
Unexecuted instantiation: encoder.c:check_reset_rc_flag
Unexecuted instantiation: encoder_utils.c:check_reset_rc_flag
Unexecuted instantiation: pass2_strategy.c:check_reset_rc_flag
40
41
static AOM_INLINE void set_primary_rc_buffer_sizes(const AV1EncoderConfig *oxcf,
42
0
                                                   AV1_PRIMARY *ppi) {
43
0
  PRIMARY_RATE_CONTROL *p_rc = &ppi->p_rc;
44
0
  const RateControlCfg *const rc_cfg = &oxcf->rc_cfg;
45
46
0
  const int64_t bandwidth = rc_cfg->target_bandwidth;
47
0
  const int64_t starting = rc_cfg->starting_buffer_level_ms;
48
0
  const int64_t optimal = rc_cfg->optimal_buffer_level_ms;
49
0
  const int64_t maximum = rc_cfg->maximum_buffer_size_ms;
50
51
0
  p_rc->starting_buffer_level = starting * bandwidth / 1000;
52
0
  p_rc->optimal_buffer_level =
53
0
      (optimal == 0) ? bandwidth / 8 : optimal * bandwidth / 1000;
54
0
  p_rc->maximum_buffer_size =
55
0
      (maximum == 0) ? bandwidth / 8 : maximum * bandwidth / 1000;
56
57
  // Under a configuration change, where maximum_buffer_size may change,
58
  // keep buffer level clipped to the maximum allowed buffer size.
59
0
  p_rc->bits_off_target =
60
0
      AOMMIN(p_rc->bits_off_target, p_rc->maximum_buffer_size);
61
0
  p_rc->buffer_level = AOMMIN(p_rc->buffer_level, p_rc->maximum_buffer_size);
62
0
}
Unexecuted instantiation: encoder.c:set_primary_rc_buffer_sizes
Unexecuted instantiation: encoder_utils.c:set_primary_rc_buffer_sizes
Unexecuted instantiation: pass2_strategy.c:set_primary_rc_buffer_sizes
63
64
static AOM_INLINE void config_target_level(AV1_COMP *const cpi,
65
0
                                           AV1_LEVEL target_level, int tier) {
66
0
  AV1EncoderConfig *const oxcf = &cpi->oxcf;
67
0
  SequenceHeader *const seq_params = cpi->common.seq_params;
68
0
  TileConfig *const tile_cfg = &oxcf->tile_cfg;
69
0
  RateControlCfg *const rc_cfg = &oxcf->rc_cfg;
70
71
  // Adjust target bitrate to be no larger than 70% of level limit.
72
0
  const BITSTREAM_PROFILE profile = seq_params->profile;
73
0
  const double level_bitrate_limit =
74
0
      av1_get_max_bitrate_for_level(target_level, tier, profile);
75
0
  const int64_t max_bitrate = (int64_t)(level_bitrate_limit * 0.70);
76
0
  rc_cfg->target_bandwidth = AOMMIN(rc_cfg->target_bandwidth, max_bitrate);
77
  // Also need to update cpi->ppi->twopass.bits_left.
78
0
  TWO_PASS *const twopass = &cpi->ppi->twopass;
79
0
  FIRSTPASS_STATS *stats = twopass->stats_buf_ctx->total_stats;
80
0
  if (stats != NULL)
81
0
    cpi->ppi->twopass.bits_left =
82
0
        (int64_t)(stats->duration * rc_cfg->target_bandwidth / 10000000.0);
83
84
  // Adjust max over-shoot percentage.
85
0
  rc_cfg->over_shoot_pct = 0;
86
87
  // Adjust max quantizer.
88
0
  rc_cfg->worst_allowed_q = 255;
89
90
  // Adjust number of tiles and tile columns to be under level limit.
91
0
  int max_tiles, max_tile_cols;
92
0
  av1_get_max_tiles_for_level(target_level, &max_tiles, &max_tile_cols);
93
0
  while (tile_cfg->tile_columns > 0 &&
94
0
         (1 << tile_cfg->tile_columns) > max_tile_cols) {
95
0
    --tile_cfg->tile_columns;
96
0
  }
97
0
  const int tile_cols = (1 << tile_cfg->tile_columns);
98
0
  while (tile_cfg->tile_rows > 0 &&
99
0
         tile_cols * (1 << tile_cfg->tile_rows) > max_tiles) {
100
0
    --tile_cfg->tile_rows;
101
0
  }
102
103
  // Adjust min compression ratio.
104
0
  const int still_picture = seq_params->still_picture;
105
0
  const double min_cr =
106
0
      av1_get_min_cr_for_level(target_level, tier, still_picture);
107
0
  rc_cfg->min_cr = AOMMAX(rc_cfg->min_cr, (unsigned int)(min_cr * 100));
108
0
}
Unexecuted instantiation: encoder.c:config_target_level
Unexecuted instantiation: encoder_utils.c:config_target_level
Unexecuted instantiation: pass2_strategy.c:config_target_level
109
110
#if !CONFIG_REALTIME_ONLY
111
112
/*!\brief Function to test for conditions that indicate we should loop
113
 * back and recode a frame.
114
 *
115
 * \ingroup rate_control
116
 *
117
 * \param[in]     cpi         Top-level encoder structure
118
 * \param[in]     high_limit  Upper rate threshold
119
 * \param[in]     low_limit   Lower rate threshold
120
 * \param[in]     q           Current q index
121
 * \param[in]     maxq        Maximum allowed q index
122
 * \param[in]     minq        Minimum allowed q index
123
 *
124
 * \return        Indicates if a recode is required.
125
 * \retval        1           Recode Required
126
 * \retval        0           No Recode required
127
 */
128
static AOM_INLINE int recode_loop_test(AV1_COMP *cpi, int high_limit,
129
                                       int low_limit, int q, int maxq,
130
0
                                       int minq) {
131
0
  const RATE_CONTROL *const rc = &cpi->rc;
132
0
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
133
0
  const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi);
134
0
  int force_recode = 0;
135
136
0
  if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
137
0
      (cpi->sf.hl_sf.recode_loop == ALLOW_RECODE) ||
138
0
      (frame_is_kfgfarf &&
139
0
       (cpi->sf.hl_sf.recode_loop == ALLOW_RECODE_KFARFGF))) {
140
    // TODO(agrange) high_limit could be greater than the scale-down threshold.
141
0
    if ((rc->projected_frame_size > high_limit && q < maxq) ||
142
0
        (rc->projected_frame_size < low_limit && q > minq)) {
143
0
      force_recode = 1;
144
0
    } else if (cpi->oxcf.rc_cfg.mode == AOM_CQ) {
145
      // Deal with frame undershoot and whether or not we are
146
      // below the automatically set cq level.
147
0
      if (q > oxcf->rc_cfg.cq_level &&
148
0
          rc->projected_frame_size < ((rc->this_frame_target * 7) >> 3)) {
149
0
        force_recode = 1;
150
0
      }
151
0
    }
152
0
  }
153
0
  return force_recode;
154
0
}
Unexecuted instantiation: encoder.c:recode_loop_test
Unexecuted instantiation: encoder_utils.c:recode_loop_test
Unexecuted instantiation: pass2_strategy.c:recode_loop_test
155
156
static AOM_INLINE double av1_get_gfu_boost_projection_factor(double min_factor,
157
                                                             double max_factor,
158
0
                                                             int frame_count) {
159
0
  double factor = sqrt((double)frame_count);
160
0
  factor = AOMMIN(factor, max_factor);
161
0
  factor = AOMMAX(factor, min_factor);
162
0
  factor = (200.0 + 10.0 * factor);
163
0
  return factor;
164
0
}
Unexecuted instantiation: encoder.c:av1_get_gfu_boost_projection_factor
Unexecuted instantiation: encoder_utils.c:av1_get_gfu_boost_projection_factor
Unexecuted instantiation: pass2_strategy.c:av1_get_gfu_boost_projection_factor
165
166
static AOM_INLINE int get_gfu_boost_from_r0_lap(double min_factor,
167
                                                double max_factor, double r0,
168
0
                                                int frames_to_key) {
169
0
  double factor = av1_get_gfu_boost_projection_factor(min_factor, max_factor,
170
0
                                                      frames_to_key);
171
0
  const int boost = (int)rint(factor / r0);
172
0
  return boost;
173
0
}
Unexecuted instantiation: encoder.c:get_gfu_boost_from_r0_lap
Unexecuted instantiation: encoder_utils.c:get_gfu_boost_from_r0_lap
Unexecuted instantiation: pass2_strategy.c:get_gfu_boost_from_r0_lap
174
175
0
static AOM_INLINE double av1_get_kf_boost_projection_factor(int frame_count) {
176
0
  double factor = sqrt((double)frame_count);
177
0
  factor = AOMMIN(factor, 10.0);
178
0
  factor = AOMMAX(factor, 4.0);
179
0
  factor = (75.0 + 14.0 * factor);
180
0
  return factor;
181
0
}
Unexecuted instantiation: encoder.c:av1_get_kf_boost_projection_factor
Unexecuted instantiation: encoder_utils.c:av1_get_kf_boost_projection_factor
Unexecuted instantiation: pass2_strategy.c:av1_get_kf_boost_projection_factor
182
183
static AOM_INLINE int get_regulated_q_overshoot(AV1_COMP *const cpi,
184
#if CONFIG_FRAME_PARALLEL_ENCODE
185
                                                int is_encode_stage,
186
#endif
187
                                                int q_low, int q_high,
188
                                                int top_index,
189
0
                                                int bottom_index) {
190
0
  const AV1_COMMON *const cm = &cpi->common;
191
0
  const RATE_CONTROL *const rc = &cpi->rc;
192
193
0
  av1_rc_update_rate_correction_factors(cpi,
194
#if CONFIG_FRAME_PARALLEL_ENCODE
195
                                        is_encode_stage,
196
#endif
197
0
                                        cm->width, cm->height);
198
199
0
  int q_regulated =
200
0
      av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
201
0
                        AOMMAX(q_high, top_index), cm->width, cm->height);
202
203
0
  int retries = 0;
204
0
  while (q_regulated < q_low && retries < 10) {
205
0
    av1_rc_update_rate_correction_factors(cpi,
206
#if CONFIG_FRAME_PARALLEL_ENCODE
207
                                          is_encode_stage,
208
#endif
209
0
                                          cm->width, cm->height);
210
0
    q_regulated =
211
0
        av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
212
0
                          AOMMAX(q_high, top_index), cm->width, cm->height);
213
0
    retries++;
214
0
  }
215
0
  return q_regulated;
216
0
}
Unexecuted instantiation: encoder.c:get_regulated_q_overshoot
Unexecuted instantiation: encoder_utils.c:get_regulated_q_overshoot
Unexecuted instantiation: pass2_strategy.c:get_regulated_q_overshoot
217
218
static AOM_INLINE int get_regulated_q_undershoot(AV1_COMP *const cpi,
219
#if CONFIG_FRAME_PARALLEL_ENCODE
220
                                                 int is_encode_stage,
221
#endif
222
                                                 int q_high, int top_index,
223
0
                                                 int bottom_index) {
224
0
  const AV1_COMMON *const cm = &cpi->common;
225
0
  const RATE_CONTROL *const rc = &cpi->rc;
226
227
0
  av1_rc_update_rate_correction_factors(cpi,
228
#if CONFIG_FRAME_PARALLEL_ENCODE
229
                                        is_encode_stage,
230
#endif
231
0
                                        cm->width, cm->height);
232
0
  int q_regulated = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
233
0
                                      top_index, cm->width, cm->height);
234
235
0
  int retries = 0;
236
0
  while (q_regulated > q_high && retries < 10) {
237
0
    av1_rc_update_rate_correction_factors(cpi,
238
#if CONFIG_FRAME_PARALLEL_ENCODE
239
                                          is_encode_stage,
240
#endif
241
0
                                          cm->width, cm->height);
242
0
    q_regulated = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
243
0
                                    top_index, cm->width, cm->height);
244
0
    retries++;
245
0
  }
246
0
  return q_regulated;
247
0
}
Unexecuted instantiation: encoder.c:get_regulated_q_undershoot
Unexecuted instantiation: encoder_utils.c:get_regulated_q_undershoot
Unexecuted instantiation: pass2_strategy.c:get_regulated_q_undershoot
248
249
/*!\brief Called after encode_with_recode_loop() has just encoded a frame.
250
 * This function works out whether we undershot or overshot our bitrate
251
 *  target and adjusts q as appropriate. It also decides whether or not
252
 *  we need to recode the frame to get closer to the target rate.
253
 *
254
 * \ingroup rate_control
255
 *
256
 * \param[in]     cpi             Top-level encoder structure
257
 * \param[out]    loop            Should we go around the recode loop again
258
 * \param[in,out] q               New q index value
259
 * \param[in,out] q_low           Low q index limit for this loop itteration
260
 * \param[in,out] q_high          High q index limit for this loop itteration
261
 * \param[in]     top_index       Max permited new value for q index
262
 * \param[in]     bottom_index    Min permited new value for q index
263
 * \param[in,out] undershoot_seen Have we seen undershoot on this frame
264
 * \param[in,out] overshoot_seen  Have we seen overshoot on this frame
265
 * \param[in,out] low_cr_seen     Have we previously trriggered recode
266
 *                                because the compression ration was less
267
 *                                than a given minimum threshold.
268
 * \param[in]     loop_count      Loop itterations so far.
269
 *
270
 */
271
static AOM_INLINE void recode_loop_update_q(
272
    AV1_COMP *const cpi, int *const loop, int *const q, int *const q_low,
273
    int *const q_high, const int top_index, const int bottom_index,
274
    int *const undershoot_seen, int *const overshoot_seen,
275
0
    int *const low_cr_seen, const int loop_count) {
276
0
  AV1_COMMON *const cm = &cpi->common;
277
0
  RATE_CONTROL *const rc = &cpi->rc;
278
0
  PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
279
0
  const RateControlCfg *const rc_cfg = &cpi->oxcf.rc_cfg;
280
0
  *loop = 0;
281
282
  // Special case for overlay frame.
283
0
  if (rc->is_src_frame_alt_ref &&
284
0
      rc->projected_frame_size < rc->max_frame_bandwidth)
285
0
    return;
286
287
0
  const int min_cr = rc_cfg->min_cr;
288
0
  if (min_cr > 0) {
289
0
    const double compression_ratio =
290
0
        av1_get_compression_ratio(cm, rc->projected_frame_size >> 3);
291
0
    const double target_cr = min_cr / 100.0;
292
0
    if (compression_ratio < target_cr) {
293
0
      *low_cr_seen = 1;
294
0
      if (*q < rc->worst_quality) {
295
0
        const double cr_ratio = target_cr / compression_ratio;
296
0
        const int projected_q = AOMMAX(*q + 1, (int)(*q * cr_ratio * cr_ratio));
297
0
        *q = AOMMIN(AOMMIN(projected_q, *q + 32), rc->worst_quality);
298
0
        *q_low = AOMMAX(*q, *q_low);
299
0
        *q_high = AOMMAX(*q, *q_high);
300
0
        *loop = 1;
301
0
      }
302
0
    }
303
0
    if (*low_cr_seen) return;
304
0
  }
305
306
0
  if (cpi->ppi->level_params.keep_level_stats &&
307
0
      !is_stat_generation_stage(cpi)) {
308
    // Initialize level info. at the beginning of each sequence.
309
0
    if (cm->current_frame.frame_type == KEY_FRAME &&
310
0
        cpi->ppi->gf_group.refbuf_state[cpi->gf_frame_index] == REFBUF_RESET) {
311
0
      av1_init_level_info(cpi);
312
0
    }
313
0
    const AV1LevelParams *const level_params = &cpi->ppi->level_params;
314
    // TODO(any): currently only checking operating point 0
315
0
    const AV1LevelInfo *const level_info = level_params->level_info[0];
316
0
    const DECODER_MODEL *const decoder_models = level_info->decoder_models;
317
0
    const AV1_LEVEL target_level = level_params->target_seq_level_idx[0];
318
319
0
    if (target_level < SEQ_LEVELS) {
320
0
      DECODER_MODEL_STATUS status = av1_decoder_model_try_smooth_buf(
321
0
          cpi, rc->projected_frame_size, &decoder_models[target_level]);
322
323
0
      if ((status == SMOOTHING_BUFFER_UNDERFLOW ||
324
0
           status == SMOOTHING_BUFFER_OVERFLOW) &&
325
0
          *q < rc->worst_quality) {
326
0
        *q = AOMMIN(*q + 10, rc->worst_quality);
327
0
        *q_low = AOMMAX(*q, *q_low);
328
0
        *q_high = AOMMAX(*q, *q_high);
329
0
        *loop = 1;
330
0
        return;
331
0
      }
332
0
    }
333
0
  }
334
335
0
  if (rc_cfg->mode == AOM_Q) return;
336
337
0
  const int last_q = *q;
338
0
  int frame_over_shoot_limit = 0, frame_under_shoot_limit = 0;
339
0
  av1_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
340
0
                                   &frame_under_shoot_limit,
341
0
                                   &frame_over_shoot_limit);
342
0
  if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
343
344
0
  if (cm->current_frame.frame_type == KEY_FRAME &&
345
0
      p_rc->this_key_frame_forced &&
346
0
      rc->projected_frame_size < rc->max_frame_bandwidth) {
347
0
    int64_t kf_err;
348
0
    const int64_t high_err_target = cpi->ambient_err;
349
0
    const int64_t low_err_target = cpi->ambient_err >> 1;
350
351
0
#if CONFIG_AV1_HIGHBITDEPTH
352
0
    if (cm->seq_params->use_highbitdepth) {
353
0
      kf_err = aom_highbd_get_y_sse(cpi->source, &cm->cur_frame->buf);
354
0
    } else {
355
0
      kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
356
0
    }
357
#else
358
    kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
359
#endif
360
    // Prevent possible divide by zero error below for perfect KF
361
0
    kf_err += !kf_err;
362
363
    // The key frame is not good enough or we can afford
364
    // to make it better without undue risk of popping.
365
0
    if ((kf_err > high_err_target &&
366
0
         rc->projected_frame_size <= frame_over_shoot_limit) ||
367
0
        (kf_err > low_err_target &&
368
0
         rc->projected_frame_size <= frame_under_shoot_limit)) {
369
      // Lower q_high
370
0
      *q_high = AOMMAX(*q - 1, *q_low);
371
372
      // Adjust Q
373
0
      *q = (int)((*q * high_err_target) / kf_err);
374
0
      *q = AOMMIN(*q, (*q_high + *q_low) >> 1);
375
0
    } else if (kf_err < low_err_target &&
376
0
               rc->projected_frame_size >= frame_under_shoot_limit) {
377
      // The key frame is much better than the previous frame
378
      // Raise q_low
379
0
      *q_low = AOMMIN(*q + 1, *q_high);
380
381
      // Adjust Q
382
0
      *q = (int)((*q * low_err_target) / kf_err);
383
0
      *q = AOMMIN(*q, (*q_high + *q_low + 1) >> 1);
384
0
    }
385
386
    // Clamp Q to upper and lower limits:
387
0
    *q = clamp(*q, *q_low, *q_high);
388
0
    *loop = (*q != last_q);
389
0
    return;
390
0
  }
391
392
0
  if (recode_loop_test(cpi, frame_over_shoot_limit, frame_under_shoot_limit, *q,
393
0
                       AOMMAX(*q_high, top_index), bottom_index)) {
394
    // Is the projected frame size out of range and are we allowed
395
    // to attempt to recode.
396
397
    // Frame size out of permitted range:
398
    // Update correction factor & compute new Q to try...
399
    // Frame is too large
400
0
    if (rc->projected_frame_size > rc->this_frame_target) {
401
      // Special case if the projected size is > the max allowed.
402
0
      if (*q == *q_high &&
403
0
          rc->projected_frame_size >= rc->max_frame_bandwidth) {
404
0
        const double q_val_high_current =
405
0
            av1_convert_qindex_to_q(*q_high, cm->seq_params->bit_depth);
406
0
        const double q_val_high_new =
407
0
            q_val_high_current *
408
0
            ((double)rc->projected_frame_size / rc->max_frame_bandwidth);
409
0
        *q_high = av1_find_qindex(q_val_high_new, cm->seq_params->bit_depth,
410
0
                                  rc->best_quality, rc->worst_quality);
411
0
      }
412
413
      // Raise Qlow as to at least the current value
414
0
      *q_low = AOMMIN(*q + 1, *q_high);
415
416
0
      if (*undershoot_seen || loop_count > 2 ||
417
0
          (loop_count == 2 && !frame_is_intra_only(cm))) {
418
0
        av1_rc_update_rate_correction_factors(cpi,
419
#if CONFIG_FRAME_PARALLEL_ENCODE
420
                                              1,
421
#endif
422
0
                                              cm->width, cm->height);
423
424
0
        *q = (*q_high + *q_low + 1) / 2;
425
0
      } else if (loop_count == 2 && frame_is_intra_only(cm)) {
426
0
        const int q_mid = (*q_high + *q_low + 1) / 2;
427
0
        const int q_regulated =
428
0
            get_regulated_q_overshoot(cpi,
429
#if CONFIG_FRAME_PARALLEL_ENCODE
430
                                      1,
431
#endif
432
0
                                      *q_low, *q_high, top_index, bottom_index);
433
        // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth
434
        // transition between loop_count < 2 and loop_count > 2.
435
0
        *q = (q_mid + q_regulated + 1) / 2;
436
0
      } else {
437
0
        *q =
438
0
            get_regulated_q_overshoot(cpi,
439
#if CONFIG_FRAME_PARALLEL_ENCODE
440
                                      1,
441
#endif
442
0
                                      *q_low, *q_high, top_index, bottom_index);
443
0
      }
444
445
0
      *overshoot_seen = 1;
446
0
    } else {
447
      // Frame is too small
448
0
      *q_high = AOMMAX(*q - 1, *q_low);
449
450
0
      if (*overshoot_seen || loop_count > 2 ||
451
0
          (loop_count == 2 && !frame_is_intra_only(cm))) {
452
0
        av1_rc_update_rate_correction_factors(cpi,
453
#if CONFIG_FRAME_PARALLEL_ENCODE
454
                                              1,
455
#endif
456
0
                                              cm->width, cm->height);
457
0
        *q = (*q_high + *q_low) / 2;
458
0
      } else if (loop_count == 2 && frame_is_intra_only(cm)) {
459
0
        const int q_mid = (*q_high + *q_low) / 2;
460
0
        const int q_regulated =
461
0
            get_regulated_q_undershoot(cpi,
462
#if CONFIG_FRAME_PARALLEL_ENCODE
463
                                       1,
464
#endif
465
0
                                       *q_high, top_index, bottom_index);
466
        // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth
467
        // transition between loop_count < 2 and loop_count > 2.
468
0
        *q = (q_mid + q_regulated) / 2;
469
470
        // Special case reset for qlow for constrained quality.
471
        // This should only trigger where there is very substantial
472
        // undershoot on a frame and the auto cq level is above
473
        // the user passsed in value.
474
0
        if (rc_cfg->mode == AOM_CQ && q_regulated < *q_low) {
475
0
          *q_low = *q;
476
0
        }
477
0
      } else {
478
0
        *q = get_regulated_q_undershoot(cpi,
479
#if CONFIG_FRAME_PARALLEL_ENCODE
480
                                        1,
481
#endif
482
0
                                        *q_high, top_index, bottom_index);
483
484
        // Special case reset for qlow for constrained quality.
485
        // This should only trigger where there is very substantial
486
        // undershoot on a frame and the auto cq level is above
487
        // the user passsed in value.
488
0
        if (rc_cfg->mode == AOM_CQ && *q < *q_low) {
489
0
          *q_low = *q;
490
0
        }
491
0
      }
492
493
0
      *undershoot_seen = 1;
494
0
    }
495
496
    // Clamp Q to upper and lower limits:
497
0
    *q = clamp(*q, *q_low, *q_high);
498
0
  }
499
500
0
  *loop = (*q != last_q);
501
0
}
Unexecuted instantiation: encoder.c:recode_loop_update_q
Unexecuted instantiation: encoder_utils.c:recode_loop_update_q
Unexecuted instantiation: pass2_strategy.c:recode_loop_update_q
502
#endif
503
504
#ifdef __cplusplus
505
}  // extern "C"
506
#endif
507
508
#endif  // AOM_AV1_ENCODER_RC_UTILS_H_