Coverage Report

Created: 2026-07-16 06:32

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
448
static uint8_t NOINLINE clamp_qp(SequenceControlSet* scs, int qp) {
50
448
    int qmin = scs->static_config.min_qp_allowed;
51
448
    int qmax = scs->static_config.max_qp_allowed;
52
448
    return (uint8_t)CLIP3(qmin, qmax, qp);
53
448
}
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
448
static void get_ref_intra_percentage(PictureControlSet* pcs, uint8_t* intra_perc) {
66
448
    assert(intra_perc != NULL);
67
448
    if (pcs->slice_type == I_SLICE) {
68
448
        *intra_perc = 100;
69
448
        return;
70
448
    }
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
448
static void get_ref_skip_percentage(PictureControlSet* pcs, uint8_t* skip_area) {
96
448
    assert(skip_area != NULL);
97
448
    if (pcs->slice_type == I_SLICE) {
98
448
        *skip_area = 0;
99
448
        return;
100
448
    }
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
448
static void get_ref_hp_percentage(PictureControlSet* pcs, int16_t* hp_area) {
118
448
    assert(hp_area != NULL);
119
448
    if (pcs->slice_type == I_SLICE) {
120
448
        *hp_area = -1;
121
448
        return;
122
448
    }
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
448
static void free_private_data_list(EbBufferHeaderType* p) {
144
448
    EbPrivDataNode* p_node = (EbPrivDataNode*)p->p_app_private;
145
448
    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
448
    p->p_app_private = NULL;
154
448
}
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
448
static void rate_control_context_dctor(EbPtr p) {
163
448
    EbThreadContext*    thread_ctx = (EbThreadContext*)p;
164
448
    RateControlContext* obj        = (RateControlContext*)thread_ctx->priv;
165
448
    EB_FREE_ARRAY(obj);
166
448
}
167
168
EbErrorType svt_aom_rate_control_context_ctor(EbThreadContext* thread_ctx, const EbEncHandle* enc_handle_ptr,
169
448
                                              int me_port_index) {
170
448
    RateControlContext* context_ptr;
171
448
    EB_CALLOC_ARRAY(context_ptr, 1);
172
448
    thread_ctx->priv  = context_ptr;
173
448
    thread_ctx->dctor = rate_control_context_dctor;
174
175
448
    context_ptr->rate_control_input_tasks_fifo_ptr = svt_system_resource_get_consumer_fifo(
176
448
        enc_handle_ptr->rate_control_tasks_resource_ptr, 0);
177
448
    context_ptr->rate_control_output_results_fifo_ptr = svt_system_resource_get_producer_fifo(
178
448
        enc_handle_ptr->rate_control_results_resource_ptr, 0);
179
448
    context_ptr->picture_decision_results_output_fifo_ptr = svt_system_resource_get_producer_fifo(
180
448
        enc_handle_ptr->picture_decision_results_resource_ptr, me_port_index);
181
182
448
    return EB_ErrorNone;
183
448
}
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
21.7k
static double def_kf_rd_multiplier(int qindex) {
361
21.7k
    return 3.3 + 0.0015 * qindex;
362
21.7k
}
363
364
21.7k
int svt_aom_compute_rd_mult_based_on_qindex(EbBitDepth bit_depth, SvtAv1FrameUpdateType update_type, int qindex) {
365
21.7k
    int     q = svt_aom_dc_quant_qtx(qindex, 0, bit_depth);
366
21.7k
    int64_t rdmult;
367
368
    // Scale rdmult based on frame type
369
21.7k
    if (update_type == SVT_AV1_KF_UPDATE) {
370
21.7k
        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
21.7k
    switch (bit_depth) {
378
10.8k
    case EB_EIGHT_BIT:
379
10.8k
        break;
380
10.8k
    case EB_TEN_BIT:
381
10.8k
        rdmult = ROUND_POWER_OF_TWO(rdmult, 4);
382
10.8k
        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
21.7k
    }
390
391
21.7k
    return rdmult > 0 ? (int)AOMMIN(rdmult, INT_MAX) : 1;
392
21.7k
}
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
33.6k
                              int64_t rdmult) {
400
33.6k
    PictureParentControlSet* ppcs       = pcs->ppcs;
401
33.6k
    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
33.6k
    uint8_t temporal_layer_index = ppcs->temporal_layer_index;
404
33.6k
    uint8_t max_temporal_layer   = ppcs->hierarchical_levels;
405
406
    // Update rdmult based on the frame's position in the miniGOP
407
33.6k
    uint8_t gf_update_type = frame_type == KEY_FRAME ? SVT_AV1_KF_UPDATE
408
33.6k
        : temporal_layer_index == 0                  ? SVT_AV1_ARF_UPDATE
409
0
        : temporal_layer_index < max_temporal_layer  ? SVT_AV1_INTNL_ARF_UPDATE
410
0
                                                     : SVT_AV1_LF_UPDATE;
411
33.6k
    rdmult                 = (rdmult * rd_frame_type_factor[bit_depth != EB_EIGHT_BIT][gf_update_type]) >> 7;
412
33.6k
    if (pcs->scs->static_config.rtc && frame_type == KEY_FRAME) {
413
0
        rdmult = (rdmult * RTC_KF_LAMBDA_BOOST) >> 7;
414
0
    }
415
33.6k
    if (pcs->scs->stats_based_sb_lambda_modulation) {
416
33.6k
        int factor = 128;
417
33.6k
        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
33.6k
        } 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
33.6k
        } else {
430
33.6k
            int qdiff = me_q_index - ppcs->frm_hdr.quantization_params.base_q_idx;
431
33.6k
            if (qdiff < 0) {
432
0
                factor = (qdiff <= -4) ? 100 : 115;
433
33.6k
            } else if (qdiff > 0) {
434
0
                factor = (qdiff <= 4) ? 135 : 150;
435
0
            }
436
33.6k
        }
437
438
33.6k
        rdmult = (rdmult * factor) >> 7;
439
33.6k
    }
440
33.6k
    return (uint32_t)rdmult;
441
33.6k
}
442
443
/*
444
 * Set the sse lambda based on the bit_depth, then update based on frame position.
445
 */
446
21.7k
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
21.7k
    int64_t rdmult = svt_aom_compute_rd_mult_based_on_qindex(bit_depth, pcs->ppcs->update_type, q_index);
449
450
21.7k
    return update_lambda(pcs, q_index, me_q_index, bit_depth, rdmult);
451
21.7k
}
452
453
uint32_t svt_aom_compute_fast_lambda(PictureControlSet* pcs, uint8_t q_index, uint8_t me_q_index,
454
11.8k
                                     EbBitDepth bit_depth) {
455
    // Always use q_index for the derivation of the initial rdmult (i.e. don't use me_q_index)
456
11.8k
    int64_t rdmult = bit_depth == EB_EIGHT_BIT ? av1_lambda_mode_decision8_bit_sad[q_index]
457
11.8k
                                               : av1lambda_mode_decision10_bit_sad[q_index];
458
459
11.8k
    return update_lambda(pcs, q_index, me_q_index, bit_depth, rdmult);
460
11.8k
}
461
462
void svt_aom_lambda_assign(PictureControlSet* pcs, uint32_t* fast_lambda, uint32_t* full_lambda, EbBitDepth bit_depth,
463
9.91k
                           uint8_t qp_index, bool multiply_lambda) {
464
9.91k
    if (bit_depth == EB_EIGHT_BIT) {
465
4.96k
        *full_lambda = svt_aom_compute_rd_mult(pcs, qp_index, qp_index, bit_depth);
466
4.96k
        *fast_lambda = av1_lambda_mode_decision8_bit_sad[qp_index];
467
4.96k
    } else if (bit_depth == EB_TEN_BIT) {
468
4.95k
        *full_lambda = svt_aom_compute_rd_mult(pcs, qp_index, qp_index, bit_depth);
469
4.95k
        *fast_lambda = av1lambda_mode_decision10_bit_sad[qp_index];
470
4.96k
        if (multiply_lambda) {
471
4.96k
            *full_lambda *= 16;
472
4.96k
            *fast_lambda *= 4;
473
4.96k
        }
474
4.95k
    } else if (bit_depth == EB_TWELVE_BIT) {
475
0
        *full_lambda = svt_aom_compute_rd_mult(pcs, qp_index, qp_index, bit_depth);
476
0
        *fast_lambda = av1lambda_mode_decision12_bit_sad[qp_index];
477
0
    } else {
478
0
        assert(0);
479
0
    }
480
481
    // NM: To be done: tune lambda based on the picture type and layer.
482
9.91k
    uint64_t scale_factor = pcs->scs->static_config.lambda_scale_factors[pcs->ppcs->update_type];
483
9.91k
    *full_lambda          = (uint32_t)((*full_lambda * scale_factor) >> 7);
484
9.91k
    *fast_lambda          = (uint32_t)((*fast_lambda * scale_factor) >> 7);
485
9.91k
}
486
487
0
void svt_av1_rc_init(SequenceControlSet* scs) {
488
0
    EncodeContext*  enc_ctx = scs->enc_ctx;
489
0
    RATE_CONTROL*   rc      = &enc_ctx->rc;
490
0
    RateControlCfg* rc_cfg  = &enc_ctx->rc_cfg;
491
0
    int             i;
492
0
    if (rc_cfg->mode == AOM_CBR) {
493
0
        rc->avg_frame_qindex[KEY_FRAME]   = rc_cfg->worst_allowed_q;
494
0
        rc->avg_frame_qindex[INTER_FRAME] = rc_cfg->worst_allowed_q;
495
0
        rc->last_q[KEY_FRAME]             = rc_cfg->worst_allowed_q;
496
0
        rc->last_q[INTER_FRAME]           = rc_cfg->worst_allowed_q;
497
0
    } else {
498
0
        rc->avg_frame_qindex[KEY_FRAME]   = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2;
499
0
        rc->avg_frame_qindex[INTER_FRAME] = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2;
500
0
        rc->last_q[KEY_FRAME]             = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2;
501
0
        rc->last_q[INTER_FRAME]           = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2;
502
0
    }
503
0
    rc->buffer_level    = rc->starting_buffer_level;
504
0
    rc->bits_off_target = rc->starting_buffer_level;
505
506
0
    rc->rolling_target_bits = rc->avg_frame_bandwidth;
507
0
    rc->rolling_actual_bits = rc->avg_frame_bandwidth;
508
0
    rc->total_actual_bits   = 0;
509
0
    rc->total_target_bits   = 0;
510
511
0
    rc->frames_since_key        = 8; // Sensible default for first frame.
512
0
    rc->frames_since_cdf_update = 0;
513
0
    rc->this_key_frame_forced   = 0;
514
0
    for (i = 0; i < MAX_TEMPORAL_LAYERS + 1; ++i) {
515
0
        rc->rate_correction_factors[i] = 0.7;
516
0
    }
517
0
    if (rc_cfg->mode != AOM_CBR) {
518
0
        rc->rate_correction_factors[KF_STD] = 1.0;
519
0
    }
520
0
    rc->baseline_gf_interval = 1 << scs->static_config.hierarchical_levels;
521
522
    // Set absolute upper and lower quality limits
523
0
    rc->worst_quality = rc_cfg->worst_allowed_q;
524
0
    rc->best_quality  = rc_cfg->best_allowed_q;
525
0
    if (rc_cfg->mode != AOM_Q) {
526
0
        double frame_rate = (double)scs->static_config.frame_rate_numerator /
527
0
            (double)scs->static_config.frame_rate_denominator;
528
        // Each frame can have a different duration, as the frame rate in the source
529
        // isn't guaranteed to be constant. The frame rate prior to the first frame
530
        // encoded in the second pass is a guess. However, the sum duration is not.
531
        // It is calculated based on the actual durations of all frames from the
532
        // first pass.
533
0
        svt_av1_new_framerate(scs, frame_rate);
534
0
    }
535
    // current and previous average base layer ME distortion
536
0
    rc->cur_avg_base_me_dist  = 0;
537
0
    rc->prev_avg_base_me_dist = 0;
538
0
    rc->avg_frame_low_motion  = 0;
539
0
}
540
541
/*********************************************************************************************
542
* Reset rate_control_param into default values
543
***********************************************************************************************/
544
0
static void rc_param_reset(RateControlIntervalParamContext* rc_param) {
545
0
    rc_param->size                     = -1;
546
0
    rc_param->processed_frame_number   = 0;
547
0
    rc_param->vbr_bits_off_target      = 0;
548
0
    rc_param->vbr_bits_off_target_fast = 0;
549
0
    rc_param->rate_error_estimate      = 0;
550
0
    rc_param->total_actual_bits        = 0;
551
0
    rc_param->total_target_bits        = 0;
552
0
    rc_param->extend_minq              = 0;
553
0
    rc_param->extend_maxq              = 0;
554
0
    rc_param->extend_minq_fast         = 0;
555
0
}
556
557
0
void svt_aom_update_rc_counts(PictureParentControlSet* ppcs) {
558
0
    SequenceControlSet* scs     = ppcs->scs;
559
0
    EncodeContext*      enc_ctx = scs->enc_ctx;
560
0
    RATE_CONTROL*       rc      = &enc_ctx->rc;
561
0
    if (ppcs->frm_hdr.showable_frame) {
562
        // If this is a show_existing_frame with a source other than altref,
563
        // or if it is not a displayed forward keyframe, the keyframe update
564
        // counters were incremented when it was originally encoded.
565
0
        rc->frames_since_key++;
566
0
        rc->frames_to_key--;
567
        // Reset whenever the CDF is updated for the current frame,
568
        // covering keyframes, warmup, scene changes, and periodic updates.
569
0
        if (ppcs->frm_hdr.disable_cdf_update == 0) {
570
0
            rc->frames_since_cdf_update = 0;
571
0
        } else {
572
0
            rc->frames_since_cdf_update++;
573
0
        }
574
0
    }
575
0
}
576
577
/****************************************************************************************
578
* reset_rc_param
579
* reset RC related variable in PPCS
580
*****************************************************************************************/
581
448
void reset_rc_param(PictureParentControlSet* ppcs) {
582
448
    ppcs->loop_count      = 0;
583
448
    ppcs->overshoot_seen  = 0;
584
448
    ppcs->undershoot_seen = 0;
585
448
}
586
587
/******************************************************
588
 * rc_init_frame_stats
589
 * Initializes frame statistics for rate control:
590
 * - Generates r0/beta values
591
 * - Initializes cyclic refresh
592
 * - Calculates reference frame statistics
593
 * - Calculates ME distortion
594
 * - Sets rate averaging period
595
 ******************************************************/
