Coverage Report

Created: 2025-06-22 08:04

/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 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: av1_cx_iface.c:check_reset_rc_flag
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 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: av1_cx_iface.c:set_primary_rc_buffer_sizes
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 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: av1_cx_iface.c:config_target_level
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 inline int recode_loop_test(AV1_COMP *cpi, int high_limit, int low_limit,
129
0
                                   int q, int maxq, int minq) {
130
0
  const RATE_CONTROL *const rc = &cpi->rc;
131
0
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
132
0
  const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi);
133
0
  int force_recode = 0;
134
135
0
  if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
136
0
      (cpi->sf.hl_sf.recode_loop == ALLOW_RECODE) ||
137
0
      (frame_is_kfgfarf &&
138
0
       (cpi->sf.hl_sf.recode_loop == ALLOW_RECODE_KFARFGF))) {
139
    // TODO(agrange) high_limit could be greater than the scale-down threshold.
140
0
    if ((rc->projected_frame_size > high_limit && q < maxq) ||
141
0
        (rc->projected_frame_size < low_limit && q > minq)) {
142
0
      force_recode = 1;
143
0
    } else if (cpi->oxcf.rc_cfg.mode == AOM_CQ) {
144
      // Deal with frame undershoot and whether or not we are
145
      // below the automatically set cq level.
146
0
      if (q > oxcf->rc_cfg.cq_level &&
147
0
          rc->projected_frame_size <
148
0
              (((int64_t)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: av1_cx_iface.c:recode_loop_test
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 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: av1_cx_iface.c:av1_get_gfu_boost_projection_factor
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 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: av1_cx_iface.c:get_gfu_boost_from_r0_lap
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 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: av1_cx_iface.c:av1_get_kf_boost_projection_factor
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 inline int get_regulated_q_overshoot(AV1_COMP *const cpi,
184
                                            int is_encode_stage, int q_low,
185
                                            int q_high, int top_index,
186
0
                                            int bottom_index) {
187
0
  const AV1_COMMON *const cm = &cpi->common;
188
0
  const RATE_CONTROL *const rc = &cpi->rc;
189
190
0
  av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
191
0
                                        cm->height);
192
193
0
  int q_regulated =
194
0
      av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
195
0
                        AOMMAX(q_high, top_index), cm->width, cm->height);
196
197
0
  int retries = 0;
198
0
  while (q_regulated < q_low && retries < 10) {
199
0
    av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
200
0
                                          cm->height);
201
0
    q_regulated =
202
0
        av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
203
0
                          AOMMAX(q_high, top_index), cm->width, cm->height);
204
0
    retries++;
205
0
  }
206
0
  return q_regulated;
207
0
}
Unexecuted instantiation: av1_cx_iface.c:get_regulated_q_overshoot
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
208
209
static inline int get_regulated_q_undershoot(AV1_COMP *const cpi,
210
                                             int is_encode_stage, int q_high,
211
0
                                             int top_index, int bottom_index) {
212
0
  const AV1_COMMON *const cm = &cpi->common;
213
0
  const RATE_CONTROL *const rc = &cpi->rc;
214
215
0
  av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
216
0
                                        cm->height);
217
0
  int q_regulated = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
218
0
                                      top_index, cm->width, cm->height);
219
220
0
  int retries = 0;
221
0
  while (q_regulated > q_high && retries < 10) {
222
0
    av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
223
0
                                          cm->height);
224
0
    q_regulated = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
225
0
                                    top_index, cm->width, cm->height);
226
0
    retries++;
227
0
  }
228
0
  return q_regulated;
