Coverage Report

Created: 2026-07-25 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aom/av1/encoder/rc_utils.h
Line
Count
Source
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
0
#if !CONFIG_REALTIME_ONLY
78
  // Also need to update cpi->ppi->twopass.bits_left.
79
0
  TWO_PASS *const twopass = &cpi->ppi->twopass;
80
0
  FIRSTPASS_STATS *stats = twopass->stats_buf_ctx->total_stats;
81
0
  if (stats != NULL)
82
0
    cpi->ppi->twopass.bits_left =
83
0
        (int64_t)(stats->duration * rc_cfg->target_bandwidth / 10000000.0);
84
0
#endif
85
86
  // Adjust max over-shoot percentage.
87
0
  rc_cfg->over_shoot_pct = 0;
88
89
  // Adjust max quantizer.
90
0
  rc_cfg->worst_allowed_q = 255;
91
92
  // Adjust number of tiles and tile columns to be under level limit.
93
0
  int max_tiles, max_tile_cols;
94
0
  av1_get_max_tiles_for_level(target_level, &max_tiles, &max_tile_cols);
95
0
  while (tile_cfg->tile_columns > 0 &&
96
0
         (1 << tile_cfg->tile_columns) > max_tile_cols) {
97
0
    --tile_cfg->tile_columns;
98
0
  }
99
0
  const int tile_cols = (1 << tile_cfg->tile_columns);
100
0
  while (tile_cfg->tile_rows > 0 &&
101
0
         tile_cols * (1 << tile_cfg->tile_rows) > max_tiles) {
102
0
    --tile_cfg->tile_rows;
103
0
  }
104
105
  // Adjust min compression ratio.
106
0
  const int still_picture = seq_params->still_picture;
107
0
  const double min_cr =
108
0
      av1_get_min_cr_for_level(target_level, tier, still_picture);
109
0
  rc_cfg->min_cr = AOMMAX(rc_cfg->min_cr, (unsigned int)(min_cr * 100));
110
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
111
112
#if !CONFIG_REALTIME_ONLY
113
114
/*!\brief Function to test for conditions that indicate we should loop
115
 * back and recode a frame.
116
 *
117
 * \ingroup rate_control
118
 *
119
 * \param[in]     cpi         Top-level encoder structure
120
 * \param[in]     high_limit  Upper rate threshold
121
 * \param[in]     low_limit   Lower rate threshold
122
 * \param[in]     q           Current q index
123
 * \param[in]     maxq        Maximum allowed q index
124
 * \param[in]     minq        Minimum allowed q index
125
 *
126
 * \return        Indicates if a recode is required.
127
 * \retval        1           Recode Required
128
 * \retval        0           No Recode required
129
 */
130
static inline int recode_loop_test(AV1_COMP *cpi, int high_limit, int low_limit,
131
0
                                   int q, int maxq, int minq) {
132
0
  const RATE_CONTROL *const rc = &cpi->rc;
133
0
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
134
0
  const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi);
135
0
  int force_recode = 0;
136
137
0
  if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
138
0
      (cpi->sf.hl_sf.recode_loop == ALLOW_RECODE) ||
139
0
      (frame_is_kfgfarf &&
140
0
       (cpi->sf.hl_sf.recode_loop == ALLOW_RECODE_KFARFGF))) {
141
    // TODO(agrange) high_limit could be greater than the scale-down threshold.
142
0
    if ((rc->projected_frame_size > high_limit && q < maxq) ||
143
0
        (rc->projected_frame_size < low_limit && q > minq)) {
144
0
      force_recode = 1;
145
0
    } else if (cpi->oxcf.rc_cfg.mode == AOM_CQ) {
146
      // Deal with frame undershoot and whether or not we are
147
      // below the automatically set cq level.
148
0
      if (q > oxcf->rc_cfg.cq_level &&
149
0
          rc->projected_frame_size <
150
0
              (((int64_t)rc->this_frame_target * 7) >> 3)) {
151
0
        force_recode = 1;
152
0
      }
153
0
    }
154
0
  }
155
0
  return force_recode;
