Coverage Report

Created: 2026-07-30 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/svt-av1/Source/Lib/Codec/rc_process.c
Line
Count
Source
1
/*
2
* Copyright(c) 2019 Intel Corporation
3
* Copyright (c) 2016, Alliance for Open Media. All rights reserved
4
*
5
* This source code is subject to the terms of the BSD 3-Clause Clear License and
6
* the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear License
7
* was not distributed with this source code in the LICENSE file, you can
8
* obtain it at https://www.aomedia.org/license. If the Alliance for Open
9
* Media Patent License 1.0 was not distributed with this source code in the
10
* PATENTS file, you can obtain it at https://www.aomedia.org/license/patent-license.
11
*/
12
#include <stdlib.h>
13
14
#include "definitions.h"
15
#include "enc_handle.h"
16
#include "rc_process.h"
17
#include "sequence_control_set.h"
18
#include "pcs.h"
19
#include "utility.h"
20
21
#include "rc_results.h"
22
#include "rc_tasks.h"
23
24
#include "svt_log.h"
25
#include "rd_cost.h"
26
#include "lambda_rate_tables.h"
27
#include "pass2_strategy.h"
28
#include "segmentation.h"
29
30
#include "pd_results.h"
31
#include "src_ops_process.h"
32
#include "enc_mode_config.h"
33
34
0
static bool use_rtc_cbr_path(SequenceControlSet* scs) {
35
0
    return scs->enc_ctx->rc_cfg.mode == AOM_CBR && scs->static_config.rtc;
36
0
}
37
38
// Specifies the weights of the ref frame in calculating qindex of non base layer frames
39
const int svt_av1_non_base_qindex_weight_ref[EB_MAX_TEMPORAL_LAYERS] = {100, 100, 100, 100, 100, 100};
40
// Specifies the weights of the worst quality in calculating qindex of non base layer frames
41
const int svt_av1_non_base_qindex_weight_wq[EB_MAX_TEMPORAL_LAYERS] = {100, 100, 300, 100, 100, 100};
42
43
const double svt_av1_tpl_hl_islice_div_factor[EB_MAX_TEMPORAL_LAYERS]     = {1, 2, 2, 1, 1, 0.7};
44
const double svt_av1_tpl_hl_base_frame_div_factor[EB_MAX_TEMPORAL_LAYERS] = {1, 3, 3, 2, 1, 1};
45
46
const double svt_av1_r0_weight[3]                = {0.75 /* I_SLICE */, 0.9 /* BASE */, 1 /* NON-BASE */};
47
const double svt_av1_qp_scale_compress_weight[4] = {1, 1.125, 1.25, 1.375};
48
49
485
static uint8_t NOINLINE clamp_qp(SequenceControlSet* scs, int qp) {
50
485
    int qmin = scs->static_config.min_qp_allowed;
51
485
    int qmax = scs->static_config.max_qp_allowed;
52
485
    return (uint8_t)CLIP3(qmin, qmax, qp);
53
485
}
54
55
0
int svt_aom_frame_is_kf_gf_arf(PictureParentControlSet* ppcs) {
56
0
    return frame_is_intra_only(ppcs) || ppcs->update_type == SVT_AV1_ARF_UPDATE ||
57
0
        ppcs->update_type == SVT_AV1_GF_UPDATE;
58
0
}
59
60
0
static EbReferenceObject* get_ref_obj(PictureControlSet* pcs, RefList ref_list, int idx) {
61
0
    return pcs->ref_pic_ptr_array[ref_list][idx]->object_ptr;
62
0
}
63
64
// intra_perc will be set to the % of intra area in two nearest ref frames
65
485
static void get_ref_intra_percentage(PictureControlSet* pcs, uint8_t* intra_perc) {
66
485
    assert(intra_perc != NULL);
67
485
    if (pcs->slice_type == I_SLICE) {
68
485
        *intra_perc = 100;
69
485
        return;
70
485
    }
71
72
0
    uint8_t            iperc      = 0;
73
0
    uint8_t            ref_cnt    = 0;
74
0
    EbReferenceObject* ref_obj_l0 = get_ref_obj(pcs, REF_LIST_0, 0);
75
0
    if (ref_obj_l0->slice_type != I_SLICE) {
76
0
        iperc = ref_obj_l0->intra_coded_area;
77
0
        ref_cnt++;
78
0
    }
79
0
    if (pcs->slice_type == B_SLICE && pcs->ppcs->ref_list1_count_try) {
80
0
        EbReferenceObject* ref_obj_l1 = get_ref_obj(pcs, REF_LIST_1, 0);
81
0
        if (ref_obj_l1->slice_type != I_SLICE) {
82
0
            iperc += ref_obj_l1->intra_coded_area;
83
0
            ref_cnt++;
84
0
        }
85
0
    }
86
87
0
    if (ref_cnt) {
88
0
        *intra_perc = iperc / ref_cnt;
89
0
    } else {
90
0
        *intra_perc = 0;
91
0
    }
92
0
}
93
94
// skip_area will be set to the % of skipped area in two nearest ref frames
95
485
static void get_ref_skip_percentage(PictureControlSet* pcs, uint8_t* skip_area) {
96
485
    assert(skip_area != NULL);
97
485
    if (pcs->slice_type == I_SLICE) {
98
485
        *skip_area = 0;
99
485
        return;
100
485
    }
101
102
0
    uint8_t skip_perc = 0;
103
104
0
    EbReferenceObject* ref_obj_l0 = get_ref_obj(pcs, REF_LIST_0, 0);
105
0
    skip_perc += (ref_obj_l0->slice_type == I_SLICE) ? 0 : ref_obj_l0->skip_coded_area;
106
0
    if (pcs->slice_type == B_SLICE && pcs->ppcs->ref_list1_count_try) {
107
0
        EbReferenceObject* ref_obj_l1 = get_ref_obj(pcs, REF_LIST_1, 0);
108
0
        skip_perc += (ref_obj_l1->slice_type == I_SLICE) ? 0 : ref_obj_l1->skip_coded_area;
109
110
        // if have two frames, divide the skip_perc by 2 to get the avg skip area
111
0
        skip_perc >>= 1;
112
0
    }
113
0
    *skip_area = skip_perc;
114
0
}
115
116
// hp_area will be set to the % of hp area in two nearest ref frames
117
485
static void get_ref_hp_percentage(PictureControlSet* pcs, int16_t* hp_area) {
118
485
    assert(hp_area != NULL);
119
485
    if (pcs->slice_type == I_SLICE) {
120
485
        *hp_area = -1;
121
485
        return;
122
485
    }
123
124
0
    EbReferenceObject* ref_obj_l0 = get_ref_obj(pcs, REF_LIST_0, 0);
125
0
    int8_t             hp_perc_l0 = ref_obj_l0->slice_type == I_SLICE ? -1 : ref_obj_l0->hp_coded_area;
126
127
0
    int8_t hp_perc_l1 = -1;
128
0
    if (pcs->slice_type == B_SLICE && pcs->ppcs->ref_list1_count_try) {
129
0
        EbReferenceObject* ref_obj_l1 = get_ref_obj(pcs, REF_LIST_1, 0);
130
0
        hp_perc_l1                    = ref_obj_l1->slice_type == I_SLICE ? -1 : ref_obj_l1->hp_coded_area;
131
0
    }
132
0
    if (hp_perc_l0 == -1 && hp_perc_l1 == -1) {
133
0
        *hp_area = -1;
134
0
    } else if (hp_perc_l1 == -1) {
135
0
        *hp_area = hp_perc_l0;
136
0
    } else if (hp_perc_l0 == -1) {
137
0
        *hp_area = hp_perc_l1;
138
0
    } else {
139
0
        *hp_area = (hp_perc_l0 + hp_perc_l1) >> 1;
140
0
    }
141
0
}
142
143
485
static void free_private_data_list(EbBufferHeaderType* p) {
144
485
    EbPrivDataNode* p_node = (EbPrivDataNode*)p->p_app_private;
145
485
    while (p_node) {
146
0
        if (p_node->node_type != PRIVATE_DATA && p_node->node_type != ROI_MAP_EVENT) {
147
0
            EB_FREE(p_node->data);
148
0
        }
149
0
        EbPrivDataNode* p_tmp = p_node;
150
0
        p_node                = p_node->next;
151
0
        EB_FREE(p_tmp);
152
0
    }
153
485
    p->p_app_private = NULL;
154
485
}
155
156
typedef struct RateControlContext {
157
    EbFifo* rate_control_input_tasks_fifo_ptr;
158
    EbFifo* rate_control_output_results_fifo_ptr;
159
    EbFifo* picture_decision_results_output_fifo_ptr;
160
} RateControlContext;
161
162
485
static void rate_control_context_dctor(EbPtr p) {
163
485
    EbThreadContext*    thread_ctx = (EbThreadContext*)p;
164
485
    RateControlContext* obj        = (RateControlContext*)thread_ctx->priv;
165
485
    EB_FREE_ARRAY(obj);
166
485
}
167
168
EbErrorType svt_aom_rate_control_context_ctor(EbThreadContext* thread_ctx, const EbEncHandle* enc_handle_ptr,
169
485
                                              int me_port_index) {
170
485
    RateControlContext* context_ptr;
171
485
    EB_CALLOC_ARRAY(context_ptr, 1);
172
485
    thread_ctx->priv  = context_ptr;
173
485
    thread_ctx->dctor = rate_control_context_dctor;
174
175
485
    context_ptr->rate_control_input_tasks_fifo_ptr = svt_system_resource_get_consumer_fifo(
176
485
        enc_handle_ptr->rate_control_tasks_resource_ptr, 0);
177
485
    context_ptr->rate_control_output_results_fifo_ptr = svt_system_resource_get_producer_fifo(
178
485
        enc_handle_ptr->rate_control_results_resource_ptr, 0);
179
485
    context_ptr->picture_decision_results_output_fifo_ptr = svt_system_resource_get_producer_fifo(
180
485
        enc_handle_ptr->picture_decision_results_resource_ptr, me_port_index);
181
182
485
    return EB_ErrorNone;
183
485
}
184
185
512
double svt_av1_convert_qindex_to_q(int32_t qindex, EbBitDepth bit_depth) {
186
    // Convert the index to a real Q value (scaled down to match old Q values)
187
512
    switch (bit_depth) {
188
256
    case EB_EIGHT_BIT:
189
256
        return svt_aom_ac_quant_qtx(qindex, 0, bit_depth) / 4.0;
190
256
    case EB_TEN_BIT:
191
256
        return svt_aom_ac_quant_qtx(qindex, 0, bit_depth) / 16.0;
192
0
    case EB_TWELVE_BIT:
193
0
        return svt_aom_ac_quant_qtx(qindex, 0, bit_depth) / 64.0;
194
0
    default:
195
0
        assert(0 && "bit_depth should be EB_EIGHT_BIT, EB_TEN_BIT or EB_TWELVE_BIT");
196
0
        return -1.0;
197
512
    }
198
512
}
199
200
0
int32_t svt_av1_compute_qdelta(double qstart, double qtarget, EbBitDepth bit_depth) {
201
0
    int32_t start_index  = MAXQ;
202
0
    int32_t target_index = MAXQ;
203
0
    int32_t i;
204
205
    // Convert the average q value to an index.
206
0
    for (i = MINQ; i < MAXQ; ++i) {
207
0
        start_index = i;
208
0
        if (svt_av1_convert_qindex_to_q(i, bit_depth) >= qstart) {
209
0
            break;
210
0
        }
211
0
    }
212
213
    // Convert the q target to an index
214
0
    for (i = MINQ; i < MAXQ; ++i) {
215
0
        target_index = i;
216
0
        if (svt_av1_convert_qindex_to_q(i, bit_depth) >= qtarget) {
217
0
            break;
218
0
        }
219
0
    }
220
221
0
    return target_index - start_index;
222
0
}
223
224
// r0 (TPL rate ratio) is normally in (0, 1] but can be exactly 0 for a zero-distortion (flat/static)
225
// frame. Floor the divisor so factor/r0 stays finite: casting +inf to int is undefined behavior
226
// (UBSan: float-cast-overflow). 1e-6 keeps the largest boost well under INT_MAX.
227
#define R0_MIN_DIVISOR 1e-6
228
229
0
int svt_av1_get_cqp_kf_boost_from_r0(double r0, int frames_to_key, ResolutionRange input_resolution) {
230
0
    double factor;
231
0
    r0 = AOMMAX(r0, R0_MIN_DIVISOR);
232
    // when frames_to_key not available, it is set to -1. In this case the factor is set to average of min and max
233
0
    if (frames_to_key == -1) {
234
0
        factor = (10.0 + 4.0) / 2;
235
0
    } else {
236
0
        factor = sqrt((double)frames_to_key);
237
0
        factor = AOMMIN(factor, 10.0);
238
0
        factor = AOMMAX(factor, 4.0);
239
0
    }
240
    // calculate boost based on resolution
241
0
    return input_resolution <= INPUT_SIZE_720p_RANGE ? (int)rint(3 * (75.0 + 17.0 * factor) / r0)
242
0
                                                     : (int)rint(4 * (75.0 + 17.0 * factor) / r0);
243
0
}
244
245
0
int svt_av1_get_gfu_boost_from_r0_lap(double min_factor, double max_factor, double r0, int frames_to_key) {
246
0
    r0            = AOMMAX(r0, R0_MIN_DIVISOR);
247
0
    double factor = sqrt((double)frames_to_key);
248
0
    factor        = AOMMIN(factor, max_factor);
249
0
    factor        = AOMMAX(factor, min_factor);
250
0
    factor        = 200.0 + 10.0 * factor;
251
0
    return (int)rint(factor / r0);
252
0
}
253
254
int svt_av1_rc_bits_per_mb(FrameType frame_type, int qindex, double correction_factor, int bit_depth,
255
0
                           int is_screen_content_type) {
256
0
    double q = svt_av1_convert_qindex_to_q(qindex, bit_depth);
257
0
    int    enumerator;
258
0
    if (is_screen_content_type) {
259
0
        enumerator = (frame_type == KEY_FRAME) ? 1000000 : 750000;
260
0
    } else {
261
0
        enumerator = (frame_type == KEY_FRAME) ? 1400000 : 1000000;
262
0
    }
263
0
    assert(correction_factor <= MAX_BPB_FACTOR && correction_factor >= MIN_BPB_FACTOR);
264
265
    // q based adjustment to baseline enumerator
266
0
    return (int)(enumerator * correction_factor / q);
267
0
}
268
269
static int find_qindex_by_rate(int desired_bits_per_mb, int bit_depth, FrameType frame_type, int is_screen_content_type,
270
0
                               int best_qindex, int worst_qindex) {
271
0
    assert(best_qindex <= worst_qindex);
272
0
    int low  = best_qindex;
273
0
    int high = worst_qindex;
274
0
    while (low < high) {
275
0
        int mid             = (low + high) >> 1;
276
0
        int mid_bits_per_mb = svt_av1_rc_bits_per_mb(frame_type, mid, 1.0, bit_depth, is_screen_content_type);
277
0
        if (mid_bits_per_mb > desired_bits_per_mb) {
278
0
            low = mid + 1;
279
0
        } else {
280
0
            high = mid;
281
0
        }
282
0
    }
283
0
    assert(low == high);
284
0
    assert(svt_av1_rc_bits_per_mb(frame_type, low, 1.0, bit_depth, is_screen_content_type) <= desired_bits_per_mb ||
285
0
           low == worst_qindex);
286
0
    return low;
287
0
}
288
289
int svt_av1_compute_qdelta_by_rate(RATE_CONTROL* rc, FrameType frame_type, int qindex, double rate_target_ratio,
290
0
                                   int bit_depth, int is_screen_content_type) {
291
    // Look up the current projected bits per block for the base index
292
0
    int base_bits_per_mb = svt_av1_rc_bits_per_mb(frame_type, qindex, 1.0, bit_depth, is_screen_content_type);
293
294
    // Find the target bits per mb based on the base value and given ratio.
295
0
    int target_bits_per_mb = (int)(rate_target_ratio * base_bits_per_mb);
296
297
0
    int target_index = find_qindex_by_rate(
298
0
        target_bits_per_mb, bit_depth, frame_type, is_screen_content_type, rc->best_quality, rc->worst_quality);
299
0
    return target_index - qindex;
300
0
}
301
302
const double svt_av1_rate_factor_deltas[RATE_FACTOR_LEVELS] = {
303
    1.00, // INTER_NORMAL
304
    1.00, // INTER_LOW
305
    1.00, // INTER_HIGH
306
    1.50, // GF_ARF_LOW
307
    2.00, // GF_ARF_STD
308
    2.00, // KF_STD
309
};
310
311
const rate_factor_level svt_av1_rate_factor_levels[SVT_AV1_FRAME_UPDATE_TYPES] = {
312
    KF_STD, // KF_UPDATE
313
    INTER_NORMAL, // LF_UPDATE
314
    GF_ARF_STD, // GF_UPDATE
315
    GF_ARF_STD, // ARF_UPDATE
316
    INTER_NORMAL, // OVERLAY_UPDATE
317
    INTER_NORMAL, // INTNL_OVERLAY_UPDATE
318
    GF_ARF_LOW, // INTNL_ARF_UPDATE
319
};
320
321
0
int svt_av1_get_q_index_from_qstep_ratio(int leaf_qindex, double qstep_ratio, int bit_depth) {
322
0
    double leaf_qstep   = svt_aom_dc_quant_qtx(leaf_qindex, 0, bit_depth);
323
0
    double target_qstep = leaf_qstep * qstep_ratio;
324
0
    int    qindex;
325
0
    if (qstep_ratio < 1.0) {
326
0
        for (qindex = leaf_qindex; qindex > MINQ; --qindex) {
327
0
            double qstep = svt_aom_dc_quant_qtx(qindex, 0, bit_depth);
328
0
            if (qstep <= target_qstep) {
329
0
                break;
330
0
            }
331
0
        }
332
0
    } else {
333
0
        for (qindex = leaf_qindex; qindex <= MAXQ; ++qindex) {
334
0
            double qstep = svt_aom_dc_quant_qtx(qindex, 0, bit_depth);
335
0
            if (qstep >= target_qstep) {
336
0
                break;
337
0
            }
338
0
        }
339
0
    }
340
0
    return qindex;
341
0
}
342
343
// Returns the default rd multiplier for inter frames for a given qindex.
344
// The function here is a first pass estimate based on data from
345
// a previous Vizer run
346
0
static double def_inter_rd_multiplier(int qindex) {
347
0
    return 3.2 + 0.0015 * qindex;
348
0
}
349
350
// Returns the default rd multiplier for ARF/Golden Frames for a given qindex.
351
// The function here is a first pass estimate based on data from
352
// a previous Vizer run
353
0
static double def_arf_rd_multiplier(int qindex) {
354
0
    return 3.25 + 0.0015 * qindex;
355
0
}
356
357
// Returns the default rd multiplier for key frames for a given qindex.
358
// The function here is a first pass estimate based on data from
359
// a previous Vizer run
360
24.2k
static double def_kf_rd_multiplier(int qindex) {
361
24.2k
    return 3.3 + 0.0015 * qindex;
362
24.2k
}
363
364
24.2k
int svt_aom_compute_rd_mult_based_on_qindex(EbBitDepth bit_depth, SvtAv1FrameUpdateType update_type, int qindex) {
365
24.2k
    int     q = svt_aom_dc_quant_qtx(qindex, 0, bit_depth);
366
24.2k
    int64_t rdmult;
367
368
    // Scale rdmult based on frame type
369
24.2k
    if (update_type == SVT_AV1_KF_UPDATE) {
370
24.2k
        rdmult = (int64_t)(def_kf_rd_multiplier(q) * q * q);
371
18.4E
    } else if (update_type == SVT_AV1_GF_UPDATE || update_type == SVT_AV1_ARF_UPDATE) {
372
0
        rdmult = (int64_t)(def_arf_rd_multiplier(q) * q * q);
373
18.4E
    } else {
374
18.4E
        rdmult = (int64_t)(def_inter_rd_multiplier(q) * q * q);
375
18.4E
    }
376
377
24.2k
    switch (bit_depth) {
378
12.1k
    case EB_EIGHT_BIT:
379
12.1k
        break;
380
12.1k
    case EB_TEN_BIT:
381
12.1k
        rdmult = ROUND_POWER_OF_TWO(rdmult, 4);
382
12.1k
        break;
383
0
    case EB_TWELVE_BIT:
384
0
        rdmult = ROUND_POWER_OF_TWO(rdmult, 8);
385
0
        break;
386
0
    default:
387
0
        assert(0 && "bit_depth should be EB_EIGHT_BIT, EB_TEN_BIT or EB_TWELVE_BIT");
388
0
        return -1;
389
24.2k
    }
390
391
18.4E
    return rdmult > 0 ? (int)AOMMIN(rdmult, INT_MAX) : 1;
392
24.2k
}
393
394
static const int rd_frame_type_factor[2][SVT_AV1_FRAME_UPDATE_TYPES] = {{150, 180, 150, 150, 180, 180, 150},
395
                                                                        {128, 144, 128, 128, 144, 144, 128}};