596
448
static void rc_init_frame_stats(PictureControlSet* pcs, SequenceControlSet* scs) {
597
448
    RATE_CONTROL*            rc   = &scs->enc_ctx->rc;
598
448
    PictureParentControlSet* ppcs = pcs->ppcs;
599
    // Get r0
600
448
    if (ppcs->r0_gen) {
601
0
        svt_aom_generate_r0beta(ppcs);
602
0
    }
603
604
    // Get reference frame statistics
605
448
    get_ref_intra_percentage(pcs, &pcs->ref_intra_percentage);
606
448
    get_ref_skip_percentage(pcs, &pcs->ref_skip_percentage);
607
448
    get_ref_hp_percentage(pcs, &pcs->ref_hp_percentage);
608
609
    // Set rate averaging period
610
448
    if (scs->passes > 1 && scs->static_config.max_bit_rate) {
611
0
        rc->rate_average_periodin_frames = (uint64_t)scs->twopass.stats_buf_ctx->total_stats->count;
612
448
    } else {
613
448
        rc->rate_average_periodin_frames = 60;
614
448
    }
615
448
    rc->rate_average_periodin_frames = MIN(rc->rate_average_periodin_frames, MAX_RATE_AVG_PERIOD);
616
617
    // Store the avg ME distortion
618
448
    if (ppcs->slice_type != I_SLICE) {
619
0
        rc->prev_avg_base_me_dist = rc->cur_avg_base_me_dist;
620
0
        uint64_t avg_me_dist      = 0;
621
0
        for (int b64_idx = 0; b64_idx < ppcs->b64_total_count; ++b64_idx) {
622
0
            avg_me_dist += ppcs->me_64x64_distortion[b64_idx];
623
0
        }
624
0
        avg_me_dist /= ppcs->b64_total_count;
625
0
        rc->cur_avg_base_me_dist = (uint32_t)avg_me_dist;
626
0
    }
627
448
}
628
629
// Calculate the number of bits to assign to boosted frames in a group.
630
0
int svt_av1_calculate_boost_bits(int frame_count, int boost, int64_t total_group_bits) {
631
0
    int allocation_chunks;
632
633
    // return 0 for invalid inputs (could arise e.g. through rounding errors)
634
0
    if (!boost || (total_group_bits <= 0)) {
635
0
        return 0;
636
0
    }
637
638
0
    if (frame_count <= 0) {
639
0
        return (int)(AOMMIN(total_group_bits, INT_MAX));
640
0
    }
641
642
0
    allocation_chunks = (frame_count * 100) + boost;
643
644
    // Prevent overflow.
645
0
    if (boost > 1023) {
646
0
        int divisor = boost >> 10;
647
0
        boost /= divisor;
648
0
        allocation_chunks /= divisor;
649
0
    }
650
651
    // Calculate the number of extra bits for use in the boosted frame or frames.
652
0
    return AOMMAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0);