229
0
}
Unexecuted instantiation: av1_cx_iface.c:get_regulated_q_undershoot
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
230
231
/*!\brief Called after encode_with_recode_loop() has just encoded a frame.
232
 * This function works out whether we undershot or overshot our bitrate
233
 *  target and adjusts q as appropriate. It also decides whether or not
234
 *  we need to recode the frame to get closer to the target rate.
235
 *
236
 * \ingroup rate_control
237
 *
238
 * \param[in]     cpi             Top-level encoder structure
239
 * \param[out]    loop            Should we go around the recode loop again
240
 * \param[in,out] q               New q index value
241
 * \param[in,out] q_low           Low q index limit for this loop itteration
242
 * \param[in,out] q_high          High q index limit for this loop itteration
243
 * \param[in]     top_index       Max permited new value for q index
244
 * \param[in]     bottom_index    Min permited new value for q index
245
 * \param[in,out] undershoot_seen Have we seen undershoot on this frame
246
 * \param[in,out] overshoot_seen  Have we seen overshoot on this frame
247
 * \param[in,out] low_cr_seen     Have we previously trriggered recode
248
 *                                because the compression ration was less
249
 *                                than a given minimum threshold.
250
 * \param[in]     loop_count      Loop itterations so far.
251
 *
252
 */
253
static inline void recode_loop_update_q(
254
    AV1_COMP *const cpi, int *const loop, int *const q, int *const q_low,
255
    int *const q_high, const int top_index, const int bottom_index,
256
    int *const undershoot_seen, int *const overshoot_seen,
257
0
    int *const low_cr_seen, const int loop_count) {
258
0
  AV1_COMMON *const cm = &cpi->common;
259
0
  RATE_CONTROL *const rc = &cpi->rc;
260
0
  PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
261
0
  const RateControlCfg *const rc_cfg = &cpi->oxcf.rc_cfg;
262
0
  *loop = 0;
263
264
  // Special case for overlay frame.
265
0
  if (rc->is_src_frame_alt_ref &&
266
0
      rc->projected_frame_size < rc->max_frame_bandwidth)
267
0
    return;
268
269
0
  const int min_cr = rc_cfg->min_cr;
270
0
  if (min_cr > 0) {
271
0
    const double compression_ratio =
272
0
        av1_get_compression_ratio(cm, rc->projected_frame_size >> 3);
273
0
    const double target_cr = min_cr / 100.0;
274
0
    if (compression_ratio < target_cr) {
275
0
      *low_cr_seen = 1;
276
0
      if (*q < rc->worst_quality) {
277
0
        const double cr_ratio = target_cr / compression_ratio;
278
0
        const int projected_q = AOMMAX(*q + 1, (int)(*q * cr_ratio * cr_ratio));
279
0
        *q = AOMMIN(AOMMIN(projected_q, *q + 32), rc->worst_quality);
280
0
        *q_low = AOMMAX(*q, *q_low);
281
0
        *q_high = AOMMAX(*q, *q_high);
282
0
        *loop = 1;
283
0
      }
284
0
    }
285
0
    if (*low_cr_seen) return;
286
0
  }
287
288
0
  if (cpi->ppi->level_params.keep_level_stats &&
289
0
      !is_stat_generation_stage(cpi)) {
290
    // Initialize level info. at the beginning of each sequence.
291
0
    if (cm->current_frame.frame_type == KEY_FRAME &&
292
0
        cpi->ppi->gf_group.refbuf_state[cpi->gf_frame_index] == REFBUF_RESET) {
293
0
      av1_init_level_info(cpi);
294
0
    }
295
0
    const AV1LevelParams *const level_params = &cpi->ppi->level_params;
296
    // TODO(any): currently only checking operating point 0
297
0
    const AV1LevelInfo *const level_info = level_params->level_info[0];
298
0
    const DECODER_MODEL *const decoder_models = level_info->decoder_models;
299
0
    const AV1_LEVEL target_level = level_params->target_seq_level_idx[0];
300
301
0
    if (target_level < SEQ_LEVELS &&
302
0
        decoder_models[target_level].status == DECODER_MODEL_OK) {
303
0
      DECODER_MODEL_STATUS status = av1_decoder_model_try_smooth_buf(
304
0
          cpi, rc->projected_frame_size, &decoder_models[target_level]);
305
306
0
      if ((status == SMOOTHING_BUFFER_UNDERFLOW ||
307
0
           status == SMOOTHING_BUFFER_OVERFLOW) &&
308
0
          *q < rc->worst_quality) {
309
0
        *q = AOMMIN(*q + 10, rc->worst_quality);
310
0
        *q_low = AOMMAX(*q, *q_low);
311
0
        *q_high = AOMMAX(*q, *q_high);
312
0
        *loop = 1;
313
0
        return;
314
0
      }
315
0
    }
316
0
  }
317
318
0
  if (rc_cfg->mode == AOM_Q) return;
319
320
0
  const int last_q = *q;
321
0
  int frame_over_shoot_limit = 0, frame_under_shoot_limit = 0;
322
0
  av1_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
323
0
                                   &frame_under_shoot_limit,
324
0
                                   &frame_over_shoot_limit);