396
0
#define RTC_KF_LAMBDA_BOOST 100
397
398
static uint32_t update_lambda(PictureControlSet* pcs, uint8_t q_index, uint8_t me_q_index, EbBitDepth bit_depth,
399
37.4k
                              int64_t rdmult) {
400
37.4k
    PictureParentControlSet* ppcs       = pcs->ppcs;
401
37.4k
    FrameType                frame_type = ppcs->frm_hdr.frame_type;
402
    // To set gf_update_type based on current TL vs. the max TL (e.g. for 5L, max TL is 4)
403
37.4k
    uint8_t temporal_layer_index = ppcs->temporal_layer_index;
404
37.4k
    uint8_t max_temporal_layer   = ppcs->hierarchical_levels;
405
406
    // Update rdmult based on the frame's position in the miniGOP
407
37.4k
    uint8_t gf_update_type = frame_type == KEY_FRAME ? SVT_AV1_KF_UPDATE
408
18.4E
        : temporal_layer_index == 0                  ? SVT_AV1_ARF_UPDATE
409
18.4E
        : temporal_layer_index < max_temporal_layer  ? SVT_AV1_INTNL_ARF_UPDATE
410
18.4E
                                                     : SVT_AV1_LF_UPDATE;
411
37.4k
    rdmult                 = (rdmult * rd_frame_type_factor[bit_depth != EB_EIGHT_BIT][gf_update_type]) >> 7;
412
37.4k
    if (pcs->scs->static_config.rtc && frame_type == KEY_FRAME) {
413
0
        rdmult = (rdmult * RTC_KF_LAMBDA_BOOST) >> 7;
414
0
    }
415
37.4k
    if (pcs->scs->stats_based_sb_lambda_modulation) {
416
37.4k
        int factor = 128;
417
37.4k
        if (pcs->scs->static_config.rtc) {
418
0
            int qdiff = me_q_index - ppcs->frm_hdr.quantization_params.base_q_idx;
419
0
            if (qdiff < 0) {
420
0
                factor = (qdiff <= -4) ? 100 : 115;
421
0
            }
422
37.4k
        } else if (ppcs->frm_hdr.delta_q_params.delta_q_present || ppcs->r0_delta_qp_md) {
423
0
            int qdiff = q_index - ppcs->frm_hdr.quantization_params.base_q_idx;
424
0
            if (qdiff < 0) {
425
0
                factor = (qdiff <= -8) ? 90 : 115;
426
0
            } else if (qdiff > 0) {
427
0
                factor = (qdiff <= 8) ? 135 : 150;
428
0
            }
429
37.4k
        } else {
430
37.4k
            int qdiff = me_q_index - ppcs->frm_hdr.quantization_params.base_q_idx;
431
37.4k
            if (qdiff < 0) {
432
0
                factor = (qdiff <= -4) ? 100 : 115;
433
37.4k
            } else if (qdiff > 0) {
434
0
                factor = (qdiff <= 4) ? 135 : 150;
435
0
            }
436
37.4k
        }
437
438
37.4k
        rdmult = (rdmult * factor) >> 7;
439
37.4k
    }
440
37.4k
    return (uint32_t)rdmult;
441
37.4k
}
442
443
/*
444
 * Set the sse lambda based on the bit_depth, then update based on frame position.
445
 */