156
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
157
158
static inline double av1_get_gfu_boost_projection_factor(double min_factor,
159
                                                         double max_factor,
160
0
                                                         int frame_count) {
161
0
  double factor = sqrt((double)frame_count);
162
0
  factor = AOMMIN(factor, max_factor);
163
0
  factor = AOMMAX(factor, min_factor);
164
0
  factor = (200.0 + 10.0 * factor);
165
0
  return factor;
166
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
167
168
static inline int get_gfu_boost_from_r0_lap(double min_factor,
169
                                            double max_factor, double r0,
170
0
                                            int frames_to_key) {
171
0
  double factor = av1_get_gfu_boost_projection_factor(min_factor, max_factor,
172
0
                                                      frames_to_key);
173
0
  const int boost = (int)rint(factor / r0);
174
0
  return boost;
175
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
176
177
0
static inline double av1_get_kf_boost_projection_factor(int frame_count) {
178
0
  double factor = sqrt((double)frame_count);
179
0
  factor = AOMMIN(factor, 10.0);
180
0
  factor = AOMMAX(factor, 4.0);
181
0
  factor = (75.0 + 14.0 * factor);
182
0
  return factor;
183
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
184
185
static inline int get_regulated_q_overshoot(AV1_COMP *const cpi,
186
                                            int is_encode_stage, int q_low,
187
                                            int q_high, int top_index,
188
0
                                            int bottom_index) {
189
0
  const AV1_COMMON *const cm = &cpi->common;
190
0
  const RATE_CONTROL *const rc = &cpi->rc;
191
192
0
  av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
193
0
                                        cm->height);
194
195
0
  int q_regulated =
196
0
      av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
197
0
                        AOMMAX(q_high, top_index), cm->width, cm->height);
198
199
0
  int retries = 0;
200
0
  while (q_regulated < q_low && retries < 10) {
201
0
    av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
202
0
                                          cm->height);
203
0
    q_regulated =
204
0
        av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
205
0
                          AOMMAX(q_high, top_index), cm->width, cm->height);
206
0
    retries++;
207
0
  }
208
0
  return q_regulated;
209
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
210
211
static inline int get_regulated_q_undershoot(AV1_COMP *const cpi,
212
                                             int is_encode_stage, int q_high,
213
0
                                             int top_index, int bottom_index) {
214
0
  const AV1_COMMON *const cm = &cpi->common;
215
0
  const RATE_CONTROL *const rc = &cpi->rc;
216
217
0
  av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
218
0
                                        cm->height);
219
0
  int q_regulated = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
220
0
                                      top_index, cm->width, cm->height);
221
222
0
  int retries = 0;
223
0
  while (q_regulated > q_high && retries < 10) {
224
0
    av1_rc_update_rate_correction_factors(cpi, is_encode_stage, cm->width,
225
0
                                          cm->height);
226
0
    q_regulated = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
227
0
                                    top_index, cm->width, cm->height);
228
0
    retries++;
229
0
  }
230
0
  return q_regulated;
231
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
232
233
/*!\brief Called after encode_with_recode_loop() has just encoded a frame.
234
 * This function works out whether we undershot or overshot our bitrate
235
 *  target and adjusts q as appropriate. It also decides whether or not
236
 *  we need to recode the frame to get closer to the target rate.
237
 *
238
 * \ingroup rate_control
239
 *
240
 * \param[in]     cpi             Top-level encoder structure
241
 * \param[out]    loop            Should we go around the recode loop again
242
 * \param[in,out] q               New q index value
243
 * \param[in,out] q_low           Low q index limit for this loop itteration
244
 * \param[in,out] q_high          High q index limit for this loop itteration
245
 * \param[in]     top_index       Max permited new value for q index
246
 * \param[in]     bottom_index    Min permited new value for q index
247
 * \param[in,out] undershoot_seen Have we seen undershoot on this frame
248
 * \param[in,out] overshoot_seen  Have we seen overshoot on this frame
249
 * \param[in,out] low_cr_seen     Have we previously trriggered recode
250
 *                                because the compression ration was less
251
 *                                than a given minimum threshold.
252
 * \param[in]     loop_count      Loop itterations so far.
253
 *
254
 */