653
0
}
654
655
/******************************************************
656
 * rc_handle_superres
657
 * Handles superres processing for 1-pass encoding:
658
 * - Determines superres parameters
659
 * - Re-initializes ME segments if needed
660
 * - Releases PA reference objects
661
 * Returns true if superres triggered (early exit needed)
662
 ******************************************************/
663
static bool rc_handle_superres(PictureControlSet* pcs, RateControlContext* context_ptr,
664
448
                               EbObjectWrapper* rate_control_tasks_wrapper_ptr) {
665
448
    PictureParentControlSet* ppcs = pcs->ppcs;
666
448
    SequenceControlSet*      scs  = pcs->scs;
667
668
448
    if (scs->static_config.pass != ENC_SINGLE_PASS) {
669
0
        return false;
670
0
    }
671
672
448
    if (scs->static_config.superres_mode <= SUPERRES_RANDOM) {
673
448
        return false;
674
448
    }
675
676
    // Determine denom and scale down picture by selected denom
677
0
    svt_aom_init_resize_picture(scs, ppcs);
678
0
    if (ppcs->frame_superres_enabled || ppcs->frame_resize_enabled) {
679
        // Reset gm based on super-res on/off
680
0
        bool super_res_off = ppcs->frame_superres_enabled == false && scs->static_config.resize_mode == RESIZE_NONE;
681
0
        svt_aom_set_gm_controls(ppcs, svt_aom_derive_gm_level(ppcs, super_res_off));
682
683
        // Initialize Segments as picture decision process
684
0
        ppcs->me_segments_completion_count = 0;
685
0
        ppcs->me_processed_b64_count       = 0;
686
687
0
        for (uint32_t segment_index = 0; segment_index < ppcs->me_segments_total_count; ++segment_index) {
688
            // Get Empty Results Object
689
0
            EbObjectWrapper* out_results_wrapper;
690
0
            svt_get_empty_object(context_ptr->picture_decision_results_output_fifo_ptr, &out_results_wrapper);
691
692
0
            PictureDecisionResults* out_results = (PictureDecisionResults*)out_results_wrapper->object_ptr;
693
0
            out_results->pcs_wrapper            = ppcs->p_pcs_wrapper_ptr;
694
0
            out_results->segment_index          = segment_index;
695
0
            out_results->task_type              = TASK_SUPERRES_RE_ME;
696
            // Post the Full Results Object
697
0
            svt_post_full_object(out_results_wrapper);
698
0
        }
699
700
        // Release Rate Control Tasks
701
0
        svt_release_object(rate_control_tasks_wrapper_ptr);
702
0
        return true; // Signal early exit
703
0
    }
704
705
    // PA ref objs are no longer needed if super-res isn't performed on current frame
706
0
    if (ppcs->tpl_ctrls.enable) {
707
0
        if (ppcs->temporal_layer_index == 0) {
708
0
            for (uint32_t i = 0; i < ppcs->tpl_group_size; i++) {
709
0
                if (svt_aom_is_incomp_mg_frame(ppcs->tpl_group[i])) {
710
0
                    if (ppcs->tpl_group[i]->ext_mg_id == ppcs->ext_mg_id + 1) {
711
0
                        svt_aom_release_pa_reference_objects(scs, ppcs->tpl_group[i]);
712
0
                    }
713
0
                } else {
714
0
                    if (ppcs->tpl_group[i]->ext_mg_id == ppcs->ext_mg_id) {
715
0
                        svt_aom_release_pa_reference_objects(scs, ppcs->tpl_group[i]);
716
0
                    }
717
0
                }
718
0
            }
719
0
        }
720
0
    } else {
721
0
        svt_aom_release_pa_reference_objects(scs, ppcs);
722
0
    }
723
724
0
    return false;
725
0
}
726
727
448
static void generate_sb_qindex(PictureControlSet* pcs) {
728
448
    PictureParentControlSet* ppcs = pcs->ppcs;
729
448
    SequenceControlSet*      scs  = pcs->scs;
730
731
448
    svt_av1_rc_init_sb_qindex(pcs, scs);
732
733
448
    if (ppcs->frm_hdr.delta_q_params.delta_q_present && ppcs->frm_hdr.delta_q_params.delta_q_res != 1) {
734
        // adjust delta q res and normalize superblock delta q values to reduce signaling overhead
735
0
        svt_av1_normalize_sb_delta_q(pcs);
736
0
    }
737
738
    // Derive a QP per 64x64 using ME distortions (to be used for lambda modulation only; not at Q/Q-1)
739
448
    if (scs->stats_based_sb_lambda_modulation) {
740
448
        svt_av1_generate_b64_me_qindex_map(pcs);
741
448
    }
742
448
}
743
744
// Process packetization feedback: update RC parameters and release resources.
745
static void rc_process_packetization_feedback(PictureParentControlSet* ppcs,
746
448
                                              const EbObjectWrapper* restrict rate_control_tasks_wrapper_ptr) {
747
448
    SequenceControlSet* scs      = ppcs->scs;
748
448
    RateControlTasks*   rc_tasks = (RateControlTasks*)rate_control_tasks_wrapper_ptr->object_ptr;
749
750
    // Prevent double counting frames with overlay
751
448
    if (!ppcs->is_overlay) {
752
448
        svt_block_on_mutex(scs->enc_ctx->rc_param_queue_mutex);
753
448
        ppcs->rate_control_param_ptr->processed_frame_number++;
754
755
        // check if all the frames in the interval have arrived
756
448
        if (ppcs->rate_control_param_ptr->size == ppcs->rate_control_param_ptr->processed_frame_number) {
757
0
            rc_param_reset(ppcs->rate_control_param_ptr);
758
0
        }
759
448
        svt_release_mutex(scs->enc_ctx->rc_param_queue_mutex);
760
448
    }
761
762
448
    if (scs->enc_ctx->rc_cfg.mode == AOM_Q) {
763
        // Queue variables
764
448
        if (scs->static_config.max_bit_rate) {
765
0
            svt_av1_coded_frames_stat_calc(ppcs);
766
0
        }
767
448
    } else {
768
0
        if (use_rtc_cbr_path(scs)) {
769
0
            svt_av1_rc_postencode_update_rtc_cbr(ppcs);
770
0
        } else {
771
0
            if (scs->static_config.gop_constraint_rc) {
772
0
                svt_av1_rc_postencode_update_gop_const(ppcs);
773
                // Qindex calculating
774
0
                if (scs->enc_ctx->rc_cfg.mode == AOM_VBR) {
775
0
                    svt_av1_twopass_postencode_update_gop_const(ppcs);
776
0
                }
777
0
            } else {
778
0
                svt_av1_rc_postencode_update(ppcs);
779
                // Qindex calculating
780
0
                if (scs->enc_ctx->rc_cfg.mode == AOM_VBR) {
781
0
                    svt_av1_twopass_postencode_update(ppcs);
782
0
                }
783
0
            }
784
0
        }
785
0
        svt_aom_update_rc_counts(ppcs);
786
0
    }
787
788
    // Release the ParentPictureControlSet
789
448
    if (ppcs->y8b_wrapper) {
790
        // y8b needs to get decremented at the same time of regular input
791
448
        svt_release_object(ppcs->y8b_wrapper);
792
448
    }
793
794
    // free private data list before release input picture buffer
795
448
    free_private_data_list((EbBufferHeaderType*)ppcs->input_pic_wrapper->object_ptr);
796
797
448
    svt_release_object(ppcs->input_pic_wrapper);
798
448
    svt_release_object(ppcs->scs_wrapper);
799
448
    svt_release_object(rc_tasks->pcs_wrapper);
800
448
}
801
802
1.34k
EbErrorType svt_aom_rate_control_kernel_iter(void* context) {
803
1.34k
    RateControlContext* context_ptr = (RateControlContext*)context;
804
805
1.34k
    SequenceControlSet*      scs  = NULL;
806
1.34k
    PictureControlSet*       pcs  = NULL;
807
1.34k
    PictureParentControlSet* ppcs = NULL;
808
809
    // Get RateControl Task
810
1.34k
    EbObjectWrapper* rate_control_tasks_wrapper_ptr;
811
1.34k
    EB_GET_FULL_OBJECT(context_ptr->rate_control_input_tasks_fifo_ptr, &rate_control_tasks_wrapper_ptr);
812
813
896
    RateControlTasks*    rc_tasks                = (RateControlTasks*)rate_control_tasks_wrapper_ptr->object_ptr;
814
896
    RateControlTaskTypes task_type               = rc_tasks->task_type;
815
896
    bool                 is_superres_recode_task = (task_type == RC_INPUT_SUPERRES_RECODE) ? true : false;
816
817
    // Modify these for different temporal layers later
818
896
    switch (task_type) {
819
0
    case RC_INPUT_SUPERRES_RECODE:
820
        // intentionally reuse code in RC_INPUT
821
448
    case RC_INPUT:
822
448
        pcs  = (PictureControlSet*)rc_tasks->pcs_wrapper->object_ptr;
823
448
        ppcs = pcs->ppcs;
824
448
        scs  = pcs->scs;
825
826
        // A superres recode task is only generated for the modes that run the
827
        // recode loop. Checked here (not in the RC_INPUT_SUPERRES_RECODE label)
828
        // because scs is not resolved until this point.
829
448
        assert(!is_superres_recode_task || scs->static_config.superres_mode == SUPERRES_QTHRESH ||
830
448
               scs->static_config.superres_mode == SUPERRES_AUTO);
831
832
448
        rc_init_frame_stats(pcs, scs);
833
834
448
        if (!is_superres_recode_task) {
835
448
            ppcs->blk_lambda_tuning = false;
836
448
        }
837
448
        reset_rc_param(ppcs);
838
839
448
        if (ppcs->is_overlay) {
840
            // overlay: ppcs->picture_qp has been updated by altref RC_INPUT
841
448
        } else {
842
448
            if (scs->enc_ctx->rc_cfg.mode == AOM_Q) {
843
448
                svt_av1_rc_calc_qindex_crf_cqp(pcs, scs);
844
448
                svt_aom_setup_segmentation(pcs, scs);
845
448
            } else if (use_rtc_cbr_path(scs)) {
846
0
                svt_av1_rc_calc_qindex_rtc_cbr(pcs);
847
0
            } else {
848
0
                if (!is_superres_recode_task) {
849
0
                    svt_av1_rc_process_rate_allocation(pcs, scs);
850
0
                }
851
0
                svt_av1_rc_calc_qindex_rate_control(pcs, scs);
852
0
            }
853
448
            ppcs->picture_qp = clamp_qp(scs, (ppcs->frm_hdr.quantization_params.base_q_idx + 2) >> 2);
854
448
        }
855
856
448
        if (ppcs->is_alt_ref) {
857
            // overlay use the same QP with alt_ref, to align with
858
            // rate_control_param_queue update code in below RC_PACKETIZATION_FEEDBACK_RESULT.
859
0
            PictureParentControlSet* overlay_ppcs     = ppcs->overlay_ppcs_ptr;
860
0
            overlay_ppcs->picture_qp                  = ppcs->picture_qp;
861
0
            overlay_ppcs->frm_hdr.quantization_params = ppcs->frm_hdr.quantization_params;
862
0
        }
863
864
448
        if (!is_superres_recode_task) {
865
448
            if (rc_handle_superres(pcs, context_ptr, rate_control_tasks_wrapper_ptr)) {
866
0
                break;
867
0
            }
868
448
        }
869
870
448
        generate_sb_qindex(pcs);
871
872
        // Get Empty Rate Control Results Buffer
873
448
        EbObjectWrapper* rc_results_wrapper;
874
448
        svt_get_empty_object(context_ptr->rate_control_output_results_fifo_ptr, &rc_results_wrapper);
875
448
        RateControlResults* rc_results = (RateControlResults*)rc_results_wrapper->object_ptr;
876
448
        rc_results->pcs_wrapper        = rc_tasks->pcs_wrapper;
877
448
        rc_results->superres_recode    = is_superres_recode_task;
878
879
        // Post Full Rate Control Results
880
448
        svt_post_full_object(rc_results_wrapper);
881
882
        // Release Rate Control Tasks
883
448
        svt_release_object(rate_control_tasks_wrapper_ptr);
884
885
448
        break;
886
887
448
    case RC_PACKETIZATION_FEEDBACK_RESULT:
888
448
        ppcs = (PictureParentControlSet*)rc_tasks->pcs_wrapper->object_ptr;
889
448
        scs  = ppcs->scs;
890
891
448
        rc_process_packetization_feedback(ppcs, rate_control_tasks_wrapper_ptr);
892
893
        // Release Rate Control Tasks
894
448
        svt_release_object(rate_control_tasks_wrapper_ptr);
895
448
        break;
896
897
0
    default:
898
0
        pcs = (PictureControlSet*)rc_tasks->pcs_wrapper->object_ptr;
899
0
        scs = pcs->scs;
900
901
0
        break;
902
896
    }
903
896
    return EB_ErrorNone;
904
896
}
905
906
448
void* svt_aom_rate_control_kernel(void* input_ptr) {
907
448
    EbThreadContext* thread_ctx = (EbThreadContext*)input_ptr;
908
1.34k
    for (;;) {
909
1.34k
        EbErrorType err = svt_aom_rate_control_kernel_iter(thread_ctx->priv);
910
1.34k
        if (err == EB_NoErrorFifoShutdown) {
911
448
            return NULL;
912
448
        }
913
1.34k
    }
914
0
    return NULL;
915
448
}