446
24.2k
uint32_t svt_aom_compute_rd_mult(PictureControlSet* pcs, uint8_t q_index, uint8_t me_q_index, EbBitDepth bit_depth) {
447
    // Always use q_index for the derivation of the initial rdmult (i.e. don't use me_q_index)
448
24.2k
    int64_t rdmult = svt_aom_compute_rd_mult_based_on_qindex(bit_depth, pcs->ppcs->update_type, q_index);
449
450
24.2k
    return update_lambda(pcs, q_index, me_q_index, bit_depth, rdmult);
451
24.2k
}
452
453
uint32_t svt_aom_compute_fast_lambda(PictureControlSet* pcs, uint8_t q_index, uint8_t me_q_index,
454
13.1k
                                     EbBitDepth bit_depth) {
455
    // Always use q_index for the derivation of the initial rdmult (i.e. don't use me_q_index)
456
13.1k
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
457
13.1k
    int64_t rdmult = bit_depth == EB_EIGHT_BIT ? av1_lambda_mode_decision8_bit_sad[q_index]
458
13.1k
                                               : av1lambda_mode_decision10_bit_sad[q_index];
459
#else
460
    int64_t rdmult = av1_lambda_mode_decision8_bit_sad[q_index]; // RTC: 8-bit only
461
#endif
462
463
13.1k
    return update_lambda(pcs, q_index, me_q_index, bit_depth, rdmult);
464
13.1k
}
465
466
void svt_aom_lambda_assign(PictureControlSet* pcs, uint32_t* fast_lambda, uint32_t* full_lambda, EbBitDepth bit_depth,
467
11.1k
                           uint8_t qp_index, bool multiply_lambda) {
468
#if !CONFIG_ENABLE_HIGH_BIT_DEPTH
469
    (void)multiply_lambda; // only used by the 10/12-bit paths (compiled out in 8-bit RTC)
470
#endif
471
11.1k
    if (bit_depth == EB_EIGHT_BIT) {
472
5.55k
        *full_lambda = svt_aom_compute_rd_mult(pcs, qp_index, qp_index, bit_depth);
473
5.55k
        *fast_lambda = av1_lambda_mode_decision8_bit_sad[qp_index];
474
5.55k
    }
475
5.55k
#if CONFIG_ENABLE_HIGH_BIT_DEPTH
476
5.55k
    else if (bit_depth == EB_TEN_BIT) {
477
5.55k
        *full_lambda = svt_aom_compute_rd_mult(pcs, qp_index, qp_index, bit_depth);
478
5.55k
        *fast_lambda = av1lambda_mode_decision10_bit_sad[qp_index];
479
5.55k
        if (multiply_lambda) {
480
5.55k
            *full_lambda *= 16;
481
5.55k
            *fast_lambda *= 4;
482
5.55k
        }
483
5.55k
    } else if (bit_depth == EB_TWELVE_BIT) {
484
0
        *full_lambda = svt_aom_compute_rd_mult(pcs, qp_index, qp_index, bit_depth);
485
0
        *fast_lambda = av1lambda_mode_decision12_bit_sad[qp_index];
486
0
    }
487
0
#endif
488
0
    else {
489
0
        assert(0);
490
0
    }
491
492
    // NM: To be done: tune lambda based on the picture type and layer.
493
11.1k
    uint64_t scale_factor = pcs->scs->static_config.lambda_scale_factors[pcs->ppcs->update_type];
494
11.1k
    *full_lambda          = (uint32_t)((*full_lambda * scale_factor) >> 7);
495
11.1k
    *fast_lambda          = (uint32_t)((*fast_lambda * scale_factor) >> 7);
496
11.1k
}
497
498
0
void svt_av1_rc_init(SequenceControlSet* scs) {
499
0
    EncodeContext*  enc_ctx = scs->enc_ctx;
500
0
    RATE_CONTROL*   rc      = &enc_ctx->rc;
501
0
    RateControlCfg* rc_cfg  = &enc_ctx->rc_cfg;
502
0
    int             i;
503
0
    if (rc_cfg->mode == AOM_CBR) {
504
0
        rc->avg_frame_qindex[KEY_FRAME]   = rc_cfg->worst_allowed_q;
505
0
        rc->avg_frame_qindex[INTER_FRAME] = rc_cfg->worst_allowed_q;
506
0
        rc->last_q[KEY_FRAME]             = rc_cfg->worst_allowed_q;
507
0
        rc->last_q[INTER_FRAME]           = rc_cfg->worst_allowed_q;
508
0
    } else {
509
0
        rc->avg_frame_qindex[KEY_FRAME]   = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2;
510
0
        rc->avg_frame_qindex[INTER_FRAME] = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2;
511
0
        rc->last_q[KEY_FRAME]             = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2;
512
0
        rc->last_q[INTER_FRAME]           = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2;
513
0
    }
514
0
    rc->buffer_level    = rc->starting_buffer_level;
515
0
    rc->bits_off_target = rc->starting_buffer_level;
516
517
0
    rc->rolling_target_bits = rc->avg_frame_bandwidth;
518
0
    rc->rolling_actual_bits = rc->avg_frame_bandwidth;
519
0
    rc->total_actual_bits   = 0;
520
0
    rc->total_target_bits   = 0;
521
522
0
    rc->frames_since_key        = 8; // Sensible default for first frame.
523
0
    rc->frames_since_cdf_update = 0;
524
0
    rc->this_key_frame_forced   = 0;
525
0
    for (i = 0; i < MAX_TEMPORAL_LAYERS + 1; ++i) {
526
0
        rc->rate_correction_factors[i] = 0.7;
527
0
    }
528
0
    if (rc_cfg->mode != AOM_CBR) {
529
0
        rc->rate_correction_factors[KF_STD] = 1.0;
530
0
    }
531
0
    rc->baseline_gf_interval = 1 << scs->static_config.hierarchical_levels;
532
533
    // Set absolute upper and lower quality limits
534
0
    rc->worst_quality = rc_cfg->worst_allowed_q;
535
0
    rc->best_quality  = rc_cfg->best_allowed_q;
536
0
    if (rc_cfg->mode != AOM_Q) {
537
0
        double frame_rate = (double)scs->static_config.frame_rate_numerator /
538
0
            (double)scs->static_config.frame_rate_denominator;
539
        // Each frame can have a different duration, as the frame rate in the source
540
        // isn't guaranteed to be constant. The frame rate prior to the first frame
541
        // encoded in the second pass is a guess. However, the sum duration is not.
542
        // It is calculated based on the actual durations of all frames from the
543
        // first pass.
544
0
        svt_av1_new_framerate(scs, frame_rate);
545
0
    }
546
    // current and previous average base layer ME distortion
547
0
    rc->cur_avg_base_me_dist  = 0;
548
0
    rc->prev_avg_base_me_dist = 0;
549
0
    rc->avg_frame_low_motion  = 0;
550
0
}
551
552
/*********************************************************************************************
553
* Reset rate_control_param into default values
554
***********************************************************************************************/
555
0
static void rc_param_reset(RateControlIntervalParamContext* rc_param) {
556
0
    rc_param->size                     = -1;
557
0
    rc_param->processed_frame_number   = 0;
558
0
    rc_param->vbr_bits_off_target      = 0;
559
0
    rc_param->vbr_bits_off_target_fast = 0;
560
0
    rc_param->rate_error_estimate      = 0;
561
0
    rc_param->total_actual_bits        = 0;
562
0
    rc_param->total_target_bits        = 0;
563
0
    rc_param->extend_minq              = 0;
564
0
    rc_param->extend_maxq              = 0;
565
0
    rc_param->extend_minq_fast         = 0;
566
0
}
567
568
0
void svt_aom_update_rc_counts(PictureParentControlSet* ppcs) {
569
0
    SequenceControlSet* scs     = ppcs->scs;
570
0
    EncodeContext*      enc_ctx = scs->enc_ctx;
571
0
    RATE_CONTROL*       rc      = &enc_ctx->rc;
572
0
    if (ppcs->frm_hdr.showable_frame) {
573
        // If this is a show_existing_frame with a source other than altref,
574
        // or if it is not a displayed forward keyframe, the keyframe update
575
        // counters were incremented when it was originally encoded.
576
0
        rc->frames_since_key++;
577
0
        rc->frames_to_key--;
578
        // Reset whenever the CDF is updated for the current frame,
579
        // covering keyframes, warmup, scene changes, and periodic updates.
580
0
        if (ppcs->frm_hdr.disable_cdf_update == 0) {
581
0
            rc->frames_since_cdf_update = 0;
582
0
        } else {
583
0
            rc->frames_since_cdf_update++;
584
0
        }
585
0
    }
586
0
}
587
588
/****************************************************************************************
589
* reset_rc_param
590
* reset RC related variable in PPCS
591
*****************************************************************************************/
592
485
void reset_rc_param(PictureParentControlSet* ppcs) {
593
485
    ppcs->loop_count      = 0;
594
485
    ppcs->overshoot_seen  = 0;
595
485
    ppcs->undershoot_seen = 0;
596
485
}
597
598
/******************************************************
599
 * rc_init_frame_stats
600
 * Initializes frame statistics for rate control:
601
 * - Generates r0/beta values
602
 * - Initializes cyclic refresh
603
 * - Calculates reference frame statistics
604
 * - Calculates ME distortion
605
 * - Sets rate averaging period
606
 ******************************************************/