255
static inline void recode_loop_update_q(
256
    AV1_COMP *const cpi, int *const loop, int *const q, int *const q_low,
257
    int *const q_high, const int top_index, const int bottom_index,
258
    int *const undershoot_seen, int *const overshoot_seen,
259
0
    int *const low_cr_seen, const int loop_count) {
260
0
  AV1_COMMON *const cm = &cpi->common;
261
0
  RATE_CONTROL *const rc = &cpi->rc;
262
0
  PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc;
263
0
  const RateControlCfg *const rc_cfg = &cpi->oxcf.rc_cfg;
264
0
  *loop = 0;
265
266
  // Special case for overlay frame.
267
0
  if (rc->is_src_frame_alt_ref &&
268
0
      rc->projected_frame_size < rc->max_frame_bandwidth)
269
0
    return;
270
271
0
  const int min_cr = rc_cfg->min_cr;
272
0
  if (min_cr > 0) {
273
0
    const double compression_ratio =
274
0
        av1_get_compression_ratio(cm, rc->projected_frame_size >> 3);
275
0
    const double target_cr = min_cr / 100.0;
276
0
    if (compression_ratio < target_cr) {
277
0
      *low_cr_seen = 1;
278
0
      if (*q < rc->worst_quality) {
279
0
        const double cr_ratio = target_cr / compression_ratio;
280
0
        const int projected_q = AOMMAX(*q + 1, (int)(*q * cr_ratio * cr_ratio));
281
0
        *q = AOMMIN(AOMMIN(projected_q, *q + 32), rc->worst_quality);
282
0
        *q_low = AOMMAX(*q, *q_low);
283
0
        *q_high = AOMMAX(*q, *q_high);
284
0
        *loop = 1;
285
0
      }
286
0
    }
287
0
    if (*low_cr_seen) return;
288
0
  }
289
290
0
  if (cpi->ppi->level_params.keep_level_stats &&
291
0
      !is_stat_generation_stage(cpi)) {
292
    // Initialize level info. at the beginning of each sequence.
293
0
    if (cm->current_frame.frame_type == KEY_FRAME &&
294
0
        cpi->ppi->gf_group.refbuf_state[cpi->gf_frame_index] == REFBUF_RESET) {
295
0
      av1_init_level_info(cpi);
296
0
    }
297
0
    const AV1LevelParams *const level_params = &cpi->ppi->level_params;
298
    // TODO(any): currently only checking operating point 0
299
0
    const AV1LevelInfo *const level_info = level_params->level_info[0];
300
0
    const DECODER_MODEL *const decoder_models = level_info->decoder_models;
301
0
    const AV1_LEVEL target_level = level_params->target_seq_level_idx[0];
302
303
0
    if (target_level < SEQ_LEVELS &&
304
0
        decoder_models[target_level].status == DECODER_MODEL_OK) {
305
0
      DECODER_MODEL_STATUS status = av1_decoder_model_try_smooth_buf(
306
0
          cpi, rc->projected_frame_size, &decoder_models[target_level]);
307
308
0
      if ((status == SMOOTHING_BUFFER_UNDERFLOW ||
309
0
           status == SMOOTHING_BUFFER_OVERFLOW) &&
310
0
          *q < rc->worst_quality) {
311
0
        *q = AOMMIN(*q + 10, rc->worst_quality);
312
0
        *q_low = AOMMAX(*q, *q_low);
313
0
        *q_high = AOMMAX(*q, *q_high);
314
0
        *loop = 1;
315
0
        return;
316
0
      }
317
0
    }
318
0
  }
319
320
0
  if (rc_cfg->mode == AOM_Q) return;
321
322
0
  const int last_q = *q;
323
0
  int frame_over_shoot_limit = 0, frame_under_shoot_limit = 0;
324
0
  av1_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
325
0
                                   &frame_under_shoot_limit,
326
0
                                   &frame_over_shoot_limit);
327
0
  if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
328
329
0
  if (cm->current_frame.frame_type == KEY_FRAME &&
330
0
      p_rc->this_key_frame_forced &&
331
0
      rc->projected_frame_size < rc->max_frame_bandwidth) {
332
0
    int64_t kf_err;
333
0
    const int64_t high_err_target = cpi->ambient_err;
334
0
    const int64_t low_err_target = cpi->ambient_err >> 1;
335
336
0
#if CONFIG_AV1_HIGHBITDEPTH
337
0
    if (cm->seq_params->use_highbitdepth) {
338
0
      kf_err = aom_highbd_get_y_sse(cpi->source, &cm->cur_frame->buf);
339
0
    } else {
340
0
      kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
341
0
    }
342
#else
343
    kf_err = aom_get_y_sse(cpi->source, &cm->cur_frame->buf);
344
#endif
345
    // Prevent possible divide by zero error below for perfect KF
346
0
    kf_err += !kf_err;
347
348
    // The key frame is not good enough or we can afford
349
    // to make it better without undue risk of popping.
350
0
    if ((kf_err > high_err_target &&
351
0
         rc->projected_frame_size <= frame_over_shoot_limit) ||
352
0
        (kf_err > low_err_target &&
353
0
         rc->projected_frame_size <= frame_under_shoot_limit)) {
354
      // Lower q_high
355
0
      *q_high = AOMMAX(*q - 1, *q_low);
356
357
      // Adjust Q
358
0
      *q = (int)((*q * high_err_target) / kf_err);
359
0
      *q = AOMMIN(*q, (*q_high + *q_low) >> 1);
360
0
    } else if (kf_err < low_err_target &&
361
0
               rc->projected_frame_size >= frame_under_shoot_limit) {
362
      // The key frame is much better than the previous frame
363
      // Raise q_low
364
0
      *q_low = AOMMIN(*q + 1, *q_high);
365
366
      // Adjust Q
367
0
      *q = (int)((*q * low_err_target) / kf_err);
368
0
      *q = AOMMIN(*q, (*q_high + *q_low + 1) >> 1);
369
0
    }
370
371
    // Clamp Q to upper and lower limits:
372
0
    *q = clamp(*q, *q_low, *q_high);
373
0
    *loop = (*q != last_q);
374
0
    return;
375
0
  }