325
0
  if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
326
327
0
  if (cm->current_frame.frame_type == KEY_FRAME &&
328
0
      p_rc->this_key_frame_forced &&
329
0
      rc->projected_frame_size < rc->max_frame_bandwidth) {
330
0
    int64_t kf_err;
331
0
    const int64_t high_err_target = cpi->ambient_err;
332
0
    const int64_t low_err_target = cpi->ambient_err >> 1;
333
334
0
#if CONFIG_AV1_HIGHBITDEPTH
335
0
    if (cm->seq_params->use_highbitdepth) {
336
0
      kf_err = aom_highbd_get_y_sse(cpi->source, &cm->cur_frame->buf);
337
0
    } else {
338
0
      kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
339
0
    }
340
#else
341
    kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
342
#endif
343
    // Prevent possible divide by zero error below for perfect KF
344
0
    kf_err += !kf_err;
345
346
    // The key frame is not good enough or we can afford
347
    // to make it better without undue risk of popping.
348
0
    if ((kf_err > high_err_target &&
349
0
         rc->projected_frame_size <= frame_over_shoot_limit) ||
350
0
        (kf_err > low_err_target &&
351
0
         rc->projected_frame_size <= frame_under_shoot_limit)) {
352
      // Lower q_high
353
0
      *q_high = AOMMAX(*q - 1, *q_low);
354
355
      // Adjust Q
356
0
      *q = (int)((*q * high_err_target) / kf_err);
357
0
      *q = AOMMIN(*q, (*q_high + *q_low) >> 1);
358
0
    } else if (kf_err < low_err_target &&
359
0
               rc->projected_frame_size >= frame_under_shoot_limit) {
360
      // The key frame is much better than the previous frame
361
      // Raise q_low
362
0
      *q_low = AOMMIN(*q + 1, *q_high);
363
364
      // Adjust Q
365
0
      *q = (int)((*q * low_err_target) / kf_err);
366
0
      *q = AOMMIN(*q, (*q_high + *q_low + 1) >> 1);
367
0
    }
368
369
    // Clamp Q to upper and lower limits:
370
0
    *q = clamp(*q, *q_low, *q_high);
371
0
    *loop = (*q != last_q);
372
0
    return;
373
0
  }