607
485
static void rc_init_frame_stats(PictureControlSet* pcs, SequenceControlSet* scs) {
608
485
    RATE_CONTROL*            rc   = &scs->enc_ctx->rc;
609
485
    PictureParentControlSet* ppcs = pcs->ppcs;
610
    // Get r0
611
485
    if (ppcs->r0_gen) {
612
0
        svt_aom_generate_r0beta(ppcs);
613
0
    }
614
615
    // Get reference frame statistics
616
485
    get_ref_intra_percentage(pcs, &pcs->ref_intra_percentage);
617
485
    get_ref_skip_percentage(pcs, &pcs->ref_skip_percentage);
618
485
    get_ref_hp_percentage(pcs, &pcs->ref_hp_percentage);
619
620
    // Set rate averaging period
621
485
    if (scs->passes > 1 && scs->static_config.max_bit_rate) {
622
0
        rc->rate_average_periodin_frames = (uint64_t)scs->twopass.stats_buf_ctx->total_stats->count;
623
485
    } else {
624
485
        rc->rate_average_periodin_frames = 60;
625
485
    }
626
485
    rc->rate_average_periodin_frames = MIN(rc->rate_average_periodin_frames, MAX_RATE_AVG_PERIOD);
627
628
    // Store the avg ME distortion
629
485
    if (ppcs->slice_type != I_SLICE) {
630
0
        rc->prev_avg_base_me_dist = rc->cur_avg_base_me_dist;
631
0
        uint64_t avg_me_dist      = 0;
632
0
        for (int b64_idx = 0; b64_idx < ppcs->b64_total_count; ++b64_idx) {
633
0
            avg_me_dist += ppcs->me_64x64_distortion[b64_idx];
634
0
        }
635
0
        avg_me_dist /= ppcs->b64_total_count;
636
0
        rc->cur_avg_base_me_dist = (uint32_t)avg_me_dist;
637
0
    }
638
485
}
639
640
// Calculate the number of bits to assign to boosted frames in a group.
641
0
int svt_av1_calculate_boost_bits(int frame_count, int boost, int64_t total_group_bits) {
642
0
    int allocation_chunks;
643
644
    // return 0 for invalid inputs (could arise e.g. through rounding errors)
645
0
    if (!boost || (total_group_bits <= 0)) {
646
0
        return 0;
647
0
    }
648
649
0
    if (frame_count <= 0) {
650
0
        return (int)(AOMMIN(total_group_bits, INT_MAX));
651
0
    }
652
653
0
    allocation_chunks = (frame_count * 100) + boost;
654
655
    // Prevent overflow.
656
0
    if (boost > 1023) {
657
0
        int divisor = boost >> 10;
658
0
        boost /= divisor;
659
0
        allocation_chunks /= divisor;
660
0
    }
661
662
    // Calculate the number of extra bits for use in the boosted frame or frames.
663
0
    return AOMMAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0);