376
377
0
  if (recode_loop_test(cpi, frame_over_shoot_limit, frame_under_shoot_limit, *q,
378
0
                       AOMMAX(*q_high, top_index), bottom_index)) {
379
    // Is the projected frame size out of range and are we allowed
380
    // to attempt to recode.
381
382
    // Frame size out of permitted range:
383
    // Update correction factor & compute new Q to try...
384
    // Frame is too large
385
0
    if (rc->projected_frame_size > rc->this_frame_target) {
386
      // Special case if the projected size is > the max allowed.
387
0
      if (*q == *q_high &&
388
0
          rc->projected_frame_size >= rc->max_frame_bandwidth) {
389
0
        const double q_val_high_current =
390
0
            av1_convert_qindex_to_q(*q_high, cm->seq_params->bit_depth);
391
0
        const double q_val_high_new =
392
0
            q_val_high_current *
393
0
            ((double)rc->projected_frame_size / rc->max_frame_bandwidth);
394
0
        *q_high = av1_find_qindex(q_val_high_new, cm->seq_params->bit_depth,
395
0
                                  rc->best_quality, rc->worst_quality);
396
0
      }
397
398
      // Raise Qlow as to at least the current value
399
0
      *q_low = AOMMIN(*q + 1, *q_high);
400
401
0
      if (*undershoot_seen || loop_count > 2 ||
402
0
          (loop_count == 2 && !frame_is_intra_only(cm))) {
403
0
        av1_rc_update_rate_correction_factors(cpi, 1, cm->width, cm->height);
404
405
0
        *q = (*q_high + *q_low + 1) / 2;
406
0
      } else if (loop_count == 2 && frame_is_intra_only(cm)) {
407
0
        const int q_mid = (*q_high + *q_low + 1) / 2;
408
0
        const int q_regulated = get_regulated_q_overshoot(
409
0
            cpi, 1, *q_low, *q_high, top_index, bottom_index);
410
        // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth
411
        // transition between loop_count < 2 and loop_count > 2.
412
0
        *q = (q_mid + q_regulated + 1) / 2;
413
0
      } else {
414
0
        *q = get_regulated_q_overshoot(cpi, 1, *q_low, *q_high, top_index,
415
0
                                       bottom_index);
416
0
      }
417
418
0
      *overshoot_seen = 1;
419
0
    } else {
420
      // Frame is too small
421
0
      *q_high = AOMMAX(*q - 1, *q_low);
422
423
0
      if (*overshoot_seen || loop_count > 2 ||
424
0
          (loop_count == 2 && !frame_is_intra_only(cm))) {
425
0
        av1_rc_update_rate_correction_factors(cpi, 1, cm->width, cm->height);
426
0
        *q = (*q_high + *q_low) / 2;
427
0
      } else if (loop_count == 2 && frame_is_intra_only(cm)) {
428
0
        const int q_mid = (*q_high + *q_low) / 2;
429
0
        const int q_regulated = get_regulated_q_undershoot(
430
0
            cpi, 1, *q_high, top_index, bottom_index);
431
        // Get 'q' in-between 'q_mid' and 'q_regulated' for a smooth
432
        // transition between loop_count < 2 and loop_count > 2.
433
0
        *q = (q_mid + q_regulated) / 2;
434
435
        // Special case reset for qlow for constrained quality.
436
        // This should only trigger where there is very substantial
437
        // undershoot on a frame and the auto cq level is above
438
        // the user passsed in value.
439
0
        if (rc_cfg->mode == AOM_CQ && q_regulated < *q_low) {
440
0
          *q_low = *q;
441
0
        }
442
0
      } else {
443
0
        *q = get_regulated_q_undershoot(cpi, 1, *q_high, top_index,
444
0
                                        bottom_index);
445
446
        // Special case reset for qlow for constrained quality.
447
        // This should only trigger where there is very substantial
448
        // undershoot on a frame and the auto cq level is above
449
        // the user passsed in value.
450
0
        if (rc_cfg->mode == AOM_CQ && *q < *q_low) {
451
0
          *q_low = *q;
452
0
        }
453
0
      }
454
455
0
      *undershoot_seen = 1;
456
0
    }
457
458
    // Clamp Q to upper and lower limits:
459
0
    *q = clamp(*q, *q_low, *q_high);
460
0
  }
461
462
0
  *loop = (*q != last_q);
463
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
464
#endif
465
466
#ifdef __cplusplus
467
}  // extern "C"
468
#endif
469
470
#endif  // AOM_AV1_ENCODER_RC_UTILS_H_