374
375
0
  if (recode_loop_test(cpi, frame_over_shoot_limit, frame_under_shoot_limit, *q,
376
0
                       AOMMAX(*q_high, top_index), bottom_index)) {
377
    // Is the projected frame size out of range and are we allowed
378
    // to attempt to recode.
379
380
    // Frame size out of permitted range:
381
    // Update correction factor & compute new Q to try...
382
    // Frame is too large
383
0
    if (rc->projected_frame_size > rc->this_frame_target) {
384
      // Special case if the projected size is > the max allowed.
385
0
      if (*q == *q_high &&
386
0
          rc->projected_frame_size >= rc->max_frame_bandwidth) {
387
0
        const double q_val_high_current =
388
0
            av1_convert_qindex_to_q(*q_high, cm->seq_params->bit_depth);
389
0
        const double q_val_high_new =
390
0
            q_val_high_current *
391
0
            ((double)rc->projected_frame_size / rc->max_frame_bandwidth);
392
0
        *q_high = av1_find_qindex(q_val_high_new, cm->seq_params->bit_depth,
393
0
                                  rc->best_quality, rc->worst_quality);
394
0
      }
395
396
      // Raise Qlow as to at least the current value
397
0
      *q_low = AOMMIN(*q + 1, *q_high);
398
399
0
      if (*undershoot_seen || loop_count > 2 ||
400
0
          (loop_count == 2 && !frame_is_intra_only(cm))) {
401
0
        av1_rc_update_rate_correction_factors(cpi, 1, cm->width, cm->height);
402
403
0
        *q = (*q_high + *q_low + 1) / 2;
404
0
      } else if (loop_count == 2 && frame_is_intra_only(cm)) {
405
0
        const int q_mid = (*q_high + *q_low + 1) / 2;
406
0
        const int q_regulated = get_regulated_q_overshoot(
407
0
            cpi, 1, *q_low, *q_high, top_index, bottom_index);
408
        // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth
409
        // transition between loop_count < 2 and loop_count > 2.
410
0
        *q = (q_mid + q_regulated + 1) / 2;
411
0
      } else {
412
0
        *q = get_regulated_q_overshoot(cpi, 1, *q_low, *q_high, top_index,
413
0
                                       bottom_index);
414
0
      }
415
416
0
      *overshoot_seen = 1;
417
0
    } else {
418
      // Frame is too small
419
0
      *q_high = AOMMAX(*q - 1, *q_low);
420
421
0
      if (*overshoot_seen || loop_count > 2 ||
422
0
          (loop_count == 2 && !frame_is_intra_only(cm))) {
423
0
        av1_rc_update_rate_correction_factors(cpi, 1, cm->width, cm->height);
424
0
        *q = (*q_high + *q_low) / 2;
425
0
      } else if (loop_count == 2 && frame_is_intra_only(cm)) {
426
0
        const int q_mid = (*q_high + *q_low) / 2;
427
0
        const int q_regulated = get_regulated_q_undershoot(
428
0
            cpi, 1, *q_high, top_index, bottom_index);
429
        // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth
430
        // transition between loop_count < 2 and loop_count > 2.
431
0
        *q = (q_mid + q_regulated) / 2;
432
433
        // Special case reset for qlow for constrained quality.
434
        // This should only trigger where there is very substantial
435
        // undershoot on a frame and the auto cq level is above
436
        // the user passsed in value.
437
0
        if (rc_cfg->mode == AOM_CQ && q_regulated < *q_low) {
438
0
          *q_low = *q;
439
0
        }
440
0
      } else {
441
0
        *q = get_regulated_q_undershoot(cpi, 1, *q_high, top_index,
442
0
                                        bottom_index);
443
444
        // Special case reset for qlow for constrained quality.
445
        // This should only trigger where there is very substantial
446
        // undershoot on a frame and the auto cq level is above
447
        // the user passsed in value.
448
0
        if (rc_cfg->mode == AOM_CQ && *q < *q_low) {
449
0
          *q_low = *q;
450
0
        }
451
0
      }
452
453
0
      *undershoot_seen = 1;
454
0
    }
455
456
    // Clamp Q to upper and lower limits:
457
0
    *q = clamp(*q, *q_low, *q_high);
458
0
  }
459
460
0
  *loop = (*q != last_q);
461
0
}
Unexecuted instantiation: av1_cx_iface.c:recode_loop_update_q
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
462
#endif
463
464
#ifdef __cplusplus
465
}  // extern "C"
466
#endif
467
468
#endif  // AOM_AV1_ENCODER_RC_UTILS_H_