664
0
}
665
666
/******************************************************
667
 * rc_handle_superres
668
 * Handles superres processing for 1-pass encoding:
669
 * - Determines superres parameters
670
 * - Re-initializes ME segments if needed
671
 * - Releases PA reference objects
672
 * Returns true if superres triggered (early exit needed)
673
 ******************************************************/
674
static bool rc_handle_superres(PictureControlSet* pcs, RateControlContext* context_ptr,
675
485
                               EbObjectWrapper* rate_control_tasks_wrapper_ptr) {
676
485
    PictureParentControlSet* ppcs = pcs->ppcs;
677
485
    SequenceControlSet*      scs  = pcs->scs;
678
679
485
    if (scs->static_config.pass != ENC_SINGLE_PASS) {
680
0
        return false;
681
0
    }
682
683
485
    if (scs->static_config.superres_mode <= SUPERRES_RANDOM) {
684
485
        return false;
685
485
    }
686
687
    // Determine denom and scale down picture by selected denom
688
0
    svt_aom_init_resize_picture(scs, ppcs);
689
0
    if (ppcs->frame_superres_enabled || ppcs->frame_resize_enabled) {
690
        // Reset gm based on super-res on/off
691
0
        bool super_res_off = ppcs->frame_superres_enabled == false && scs->static_config.resize_mode == RESIZE_NONE;
692
0
        svt_aom_set_gm_controls(ppcs, svt_aom_derive_gm_level(ppcs, super_res_off));
693
694
        // Initialize Segments as picture decision process
695
0
        ppcs->me_segments_completion_count = 0;
696
0
        ppcs->me_processed_b64_count       = 0;
697
698
0
        for (uint32_t segment_index = 0; segment_index < ppcs->me_segments_total_count; ++segment_index) {
699
            // Get Empty Results Object
700
0
            EbObjectWrapper* out_results_wrapper;
701
0
            svt_get_empty_object(context_ptr->picture_decision_results_output_fifo_ptr, &out_results_wrapper);
702
703
0
            PictureDecisionResults* out_results = (PictureDecisionResults*)out_results_wrapper->object_ptr;
704
0
            out_results->pcs_wrapper            = ppcs->p_pcs_wrapper_ptr;
705
0
            out_results->segment_index          = segment_index;
706
0
            out_results->task_type              = TASK_SUPERRES_RE_ME;
707
            // Post the Full Results Object
708
0
            svt_post_full_object(out_results_wrapper);
709
0
        }
710
711
        // Release Rate Control Tasks
712
0
        svt_release_object(rate_control_tasks_wrapper_ptr);
713
0
        return true; // Signal early exit
714
0
    }
715
716
    // PA ref objs are no longer needed if super-res isn't performed on current frame
717
0
    if (ppcs->tpl_ctrls.enable) {
718
0
        if (ppcs->temporal_layer_index == 0) {
719
0
            for (uint32_t i = 0; i < ppcs->tpl_group_size; i++) {
720
0
                if (svt_aom_is_incomp_mg_frame(ppcs->tpl_group[i])) {
721
0
                    if (ppcs->tpl_group[i]->ext_mg_id == ppcs->ext_mg_id + 1) {
722
0
                        svt_aom_release_pa_reference_objects(scs, ppcs->tpl_group[i]);
723
0
                    }
724
0
                } else {
725
0
                    if (ppcs->tpl_group[i]->ext_mg_id == ppcs->ext_mg_id) {
726
0
                        svt_aom_release_pa_reference_objects(scs, ppcs->tpl_group[i]);
727
0
                    }
728
0
                }
729
0
            }
730
0
        }
731
0
    } else {
732
0
        svt_aom_release_pa_reference_objects(scs, ppcs);
733
0
    }
734
735
0
    return false;
736
0
}
737
738
485
static void generate_sb_qindex(PictureControlSet* pcs) {
739
485
    PictureParentControlSet* ppcs = pcs->ppcs;
740
485
    SequenceControlSet*      scs  = pcs->scs;
741
742
485
    svt_av1_rc_init_sb_qindex(pcs, scs);
743
744
485
    if (ppcs->frm_hdr.delta_q_params.delta_q_present && ppcs->frm_hdr.delta_q_params.delta_q_res != 1) {
745
        // adjust delta q res and normalize superblock delta q values to reduce signaling overhead
746
0
        svt_av1_normalize_sb_delta_q(pcs);
747
0
    }
748
749
    // Derive a QP per 64x64 using ME distortions (to be used for lambda modulation only; not at Q/Q-1)
750
485
    if (scs->stats_based_sb_lambda_modulation) {
751
485
        svt_av1_generate_b64_me_qindex_map(pcs);
752
485
    }
753
485
}
754
755
// Process packetization feedback: update RC parameters and release resources.
756
static void rc_process_packetization_feedback(PictureParentControlSet* ppcs,
757
485
                                              const EbObjectWrapper* restrict rate_control_tasks_wrapper_ptr) {
758
485
    SequenceControlSet* scs      = ppcs->scs;
759
485
    RateControlTasks*   rc_tasks = (RateControlTasks*)rate_control_tasks_wrapper_ptr->object_ptr;
760
761
    // Prevent double counting frames with overlay
762
485
    if (!ppcs->is_overlay) {
763
485
        svt_block_on_mutex(scs->enc_ctx->rc_param_queue_mutex);
764
485
        ppcs->rate_control_param_ptr->processed_frame_number++;
765
766
        // check if all the frames in the interval have arrived
767
485
        if (ppcs->rate_control_param_ptr->size == ppcs->rate_control_param_ptr->processed_frame_number) {
768
0
            rc_param_reset(ppcs->rate_control_param_ptr);
769
0
        }
770
485
        svt_release_mutex(scs->enc_ctx->rc_param_queue_mutex);
771
485
    }
772
773
485
    if (scs->enc_ctx->rc_cfg.mode == AOM_Q) {
774
        // Queue variables
775
485
        if (scs->static_config.max_bit_rate) {
776
0
            svt_av1_coded_frames_stat_calc(ppcs);
777
0
        }
778
485
    } else {
779
0
        if (use_rtc_cbr_path(scs)) {
780
0
            svt_av1_rc_postencode_update_rtc_cbr(ppcs);
781
0
        } else {
782
0
            if (scs->static_config.gop_constraint_rc) {
783
0
                svt_av1_rc_postencode_update_gop_const(ppcs);
784
                // Qindex calculating
785
0
                if (scs->enc_ctx->rc_cfg.mode == AOM_VBR) {
786
0
                    svt_av1_twopass_postencode_update_gop_const(ppcs);
787
0
                }
788
0
            } else {
789
0
                svt_av1_rc_postencode_update(ppcs);
790
                // Qindex calculating
791
0
                if (scs->enc_ctx->rc_cfg.mode == AOM_VBR) {
792
0
                    svt_av1_twopass_postencode_update(ppcs);
793
0
                }
794
0
            }
795
0
        }
796
0
        svt_aom_update_rc_counts(ppcs);
797
0
    }
798
799
    // Release the ParentPictureControlSet
800
485
    if (ppcs->y8b_wrapper) {
801
        // y8b needs to get decremented at the same time of regular input
802
485
        svt_release_object(ppcs->y8b_wrapper);
803
485
    }
804
805
    // free private data list before release input picture buffer
806
485
    free_private_data_list((EbBufferHeaderType*)ppcs->input_pic_wrapper->object_ptr);
807
808
485
    svt_release_object(ppcs->input_pic_wrapper);
809
485
    svt_release_object(ppcs->scs_wrapper);
810
485
    svt_release_object(rc_tasks->pcs_wrapper);
811
485
}
812
813
1.45k
EbErrorType svt_aom_rate_control_kernel_iter(void* context) {
814
1.45k
    RateControlContext* context_ptr = (RateControlContext*)context;
815
816
1.45k
    SequenceControlSet*      scs  = NULL;
817
1.45k
    PictureControlSet*       pcs  = NULL;
818
1.45k
    PictureParentControlSet* ppcs = NULL;
819
820
    // Get RateControl Task
821
1.45k
    EbObjectWrapper* rate_control_tasks_wrapper_ptr;
822
1.45k
    EB_GET_FULL_OBJECT(context_ptr->rate_control_input_tasks_fifo_ptr, &rate_control_tasks_wrapper_ptr);
823
824
970
    RateControlTasks*    rc_tasks                = (RateControlTasks*)rate_control_tasks_wrapper_ptr->object_ptr;
825
970
    RateControlTaskTypes task_type               = rc_tasks->task_type;
826
970
    bool                 is_superres_recode_task = (task_type == RC_INPUT_SUPERRES_RECODE) ? true : false;
827
828
    // Modify these for different temporal layers later
829
970
    switch (task_type) {
830
0
    case RC_INPUT_SUPERRES_RECODE:
831
        // intentionally reuse code in RC_INPUT
832
485
    case RC_INPUT:
833
485
        pcs  = (PictureControlSet*)rc_tasks->pcs_wrapper->object_ptr;
834
485
        ppcs = pcs->ppcs;
835
485
        scs  = pcs->scs;
836
837
        // A superres recode task is only generated for the modes that run the
838
        // recode loop. Checked here (not in the RC_INPUT_SUPERRES_RECODE label)
839
        // because scs is not resolved until this point.
840
485
        assert(!is_superres_recode_task || scs->static_config.superres_mode == SUPERRES_QTHRESH ||
841
485
               scs->static_config.superres_mode == SUPERRES_AUTO);
842
843
485
        rc_init_frame_stats(pcs, scs);
844
845
485
        if (!is_superres_recode_task) {
846
485
            ppcs->blk_lambda_tuning = false;
847
485
        }
848
485
        reset_rc_param(ppcs);
849
850
485
        if (ppcs->is_overlay) {
851
            // overlay: ppcs->picture_qp has been updated by altref RC_INPUT
852
485
        } else {
853
485
            if (scs->enc_ctx->rc_cfg.mode == AOM_Q) {
854
485
                svt_av1_rc_calc_qindex_crf_cqp(pcs, scs);
855
485
                svt_aom_setup_segmentation(pcs, scs);
856
485
            } else if (use_rtc_cbr_path(scs)) {
857
0
                svt_av1_rc_calc_qindex_rtc_cbr(pcs);
858
0
            } else {
859
0
                if (!is_superres_recode_task) {
860
0
                    svt_av1_rc_process_rate_allocation(pcs, scs);
861
0
                }
862
0
                svt_av1_rc_calc_qindex_rate_control(pcs, scs);
863
0
            }
864
485
            ppcs->picture_qp = clamp_qp(scs, (ppcs->frm_hdr.quantization_params.base_q_idx + 2) >> 2);
865
485
        }
866
867
485
        if (ppcs->is_alt_ref) {
868
            // overlay use the same QP with alt_ref, to align with
869
            // rate_control_param_queue update code in below RC_PACKETIZATION_FEEDBACK_RESULT.
870
0
            PictureParentControlSet* overlay_ppcs     = ppcs->overlay_ppcs_ptr;
871
0
            overlay_ppcs->picture_qp                  = ppcs->picture_qp;
872
0
            overlay_ppcs->frm_hdr.quantization_params = ppcs->frm_hdr.quantization_params;
873
0
        }
874
875
485
        if (!is_superres_recode_task) {
876
485
            if (rc_handle_superres(pcs, context_ptr, rate_control_tasks_wrapper_ptr)) {
877
0
                break;
878
0
            }
879
485
        }
880
881
485
        generate_sb_qindex(pcs);
882
883
        // Get Empty Rate Control Results Buffer
884
485
        EbObjectWrapper* rc_results_wrapper;
885
485
        svt_get_empty_object(context_ptr->rate_control_output_results_fifo_ptr, &rc_results_wrapper);
886
485
        RateControlResults* rc_results = (RateControlResults*)rc_results_wrapper->object_ptr;
887
485
        rc_results->pcs_wrapper        = rc_tasks->pcs_wrapper;
888
485
        rc_results->superres_recode    = is_superres_recode_task;
889
890
        // Post Full Rate Control Results
891
485
        svt_post_full_object(rc_results_wrapper);
892
893
        // Release Rate Control Tasks
894
485
        svt_release_object(rate_control_tasks_wrapper_ptr);
895
896
485
        break;
897
898
485
    case RC_PACKETIZATION_FEEDBACK_RESULT:
899
485
        ppcs = (PictureParentControlSet*)rc_tasks->pcs_wrapper->object_ptr;
900
485
        scs  = ppcs->scs;
901
902
485
        rc_process_packetization_feedback(ppcs, rate_control_tasks_wrapper_ptr);
903
904
        // Release Rate Control Tasks
905
485
        svt_release_object(rate_control_tasks_wrapper_ptr);
906
485
        break;
907
908
0
    default:
909
0
        pcs = (PictureControlSet*)rc_tasks->pcs_wrapper->object_ptr;
910
0
        scs = pcs->scs;
911
912
0
        break;
913
970
    }
914
970
    return EB_ErrorNone;
915
970
}
916
917
485
void* svt_aom_rate_control_kernel(void* input_ptr) {
918
485
    EbThreadContext* thread_ctx = (EbThreadContext*)input_ptr;
919
1.45k
    for (;;) {
920
1.45k
        EbErrorType err = svt_aom_rate_control_kernel_iter(thread_ctx->priv);
921
1.45k
        if (err == EB_NoErrorFifoShutdown) {
922
485
            return NULL;
923
485
        }
924
1.45k
    }
925
0
    return NULL;
926
485
}