/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 | 474 | static uint8_t NOINLINE clamp_qp(SequenceControlSet* scs, int qp) { |
50 | 474 | int qmin = scs->static_config.min_qp_allowed; |
51 | 474 | int qmax = scs->static_config.max_qp_allowed; |
52 | 474 | return (uint8_t)CLIP3(qmin, qmax, qp); |
53 | 474 | } |
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 | 474 | static void get_ref_intra_percentage(PictureControlSet* pcs, uint8_t* intra_perc) { |
66 | 474 | assert(intra_perc != NULL); |
67 | 474 | if (pcs->slice_type == I_SLICE) { |
68 | 474 | *intra_perc = 100; |
69 | 474 | return; |
70 | 474 | } |
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 | 474 | static void get_ref_skip_percentage(PictureControlSet* pcs, uint8_t* skip_area) { |
96 | 474 | assert(skip_area != NULL); |
97 | 474 | if (pcs->slice_type == I_SLICE) { |
98 | 474 | *skip_area = 0; |
99 | 474 | return; |
100 | 474 | } |
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 | 474 | static void get_ref_hp_percentage(PictureControlSet* pcs, int16_t* hp_area) { |
118 | 474 | assert(hp_area != NULL); |
119 | 474 | if (pcs->slice_type == I_SLICE) { |
120 | 474 | *hp_area = -1; |
121 | 474 | return; |
122 | 474 | } |
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 | 474 | static void free_private_data_list(EbBufferHeaderType* p) { |
144 | 474 | EbPrivDataNode* p_node = (EbPrivDataNode*)p->p_app_private; |
145 | 474 | 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 | 474 | p->p_app_private = NULL; |
154 | 474 | } |
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 | | EbErrorType svt_aom_rate_control_coded_frames_stats_context_ctor(coded_frames_stats_entry* entry_ptr, |
163 | 948k | uint64_t picture_number) { |
164 | 948k | entry_ptr->picture_number = picture_number; |
165 | 948k | entry_ptr->frame_total_bit_actual = -1; |
166 | | |
167 | 948k | return EB_ErrorNone; |
168 | 948k | } |
169 | | |
170 | 474 | static void rate_control_context_dctor(EbPtr p) { |
171 | 474 | EbThreadContext* thread_ctx = (EbThreadContext*)p; |
172 | 474 | RateControlContext* obj = (RateControlContext*)thread_ctx->priv; |
173 | 474 | EB_FREE_ARRAY(obj); |
174 | 474 | } |
175 | | |
176 | | EbErrorType svt_aom_rate_control_context_ctor(EbThreadContext* thread_ctx, const EbEncHandle* enc_handle_ptr, |
177 | 474 | int me_port_index) { |
178 | 474 | RateControlContext* context_ptr; |
179 | 474 | EB_CALLOC_ARRAY(context_ptr, 1); |
180 | 474 | thread_ctx->priv = context_ptr; |
181 | 474 | thread_ctx->dctor = rate_control_context_dctor; |
182 | | |
183 | 474 | context_ptr->rate_control_input_tasks_fifo_ptr = svt_system_resource_get_consumer_fifo( |
184 | 474 | enc_handle_ptr->rate_control_tasks_resource_ptr, 0); |
185 | 474 | context_ptr->rate_control_output_results_fifo_ptr = svt_system_resource_get_producer_fifo( |
186 | 474 | enc_handle_ptr->rate_control_results_resource_ptr, 0); |
187 | 474 | context_ptr->picture_decision_results_output_fifo_ptr = svt_system_resource_get_producer_fifo( |
188 | 474 | enc_handle_ptr->picture_decision_results_resource_ptr, me_port_index); |
189 | | |
190 | 474 | return EB_ErrorNone; |
191 | 474 | } |
192 | | |
193 | 512 | double svt_av1_convert_qindex_to_q(int32_t qindex, EbBitDepth bit_depth) { |
194 | | // Convert the index to a real Q value (scaled down to match old Q values) |
195 | 512 | switch (bit_depth) { |
196 | 256 | case EB_EIGHT_BIT: |
197 | 256 | return svt_aom_ac_quant_qtx(qindex, 0, bit_depth) / 4.0; |
198 | 256 | case EB_TEN_BIT: |
199 | 256 | return svt_aom_ac_quant_qtx(qindex, 0, bit_depth) / 16.0; |
200 | 0 | case EB_TWELVE_BIT: |
201 | 0 | return svt_aom_ac_quant_qtx(qindex, 0, bit_depth) / 64.0; |
202 | 0 | default: |
203 | 0 | assert(0 && "bit_depth should be EB_EIGHT_BIT, EB_TEN_BIT or EB_TWELVE_BIT"); |
204 | 0 | return -1.0; |
205 | 512 | } |
206 | 512 | } |
207 | | |
208 | 0 | int32_t svt_av1_compute_qdelta(double qstart, double qtarget, EbBitDepth bit_depth) { |
209 | 0 | int32_t start_index = MAXQ; |
210 | 0 | int32_t target_index = MAXQ; |
211 | 0 | int32_t i; |
212 | | |
213 | | // Convert the average q value to an index. |
214 | 0 | for (i = MINQ; i < MAXQ; ++i) { |
215 | 0 | start_index = i; |
216 | 0 | if (svt_av1_convert_qindex_to_q(i, bit_depth) >= qstart) { |
217 | 0 | break; |
218 | 0 | } |
219 | 0 | } |
220 | | |
221 | | // Convert the q target to an index |
222 | 0 | for (i = MINQ; i < MAXQ; ++i) { |
223 | 0 | target_index = i; |
224 | 0 | if (svt_av1_convert_qindex_to_q(i, bit_depth) >= qtarget) { |
225 | 0 | break; |
226 | 0 | } |
227 | 0 | } |
228 | |
|
229 | 0 | return target_index - start_index; |
230 | 0 | } |
231 | | |
232 | 0 | int svt_av1_get_cqp_kf_boost_from_r0(double r0, int frames_to_key, ResolutionRange input_resolution) { |
233 | 0 | double factor; |
234 | | // when frames_to_key not available, it is set to -1. In this case the factor is set to average of min and max |
235 | 0 | if (frames_to_key == -1) { |
236 | 0 | factor = (10.0 + 4.0) / 2; |
237 | 0 | } else { |
238 | 0 | factor = sqrt((double)frames_to_key); |
239 | 0 | factor = AOMMIN(factor, 10.0); |
240 | 0 | factor = AOMMAX(factor, 4.0); |
241 | 0 | } |
242 | | // calculate boost based on resolution |
243 | 0 | return input_resolution <= INPUT_SIZE_720p_RANGE ? (int)rint(3 * (75.0 + 17.0 * factor) / r0) |
244 | 0 | : (int)rint(4 * (75.0 + 17.0 * factor) / r0); |
245 | 0 | } |
246 | | |
247 | 0 | int svt_av1_get_gfu_boost_from_r0_lap(double min_factor, double max_factor, double r0, int frames_to_key) { |
248 | 0 | double factor = sqrt((double)frames_to_key); |
249 | 0 | factor = AOMMIN(factor, max_factor); |
250 | 0 | factor = AOMMAX(factor, min_factor); |
251 | 0 | factor = 200.0 + 10.0 * factor; |
252 | 0 | return (int)rint(factor / r0); |
253 | 0 | } |
254 | | |
255 | | int svt_av1_rc_bits_per_mb(FrameType frame_type, int qindex, double correction_factor, int bit_depth, |
256 | 0 | int is_screen_content_type) { |
257 | 0 | double q = svt_av1_convert_qindex_to_q(qindex, bit_depth); |
258 | 0 | int enumerator; |
259 | 0 | if (is_screen_content_type) { |
260 | 0 | enumerator = (frame_type == KEY_FRAME) ? 1000000 : 750000; |
261 | 0 | } else { |
262 | 0 | enumerator = (frame_type == KEY_FRAME) ? 1400000 : 1000000; |
263 | 0 | } |
264 | 0 | assert(correction_factor <= MAX_BPB_FACTOR && correction_factor >= MIN_BPB_FACTOR); |
265 | | |
266 | | // q based adjustment to baseline enumerator |
267 | 0 | return (int)(enumerator * correction_factor / q); |
268 | 0 | } |
269 | | |
270 | | static int find_qindex_by_rate(int desired_bits_per_mb, int bit_depth, FrameType frame_type, int is_screen_content_type, |
271 | 0 | int best_qindex, int worst_qindex) { |
272 | 0 | assert(best_qindex <= worst_qindex); |
273 | 0 | int low = best_qindex; |
274 | 0 | int high = worst_qindex; |
275 | 0 | while (low < high) { |
276 | 0 | int mid = (low + high) >> 1; |
277 | 0 | int mid_bits_per_mb = svt_av1_rc_bits_per_mb(frame_type, mid, 1.0, bit_depth, is_screen_content_type); |
278 | 0 | if (mid_bits_per_mb > desired_bits_per_mb) { |
279 | 0 | low = mid + 1; |
280 | 0 | } else { |
281 | 0 | high = mid; |
282 | 0 | } |
283 | 0 | } |
284 | 0 | assert(low == high); |
285 | 0 | assert(svt_av1_rc_bits_per_mb(frame_type, low, 1.0, bit_depth, is_screen_content_type) <= desired_bits_per_mb || |
286 | 0 | low == worst_qindex); |
287 | 0 | return low; |
288 | 0 | } |
289 | | |
290 | | int svt_av1_compute_qdelta_by_rate(RATE_CONTROL* rc, FrameType frame_type, int qindex, double rate_target_ratio, |
291 | 0 | int bit_depth, int is_screen_content_type) { |
292 | | // Look up the current projected bits per block for the base index |
293 | 0 | int base_bits_per_mb = svt_av1_rc_bits_per_mb(frame_type, qindex, 1.0, bit_depth, is_screen_content_type); |
294 | | |
295 | | // Find the target bits per mb based on the base value and given ratio. |
296 | 0 | int target_bits_per_mb = (int)(rate_target_ratio * base_bits_per_mb); |
297 | |
|
298 | 0 | int target_index = find_qindex_by_rate( |
299 | 0 | target_bits_per_mb, bit_depth, frame_type, is_screen_content_type, rc->best_quality, rc->worst_quality); |
300 | 0 | return target_index - qindex; |
301 | 0 | } |
302 | | |
303 | | const double svt_av1_rate_factor_deltas[RATE_FACTOR_LEVELS] = { |
304 | | 1.00, // INTER_NORMAL |
305 | | 1.00, // INTER_LOW |
306 | | 1.00, // INTER_HIGH |
307 | | 1.50, // GF_ARF_LOW |
308 | | 2.00, // GF_ARF_STD |
309 | | 2.00, // KF_STD |
310 | | }; |
311 | | |
312 | | const rate_factor_level svt_av1_rate_factor_levels[SVT_AV1_FRAME_UPDATE_TYPES] = { |
313 | | KF_STD, // KF_UPDATE |
314 | | INTER_NORMAL, // LF_UPDATE |
315 | | GF_ARF_STD, // GF_UPDATE |
316 | | GF_ARF_STD, // ARF_UPDATE |
317 | | INTER_NORMAL, // OVERLAY_UPDATE |
318 | | INTER_NORMAL, // INTNL_OVERLAY_UPDATE |
319 | | GF_ARF_LOW, // INTNL_ARF_UPDATE |
320 | | }; |
321 | | |
322 | 0 | int svt_av1_get_q_index_from_qstep_ratio(int leaf_qindex, double qstep_ratio, int bit_depth) { |
323 | 0 | double leaf_qstep = svt_aom_dc_quant_qtx(leaf_qindex, 0, bit_depth); |
324 | 0 | double target_qstep = leaf_qstep * qstep_ratio; |
325 | 0 | int qindex; |
326 | 0 | if (qstep_ratio < 1.0) { |
327 | 0 | for (qindex = leaf_qindex; qindex > MINQ; --qindex) { |
328 | 0 | double qstep = svt_aom_dc_quant_qtx(qindex, 0, bit_depth); |
329 | 0 | if (qstep <= target_qstep) { |
330 | 0 | break; |
331 | 0 | } |
332 | 0 | } |
333 | 0 | } else { |
334 | 0 | for (qindex = leaf_qindex; qindex <= MAXQ; ++qindex) { |
335 | 0 | double qstep = svt_aom_dc_quant_qtx(qindex, 0, bit_depth); |
336 | 0 | if (qstep >= target_qstep) { |
337 | 0 | break; |
338 | 0 | } |
339 | 0 | } |
340 | 0 | } |
341 | 0 | return qindex; |
342 | 0 | } |
343 | | |
344 | | // Returns the default rd multiplier for inter frames for a given qindex. |
345 | | // The function here is a first pass estimate based on data from |
346 | | // a previous Vizer run |
347 | 0 | static double def_inter_rd_multiplier(int qindex) { |
348 | 0 | return 3.2 + 0.0015 * qindex; |
349 | 0 | } |
350 | | |
351 | | // Returns the default rd multiplier for ARF/Golden Frames for a given qindex. |
352 | | // The function here is a first pass estimate based on data from |
353 | | // a previous Vizer run |
354 | 0 | static double def_arf_rd_multiplier(int qindex) { |
355 | 0 | return 3.25 + 0.0015 * qindex; |
356 | 0 | } |
357 | | |
358 | | // Returns the default rd multiplier for key frames for a given qindex. |
359 | | // The function here is a first pass estimate based on data from |
360 | | // a previous Vizer run |
361 | 22.7k | static double def_kf_rd_multiplier(int qindex) { |
362 | 22.7k | return 3.3 + 0.0015 * qindex; |
363 | 22.7k | } |
364 | | |
365 | 22.7k | int svt_aom_compute_rd_mult_based_on_qindex(EbBitDepth bit_depth, SvtAv1FrameUpdateType update_type, int qindex) { |
366 | 22.7k | int q = svt_aom_dc_quant_qtx(qindex, 0, bit_depth); |
367 | 22.7k | int64_t rdmult; |
368 | | |
369 | | // Scale rdmult based on frame type |
370 | 22.7k | if (update_type == SVT_AV1_KF_UPDATE) { |
371 | 22.7k | rdmult = (int64_t)(def_kf_rd_multiplier(q) * q * q); |
372 | 22.7k | } else if (update_type == SVT_AV1_GF_UPDATE || update_type == SVT_AV1_ARF_UPDATE) { |
373 | 0 | rdmult = (int64_t)(def_arf_rd_multiplier(q) * q * q); |
374 | 0 | } else { |
375 | 0 | rdmult = (int64_t)(def_inter_rd_multiplier(q) * q * q); |
376 | 0 | } |
377 | | |
378 | 22.7k | switch (bit_depth) { |
379 | 11.3k | case EB_EIGHT_BIT: |
380 | 11.3k | break; |
381 | 11.3k | case EB_TEN_BIT: |
382 | 11.3k | rdmult = ROUND_POWER_OF_TWO(rdmult, 4); |
383 | 11.3k | break; |
384 | 0 | case EB_TWELVE_BIT: |
385 | 0 | rdmult = ROUND_POWER_OF_TWO(rdmult, 8); |
386 | 0 | break; |
387 | 0 | default: |
388 | 0 | assert(0 && "bit_depth should be EB_EIGHT_BIT, EB_TEN_BIT or EB_TWELVE_BIT"); |
389 | 0 | return -1; |
390 | 22.7k | } |
391 | | |
392 | 22.7k | return rdmult > 0 ? (int)AOMMIN(rdmult, INT_MAX) : 1; |
393 | 22.7k | } |
394 | | |
395 | | static const int rd_frame_type_factor[2][SVT_AV1_FRAME_UPDATE_TYPES] = {{150, 180, 150, 150, 180, 180, 150}, |
396 | | {128, 144, 128, 128, 144, 144, 128}}; |
397 | 0 | #define RTC_KF_LAMBDA_BOOST 100 |
398 | | |
399 | | static uint32_t update_lambda(PictureControlSet* pcs, uint8_t q_index, uint8_t me_q_index, EbBitDepth bit_depth, |
400 | 35.2k | int64_t rdmult) { |
401 | 35.2k | PictureParentControlSet* ppcs = pcs->ppcs; |
402 | 35.2k | FrameType frame_type = ppcs->frm_hdr.frame_type; |
403 | | // To set gf_update_type based on current TL vs. the max TL (e.g. for 5L, max TL is 4) |
404 | 35.2k | uint8_t temporal_layer_index = pcs->scs->use_flat_ipp ? 0 : ppcs->temporal_layer_index; |
405 | 35.2k | uint8_t max_temporal_layer = pcs->scs->use_flat_ipp ? 0 : ppcs->hierarchical_levels; |
406 | | |
407 | | // Update rdmult based on the frame's position in the miniGOP |
408 | 35.2k | uint8_t gf_update_type = frame_type == KEY_FRAME ? SVT_AV1_KF_UPDATE |
409 | 35.2k | : temporal_layer_index == 0 ? SVT_AV1_ARF_UPDATE |
410 | 0 | : temporal_layer_index < max_temporal_layer ? SVT_AV1_INTNL_ARF_UPDATE |
411 | 0 | : SVT_AV1_LF_UPDATE; |
412 | 35.2k | rdmult = (rdmult * rd_frame_type_factor[bit_depth != EB_EIGHT_BIT][gf_update_type]) >> 7; |
413 | 35.2k | if (pcs->scs->static_config.rtc && frame_type == KEY_FRAME) { |
414 | 0 | rdmult = (rdmult * RTC_KF_LAMBDA_BOOST) >> 7; |
415 | 0 | } |
416 | 35.2k | if (pcs->scs->stats_based_sb_lambda_modulation) { |
417 | 35.2k | int factor = 128; |
418 | 35.2k | if (pcs->scs->static_config.rtc) { |
419 | 0 | int qdiff = me_q_index - ppcs->frm_hdr.quantization_params.base_q_idx; |
420 | 0 | if (qdiff < 0) { |
421 | 0 | factor = (qdiff <= -4) ? 100 : 115; |
422 | 0 | } |
423 | 35.2k | } else if (ppcs->frm_hdr.delta_q_params.delta_q_present || ppcs->r0_delta_qp_md) { |
424 | 0 | int qdiff = q_index - ppcs->frm_hdr.quantization_params.base_q_idx; |
425 | 0 | if (qdiff < 0) { |
426 | 0 | factor = (qdiff <= -8) ? 90 : 115; |
427 | 0 | } else if (qdiff > 0) { |
428 | 0 | factor = (qdiff <= 8) ? 135 : 150; |
429 | 0 | } |
430 | 35.2k | } else { |
431 | 35.2k | int qdiff = me_q_index - ppcs->frm_hdr.quantization_params.base_q_idx; |
432 | 35.2k | if (qdiff < 0) { |
433 | 0 | factor = (qdiff <= -4) ? 100 : 115; |
434 | 35.2k | } else if (qdiff > 0) { |
435 | 0 | factor = (qdiff <= 4) ? 135 : 150; |
436 | 0 | } |
437 | 35.2k | } |
438 | | |
439 | 35.2k | rdmult = (rdmult * factor) >> 7; |
440 | 35.2k | } |
441 | 35.2k | return (uint32_t)rdmult; |
442 | 35.2k | } |
443 | | |
444 | | /* |
445 | | * Set the sse lambda based on the bit_depth, then update based on frame position. |
446 | | */ |
447 | 22.7k | uint32_t svt_aom_compute_rd_mult(PictureControlSet* pcs, uint8_t q_index, uint8_t me_q_index, EbBitDepth bit_depth) { |
448 | | // Always use q_index for the derivation of the initial rdmult (i.e. don't use me_q_index) |
449 | 22.7k | int64_t rdmult = svt_aom_compute_rd_mult_based_on_qindex(bit_depth, pcs->ppcs->update_type, q_index); |
450 | | |
451 | 22.7k | return update_lambda(pcs, q_index, me_q_index, bit_depth, rdmult); |
452 | 22.7k | } |
453 | | |
454 | | uint32_t svt_aom_compute_fast_lambda(PictureControlSet* pcs, uint8_t q_index, uint8_t me_q_index, |
455 | 12.4k | EbBitDepth bit_depth) { |
456 | | // Always use q_index for the derivation of the initial rdmult (i.e. don't use me_q_index) |
457 | 12.4k | int64_t rdmult = bit_depth == EB_EIGHT_BIT ? av1_lambda_mode_decision8_bit_sad[q_index] |
458 | 12.4k | : av1lambda_mode_decision10_bit_sad[q_index]; |
459 | | |
460 | 12.4k | return update_lambda(pcs, q_index, me_q_index, bit_depth, rdmult); |
461 | 12.4k | } |
462 | | |
463 | | void svt_aom_lambda_assign(PictureControlSet* pcs, uint32_t* fast_lambda, uint32_t* full_lambda, EbBitDepth bit_depth, |
464 | 10.3k | uint8_t qp_index, bool multiply_lambda) { |
465 | 10.3k | if (bit_depth == EB_EIGHT_BIT) { |
466 | 5.16k | *full_lambda = svt_aom_compute_rd_mult(pcs, qp_index, qp_index, bit_depth); |
467 | 5.16k | *fast_lambda = av1_lambda_mode_decision8_bit_sad[qp_index]; |
468 | 5.16k | } else if (bit_depth == EB_TEN_BIT) { |
469 | 5.16k | *full_lambda = svt_aom_compute_rd_mult(pcs, qp_index, qp_index, bit_depth); |
470 | 5.16k | *fast_lambda = av1lambda_mode_decision10_bit_sad[qp_index]; |
471 | 5.16k | if (multiply_lambda) { |
472 | 5.16k | *full_lambda *= 16; |
473 | 5.16k | *fast_lambda *= 4; |
474 | 5.16k | } |
475 | 5.16k | } else if (bit_depth == EB_TWELVE_BIT) { |
476 | 0 | *full_lambda = svt_aom_compute_rd_mult(pcs, qp_index, qp_index, bit_depth); |
477 | 0 | *fast_lambda = av1lambda_mode_decision12_bit_sad[qp_index]; |
478 | 0 | } else { |
479 | 0 | assert(0); |
480 | 0 | } |
481 | | |
482 | | // NM: To be done: tune lambda based on the picture type and layer. |
483 | 10.3k | uint64_t scale_factor = pcs->scs->static_config.lambda_scale_factors[pcs->ppcs->update_type]; |
484 | 10.3k | *full_lambda = (uint32_t)((*full_lambda * scale_factor) >> 7); |
485 | 10.3k | *fast_lambda = (uint32_t)((*fast_lambda * scale_factor) >> 7); |
486 | 10.3k | } |
487 | | |
488 | 0 | void svt_av1_rc_init(SequenceControlSet* scs) { |
489 | 0 | EncodeContext* enc_ctx = scs->enc_ctx; |
490 | 0 | RATE_CONTROL* rc = &enc_ctx->rc; |
491 | 0 | RateControlCfg* rc_cfg = &enc_ctx->rc_cfg; |
492 | 0 | int i; |
493 | 0 | if (rc_cfg->mode == AOM_CBR) { |
494 | 0 | rc->avg_frame_qindex[KEY_FRAME] = rc_cfg->worst_allowed_q; |
495 | 0 | rc->avg_frame_qindex[INTER_FRAME] = rc_cfg->worst_allowed_q; |
496 | 0 | rc->last_q[KEY_FRAME] = rc_cfg->worst_allowed_q; |
497 | 0 | rc->last_q[INTER_FRAME] = rc_cfg->worst_allowed_q; |
498 | 0 | } else { |
499 | 0 | rc->avg_frame_qindex[KEY_FRAME] = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2; |
500 | 0 | rc->avg_frame_qindex[INTER_FRAME] = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2; |
501 | 0 | rc->last_q[KEY_FRAME] = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2; |
502 | 0 | rc->last_q[INTER_FRAME] = (rc_cfg->worst_allowed_q + rc_cfg->best_allowed_q) / 2; |
503 | 0 | } |
504 | 0 | rc->buffer_level = rc->starting_buffer_level; |
505 | 0 | rc->bits_off_target = rc->starting_buffer_level; |
506 | |
|
507 | 0 | rc->rolling_target_bits = rc->avg_frame_bandwidth; |
508 | 0 | rc->rolling_actual_bits = rc->avg_frame_bandwidth; |
509 | 0 | rc->total_actual_bits = 0; |
510 | 0 | rc->total_target_bits = 0; |
511 | |
|
512 | 0 | rc->frames_since_key = 8; // Sensible default for first frame. |
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 | 0 | } |
568 | 0 | } |
569 | | |
570 | | /**************************************************************************************** |
571 | | * reset_rc_param |
572 | | * reset RC related variable in PPCS |
573 | | *****************************************************************************************/ |
574 | 474 | void reset_rc_param(PictureParentControlSet* ppcs) { |
575 | 474 | ppcs->loop_count = 0; |
576 | 474 | ppcs->overshoot_seen = 0; |
577 | 474 | ppcs->undershoot_seen = 0; |
578 | 474 | } |
579 | | |
580 | | /****************************************************** |
581 | | * rc_init_frame_stats |
582 | | * Initializes frame statistics for rate control: |
583 | | * - Generates r0/beta values |
584 | | * - Initializes cyclic refresh |
585 | | * - Calculates reference frame statistics |
586 | | * - Calculates ME distortion |
587 | | * - Sets rate averaging period |
588 | | ******************************************************/ |
589 | 474 | static void rc_init_frame_stats(PictureControlSet* pcs, SequenceControlSet* scs) { |
590 | 474 | RATE_CONTROL* rc = &scs->enc_ctx->rc; |
591 | 474 | PictureParentControlSet* ppcs = pcs->ppcs; |
592 | | // Get r0 |
593 | 474 | if (ppcs->r0_gen) { |
594 | 0 | svt_aom_generate_r0beta(ppcs); |
595 | 0 | } |
596 | | |
597 | | // Get reference frame statistics |
598 | 474 | get_ref_intra_percentage(pcs, &pcs->ref_intra_percentage); |
599 | 474 | get_ref_skip_percentage(pcs, &pcs->ref_skip_percentage); |
600 | 474 | get_ref_hp_percentage(pcs, &pcs->ref_hp_percentage); |
601 | | |
602 | | // Set rate averaging period |
603 | 474 | if (scs->passes > 1 && scs->static_config.max_bit_rate) { |
604 | 0 | rc->rate_average_periodin_frames = (uint64_t)scs->twopass.stats_buf_ctx->total_stats->count; |
605 | 474 | } else { |
606 | 474 | rc->rate_average_periodin_frames = 60; |
607 | 474 | } |
608 | 474 | rc->rate_average_periodin_frames = MIN(rc->rate_average_periodin_frames, MAX_RATE_AVG_PERIOD); |
609 | | |
610 | | // Store the avg ME distortion |
611 | 474 | if (ppcs->slice_type != I_SLICE) { |
612 | 0 | rc->prev_avg_base_me_dist = rc->cur_avg_base_me_dist; |
613 | 0 | uint64_t avg_me_dist = 0; |
614 | 0 | for (int b64_idx = 0; b64_idx < ppcs->b64_total_count; ++b64_idx) { |
615 | 0 | avg_me_dist += ppcs->me_64x64_distortion[b64_idx]; |
616 | 0 | } |
617 | 0 | avg_me_dist /= ppcs->b64_total_count; |
618 | 0 | rc->cur_avg_base_me_dist = (uint32_t)avg_me_dist; |
619 | 0 | } |
620 | 474 | } |
621 | | |
622 | | // Calculate the number of bits to assign to boosted frames in a group. |
623 | 0 | int svt_av1_calculate_boost_bits(int frame_count, int boost, int64_t total_group_bits) { |
624 | 0 | int allocation_chunks; |
625 | | |
626 | | // return 0 for invalid inputs (could arise e.g. through rounding errors) |
627 | 0 | if (!boost || (total_group_bits <= 0)) { |
628 | 0 | return 0; |
629 | 0 | } |
630 | | |
631 | 0 | if (frame_count <= 0) { |
632 | 0 | return (int)(AOMMIN(total_group_bits, INT_MAX)); |
633 | 0 | } |
634 | | |
635 | 0 | allocation_chunks = (frame_count * 100) + boost; |
636 | | |
637 | | // Prevent overflow. |
638 | 0 | if (boost > 1023) { |
639 | 0 | int divisor = boost >> 10; |
640 | 0 | boost /= divisor; |
641 | 0 | allocation_chunks /= divisor; |
642 | 0 | } |
643 | | |
644 | | // Calculate the number of extra bits for use in the boosted frame or frames. |
645 | 0 | return AOMMAX((int)(((int64_t)boost * total_group_bits) / allocation_chunks), 0); |
646 | 0 | } |
647 | | |
648 | | /****************************************************** |
649 | | * rc_handle_superres |
650 | | * Handles superres processing for 1-pass encoding: |
651 | | * - Determines superres parameters |
652 | | * - Re-initializes ME segments if needed |
653 | | * - Releases PA reference objects |
654 | | * Returns true if superres triggered (early exit needed) |
655 | | ******************************************************/ |
656 | | static bool rc_handle_superres(PictureControlSet* pcs, RateControlContext* context_ptr, |
657 | 474 | EbObjectWrapper* rate_control_tasks_wrapper_ptr) { |
658 | 474 | PictureParentControlSet* ppcs = pcs->ppcs; |
659 | 474 | SequenceControlSet* scs = pcs->scs; |
660 | | |
661 | 474 | if (scs->static_config.pass != ENC_SINGLE_PASS) { |
662 | 0 | return false; |
663 | 0 | } |
664 | | |
665 | 474 | if (scs->static_config.superres_mode <= SUPERRES_RANDOM) { |
666 | 474 | return false; |
667 | 474 | } |
668 | | |
669 | | // Determine denom and scale down picture by selected denom |
670 | 0 | svt_aom_init_resize_picture(scs, ppcs); |
671 | 0 | if (ppcs->frame_superres_enabled || ppcs->frame_resize_enabled) { |
672 | | // Reset gm based on super-res on/off |
673 | 0 | bool super_res_off = ppcs->frame_superres_enabled == false && scs->static_config.resize_mode == RESIZE_NONE; |
674 | 0 | svt_aom_set_gm_controls(ppcs, svt_aom_derive_gm_level(ppcs, super_res_off)); |
675 | | |
676 | | // Initialize Segments as picture decision process |
677 | 0 | ppcs->me_segments_completion_count = 0; |
678 | 0 | ppcs->me_processed_b64_count = 0; |
679 | |
|
680 | 0 | for (uint32_t segment_index = 0; segment_index < ppcs->me_segments_total_count; ++segment_index) { |
681 | | // Get Empty Results Object |
682 | 0 | EbObjectWrapper* out_results_wrapper; |
683 | 0 | svt_get_empty_object(context_ptr->picture_decision_results_output_fifo_ptr, &out_results_wrapper); |
684 | |
|
685 | 0 | PictureDecisionResults* out_results = (PictureDecisionResults*)out_results_wrapper->object_ptr; |
686 | 0 | out_results->pcs_wrapper = ppcs->p_pcs_wrapper_ptr; |
687 | 0 | out_results->segment_index = segment_index; |
688 | 0 | out_results->task_type = TASK_SUPERRES_RE_ME; |
689 | | // Post the Full Results Object |
690 | 0 | svt_post_full_object(out_results_wrapper); |
691 | 0 | } |
692 | | |
693 | | // Release Rate Control Tasks |
694 | 0 | svt_release_object(rate_control_tasks_wrapper_ptr); |
695 | 0 | return true; // Signal early exit |
696 | 0 | } |
697 | | |
698 | | // PA ref objs are no longer needed if super-res isn't performed on current frame |
699 | 0 | if (ppcs->tpl_ctrls.enable) { |
700 | 0 | if (ppcs->temporal_layer_index == 0) { |
701 | 0 | for (uint32_t i = 0; i < ppcs->tpl_group_size; i++) { |
702 | 0 | if (svt_aom_is_incomp_mg_frame(ppcs->tpl_group[i])) { |
703 | 0 | if (ppcs->tpl_group[i]->ext_mg_id == ppcs->ext_mg_id + 1) { |
704 | 0 | svt_aom_release_pa_reference_objects(scs, ppcs->tpl_group[i]); |
705 | 0 | } |
706 | 0 | } else { |
707 | 0 | if (ppcs->tpl_group[i]->ext_mg_id == ppcs->ext_mg_id) { |
708 | 0 | svt_aom_release_pa_reference_objects(scs, ppcs->tpl_group[i]); |
709 | 0 | } |
710 | 0 | } |
711 | 0 | } |
712 | 0 | } |
713 | 0 | } else { |
714 | 0 | svt_aom_release_pa_reference_objects(scs, ppcs); |
715 | 0 | } |
716 | |
|
717 | 0 | return false; |
718 | 0 | } |
719 | | |
720 | 474 | static void generate_sb_qindex(PictureControlSet* pcs) { |
721 | 474 | PictureParentControlSet* ppcs = pcs->ppcs; |
722 | 474 | SequenceControlSet* scs = pcs->scs; |
723 | | |
724 | 474 | svt_av1_rc_init_sb_qindex(pcs, scs); |
725 | | |
726 | 474 | if (ppcs->frm_hdr.delta_q_params.delta_q_present && ppcs->frm_hdr.delta_q_params.delta_q_res != 1) { |
727 | | // adjust delta q res and normalize superblock delta q values to reduce signaling overhead |
728 | 0 | svt_av1_normalize_sb_delta_q(pcs); |
729 | 0 | } |
730 | | |
731 | | // Derive a QP per 64x64 using ME distortions (to be used for lambda modulation only; not at Q/Q-1) |
732 | 474 | if (scs->stats_based_sb_lambda_modulation) { |
733 | 474 | svt_av1_generate_b64_me_qindex_map(pcs); |
734 | 474 | } |
735 | 474 | } |
736 | | |
737 | | // Process packetization feedback: update RC parameters and release resources. |
738 | | static void rc_process_packetization_feedback(PictureParentControlSet* ppcs, |
739 | 474 | const EbObjectWrapper* restrict rate_control_tasks_wrapper_ptr) { |
740 | 474 | SequenceControlSet* scs = ppcs->scs; |
741 | 474 | RateControlTasks* rc_tasks = (RateControlTasks*)rate_control_tasks_wrapper_ptr->object_ptr; |
742 | | |
743 | | // Prevent double counting frames with overlay |
744 | 474 | if (!ppcs->is_overlay) { |
745 | 474 | svt_block_on_mutex(scs->enc_ctx->rc_param_queue_mutex); |
746 | 474 | ppcs->rate_control_param_ptr->processed_frame_number++; |
747 | | |
748 | | // check if all the frames in the interval have arrived |
749 | 474 | if (ppcs->rate_control_param_ptr->size == ppcs->rate_control_param_ptr->processed_frame_number) { |
750 | 0 | rc_param_reset(ppcs->rate_control_param_ptr); |
751 | 0 | } |
752 | 474 | svt_release_mutex(scs->enc_ctx->rc_param_queue_mutex); |
753 | 474 | } |
754 | | |
755 | 474 | if (scs->enc_ctx->rc_cfg.mode == AOM_Q) { |
756 | | // Queue variables |
757 | 474 | if (scs->static_config.max_bit_rate) { |
758 | 0 | svt_av1_coded_frames_stat_calc(ppcs); |
759 | 0 | } |
760 | 474 | } else { |
761 | 0 | if (use_rtc_cbr_path(scs)) { |
762 | 0 | svt_av1_rc_postencode_update_rtc_cbr(ppcs); |
763 | 0 | } else { |
764 | 0 | if (scs->static_config.gop_constraint_rc) { |
765 | 0 | svt_av1_rc_postencode_update_gop_const(ppcs); |
766 | | // Qindex calculating |
767 | 0 | if (scs->enc_ctx->rc_cfg.mode == AOM_VBR) { |
768 | 0 | svt_av1_twopass_postencode_update_gop_const(ppcs); |
769 | 0 | } |
770 | 0 | } else { |
771 | 0 | svt_av1_rc_postencode_update(ppcs); |
772 | | // Qindex calculating |
773 | 0 | if (scs->enc_ctx->rc_cfg.mode == AOM_VBR) { |
774 | 0 | svt_av1_twopass_postencode_update(ppcs); |
775 | 0 | } |
776 | 0 | } |
777 | 0 | } |
778 | 0 | svt_aom_update_rc_counts(ppcs); |
779 | 0 | } |
780 | | |
781 | | // Release the ParentPictureControlSet |
782 | 474 | if (ppcs->y8b_wrapper) { |
783 | | // y8b needs to get decremented at the same time of regular input |
784 | 474 | svt_release_object(ppcs->y8b_wrapper); |
785 | 474 | } |
786 | | |
787 | | // free private data list before release input picture buffer |
788 | 474 | free_private_data_list((EbBufferHeaderType*)ppcs->input_pic_wrapper->object_ptr); |
789 | | |
790 | 474 | svt_release_object(ppcs->input_pic_wrapper); |
791 | 474 | svt_release_object(ppcs->scs_wrapper); |
792 | 474 | svt_release_object(rc_tasks->pcs_wrapper); |
793 | 474 | } |
794 | | |
795 | 1.42k | EbErrorType svt_aom_rate_control_kernel_iter(void* context) { |
796 | 1.42k | RateControlContext* context_ptr = (RateControlContext*)context; |
797 | | |
798 | 1.42k | SequenceControlSet* scs = NULL; |
799 | 1.42k | PictureControlSet* pcs = NULL; |
800 | 1.42k | PictureParentControlSet* ppcs = NULL; |
801 | | |
802 | | // Get RateControl Task |
803 | 1.42k | EbObjectWrapper* rate_control_tasks_wrapper_ptr; |
804 | 1.42k | EB_GET_FULL_OBJECT(context_ptr->rate_control_input_tasks_fifo_ptr, &rate_control_tasks_wrapper_ptr); |
805 | | |
806 | 948 | RateControlTasks* rc_tasks = (RateControlTasks*)rate_control_tasks_wrapper_ptr->object_ptr; |
807 | 948 | RateControlTaskTypes task_type = rc_tasks->task_type; |
808 | 948 | bool is_superres_recode_task = (task_type == RC_INPUT_SUPERRES_RECODE) ? true : false; |
809 | | |
810 | | // Modify these for different temporal layers later |
811 | 948 | switch (task_type) { |
812 | 0 | case RC_INPUT_SUPERRES_RECODE: |
813 | 0 | assert(scs->static_config.superres_mode == SUPERRES_QTHRESH || |
814 | 0 | scs->static_config.superres_mode == SUPERRES_AUTO); |
815 | | // intentionally reuse code in RC_INPUT |
816 | 474 | case RC_INPUT: |
817 | 474 | pcs = (PictureControlSet*)rc_tasks->pcs_wrapper->object_ptr; |
818 | 474 | ppcs = pcs->ppcs; |
819 | 474 | scs = pcs->scs; |
820 | | |
821 | 474 | rc_init_frame_stats(pcs, scs); |
822 | | |
823 | 474 | if (!is_superres_recode_task) { |
824 | 474 | ppcs->blk_lambda_tuning = false; |
825 | 474 | } |
826 | 474 | reset_rc_param(ppcs); |
827 | | |
828 | 474 | if (ppcs->is_overlay) { |
829 | | // overlay: ppcs->picture_qp has been updated by altref RC_INPUT |
830 | 474 | } else { |
831 | 474 | if (scs->enc_ctx->rc_cfg.mode == AOM_Q) { |
832 | 474 | svt_av1_rc_calc_qindex_crf_cqp(pcs, scs); |
833 | 474 | svt_aom_setup_segmentation(pcs, scs); |
834 | 474 | } else if (use_rtc_cbr_path(scs)) { |
835 | 0 | svt_av1_rc_calc_qindex_rtc_cbr(pcs); |
836 | 0 | } else { |
837 | 0 | if (!is_superres_recode_task) { |
838 | 0 | svt_av1_rc_process_rate_allocation(pcs, scs); |
839 | 0 | } |
840 | 0 | svt_av1_rc_calc_qindex_rate_control(pcs, scs); |
841 | 0 | } |
842 | 474 | ppcs->picture_qp = clamp_qp(scs, (ppcs->frm_hdr.quantization_params.base_q_idx + 2) >> 2); |
843 | 474 | } |
844 | | |
845 | 474 | if (ppcs->is_alt_ref) { |
846 | | // overlay use the same QP with alt_ref, to align with |
847 | | // rate_control_param_queue update code in below RC_PACKETIZATION_FEEDBACK_RESULT. |
848 | 0 | PictureParentControlSet* overlay_ppcs = ppcs->overlay_ppcs_ptr; |
849 | 0 | overlay_ppcs->picture_qp = ppcs->picture_qp; |
850 | 0 | overlay_ppcs->frm_hdr.quantization_params = ppcs->frm_hdr.quantization_params; |
851 | 0 | } |
852 | | |
853 | 474 | if (!is_superres_recode_task) { |
854 | 474 | if (rc_handle_superres(pcs, context_ptr, rate_control_tasks_wrapper_ptr)) { |
855 | 0 | break; |
856 | 0 | } |
857 | 474 | } |
858 | | |
859 | 474 | generate_sb_qindex(pcs); |
860 | | |
861 | | // Get Empty Rate Control Results Buffer |
862 | 474 | EbObjectWrapper* rc_results_wrapper; |
863 | 474 | svt_get_empty_object(context_ptr->rate_control_output_results_fifo_ptr, &rc_results_wrapper); |
864 | 474 | RateControlResults* rc_results = (RateControlResults*)rc_results_wrapper->object_ptr; |
865 | 474 | rc_results->pcs_wrapper = rc_tasks->pcs_wrapper; |
866 | 474 | rc_results->superres_recode = is_superres_recode_task; |
867 | | |
868 | | // Post Full Rate Control Results |
869 | 474 | svt_post_full_object(rc_results_wrapper); |
870 | | |
871 | | // Release Rate Control Tasks |
872 | 474 | svt_release_object(rate_control_tasks_wrapper_ptr); |
873 | | |
874 | 474 | break; |
875 | | |
876 | 474 | case RC_PACKETIZATION_FEEDBACK_RESULT: |
877 | 474 | ppcs = (PictureParentControlSet*)rc_tasks->pcs_wrapper->object_ptr; |
878 | 474 | scs = ppcs->scs; |
879 | | |
880 | 474 | rc_process_packetization_feedback(ppcs, rate_control_tasks_wrapper_ptr); |
881 | | |
882 | | // Release Rate Control Tasks |
883 | 474 | svt_release_object(rate_control_tasks_wrapper_ptr); |
884 | 474 | break; |
885 | | |
886 | 0 | default: |
887 | 0 | pcs = (PictureControlSet*)rc_tasks->pcs_wrapper->object_ptr; |
888 | 0 | scs = pcs->scs; |
889 | |
|
890 | 0 | break; |
891 | 948 | } |
892 | 948 | return EB_ErrorNone; |
893 | 948 | } |
894 | | |
895 | 474 | void* svt_aom_rate_control_kernel(void* input_ptr) { |
896 | 474 | EbThreadContext* thread_ctx = (EbThreadContext*)input_ptr; |
897 | 1.42k | for (;;) { |
898 | 1.42k | EbErrorType err = svt_aom_rate_control_kernel_iter(thread_ctx->priv); |
899 | 1.42k | if (err == EB_NoErrorFifoShutdown) { |
900 | 474 | return NULL; |
901 | 474 | } |
902 | 1.42k | } |
903 | 0 | return NULL; |
904 | 474 | } |