Bug Summary

File:root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c
Warning:line 1498, column 26
Subtraction of a null pointer (from variable 'tok') and a probably non-null pointer (via field 'start') may result in undefined behavior

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name encodeframe.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libaom -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libaom -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_HAS_MOZGLUE -I /root/firefox-clang/media/libaom -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/media/libaom -I /root/firefox-clang/media/libaom/config/linux/x64 -I /root/firefox-clang/media/libaom/config -I /root/firefox-clang/third_party/aom -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -Wno-sign-compare -Wno-unused-function -Wno-unreachable-code -Wno-unneeded-internal-declaration -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c /root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c
1/*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12#include <limits.h>
13#include <float.h>
14#include <math.h>
15#include <stdbool.h>
16#include <stdio.h>
17
18#include "config/aom_config.h"
19#include "config/aom_dsp_rtcd.h"
20#include "config/av1_rtcd.h"
21
22#include "aom_dsp/aom_dsp_common.h"
23#include "aom_dsp/binary_codes_writer.h"
24#include "aom_ports/mem.h"
25#include "aom_ports/aom_timer.h"
26#include "aom_util/aom_pthread.h"
27#if CONFIG_MISMATCH_DEBUG0
28#include "aom_util/debug_util.h"
29#endif // CONFIG_MISMATCH_DEBUG
30
31#include "av1/common/cfl.h"
32#include "av1/common/common.h"
33#include "av1/common/common_data.h"
34#include "av1/common/entropy.h"
35#include "av1/common/entropymode.h"
36#include "av1/common/idct.h"
37#include "av1/common/mv.h"
38#include "av1/common/mvref_common.h"
39#include "av1/common/pred_common.h"
40#include "av1/common/quant_common.h"
41#include "av1/common/reconintra.h"
42#include "av1/common/reconinter.h"
43#include "av1/common/seg_common.h"
44#include "av1/common/tile_common.h"
45#include "av1/common/warped_motion.h"
46
47#include "av1/encoder/allintra_vis.h"
48#include "av1/encoder/aq_complexity.h"
49#include "av1/encoder/aq_cyclicrefresh.h"
50#include "av1/encoder/aq_variance.h"
51#include "av1/encoder/av1_quantize.h"
52#include "av1/encoder/global_motion_facade.h"
53#include "av1/encoder/encodeframe.h"
54#include "av1/encoder/encodeframe_utils.h"
55#include "av1/encoder/encodemb.h"
56#include "av1/encoder/encodemv.h"
57#include "av1/encoder/encodetxb.h"
58#include "av1/encoder/ethread.h"
59#include "av1/encoder/extend.h"
60#include "av1/encoder/intra_mode_search_utils.h"
61#include "av1/encoder/ml.h"
62#include "av1/encoder/motion_search_facade.h"
63#include "av1/encoder/partition_strategy.h"
64#if !CONFIG_REALTIME_ONLY0
65#include "av1/encoder/partition_model_weights.h"
66#endif
67#include "av1/encoder/partition_search.h"
68#include "av1/encoder/rd.h"
69#include "av1/encoder/rdopt.h"
70#include "av1/encoder/reconinter_enc.h"
71#include "av1/encoder/segmentation.h"
72#include "av1/encoder/tokenize.h"
73#include "av1/encoder/tpl_model.h"
74#include "av1/encoder/var_based_part.h"
75
76#if CONFIG_TUNE_VMAF0
77#include "av1/encoder/tune_vmaf.h"
78#endif
79
80/*!\cond */
81// This is used as a reference when computing the source variance for the
82// purposes of activity masking.
83// Eventually this should be replaced by custom no-reference routines,
84// which will be faster.
85static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE(1 << 7)] = {
86 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
87 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
88 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
89 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
90 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
91 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
92 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
93 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
94 128, 128, 128, 128, 128, 128, 128, 128
95};
96
97#if CONFIG_AV1_HIGHBITDEPTH1
98static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE(1 << 7)] = {
99 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
100 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
101 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
102 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
103 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
104 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
105 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
106 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
107 128, 128, 128, 128, 128, 128, 128, 128
108};
109
110static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE(1 << 7)] = {
111 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
112 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
113 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
114 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
115 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
116 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
117 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
118 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
119 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
120 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
121 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
122 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
123 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
124 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
125 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
126 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4
127};
128
129static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE(1 << 7)] = {
130 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
131 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
132 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
133 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
134 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
135 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
136 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
137 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
138 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
139 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
140 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
141 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
142 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
143 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
144 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
145 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
146 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
147 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
148 128 * 16, 128 * 16
149};
150#endif // CONFIG_AV1_HIGHBITDEPTH
151/*!\endcond */
152
153// For the given bit depth, returns a constant array used to assist the
154// calculation of source block variance, which will then be used to decide
155// adaptive quantizers.
156static const uint8_t *get_var_offs(int use_hbd, int bd) {
157#if CONFIG_AV1_HIGHBITDEPTH1
158 if (use_hbd) {
159 assert(bd == 8 || bd == 10 || bd == 12)((void) sizeof ((bd == 8 || bd == 10 || bd == 12) ? 1 : 0), __extension__
({ if (bd == 8 || bd == 10 || bd == 12) ; else __assert_fail
("bd == 8 || bd == 10 || bd == 12", "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 159, __extension__ __PRETTY_FUNCTION__); }))
;
160 const int off_index = (bd - 8) >> 1;
161 static const uint16_t *high_var_offs[3] = { AV1_HIGH_VAR_OFFS_8,
162 AV1_HIGH_VAR_OFFS_10,
163 AV1_HIGH_VAR_OFFS_12 };
164 return CONVERT_TO_BYTEPTR(high_var_offs[off_index])((uint8_t *)(((uintptr_t)(high_var_offs[off_index])) >>
1))
;
165 }
166#else
167 (void)use_hbd;
168 (void)bd;
169 assert(!use_hbd)((void) sizeof ((!use_hbd) ? 1 : 0), __extension__ ({ if (!use_hbd
) ; else __assert_fail ("!use_hbd", "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 169, __extension__ __PRETTY_FUNCTION__); }))
;
170#endif
171 assert(bd == 8)((void) sizeof ((bd == 8) ? 1 : 0), __extension__ ({ if (bd ==
8) ; else __assert_fail ("bd == 8", "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 171, __extension__ __PRETTY_FUNCTION__); }))
;
172 return AV1_VAR_OFFS;
173}
174
175void av1_init_rtc_counters(MACROBLOCK *const x) {
176 av1_init_cyclic_refresh_counters(x);
177 x->cnt_zeromv = 0;
178 x->sb_col_scroll = 0;
179 x->sb_row_scroll = 0;
180}
181
182void av1_accumulate_rtc_counters(AV1_COMP *cpi, const MACROBLOCK *const x) {
183 if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ)
184 av1_accumulate_cyclic_refresh_counters(cpi->cyclic_refresh, x);
185 cpi->rc.cnt_zeromv += x->cnt_zeromv;
186 cpi->rc.num_col_blscroll_last_tl0 += x->sb_col_scroll;
187 cpi->rc.num_row_blscroll_last_tl0 += x->sb_row_scroll;
188}
189
190unsigned int av1_get_perpixel_variance(const AV1_COMP *cpi,
191 const MACROBLOCKD *xd,
192 const struct buf_2d *ref,
193 BLOCK_SIZE bsize, int plane,
194 int use_hbd) {
195 const int subsampling_x = xd->plane[plane].subsampling_x;
196 const int subsampling_y = xd->plane[plane].subsampling_y;
197 const BLOCK_SIZE plane_bsize =
198 get_plane_block_size(bsize, subsampling_x, subsampling_y);
199 unsigned int sse;
200 const unsigned int var = cpi->ppi->fn_ptr[plane_bsize].vf(
201 ref->buf, ref->stride, get_var_offs(use_hbd, xd->bd), 0, &sse);
202 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[plane_bsize])(((var) + (((1 << (num_pels_log2_lookup[plane_bsize])) >>
1))) >> (num_pels_log2_lookup[plane_bsize]))
;
203}
204
205unsigned int av1_get_perpixel_variance_facade(const AV1_COMP *cpi,
206 const MACROBLOCKD *xd,
207 const struct buf_2d *ref,
208 BLOCK_SIZE bsize, int plane) {
209 const int use_hbd = is_cur_buf_hbd(xd);
210 return av1_get_perpixel_variance(cpi, xd, ref, bsize, plane, use_hbd);
211}
212
213void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
214 int mi_row, int mi_col, const int num_planes,
215 BLOCK_SIZE bsize) {
216 // Set current frame pointer.
217 x->e_mbd.cur_buf = src;
218
219 // We use AOMMIN(num_planes, MAX_MB_PLANE) instead of num_planes to quiet
220 // the static analysis warnings.
221 for (int i = 0; i < AOMMIN(num_planes, MAX_MB_PLANE)(((num_planes) < (3)) ? (num_planes) : (3)); i++) {
222 const int is_uv = i > 0;
223 setup_pred_plane(
224 &x->plane[i].src, bsize, src->buffers[i], src->crop_widths[is_uv],
225 src->crop_heights[is_uv], src->strides[is_uv], mi_row, mi_col, NULL((void*)0),
226 x->e_mbd.plane[i].subsampling_x, x->e_mbd.plane[i].subsampling_y);
227 }
228}
229
230#if !CONFIG_REALTIME_ONLY0
231/*!\brief Assigns different quantization parameters to each superblock
232 * based on statistics relevant to the selected delta-q mode (variance).
233 * This is the non-rd version.
234 *
235 * \param[in] cpi Top level encoder instance structure
236 * \param[in,out] td Thread data structure
237 * \param[in,out] x Superblock level data for this block.
238 * \param[in] tile_info Tile information / identification
239 * \param[in] mi_row Block row (in "MI_SIZE" units) index
240 * \param[in] mi_col Block column (in "MI_SIZE" units) index
241 * \param[out] num_planes Number of image planes (e.g. Y,U,V)
242 *
243 * \remark No return value but updates superblock and thread data
244 * related to the q / q delta to be used.
245 */
246static inline void setup_delta_q_nonrd(AV1_COMP *const cpi, ThreadData *td,
247 MACROBLOCK *const x,
248 const TileInfo *const tile_info,
249 int mi_row, int mi_col, int num_planes) {
250 AV1_COMMON *const cm = &cpi->common;
251 const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
252 assert(delta_q_info->delta_q_present_flag)((void) sizeof ((delta_q_info->delta_q_present_flag) ? 1 :
0), __extension__ ({ if (delta_q_info->delta_q_present_flag
) ; else __assert_fail ("delta_q_info->delta_q_present_flag"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 252, __extension__ __PRETTY_FUNCTION__); }))
;
253
254 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
255 av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, sb_size);
256
257 const int delta_q_res = delta_q_info->delta_q_res;
258 int current_qindex = cm->quant_params.base_qindex;
259
260 if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_VARIANCE_BOOST) {
261 current_qindex = av1_get_sbq_variance_boost(cpi, x);
262 }
263
264 x->rdmult_cur_qindex = current_qindex;
265 MACROBLOCKD *const xd = &x->e_mbd;
266 current_qindex = av1_adjust_q_from_delta_q_res(
267 delta_q_res, xd->current_base_qindex, current_qindex);
268
269 x->delta_qindex = current_qindex - cm->quant_params.base_qindex;
270 x->rdmult_delta_qindex = x->delta_qindex;
271
272 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
273 xd->mi[0]->current_qindex = current_qindex;
274 av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 0);
275
276 // keep track of any non-zero delta-q used
277 td->deltaq_used |= (x->delta_qindex != 0);
278}
279
280/*!\brief Assigns different quantization parameters to each superblock
281 * based on statistics relevant to the selected delta-q mode (TPL weight,
282 * variance, HDR, etc).
283 *
284 * \ingroup tpl_modelling
285 *
286 * \param[in] cpi Top level encoder instance structure
287 * \param[in,out] td Thread data structure
288 * \param[in,out] x Superblock level data for this block.
289 * \param[in] tile_info Tile information / identification
290 * \param[in] mi_row Block row (in "MI_SIZE" units) index
291 * \param[in] mi_col Block column (in "MI_SIZE" units) index
292 * \param[out] num_planes Number of image planes (e.g. Y,U,V)
293 *
294 * \remark No return value but updates superblock and thread data
295 * related to the q / q delta to be used.
296 */
297static inline void setup_delta_q(AV1_COMP *const cpi, ThreadData *td,
298 MACROBLOCK *const x,
299 const TileInfo *const tile_info, int mi_row,
300 int mi_col, int num_planes) {
301 AV1_COMMON *const cm = &cpi->common;
302 const CommonModeInfoParams *const mi_params = &cm->mi_params;
303 const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
304
305 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
306 av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, sb_size);
307
308 const int delta_q_res = delta_q_info->delta_q_res;
309 int current_qindex = cm->quant_params.base_qindex;
310 const int sb_row = mi_row >> cm->seq_params->mib_size_log2;
311 const int sb_col = mi_col >> cm->seq_params->mib_size_log2;
312 const int sb_cols =
313 CEIL_POWER_OF_TWO(cm->mi_params.mi_cols, cm->seq_params->mib_size_log2)(((cm->mi_params.mi_cols) + (1 << (cm->seq_params
->mib_size_log2)) - 1) >> (cm->seq_params->mib_size_log2
))
;
314 const int sb_index = sb_row * sb_cols + sb_col;
315 if (cpi->use_ducky_encode && cpi->ducky_encode_info.frame_info.qp_mode ==
316 DUCKY_ENCODE_FRAME_MODE_QINDEX) {
317 current_qindex =
318 cpi->ducky_encode_info.frame_info.superblock_encode_qindex[sb_index];
319 } else if (cpi->ext_ratectrl.ready &&
320 (cpi->ext_ratectrl.funcs.rc_type & AOM_RC_QP) != 0 &&
321 cpi->ext_ratectrl.funcs.get_encodeframe_decision != NULL((void*)0) &&
322 cpi->ext_ratectrl.sb_params_list != NULL((void*)0)) {
323 if (cpi->ext_ratectrl.use_delta_q) {
324 // Only used for per-coding-block RD mult calculation later.
325 current_qindex = av1_get_q_for_deltaq_objective(cpi, td, NULL((void*)0), sb_size,
326 mi_row, mi_col);
327
328 const int q_index = cpi->ext_ratectrl.sb_params_list[sb_index].q_index;
329 if (q_index != AOM_DEFAULT_Q-1) {
330 current_qindex = q_index;
331 }
332 }
333 } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL) {
334 if (DELTA_Q_PERCEPTUAL_MODULATION1 == 1) {
335 const int block_wavelet_energy_level =
336 av1_block_wavelet_energy_level(cpi, x, sb_size);
337 x->sb_energy_level = block_wavelet_energy_level;
338 current_qindex = av1_compute_q_from_energy_level_deltaq_mode(
339 cpi, block_wavelet_energy_level);
340 } else {
341 const int block_var_level = av1_log_block_var(cpi, x, sb_size);
342 x->sb_energy_level = block_var_level;
343 current_qindex =
344 av1_compute_q_from_energy_level_deltaq_mode(cpi, block_var_level);
345 }
346 } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_OBJECTIVE &&
347 cpi->oxcf.algo_cfg.enable_tpl_model) {
348 // Setup deltaq based on tpl stats
349 current_qindex =
350 av1_get_q_for_deltaq_objective(cpi, td, NULL((void*)0), sb_size, mi_row, mi_col);
351 } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL_AI) {
352 current_qindex = av1_get_sbq_perceptual_ai(cpi, sb_size, mi_row, mi_col);
353 } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_USER_RATING_BASED) {
354 current_qindex = av1_get_sbq_user_rating_based(cpi, mi_row, mi_col);
355 } else if (cpi->oxcf.q_cfg.enable_hdr_deltaq) {
356 current_qindex = av1_get_q_for_hdr(cpi, x, sb_size, mi_row, mi_col);
357 } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_VARIANCE_BOOST) {
358 current_qindex = av1_get_sbq_variance_boost(cpi, x);
359 }
360
361 x->rdmult_cur_qindex = current_qindex;
362 MACROBLOCKD *const xd = &x->e_mbd;
363 const int adjusted_qindex = av1_adjust_q_from_delta_q_res(
364 delta_q_res, xd->current_base_qindex, current_qindex);
365 if (cpi->use_ducky_encode) {
366 assert(adjusted_qindex == current_qindex)((void) sizeof ((adjusted_qindex == current_qindex) ? 1 : 0),
__extension__ ({ if (adjusted_qindex == current_qindex) ; else
__assert_fail ("adjusted_qindex == current_qindex", "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 366, __extension__ __PRETTY_FUNCTION__); }))
;
367 }
368 current_qindex = adjusted_qindex;
369
370 x->delta_qindex = cm->delta_q_info.delta_q_present_flag
371 ? current_qindex - cm->quant_params.base_qindex
372 : 0;
373 x->rdmult_delta_qindex = current_qindex - cm->quant_params.base_qindex;
374
375 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
376 xd->mi[0]->current_qindex = cm->delta_q_info.delta_q_present_flag
377 ? current_qindex
378 : cm->quant_params.base_qindex;
379 av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 0);
380
381 // keep track of any non-zero delta-q used
382 td->deltaq_used |= (x->delta_qindex != 0);
383
384 if (cpi->oxcf.tool_cfg.enable_deltalf_mode &&
385 cm->delta_q_info.delta_q_present_flag) {
386 const int delta_lf_res = delta_q_info->delta_lf_res;
387 const int lfmask = ~(delta_lf_res - 1);
388 const int delta_lf_from_base =
389 ((x->delta_qindex / 4 + delta_lf_res / 2) & lfmask);
390 const int8_t delta_lf =
391 (int8_t)clamp(delta_lf_from_base, -MAX_LOOP_FILTER63, MAX_LOOP_FILTER63);
392 const int frame_lf_count =
393 av1_num_planes(cm) > 1 ? FRAME_LF_COUNT4 : FRAME_LF_COUNT4 - 2;
394 const int mib_size = cm->seq_params->mib_size;
395
396 // pre-set the delta lf for loop filter. Note that this value is set
397 // before mi is assigned for each block in current superblock
398 for (int j = 0; j < AOMMIN(mib_size, mi_params->mi_rows - mi_row)(((mib_size) < (mi_params->mi_rows - mi_row)) ? (mib_size
) : (mi_params->mi_rows - mi_row))
; j++) {
399 for (int k = 0; k < AOMMIN(mib_size, mi_params->mi_cols - mi_col)(((mib_size) < (mi_params->mi_cols - mi_col)) ? (mib_size
) : (mi_params->mi_cols - mi_col))
; k++) {
400 const int grid_idx = get_mi_grid_idx(mi_params, mi_row + j, mi_col + k);
401 mi_params->mi_alloc[grid_idx].delta_lf_from_base = delta_lf;
402 for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) {
403 mi_params->mi_alloc[grid_idx].delta_lf[lf_id] = delta_lf;
404 }
405 }
406 }
407 }
408}
409
410static void init_ref_frame_space(AV1_COMP *cpi, ThreadData *td, int mi_row,
411 int mi_col) {
412 const AV1_COMMON *cm = &cpi->common;
413 const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
414 const CommonModeInfoParams *const mi_params = &cm->mi_params;
415 MACROBLOCK *x = &td->mb;
416 const int frame_idx = cpi->gf_frame_index;
417 TplParams *const tpl_data = &cpi->ppi->tpl_data;
418 const uint8_t block_mis_log2 = tpl_data->tpl_stats_block_mis_log2;
419
420 av1_zero(x->tpl_keep_ref_frame)memset(&(x->tpl_keep_ref_frame), 0, sizeof(x->tpl_keep_ref_frame
))
;
421
422 if (!av1_tpl_stats_ready(tpl_data, frame_idx)) return;
423 if (!is_frame_tpl_eligible(gf_group, cpi->gf_frame_index)) return;
424 if (cpi->oxcf.q_cfg.aq_mode != NO_AQ) return;
425
426 const int is_overlay =
427 cpi->ppi->gf_group.update_type[frame_idx] == OVERLAY_UPDATE;
428 if (is_overlay) {
429 memset(x->tpl_keep_ref_frame, 1, sizeof(x->tpl_keep_ref_frame));
430 return;
431 }
432
433 TplDepFrame *tpl_frame = &tpl_data->tpl_frame[frame_idx];
434 TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
435 const int tpl_stride = tpl_frame->stride;
436 int64_t inter_cost[INTER_REFS_PER_FRAME] = { 0 };
437 const int step = 1 << block_mis_log2;
438 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
439
440 const int mi_row_end =
441 AOMMIN(mi_size_high[sb_size] + mi_row, mi_params->mi_rows)(((mi_size_high[sb_size] + mi_row) < (mi_params->mi_rows
)) ? (mi_size_high[sb_size] + mi_row) : (mi_params->mi_rows
))
;
442 const int mi_cols_sr = av1_pixels_to_mi(cm->superres_upscaled_width);
443 const int mi_col_sr =
444 coded_to_superres_mi(mi_col, cm->superres_scale_denominator);
445 const int mi_col_end_sr =
446 AOMMIN(coded_to_superres_mi(mi_col + mi_size_wide[sb_size],(((coded_to_superres_mi(mi_col + mi_size_wide[sb_size], cm->
superres_scale_denominator)) < (mi_cols_sr)) ? (coded_to_superres_mi
(mi_col + mi_size_wide[sb_size], cm->superres_scale_denominator
)) : (mi_cols_sr))
447 cm->superres_scale_denominator),(((coded_to_superres_mi(mi_col + mi_size_wide[sb_size], cm->
superres_scale_denominator)) < (mi_cols_sr)) ? (coded_to_superres_mi
(mi_col + mi_size_wide[sb_size], cm->superres_scale_denominator
)) : (mi_cols_sr))
448 mi_cols_sr)(((coded_to_superres_mi(mi_col + mi_size_wide[sb_size], cm->
superres_scale_denominator)) < (mi_cols_sr)) ? (coded_to_superres_mi
(mi_col + mi_size_wide[sb_size], cm->superres_scale_denominator
)) : (mi_cols_sr))
;
449 const int row_step = step;
450 const int col_step_sr =
451 coded_to_superres_mi(step, cm->superres_scale_denominator);
452 for (int row = mi_row; row < mi_row_end; row += row_step) {
453 for (int col = mi_col_sr; col < mi_col_end_sr; col += col_step_sr) {
454 const TplDepStats *this_stats =
455 &tpl_stats[av1_tpl_ptr_pos(row, col, tpl_stride, block_mis_log2)];
456 int64_t tpl_pred_error[INTER_REFS_PER_FRAME] = { 0 };
457 // Find the winner ref frame idx for the current block
458 int64_t best_inter_cost = this_stats->pred_error[0];
459 int best_rf_idx = 0;
460 for (int idx = 1; idx < INTER_REFS_PER_FRAME; ++idx) {
461 if ((this_stats->pred_error[idx] < best_inter_cost) &&
462 (this_stats->pred_error[idx] != 0)) {
463 best_inter_cost = this_stats->pred_error[idx];
464 best_rf_idx = idx;
465 }
466 }
467 // tpl_pred_error is the pred_error reduction of best_ref w.r.t.
468 // LAST_FRAME.
469 tpl_pred_error[best_rf_idx] = this_stats->pred_error[best_rf_idx] -
470 this_stats->pred_error[LAST_FRAME - 1];
471
472 for (int rf_idx = 1; rf_idx < INTER_REFS_PER_FRAME; ++rf_idx)
473 inter_cost[rf_idx] += tpl_pred_error[rf_idx];
474 }
475 }
476
477 int rank_index[INTER_REFS_PER_FRAME - 1];
478 for (int idx = 0; idx < INTER_REFS_PER_FRAME - 1; ++idx) {
479 rank_index[idx] = idx + 1;
480 for (int i = idx; i > 0; --i) {
481 if (inter_cost[rank_index[i - 1]] > inter_cost[rank_index[i]]) {
482 const int tmp = rank_index[i - 1];
483 rank_index[i - 1] = rank_index[i];
484 rank_index[i] = tmp;
485 }
486 }
487 }
488
489 x->tpl_keep_ref_frame[INTRA_FRAME] = 1;
490 x->tpl_keep_ref_frame[LAST_FRAME] = 1;
491
492 int cutoff_ref = 0;
493 for (int idx = 0; idx < INTER_REFS_PER_FRAME - 1; ++idx) {
494 x->tpl_keep_ref_frame[rank_index[idx] + LAST_FRAME] = 1;
495 if (idx > 2) {
496 if (!cutoff_ref) {
497 // If the predictive coding gains are smaller than the previous more
498 // relevant frame over certain amount, discard this frame and all the
499 // frames afterwards.
500 if (llabs(inter_cost[rank_index[idx]]) <
501 llabs(inter_cost[rank_index[idx - 1]]) / 8 ||
502 inter_cost[rank_index[idx]] == 0)
503 cutoff_ref = 1;
504 }
505
506 if (cutoff_ref) x->tpl_keep_ref_frame[rank_index[idx] + LAST_FRAME] = 0;
507 }
508 }
509}
510
511static inline void adjust_rdmult_tpl_model(AV1_COMP *cpi, MACROBLOCK *x,
512 int mi_row, int mi_col) {
513 const BLOCK_SIZE sb_size = cpi->common.seq_params->sb_size;
514 const int orig_rdmult = cpi->rd.RDMULT;
515
516 assert(IMPLIES(cpi->ppi->gf_group.size > 0,((void) sizeof (((!(cpi->ppi->gf_group.size > 0) || (
cpi->gf_frame_index < cpi->ppi->gf_group.size))) ?
1 : 0), __extension__ ({ if ((!(cpi->ppi->gf_group.size
> 0) || (cpi->gf_frame_index < cpi->ppi->gf_group
.size))) ; else __assert_fail ("IMPLIES(cpi->ppi->gf_group.size > 0, cpi->gf_frame_index < cpi->ppi->gf_group.size)"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 517, __extension__ __PRETTY_FUNCTION__); }))
517 cpi->gf_frame_index < cpi->ppi->gf_group.size))((void) sizeof (((!(cpi->ppi->gf_group.size > 0) || (
cpi->gf_frame_index < cpi->ppi->gf_group.size))) ?
1 : 0), __extension__ ({ if ((!(cpi->ppi->gf_group.size
> 0) || (cpi->gf_frame_index < cpi->ppi->gf_group
.size))) ; else __assert_fail ("IMPLIES(cpi->ppi->gf_group.size > 0, cpi->gf_frame_index < cpi->ppi->gf_group.size)"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 517, __extension__ __PRETTY_FUNCTION__); }))
;
518 const int gf_group_index = cpi->gf_frame_index;
519 if (cpi->oxcf.algo_cfg.enable_tpl_model && cpi->oxcf.q_cfg.aq_mode == NO_AQ &&
520 cpi->oxcf.q_cfg.deltaq_mode == NO_DELTA_Q && gf_group_index > 0 &&
521 cpi->ppi->gf_group.update_type[gf_group_index] == ARF_UPDATE) {
522 const int dr =
523 av1_get_rdmult_delta(cpi, sb_size, mi_row, mi_col, orig_rdmult);
524 x->rdmult = dr;
525 }
526}
527#endif // !CONFIG_REALTIME_ONLY
528
529#if CONFIG_RT_ML_PARTITIONING0
530// Get a prediction(stored in x->est_pred) for the whole superblock.
531static void get_estimated_pred(AV1_COMP *cpi, const TileInfo *const tile,
532 MACROBLOCK *x, int mi_row, int mi_col) {
533 AV1_COMMON *const cm = &cpi->common;
534 const int is_key_frame = frame_is_intra_only(cm);
535 MACROBLOCKD *xd = &x->e_mbd;
536
537 // TODO(kyslov) Extend to 128x128
538 assert(cm->seq_params->sb_size == BLOCK_64X64)((void) sizeof ((cm->seq_params->sb_size == BLOCK_64X64
) ? 1 : 0), __extension__ ({ if (cm->seq_params->sb_size
== BLOCK_64X64) ; else __assert_fail ("cm->seq_params->sb_size == BLOCK_64X64"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 538, __extension__ __PRETTY_FUNCTION__); }))
;
539
540 av1_set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64);
541
542 if (!is_key_frame) {
543 MB_MODE_INFO *mi = xd->mi[0];
544 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_yv12_buf(cm, LAST_FRAME);
545
546 assert(yv12 != NULL)((void) sizeof ((yv12 != ((void*)0)) ? 1 : 0), __extension__ (
{ if (yv12 != ((void*)0)) ; else __assert_fail ("yv12 != NULL"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 546, __extension__ __PRETTY_FUNCTION__); }))
;
547
548 av1_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
549 get_ref_scale_factors(cm, LAST_FRAME), 1);
550 mi->ref_frame[0] = LAST_FRAME;
551 mi->ref_frame[1] = NONE;
552 mi->bsize = BLOCK_64X64;
553 mi->mv[0].as_int = 0;
554 mi->interp_filters = av1_broadcast_interp_filter(BILINEAR);
555
556 set_ref_ptrs(cm, xd, mi->ref_frame[0], mi->ref_frame[1]);
557
558 xd->plane[0].dst.buf = x->est_pred;
559 xd->plane[0].dst.stride = 64;
560 av1_enc_build_inter_predictor_y(xd, mi_row, mi_col);
561 } else {
562#if CONFIG_AV1_HIGHBITDEPTH1
563 switch (xd->bd) {
564 case 8: memset(x->est_pred, 128, 64 * 64 * sizeof(x->est_pred[0])); break;
565 case 10:
566 memset(x->est_pred, 128 * 4, 64 * 64 * sizeof(x->est_pred[0]));
567 break;
568 case 12:
569 memset(x->est_pred, 128 * 16, 64 * 64 * sizeof(x->est_pred[0]));
570 break;
571 }
572#else
573 memset(x->est_pred, 128, 64 * 64 * sizeof(x->est_pred[0]));
574#endif // CONFIG_VP9_HIGHBITDEPTH
575 }
576}
577#endif // CONFIG_RT_ML_PARTITIONING
578
579#define AVG_CDF_WEIGHT_LEFT3 3
580#define AVG_CDF_WEIGHT_TOP_RIGHT1 1
581
582/*!\brief Encode a superblock (minimal RD search involved)
583 *
584 * \ingroup partition_search
585 * Encodes the superblock by a pre-determined partition pattern, only minor
586 * rd-based searches are allowed to adjust the initial pattern. It is only used
587 * by realtime encoding.
588 */
589static inline void encode_nonrd_sb(AV1_COMP *cpi, ThreadData *td,
590 TileDataEnc *tile_data, TokenExtra **tp,
591 const int mi_row, const int mi_col,
592 const int seg_skip) {
593 AV1_COMMON *const cm = &cpi->common;
594 MACROBLOCK *const x = &td->mb;
595 const SPEED_FEATURES *const sf = &cpi->sf;
596 const TileInfo *const tile_info = &tile_data->tile_info;
597 MB_MODE_INFO **mi = cm->mi_params.mi_grid_base +
598 get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
599 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
600 PC_TREE *const pc_root = td->pc_root;
601
602#if !CONFIG_REALTIME_ONLY0
603 if (cm->delta_q_info.delta_q_present_flag) {
604 const int num_planes = av1_num_planes(cm);
605
606 setup_delta_q_nonrd(cpi, td, x, tile_info, mi_row, mi_col, num_planes);
607 }
608#endif
609#if CONFIG_RT_ML_PARTITIONING0
610 if (sf->part_sf.partition_search_type == ML_BASED_PARTITION) {
611 RD_STATS dummy_rdc;
612 get_estimated_pred(cpi, tile_info, x, mi_row, mi_col);
613 av1_nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col,
614 BLOCK_64X64, &dummy_rdc, 1, INT64_MAX(9223372036854775807L), pc_root);
615 return;
616 }
617#endif
618 // Set the partition
619 if (sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip ||
620 (sf->rt_sf.use_fast_fixed_part && x->sb_force_fixed_part == 1 &&
621 (!frame_is_intra_only(cm) &&
622 (!cpi->ppi->use_svc ||
623 !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame)))) {
624 // set a fixed-size partition
625 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
626 BLOCK_SIZE bsize_select = sf->part_sf.fixed_partition_size;
627 if (sf->rt_sf.use_fast_fixed_part &&
628 x->content_state_sb.source_sad_nonrd < kLowSad) {
629 bsize_select = cm->seq_params->sb_size;
630 }
631 if (cpi->sf.rt_sf.skip_encoding_non_reference_slide_change &&
632 cpi->rc.high_source_sad && cpi->ppi->rtc_ref.non_reference_frame) {
633 bsize_select = cm->seq_params->sb_size;
634 x->force_zeromv_skip_for_sb = 1;
635 }
636 const BLOCK_SIZE bsize = seg_skip ? sb_size : bsize_select;
637 if (x->content_state_sb.source_sad_nonrd > kZeroSad)
638 x->force_color_check_block_level = 1;
639 av1_set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
640 } else if (sf->part_sf.partition_search_type == VAR_BASED_PARTITION) {
641 // set a variance-based partition
642 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
643 av1_choose_var_based_partitioning(cpi, tile_info, td, x, mi_row, mi_col);
644 }
645 assert(sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip ||((void) sizeof ((sf->part_sf.partition_search_type == FIXED_PARTITION
|| seg_skip || sf->part_sf.partition_search_type == VAR_BASED_PARTITION
) ? 1 : 0), __extension__ ({ if (sf->part_sf.partition_search_type
== FIXED_PARTITION || seg_skip || sf->part_sf.partition_search_type
== VAR_BASED_PARTITION) ; else __assert_fail ("sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip || sf->part_sf.partition_search_type == VAR_BASED_PARTITION"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 646, __extension__ __PRETTY_FUNCTION__); }))
646 sf->part_sf.partition_search_type == VAR_BASED_PARTITION)((void) sizeof ((sf->part_sf.partition_search_type == FIXED_PARTITION
|| seg_skip || sf->part_sf.partition_search_type == VAR_BASED_PARTITION
) ? 1 : 0), __extension__ ({ if (sf->part_sf.partition_search_type
== FIXED_PARTITION || seg_skip || sf->part_sf.partition_search_type
== VAR_BASED_PARTITION) ; else __assert_fail ("sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip || sf->part_sf.partition_search_type == VAR_BASED_PARTITION"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 646, __extension__ __PRETTY_FUNCTION__); }))
;
647 set_cb_offsets(td->mb.cb_offset, 0, 0);
648
649 // Initialize the flag to skip cdef to 1.
650 if (sf->rt_sf.skip_cdef_sb) {
651 const int block64_in_sb = (sb_size == BLOCK_128X128) ? 2 : 1;
652 // If 128x128 block is used, we need to set the flag for all 4 64x64 sub
653 // "blocks".
654 for (int r = 0; r < block64_in_sb; ++r) {
655 for (int c = 0; c < block64_in_sb; ++c) {
656 const int idx_in_sb =
657 r * MI_SIZE_64X64(64 >> 2) * cm->mi_params.mi_stride + c * MI_SIZE_64X64(64 >> 2);
658 if (mi[idx_in_sb]) mi[idx_in_sb]->cdef_strength = 1;
659 }
660 }
661 }
662
663#if CONFIG_COLLECT_COMPONENT_TIMING0
664 start_timing(cpi, nonrd_use_partition_time);
665#endif
666 av1_nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
667 pc_root);
668#if CONFIG_COLLECT_COMPONENT_TIMING0
669 end_timing(cpi, nonrd_use_partition_time);
670#endif
671}
672
673// This function initializes the stats for encode_rd_sb.
674static inline void init_encode_rd_sb(AV1_COMP *cpi, ThreadData *td,
675 const TileDataEnc *tile_data,
676 SIMPLE_MOTION_DATA_TREE *sms_root,
677 RD_STATS *rd_cost, int mi_row, int mi_col,
678 int gather_tpl_data) {
679 const AV1_COMMON *cm = &cpi->common;
680 const TileInfo *tile_info = &tile_data->tile_info;
681 MACROBLOCK *x = &td->mb;
682
683 const SPEED_FEATURES *sf = &cpi->sf;
684 const int use_simple_motion_search =
685 (sf->part_sf.simple_motion_search_split ||
686 sf->part_sf.simple_motion_search_prune_rect ||
687 sf->part_sf.simple_motion_search_early_term_none ||
688 sf->part_sf.ml_early_term_after_part_split_level) &&
689 !frame_is_intra_only(cm);
690 if (use_simple_motion_search) {
691 av1_init_simple_motion_search_mvs_for_sb(cpi, tile_info, x, sms_root,
692 mi_row, mi_col);
693 }
694
695#if !CONFIG_REALTIME_ONLY0
696 if (!(has_no_stats_stage(cpi) && cpi->oxcf.mode == REALTIME &&
697 cpi->oxcf.gf_cfg.lag_in_frames == 0)) {
698 init_ref_frame_space(cpi, td, mi_row, mi_col);
699 x->sb_energy_level = 0;
700 x->part_search_info.cnn_output_valid = 0;
701 if (gather_tpl_data) {
702 if (cpi->cb_delta_rdmult_enabled) {
703 const int num_planes = av1_num_planes(cm);
704 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
705 setup_delta_q(cpi, td, x, tile_info, mi_row, mi_col, num_planes);
706 av1_tpl_rdmult_setup_sb(cpi, x, sb_size, mi_row, mi_col);
707 }
708
709 // TODO(jingning): revisit this function.
710 if (cpi->oxcf.algo_cfg.enable_tpl_model && (0)) {
711 adjust_rdmult_tpl_model(cpi, x, mi_row, mi_col);
712 }
713 }
714 }
715#else
716 (void)tile_info;
717 (void)mi_row;
718 (void)mi_col;
719 (void)gather_tpl_data;
720#endif
721
722 x->reuse_inter_pred = false0;
723 x->txfm_search_params.mode_eval_type = DEFAULT_EVAL;
724 reset_mb_rd_record(x->txfm_search_info.mb_rd_record);
725 av1_zero(x->picked_ref_frames_mask)memset(&(x->picked_ref_frames_mask), 0, sizeof(x->picked_ref_frames_mask
))
;
726 av1_invalid_rd_stats(rd_cost);
727}
728
729#if !CONFIG_REALTIME_ONLY0
730static void sb_qp_sweep_init_quantizers(AV1_COMP *cpi, ThreadData *td,
731 const TileDataEnc *tile_data,
732 SIMPLE_MOTION_DATA_TREE *sms_tree,
733 RD_STATS *rd_cost, int mi_row,
734 int mi_col, int delta_qp_ofs) {
735 AV1_COMMON *const cm = &cpi->common;
736 MACROBLOCK *const x = &td->mb;
737 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
738 const TileInfo *tile_info = &tile_data->tile_info;
739 const CommonModeInfoParams *const mi_params = &cm->mi_params;
740 const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
741 assert(delta_q_info->delta_q_present_flag)((void) sizeof ((delta_q_info->delta_q_present_flag) ? 1 :
0), __extension__ ({ if (delta_q_info->delta_q_present_flag
) ; else __assert_fail ("delta_q_info->delta_q_present_flag"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 741, __extension__ __PRETTY_FUNCTION__); }))
;
742 const int delta_q_res = delta_q_info->delta_q_res;
743
744 const SPEED_FEATURES *sf = &cpi->sf;
745 const int use_simple_motion_search =
746 (sf->part_sf.simple_motion_search_split ||
747 sf->part_sf.simple_motion_search_prune_rect ||
748 sf->part_sf.simple_motion_search_early_term_none ||
749 sf->part_sf.ml_early_term_after_part_split_level) &&
750 !frame_is_intra_only(cm);
751 if (use_simple_motion_search) {
752 av1_init_simple_motion_search_mvs_for_sb(cpi, tile_info, x, sms_tree,
753 mi_row, mi_col);
754 }
755
756 int current_qindex = x->rdmult_cur_qindex + delta_qp_ofs;
757
758 MACROBLOCKD *const xd = &x->e_mbd;
759 current_qindex = av1_adjust_q_from_delta_q_res(
760 delta_q_res, xd->current_base_qindex, current_qindex);
761
762 x->delta_qindex = current_qindex - cm->quant_params.base_qindex;
763
764 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
765 xd->mi[0]->current_qindex = current_qindex;
766 av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 0);
767
768 // keep track of any non-zero delta-q used
769 td->deltaq_used |= (x->delta_qindex != 0);
770
771 if (cpi->oxcf.tool_cfg.enable_deltalf_mode) {
772 const int delta_lf_res = delta_q_info->delta_lf_res;
773 const int lfmask = ~(delta_lf_res - 1);
774 const int delta_lf_from_base =
775 ((x->delta_qindex / 4 + delta_lf_res / 2) & lfmask);
776 const int8_t delta_lf =
777 (int8_t)clamp(delta_lf_from_base, -MAX_LOOP_FILTER63, MAX_LOOP_FILTER63);
778 const int frame_lf_count =
779 av1_num_planes(cm) > 1 ? FRAME_LF_COUNT4 : FRAME_LF_COUNT4 - 2;
780 const int mib_size = cm->seq_params->mib_size;
781
782 // pre-set the delta lf for loop filter. Note that this value is set
783 // before mi is assigned for each block in current superblock
784 for (int j = 0; j < AOMMIN(mib_size, mi_params->mi_rows - mi_row)(((mib_size) < (mi_params->mi_rows - mi_row)) ? (mib_size
) : (mi_params->mi_rows - mi_row))
; j++) {
785 for (int k = 0; k < AOMMIN(mib_size, mi_params->mi_cols - mi_col)(((mib_size) < (mi_params->mi_cols - mi_col)) ? (mib_size
) : (mi_params->mi_cols - mi_col))
; k++) {
786 const int grid_idx = get_mi_grid_idx(mi_params, mi_row + j, mi_col + k);
787 mi_params->mi_alloc[grid_idx].delta_lf_from_base = delta_lf;
788 for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) {
789 mi_params->mi_alloc[grid_idx].delta_lf[lf_id] = delta_lf;
790 }
791 }
792 }
793 }
794
795 x->reuse_inter_pred = false0;
796 x->txfm_search_params.mode_eval_type = DEFAULT_EVAL;
797 reset_mb_rd_record(x->txfm_search_info.mb_rd_record);
798 av1_zero(x->picked_ref_frames_mask)memset(&(x->picked_ref_frames_mask), 0, sizeof(x->picked_ref_frames_mask
))
;
799 av1_invalid_rd_stats(rd_cost);
800}
801
802static int sb_qp_sweep(AV1_COMP *const cpi, ThreadData *td,
803 TileDataEnc *tile_data, TokenExtra **tp, int mi_row,
804 int mi_col, BLOCK_SIZE bsize,
805 SIMPLE_MOTION_DATA_TREE *sms_tree,
806 SB_FIRST_PASS_STATS *sb_org_stats) {
807 AV1_COMMON *const cm = &cpi->common;
808 MACROBLOCK *const x = &td->mb;
809 RD_STATS rdc_winner, cur_rdc;
810 av1_invalid_rd_stats(&rdc_winner);
811
812 int best_qindex = td->mb.rdmult_delta_qindex;
813 const int start = cm->current_frame.frame_type == KEY_FRAME ? -20 : -12;
814 const int end = cm->current_frame.frame_type == KEY_FRAME ? 20 : 12;
815 const int step = cm->delta_q_info.delta_q_res;
816
817 for (int sweep_qp_delta = start; sweep_qp_delta <= end;
818 sweep_qp_delta += step) {
819 sb_qp_sweep_init_quantizers(cpi, td, tile_data, sms_tree, &cur_rdc, mi_row,
820 mi_col, sweep_qp_delta);
821
822 const int alloc_mi_idx = get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
823 const int backup_current_qindex =
824 cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex;
825
826 av1_reset_mbmi(&cm->mi_params, bsize, mi_row, mi_col);
827 av1_restore_sb_state(sb_org_stats, cpi, td, tile_data, mi_row, mi_col);
828 cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex = backup_current_qindex;
829
830 td->pc_root = av1_alloc_pc_tree_node(bsize);
831 if (!td->pc_root)
832 aom_internal_error(x->e_mbd.error_info, AOM_CODEC_MEM_ERROR,
833 "Failed to allocate PC_TREE");
834 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize,
835 &cur_rdc, cur_rdc, td->pc_root, sms_tree, NULL((void*)0),
836 SB_DRY_PASS, NULL((void*)0));
837
838 if ((rdc_winner.rdcost > cur_rdc.rdcost) ||
839 (abs(sweep_qp_delta) < abs(best_qindex - x->rdmult_delta_qindex) &&
840 rdc_winner.rdcost == cur_rdc.rdcost)) {
841 rdc_winner = cur_rdc;
842 best_qindex = x->rdmult_delta_qindex + sweep_qp_delta;
843 }
844 }
845
846 return best_qindex;
847}
848#endif //! CONFIG_REALTIME_ONLY
849
850/*!\brief Encode a superblock (RD-search-based)
851 *
852 * \ingroup partition_search
853 * Conducts partition search for a superblock, based on rate-distortion costs,
854 * from scratch or adjusting from a pre-calculated partition pattern.
855 */
856static inline void encode_rd_sb(AV1_COMP *cpi, ThreadData *td,
857 TileDataEnc *tile_data, TokenExtra **tp,
858 const int mi_row, const int mi_col,
859 const int seg_skip) {
860 AV1_COMMON *const cm = &cpi->common;
861 MACROBLOCK *const x = &td->mb;
862 MACROBLOCKD *const xd = &x->e_mbd;
863 const SPEED_FEATURES *const sf = &cpi->sf;
864 const TileInfo *const tile_info = &tile_data->tile_info;
865 MB_MODE_INFO **mi = cm->mi_params.mi_grid_base +
866 get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
867 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
868 const int num_planes = av1_num_planes(cm);
869 int dummy_rate;
870 int64_t dummy_dist;
871 RD_STATS dummy_rdc;
872 SIMPLE_MOTION_DATA_TREE *const sms_root = td->sms_root;
873
874#if CONFIG_REALTIME_ONLY0
875 (void)seg_skip;
876#endif // CONFIG_REALTIME_ONLY
877
878 init_encode_rd_sb(cpi, td, tile_data, sms_root, &dummy_rdc, mi_row, mi_col,
879 1);
880
881 // Encode the superblock
882 if (sf->part_sf.partition_search_type == VAR_BASED_PARTITION) {
883 // partition search starting from a variance-based partition
884 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
885 av1_choose_var_based_partitioning(cpi, tile_info, td, x, mi_row, mi_col);
886
887#if CONFIG_COLLECT_COMPONENT_TIMING0
888 start_timing(cpi, rd_use_partition_time);
889#endif
890 td->pc_root = av1_alloc_pc_tree_node(sb_size);
891 if (!td->pc_root)
892 aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
893 "Failed to allocate PC_TREE");
894 av1_rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
895 &dummy_rate, &dummy_dist, 1, td->pc_root);
896 av1_free_pc_tree_recursive(td->pc_root, num_planes, 0, 0,
897 sf->part_sf.partition_search_type);
898 td->pc_root = NULL((void*)0);
899#if CONFIG_COLLECT_COMPONENT_TIMING0
900 end_timing(cpi, rd_use_partition_time);
901#endif
902 }
903#if !CONFIG_REALTIME_ONLY0
904 else if (sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip) {
905 // partition search by adjusting a fixed-size partition
906 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
907 const BLOCK_SIZE bsize =
908 seg_skip ? sb_size : sf->part_sf.fixed_partition_size;
909 av1_set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
910 td->pc_root = av1_alloc_pc_tree_node(sb_size);
911 if (!td->pc_root)
912 aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
913 "Failed to allocate PC_TREE");
914 av1_rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
915 &dummy_rate, &dummy_dist, 1, td->pc_root);
916 av1_free_pc_tree_recursive(td->pc_root, num_planes, 0, 0,
917 sf->part_sf.partition_search_type);
918 td->pc_root = NULL((void*)0);
919 } else {
920 // The most exhaustive recursive partition search
921 SuperBlockEnc *sb_enc = &x->sb_enc;
922 // No stats for overlay frames. Exclude key frame.
923 av1_get_tpl_stats_sb(cpi, sb_size, mi_row, mi_col, sb_enc);
924
925 // Reset the tree for simple motion search data
926 av1_reset_simple_motion_tree_partition(sms_root, sb_size);
927
928#if CONFIG_COLLECT_COMPONENT_TIMING0
929 start_timing(cpi, rd_pick_partition_time);
930#endif
931
932 // Estimate the maximum square partition block size, which will be used
933 // as the starting block size for partitioning the sb
934 set_max_min_partition_size(sb_enc, cpi, x, sf, sb_size, mi_row, mi_col);
935
936 // The superblock can be searched only once, or twice consecutively for
937 // better quality. Note that the meaning of passes here is different from
938 // the general concept of 1-pass/2-pass encoders.
939 const int num_passes =
940 cpi->oxcf.unit_test_cfg.sb_multipass_unit_test ? 2 : 1;
941
942 if (cpi->oxcf.sb_qp_sweep &&
943 !(has_no_stats_stage(cpi) && cpi->oxcf.mode == REALTIME &&
944 cpi->oxcf.gf_cfg.lag_in_frames == 0) &&
945 cm->delta_q_info.delta_q_present_flag) {
946 AOM_CHECK_MEM_ERROR(do { ((void) sizeof (((x->e_mbd.error_info)->setjmp) ? 1
: 0), __extension__ ({ if ((x->e_mbd.error_info)->setjmp
) ; else __assert_fail ("(x->e_mbd.error_info)->setjmp"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 948, __extension__ __PRETTY_FUNCTION__); })); td->mb.sb_stats_cache
= ((SB_FIRST_PASS_STATS *)aom_malloc(sizeof(*td->mb.sb_stats_cache
))); if (!td->mb.sb_stats_cache) aom_internal_error(x->
e_mbd.error_info, AOM_CODEC_MEM_ERROR, "Failed to allocate " "td->mb.sb_stats_cache"
); } while (0)
947 x->e_mbd.error_info, td->mb.sb_stats_cache,do { ((void) sizeof (((x->e_mbd.error_info)->setjmp) ? 1
: 0), __extension__ ({ if ((x->e_mbd.error_info)->setjmp
) ; else __assert_fail ("(x->e_mbd.error_info)->setjmp"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 948, __extension__ __PRETTY_FUNCTION__); })); td->mb.sb_stats_cache
= ((SB_FIRST_PASS_STATS *)aom_malloc(sizeof(*td->mb.sb_stats_cache
))); if (!td->mb.sb_stats_cache) aom_internal_error(x->
e_mbd.error_info, AOM_CODEC_MEM_ERROR, "Failed to allocate " "td->mb.sb_stats_cache"
); } while (0)
948 (SB_FIRST_PASS_STATS *)aom_malloc(sizeof(*td->mb.sb_stats_cache)))do { ((void) sizeof (((x->e_mbd.error_info)->setjmp) ? 1
: 0), __extension__ ({ if ((x->e_mbd.error_info)->setjmp
) ; else __assert_fail ("(x->e_mbd.error_info)->setjmp"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 948, __extension__ __PRETTY_FUNCTION__); })); td->mb.sb_stats_cache
= ((SB_FIRST_PASS_STATS *)aom_malloc(sizeof(*td->mb.sb_stats_cache
))); if (!td->mb.sb_stats_cache) aom_internal_error(x->
e_mbd.error_info, AOM_CODEC_MEM_ERROR, "Failed to allocate " "td->mb.sb_stats_cache"
); } while (0)
;
949 av1_backup_sb_state(td->mb.sb_stats_cache, cpi, td, tile_data, mi_row,
950 mi_col);
951 assert(x->rdmult_delta_qindex == x->delta_qindex)((void) sizeof ((x->rdmult_delta_qindex == x->delta_qindex
) ? 1 : 0), __extension__ ({ if (x->rdmult_delta_qindex ==
x->delta_qindex) ; else __assert_fail ("x->rdmult_delta_qindex == x->delta_qindex"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 951, __extension__ __PRETTY_FUNCTION__); }))
;
952
953 const int best_qp_diff =
954 sb_qp_sweep(cpi, td, tile_data, tp, mi_row, mi_col, sb_size, sms_root,
955 td->mb.sb_stats_cache) -
956 x->rdmult_delta_qindex;
957
958 sb_qp_sweep_init_quantizers(cpi, td, tile_data, sms_root, &dummy_rdc,
959 mi_row, mi_col, best_qp_diff);
960
961 const int alloc_mi_idx = get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
962 const int backup_current_qindex =
963 cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex;
964
965 av1_reset_mbmi(&cm->mi_params, sb_size, mi_row, mi_col);
966 av1_restore_sb_state(td->mb.sb_stats_cache, cpi, td, tile_data, mi_row,
967 mi_col);
968
969 cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex =
970 backup_current_qindex;
971 aom_free(td->mb.sb_stats_cache);
972 td->mb.sb_stats_cache = NULL((void*)0);
973 }
974 if (num_passes == 1) {
975#if CONFIG_PARTITION_SEARCH_ORDER0
976 if (cpi->ext_part_controller.ready && !frame_is_intra_only(cm)) {
977 av1_reset_part_sf(&cpi->sf.part_sf);
978 av1_reset_sf_for_ext_part(cpi);
979 RD_STATS this_rdc;
980 av1_rd_partition_search(cpi, td, tile_data, tp, sms_root, mi_row,
981 mi_col, sb_size, &this_rdc);
982 } else {
983 td->pc_root = av1_alloc_pc_tree_node(sb_size);
984 if (!td->pc_root)
985 aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
986 "Failed to allocate PC_TREE");
987 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
988 &dummy_rdc, dummy_rdc, td->pc_root, sms_root,
989 NULL((void*)0), SB_SINGLE_PASS, NULL((void*)0));
990 }
991#else
992 td->pc_root = av1_alloc_pc_tree_node(sb_size);
993 if (!td->pc_root)
994 aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
995 "Failed to allocate PC_TREE");
996 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
997 &dummy_rdc, dummy_rdc, td->pc_root, sms_root, NULL((void*)0),
998 SB_SINGLE_PASS, NULL((void*)0));
999#endif // CONFIG_PARTITION_SEARCH_ORDER
1000 } else {
1001 // First pass
1002 AOM_CHECK_MEM_ERROR(do { ((void) sizeof (((x->e_mbd.error_info)->setjmp) ? 1
: 0), __extension__ ({ if ((x->e_mbd.error_info)->setjmp
) ; else __assert_fail ("(x->e_mbd.error_info)->setjmp"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1004, __extension__ __PRETTY_FUNCTION__); })); td->mb.sb_fp_stats
= ((SB_FIRST_PASS_STATS *)aom_malloc(sizeof(*td->mb.sb_fp_stats
))); if (!td->mb.sb_fp_stats) aom_internal_error(x->e_mbd
.error_info, AOM_CODEC_MEM_ERROR, "Failed to allocate " "td->mb.sb_fp_stats"
); } while (0)
1003 x->e_mbd.error_info, td->mb.sb_fp_stats,do { ((void) sizeof (((x->e_mbd.error_info)->setjmp) ? 1
: 0), __extension__ ({ if ((x->e_mbd.error_info)->setjmp
) ; else __assert_fail ("(x->e_mbd.error_info)->setjmp"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1004, __extension__ __PRETTY_FUNCTION__); })); td->mb.sb_fp_stats
= ((SB_FIRST_PASS_STATS *)aom_malloc(sizeof(*td->mb.sb_fp_stats
))); if (!td->mb.sb_fp_stats) aom_internal_error(x->e_mbd
.error_info, AOM_CODEC_MEM_ERROR, "Failed to allocate " "td->mb.sb_fp_stats"
); } while (0)
1004 (SB_FIRST_PASS_STATS *)aom_malloc(sizeof(*td->mb.sb_fp_stats)))do { ((void) sizeof (((x->e_mbd.error_info)->setjmp) ? 1
: 0), __extension__ ({ if ((x->e_mbd.error_info)->setjmp
) ; else __assert_fail ("(x->e_mbd.error_info)->setjmp"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1004, __extension__ __PRETTY_FUNCTION__); })); td->mb.sb_fp_stats
= ((SB_FIRST_PASS_STATS *)aom_malloc(sizeof(*td->mb.sb_fp_stats
))); if (!td->mb.sb_fp_stats) aom_internal_error(x->e_mbd
.error_info, AOM_CODEC_MEM_ERROR, "Failed to allocate " "td->mb.sb_fp_stats"
); } while (0)
;
1005 av1_backup_sb_state(td->mb.sb_fp_stats, cpi, td, tile_data, mi_row,
1006 mi_col);
1007 td->pc_root = av1_alloc_pc_tree_node(sb_size);
1008 if (!td->pc_root)
1009 aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
1010 "Failed to allocate PC_TREE");
1011 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
1012 &dummy_rdc, dummy_rdc, td->pc_root, sms_root, NULL((void*)0),
1013 SB_DRY_PASS, NULL((void*)0));
1014
1015 // Second pass
1016 init_encode_rd_sb(cpi, td, tile_data, sms_root, &dummy_rdc, mi_row,
1017 mi_col, 0);
1018 av1_reset_mbmi(&cm->mi_params, sb_size, mi_row, mi_col);
1019 av1_reset_simple_motion_tree_partition(sms_root, sb_size);
1020
1021 av1_restore_sb_state(td->mb.sb_fp_stats, cpi, td, tile_data, mi_row,
1022 mi_col);
1023
1024 td->pc_root = av1_alloc_pc_tree_node(sb_size);
1025 if (!td->pc_root)
1026 aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
1027 "Failed to allocate PC_TREE");
1028 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
1029 &dummy_rdc, dummy_rdc, td->pc_root, sms_root, NULL((void*)0),
1030 SB_WET_PASS, NULL((void*)0));
1031 aom_free(td->mb.sb_fp_stats);
1032 td->mb.sb_fp_stats = NULL((void*)0);
1033 }
1034
1035 // Reset to 0 so that it wouldn't be used elsewhere mistakenly.
1036 sb_enc->tpl_data_count = 0;
1037#if CONFIG_COLLECT_COMPONENT_TIMING0
1038 end_timing(cpi, rd_pick_partition_time);
1039#endif
1040 }
1041#endif // !CONFIG_REALTIME_ONLY
1042
1043 // Update the inter rd model
1044 // TODO(angiebird): Let inter_mode_rd_model_estimation support multi-tile.
1045 if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 1 &&
1046 cm->tiles.cols == 1 && cm->tiles.rows == 1) {
1047 av1_inter_mode_data_fit(tile_data, x->rdmult);
1048 }
1049}
1050
1051// Check if the cost update of symbols mode, coeff and dv are tile or off.
1052static inline int is_mode_coeff_dv_upd_freq_tile_or_off(
1053 const AV1_COMP *const cpi) {
1054 const INTER_MODE_SPEED_FEATURES *const inter_sf = &cpi->sf.inter_sf;
1055
1056 return (inter_sf->coeff_cost_upd_level <= INTERNAL_COST_UPD_TILE &&
1057 inter_sf->mode_cost_upd_level <= INTERNAL_COST_UPD_TILE &&
1058 cpi->sf.intra_sf.dv_cost_upd_level <= INTERNAL_COST_UPD_TILE);
1059}
1060
1061// When row-mt is enabled and cost update frequencies are set to off/tile,
1062// processing of current SB can start even before processing of top-right SB
1063// is finished. This function checks if it is sufficient to wait for top SB
1064// to finish processing before current SB starts processing.
1065static inline int delay_wait_for_top_right_sb(const AV1_COMP *const cpi) {
1066 const MODE mode = cpi->oxcf.mode;
1067 if (mode == GOOD) return 0;
1068
1069 if (mode == ALLINTRA)
1070 return is_mode_coeff_dv_upd_freq_tile_or_off(cpi);
1071 else if (mode == REALTIME)
1072 return (is_mode_coeff_dv_upd_freq_tile_or_off(cpi) &&
1073 cpi->sf.inter_sf.mv_cost_upd_level <= INTERNAL_COST_UPD_TILE);
1074 else
1075 return 0;
1076}
1077
1078/*!\brief Calculate source SAD at superblock level using 64x64 block source SAD
1079 *
1080 * \ingroup partition_search
1081 * \callgraph
1082 * \callergraph
1083 */
1084static inline uint64_t get_sb_source_sad(const AV1_COMP *cpi, int mi_row,
1085 int mi_col) {
1086 if (cpi->src_sad_blk_64x64 == NULL((void*)0)) return UINT64_MAX(18446744073709551615UL);
1087
1088 const AV1_COMMON *const cm = &cpi->common;
1089 const int blk_64x64_in_mis = (cm->seq_params->sb_size == BLOCK_128X128)
1090 ? (cm->seq_params->mib_size >> 1)
1091 : cm->seq_params->mib_size;
1092 const int num_blk_64x64_cols =
1093 (cm->mi_params.mi_cols + blk_64x64_in_mis - 1) / blk_64x64_in_mis;
1094 const int num_blk_64x64_rows =
1095 (cm->mi_params.mi_rows + blk_64x64_in_mis - 1) / blk_64x64_in_mis;
1096 const int blk_64x64_col_index = mi_col / blk_64x64_in_mis;
1097 const int blk_64x64_row_index = mi_row / blk_64x64_in_mis;
1098 uint64_t curr_sb_sad = UINT64_MAX(18446744073709551615UL);
1099 // Avoid the border as sad_blk_64x64 may not be set for the border
1100 // in the scene detection.
1101 if ((blk_64x64_row_index >= num_blk_64x64_rows - 1) ||
1102 (blk_64x64_col_index >= num_blk_64x64_cols - 1)) {
1103 return curr_sb_sad;
1104 }
1105 const uint64_t *const src_sad_blk_64x64_data =
1106 &cpi->src_sad_blk_64x64[blk_64x64_col_index +
1107 blk_64x64_row_index * num_blk_64x64_cols];
1108 if (cm->seq_params->sb_size == BLOCK_128X128) {
1109 // Calculate SB source SAD by accumulating source SAD of 64x64 blocks in the
1110 // superblock
1111 curr_sb_sad = src_sad_blk_64x64_data[0] + src_sad_blk_64x64_data[1] +
1112 src_sad_blk_64x64_data[num_blk_64x64_cols] +
1113 src_sad_blk_64x64_data[num_blk_64x64_cols + 1];
1114 } else if (cm->seq_params->sb_size == BLOCK_64X64) {
1115 curr_sb_sad = src_sad_blk_64x64_data[0];
1116 }
1117 return curr_sb_sad;
1118}
1119
1120/*!\brief Determine whether grading content can be skipped based on sad stat
1121 *
1122 * \ingroup partition_search
1123 * \callgraph
1124 * \callergraph
1125 */
1126static inline bool_Bool is_calc_src_content_needed(AV1_COMP *cpi,
1127 MACROBLOCK *const x, int mi_row,
1128 int mi_col) {
1129 if (cpi->svc.spatial_layer_id < cpi->svc.number_spatial_layers - 1)
1130 return true1;
1131 const uint64_t curr_sb_sad = get_sb_source_sad(cpi, mi_row, mi_col);
1132 if (curr_sb_sad == UINT64_MAX(18446744073709551615UL)) return true1;
1133 if (curr_sb_sad == 0) {
1134 x->content_state_sb.source_sad_nonrd = kZeroSad;
1135 return false0;
1136 }
1137 AV1_COMMON *const cm = &cpi->common;
1138 bool_Bool do_calc_src_content = true1;
1139
1140 if (cpi->oxcf.speed < 9) return do_calc_src_content;
1141
1142 // TODO(yunqing): Tune/validate the thresholds for 128x128 SB size.
1143 if (AOMMIN(cm->width, cm->height)(((cm->width) < (cm->height)) ? (cm->width) : (cm
->height))
< 360) {
1144 // Derive Average 64x64 block source SAD from SB source SAD
1145 const uint64_t avg_64x64_blk_sad =
1146 (cm->seq_params->sb_size == BLOCK_128X128) ? ((curr_sb_sad + 2) >> 2)
1147 : curr_sb_sad;
1148
1149 // The threshold is determined based on kLowSad and kHighSad threshold and
1150 // test results.
1151 uint64_t thresh_low = 15000;
1152 uint64_t thresh_high = 40000;
1153
1154 if (cpi->sf.rt_sf.increase_source_sad_thresh) {
1155 thresh_low = thresh_low << 1;
1156 thresh_high = thresh_high << 1;
1157 }
1158
1159 if (avg_64x64_blk_sad > thresh_low && avg_64x64_blk_sad < thresh_high) {
1160 do_calc_src_content = false0;
1161 // Note: set x->content_state_sb.source_sad_rd as well if this is extended
1162 // to RTC rd path.
1163 x->content_state_sb.source_sad_nonrd = kMedSad;
1164 }
1165 }
1166
1167 return do_calc_src_content;
1168}
1169
1170/*!\brief Determine whether grading content is needed based on sf and frame stat
1171 *
1172 * \ingroup partition_search
1173 * \callgraph
1174 * \callergraph
1175 */
1176// TODO(any): consolidate sfs to make interface cleaner
1177static inline void grade_source_content_sb(AV1_COMP *cpi, MACROBLOCK *const x,
1178 TileDataEnc *tile_data, int mi_row,
1179 int mi_col) {
1180 AV1_COMMON *const cm = &cpi->common;
1181 if (cm->current_frame.frame_type == KEY_FRAME ||
1182 (cpi->ppi->use_svc &&
1183 cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame)) {
1184 assert(x->content_state_sb.source_sad_nonrd == kMedSad)((void) sizeof ((x->content_state_sb.source_sad_nonrd == kMedSad
) ? 1 : 0), __extension__ ({ if (x->content_state_sb.source_sad_nonrd
== kMedSad) ; else __assert_fail ("x->content_state_sb.source_sad_nonrd == kMedSad"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1184, __extension__ __PRETTY_FUNCTION__); }))
;
1185 assert(x->content_state_sb.source_sad_rd == kMedSad)((void) sizeof ((x->content_state_sb.source_sad_rd == kMedSad
) ? 1 : 0), __extension__ ({ if (x->content_state_sb.source_sad_rd
== kMedSad) ; else __assert_fail ("x->content_state_sb.source_sad_rd == kMedSad"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1185, __extension__ __PRETTY_FUNCTION__); }))
;
1186 return;
1187 }
1188 bool_Bool calc_src_content = false0;
1189
1190 if (cpi->sf.rt_sf.source_metrics_sb_nonrd) {
1191 if (!cpi->sf.rt_sf.check_scene_detection || cpi->rc.frame_source_sad > 0) {
1192 calc_src_content = is_calc_src_content_needed(cpi, x, mi_row, mi_col);
1193 } else {
1194 x->content_state_sb.source_sad_nonrd = kZeroSad;
1195 }
1196 } else if ((cpi->sf.rt_sf.var_part_based_on_qidx >= 1) &&
1197 (cm->width * cm->height <= 352 * 288)) {
1198 if (cpi->rc.frame_source_sad > 0)
1199 calc_src_content = true1;
1200 else
1201 x->content_state_sb.source_sad_rd = kZeroSad;
1202 }
1203 if (calc_src_content)
1204 av1_source_content_sb(cpi, x, tile_data, mi_row, mi_col);
1205}
1206
1207/*!\brief Encode a superblock row by breaking it into superblocks
1208 *
1209 * \ingroup partition_search
1210 * \callgraph
1211 * \callergraph
1212 * Do partition and mode search for an sb row: one row of superblocks filling up
1213 * the width of the current tile.
1214 */
1215static inline void encode_sb_row(AV1_COMP *cpi, ThreadData *td,
1216 TileDataEnc *tile_data, int mi_row,
1217 TokenExtra **tp) {
1218 AV1_COMMON *const cm = &cpi->common;
1219 const TileInfo *const tile_info = &tile_data->tile_info;
1220 MultiThreadInfo *const mt_info = &cpi->mt_info;
1221 AV1EncRowMultiThreadInfo *const enc_row_mt = &mt_info->enc_row_mt;
1222 AV1EncRowMultiThreadSync *const row_mt_sync = &tile_data->row_mt_sync;
1223 bool_Bool row_mt_enabled = mt_info->row_mt_enabled;
1224 MACROBLOCK *const x = &td->mb;
1225 MACROBLOCKD *const xd = &x->e_mbd;
1226 const int sb_cols_in_tile = av1_get_sb_cols_in_tile(cm, tile_info);
1227 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
1228 const int mib_size = cm->seq_params->mib_size;
1229 const int mib_size_log2 = cm->seq_params->mib_size_log2;
1230 const int sb_row = (mi_row - tile_info->mi_row_start) >> mib_size_log2;
1231 const int use_nonrd_mode = cpi->sf.rt_sf.use_nonrd_pick_mode;
1232
1233#if CONFIG_COLLECT_COMPONENT_TIMING0
1234 start_timing(cpi, encode_sb_row_time);
1235#endif
1236
1237 // Initialize the left context for the new SB row
1238 av1_zero_left_context(xd);
1239
1240 // Reset delta for quantizer and loof filters at the beginning of every tile
1241 if (mi_row
21.1
'mi_row' is equal to field 'mi_row_start'
== tile_info->mi_row_start || row_mt_enabled) {
1242 if (cpi->cb_delta_rdmult_enabled)
22
Assuming field 'cb_delta_rdmult_enabled' is 0
23
Taking false branch
1243 xd->current_base_qindex = cm->quant_params.base_qindex;
1244 if (cm->delta_q_info.delta_lf_present_flag) {
24
Assuming field 'delta_lf_present_flag' is 0
25
Taking false branch
1245 av1_reset_loop_filter_delta(xd, av1_num_planes(cm));
1246 }
1247 }
1248
1249 reset_thresh_freq_fact(x);
1250
1251 // Code each SB in the row
1252 for (int mi_col = tile_info->mi_col_start, sb_col_in_tile = 0;
27
Loop condition is false. Execution continues on line 1524
1253 mi_col < tile_info->mi_col_end; mi_col += mib_size, sb_col_in_tile++) {
26
Assuming 'mi_col' is >= field 'mi_col_end'
1254 // In realtime/allintra mode and when frequency of cost updates is off/tile,
1255 // wait for the top superblock to finish encoding. Otherwise, wait for the
1256 // top-right superblock to finish encoding.
1257 enc_row_mt->sync_read_ptr(
1258 row_mt_sync, sb_row, sb_col_in_tile - delay_wait_for_top_right_sb(cpi));
1259
1260#if CONFIG_MULTITHREAD1
1261 if (row_mt_enabled) {
1262 pthread_mutex_lock(enc_row_mt->mutex_);
1263 const bool_Bool row_mt_exit = enc_row_mt->row_mt_exit;
1264 pthread_mutex_unlock(enc_row_mt->mutex_);
1265 // Exit in case any worker has encountered an error.
1266 if (row_mt_exit) return;
1267 }
1268#endif
1269
1270 const int update_cdf = tile_data->allow_update_cdf && row_mt_enabled;
1271 if (update_cdf && (tile_info->mi_row_start != mi_row)) {
1272 if ((tile_info->mi_col_start == mi_col)) {
1273 // restore frame context at the 1st column sb
1274 *xd->tile_ctx = *x->row_ctx;
1275 } else {
1276 // update context
1277 int wt_left = AVG_CDF_WEIGHT_LEFT3;
1278 int wt_tr = AVG_CDF_WEIGHT_TOP_RIGHT1;
1279 if (tile_info->mi_col_end > (mi_col + mib_size))
1280 av1_avg_cdf_symbols(xd->tile_ctx, x->row_ctx + sb_col_in_tile,
1281 wt_left, wt_tr);
1282 else
1283 av1_avg_cdf_symbols(xd->tile_ctx, x->row_ctx + sb_col_in_tile - 1,
1284 wt_left, wt_tr);
1285 }
1286 }
1287
1288 // Update the rate cost tables for some symbols
1289 av1_set_cost_upd_freq(cpi, td, tile_info, mi_row, mi_col);
1290
1291 // Reset color coding related parameters
1292 av1_zero(x->color_sensitivity_sb)memset(&(x->color_sensitivity_sb), 0, sizeof(x->color_sensitivity_sb
))
;
1293 av1_zero(x->color_sensitivity_sb_g)memset(&(x->color_sensitivity_sb_g), 0, sizeof(x->color_sensitivity_sb_g
))
;
1294 av1_zero(x->color_sensitivity_sb_alt)memset(&(x->color_sensitivity_sb_alt), 0, sizeof(x->
color_sensitivity_sb_alt))
;
1295 av1_zero(x->color_sensitivity)memset(&(x->color_sensitivity), 0, sizeof(x->color_sensitivity
))
;
1296 x->content_state_sb.source_sad_nonrd = kMedSad;
1297 x->content_state_sb.source_sad_rd = kMedSad;
1298 x->content_state_sb.lighting_change = 0;
1299 x->content_state_sb.low_sumdiff = 0;
1300 x->force_zeromv_skip_for_sb = 0;
1301 x->sb_me_block = 0;
1302 x->sb_me_partition = 0;
1303 x->sb_me_mv.as_int = 0;
1304 x->sb_force_fixed_part = 1;
1305 x->color_palette_thresh = 64;
1306 x->force_color_check_block_level = 0;
1307 x->nonrd_prune_ref_frame_search =
1308 cpi->sf.rt_sf.nonrd_prune_ref_frame_search;
1309
1310 if (cpi->oxcf.mode == ALLINTRA) {
1311 x->intra_sb_rdmult_modifier = 128;
1312 }
1313
1314 xd->cur_frame_force_integer_mv = cm->features.cur_frame_force_integer_mv;
1315 x->source_variance = UINT_MAX(2147483647 *2U +1U);
1316 td->mb.cb_coef_buff = av1_get_cb_coeff_buffer(cpi, mi_row, mi_col);
1317
1318 // Get segment id and skip flag
1319 const struct segmentation *const seg = &cm->seg;
1320 int seg_skip = 0;
1321 if (seg->enabled) {
1322 const uint8_t *const map =
1323 seg->update_map ? cpi->enc_seg.map : cm->last_frame_seg_map;
1324 const uint8_t segment_id =
1325 map ? get_segment_id(&cm->mi_params, map, sb_size, mi_row, mi_col)
1326 : 0;
1327 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
1328 }
1329
1330 produce_gradients_for_sb(cpi, x, sb_size, mi_row, mi_col);
1331
1332 init_src_var_info_of_4x4_sub_blocks(cpi, x->src_var_info_of_4x4_sub_blocks,
1333 sb_size);
1334
1335 // Grade the temporal variation of the sb, the grade will be used to decide
1336 // fast mode search strategy for coding blocks
1337 if (!seg_skip) grade_source_content_sb(cpi, x, tile_data, mi_row, mi_col);
1338
1339 // encode the superblock
1340 if (use_nonrd_mode) {
1341 encode_nonrd_sb(cpi, td, tile_data, tp, mi_row, mi_col, seg_skip);
1342 } else {
1343 encode_rd_sb(cpi, td, tile_data, tp, mi_row, mi_col, seg_skip);
1344 }
1345
1346 // Update the top-right context in row_mt coding
1347 if (update_cdf && (tile_info->mi_row_end > (mi_row + mib_size))) {
1348 if (sb_cols_in_tile == 1)
1349 x->row_ctx[0] = *xd->tile_ctx;
1350 else if (sb_col_in_tile >= 1)
1351 x->row_ctx[sb_col_in_tile - 1] = *xd->tile_ctx;
1352 }
1353 enc_row_mt->sync_write_ptr(row_mt_sync, sb_row, sb_col_in_tile,
1354 sb_cols_in_tile);
1355 }
1356
1357#if CONFIG_COLLECT_COMPONENT_TIMING0
1358 end_timing(cpi, encode_sb_row_time);
1359#endif
1360}
28
Returning without writing to '*tp'
1361
1362static inline void init_encode_frame_mb_context(AV1_COMP *cpi) {
1363 AV1_COMMON *const cm = &cpi->common;
1364 const int num_planes = av1_num_planes(cm);
1365 MACROBLOCK *const x = &cpi->td.mb;
1366 MACROBLOCKD *const xd = &x->e_mbd;
1367
1368 // Copy data over into macro block data structures.
1369 av1_setup_src_planes(x, cpi->source, 0, 0, num_planes,
1370 cm->seq_params->sb_size);
1371
1372 av1_setup_block_planes(xd, cm->seq_params->subsampling_x,
1373 cm->seq_params->subsampling_y, num_planes);
1374}
1375
1376void av1_alloc_tile_data(AV1_COMP *cpi) {
1377 AV1_COMMON *const cm = &cpi->common;
1378 const int tile_cols = cm->tiles.cols;
1379 const int tile_rows = cm->tiles.rows;
1380
1381 av1_row_mt_mem_dealloc(cpi);
1382
1383 aom_free(cpi->tile_data);
1384 cpi->allocated_tiles = 0;
1385
1386 CHECK_MEM_ERROR(do { ((void) sizeof ((((cm)->error)->setjmp) ? 1 : 0), __extension__
({ if (((cm)->error)->setjmp) ; else __assert_fail ("((cm)->error)->setjmp"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1388, __extension__ __PRETTY_FUNCTION__); })); cpi->tile_data
= (aom_memalign(32, tile_cols * tile_rows * sizeof(*cpi->
tile_data))); if (!cpi->tile_data) aom_internal_error((cm)
->error, AOM_CODEC_MEM_ERROR, "Failed to allocate " "cpi->tile_data"
); } while (0)
1387 cm, cpi->tile_data,do { ((void) sizeof ((((cm)->error)->setjmp) ? 1 : 0), __extension__
({ if (((cm)->error)->setjmp) ; else __assert_fail ("((cm)->error)->setjmp"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1388, __extension__ __PRETTY_FUNCTION__); })); cpi->tile_data
= (aom_memalign(32, tile_cols * tile_rows * sizeof(*cpi->
tile_data))); if (!cpi->tile_data) aom_internal_error((cm)
->error, AOM_CODEC_MEM_ERROR, "Failed to allocate " "cpi->tile_data"
); } while (0)
1388 aom_memalign(32, tile_cols * tile_rows * sizeof(*cpi->tile_data)))do { ((void) sizeof ((((cm)->error)->setjmp) ? 1 : 0), __extension__
({ if (((cm)->error)->setjmp) ; else __assert_fail ("((cm)->error)->setjmp"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1388, __extension__ __PRETTY_FUNCTION__); })); cpi->tile_data
= (aom_memalign(32, tile_cols * tile_rows * sizeof(*cpi->
tile_data))); if (!cpi->tile_data) aom_internal_error((cm)
->error, AOM_CODEC_MEM_ERROR, "Failed to allocate " "cpi->tile_data"
); } while (0)
;
1389
1390 cpi->allocated_tiles = tile_cols * tile_rows;
1391 for (int tile_row = 0; tile_row < tile_rows; ++tile_row) {
1392 for (int tile_col = 0; tile_col < tile_cols; ++tile_col) {
1393 const int tile_index = tile_row * tile_cols + tile_col;
1394 TileDataEnc *const this_tile = &cpi->tile_data[tile_index];
1395 av1_zero(this_tile->row_mt_sync)memset(&(this_tile->row_mt_sync), 0, sizeof(this_tile->
row_mt_sync))
;
1396 this_tile->row_ctx = NULL((void*)0);
1397 }
1398 }
1399}
1400
1401void av1_init_tile_data(AV1_COMP *cpi) {
1402 AV1_COMMON *const cm = &cpi->common;
1403 const int num_planes = av1_num_planes(cm);
1404 const int tile_cols = cm->tiles.cols;
1405 const int tile_rows = cm->tiles.rows;
1406 int tile_col, tile_row;
1407 TokenInfo *const token_info = &cpi->token_info;
1408 TokenExtra *pre_tok = token_info->tile_tok[0][0];
1409 TokenList *tplist = token_info->tplist[0][0];
1410 unsigned int tile_tok = 0;
1411 int tplist_count = 0;
1412
1413 if (!is_stat_generation_stage(cpi) &&
1414 cm->features.allow_screen_content_tools) {
1415 // Number of tokens for which token info needs to be allocated.
1416 unsigned int tokens_required =
1417 get_token_alloc(cm->mi_params.mb_rows, cm->mi_params.mb_cols,
1418 MAX_SB_SIZE_LOG27, num_planes);
1419 // Allocate/reallocate memory for token related info if the number of tokens
1420 // required is more than the number of tokens already allocated. This could
1421 // occur in case of the following:
1422 // 1) If the memory is not yet allocated
1423 // 2) If the frame dimensions have changed
1424 const bool_Bool realloc_tokens = tokens_required > token_info->tokens_allocated;
1425 if (realloc_tokens) {
1426 free_token_info(token_info);
1427 alloc_token_info(cm, token_info, tokens_required);
1428 pre_tok = token_info->tile_tok[0][0];
1429 tplist = token_info->tplist[0][0];
1430 }
1431 }
1432
1433 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
1434 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
1435 TileDataEnc *const tile_data =
1436 &cpi->tile_data[tile_row * tile_cols + tile_col];
1437 TileInfo *const tile_info = &tile_data->tile_info;
1438 av1_tile_init(tile_info, cm, tile_row, tile_col);
1439 tile_data->firstpass_top_mv = kZeroMv;
1440 tile_data->abs_sum_level = 0;
1441
1442 if (is_token_info_allocated(token_info)) {
1443 token_info->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
1444 pre_tok = token_info->tile_tok[tile_row][tile_col];
1445 tile_tok = allocated_tokens(
1446 tile_info, cm->seq_params->mib_size_log2 + MI_SIZE_LOG22,
1447 num_planes);
1448 token_info->tplist[tile_row][tile_col] = tplist + tplist_count;
1449 tplist = token_info->tplist[tile_row][tile_col];
1450 tplist_count = av1_get_sb_rows_in_tile(cm, tile_info);
1451 }
1452 tile_data->allow_update_cdf = !cm->tiles.large_scale;
1453 tile_data->allow_update_cdf = tile_data->allow_update_cdf &&
1454 !cm->features.disable_cdf_update &&
1455 !delay_wait_for_top_right_sb(cpi);
1456 tile_data->tctx = *cm->fc;
1457 }
1458 }
1459}
1460
1461// Populate the start palette token info prior to encoding an SB row.
1462static inline void get_token_start(AV1_COMP *cpi, const TileInfo *tile_info,
1463 int tile_row, int tile_col, int mi_row,
1464 TokenExtra **tp) {
1465 const TokenInfo *token_info = &cpi->token_info;
1466 if (!is_token_info_allocated(token_info)) return;
18
Taking true branch
19
Returning without writing to '*tp'
1467
1468 const AV1_COMMON *cm = &cpi->common;
1469 const int num_planes = av1_num_planes(cm);
1470 TokenList *const tplist = cpi->token_info.tplist[tile_row][tile_col];
1471 const int sb_row_in_tile =
1472 (mi_row - tile_info->mi_row_start) >> cm->seq_params->mib_size_log2;
1473
1474 get_start_tok(cpi, tile_row, tile_col, mi_row, tp,
1475 cm->seq_params->mib_size_log2 + MI_SIZE_LOG22, num_planes);
1476 assert(tplist != NULL)((void) sizeof ((tplist != ((void*)0)) ? 1 : 0), __extension__
({ if (tplist != ((void*)0)) ; else __assert_fail ("tplist != NULL"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1476, __extension__ __PRETTY_FUNCTION__); }))
;
1477 tplist[sb_row_in_tile].start = *tp;
1478}
1479
1480// Populate the token count after encoding an SB row.
1481static inline void populate_token_count(AV1_COMP *cpi,
1482 const TileInfo *tile_info, int tile_row,
1483 int tile_col, int mi_row,
1484 TokenExtra *tok) {
1485 const TokenInfo *token_info = &cpi->token_info;
1486 if (!is_token_info_allocated(token_info)) return;
32
Taking false branch
1487
1488 const AV1_COMMON *cm = &cpi->common;
1489 const int num_planes = av1_num_planes(cm);
1490 TokenList *const tplist = token_info->tplist[tile_row][tile_col];
1491 const int sb_row_in_tile =
1492 (mi_row - tile_info->mi_row_start) >> cm->seq_params->mib_size_log2;
33
Assuming right operand of bit shift is non-negative but less than 32
1493 const int tile_mb_cols =
1494 (tile_info->mi_col_end - tile_info->mi_col_start + 2) >> 2;
1495 const int num_mb_rows_in_sb =
1496 ((1 << (cm->seq_params->mib_size_log2 + MI_SIZE_LOG22)) + 8) >> 4;
34
Assuming right operand of bit shift is less than 32
1497 tplist[sb_row_in_tile].count =
1498 (unsigned int)(tok - tplist[sb_row_in_tile].start);
35
Subtraction of a null pointer (from variable 'tok') and a probably non-null pointer (via field 'start') may result in undefined behavior
1499
1500 assert((unsigned int)(tok - tplist[sb_row_in_tile].start) <=((void) sizeof (((unsigned int)(tok - tplist[sb_row_in_tile].
start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols,
cm->seq_params->mib_size_log2 + 2, num_planes)) ? 1 : 0
), __extension__ ({ if ((unsigned int)(tok - tplist[sb_row_in_tile
].start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols
, cm->seq_params->mib_size_log2 + 2, num_planes)) ; else
__assert_fail ("(unsigned int)(tok - tplist[sb_row_in_tile].start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols, cm->seq_params->mib_size_log2 + MI_SIZE_LOG2, num_planes)"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1503, __extension__ __PRETTY_FUNCTION__); }))
1501 get_token_alloc(num_mb_rows_in_sb, tile_mb_cols,((void) sizeof (((unsigned int)(tok - tplist[sb_row_in_tile].
start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols,
cm->seq_params->mib_size_log2 + 2, num_planes)) ? 1 : 0
), __extension__ ({ if ((unsigned int)(tok - tplist[sb_row_in_tile
].start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols
, cm->seq_params->mib_size_log2 + 2, num_planes)) ; else
__assert_fail ("(unsigned int)(tok - tplist[sb_row_in_tile].start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols, cm->seq_params->mib_size_log2 + MI_SIZE_LOG2, num_planes)"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1503, __extension__ __PRETTY_FUNCTION__); }))
1502 cm->seq_params->mib_size_log2 + MI_SIZE_LOG2,((void) sizeof (((unsigned int)(tok - tplist[sb_row_in_tile].
start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols,
cm->seq_params->mib_size_log2 + 2, num_planes)) ? 1 : 0
), __extension__ ({ if ((unsigned int)(tok - tplist[sb_row_in_tile
].start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols
, cm->seq_params->mib_size_log2 + 2, num_planes)) ; else
__assert_fail ("(unsigned int)(tok - tplist[sb_row_in_tile].start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols, cm->seq_params->mib_size_log2 + MI_SIZE_LOG2, num_planes)"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1503, __extension__ __PRETTY_FUNCTION__); }))
1503 num_planes))((void) sizeof (((unsigned int)(tok - tplist[sb_row_in_tile].
start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols,
cm->seq_params->mib_size_log2 + 2, num_planes)) ? 1 : 0
), __extension__ ({ if ((unsigned int)(tok - tplist[sb_row_in_tile
].start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols
, cm->seq_params->mib_size_log2 + 2, num_planes)) ; else
__assert_fail ("(unsigned int)(tok - tplist[sb_row_in_tile].start) <= get_token_alloc(num_mb_rows_in_sb, tile_mb_cols, cm->seq_params->mib_size_log2 + MI_SIZE_LOG2, num_planes)"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1503, __extension__ __PRETTY_FUNCTION__); }))
;
1504
1505 (void)num_planes;
1506 (void)tile_mb_cols;
1507 (void)num_mb_rows_in_sb;
1508}
1509
1510/*!\brief Encode a superblock row
1511 *
1512 * \ingroup partition_search
1513 */
1514void av1_encode_sb_row(AV1_COMP *cpi, ThreadData *td, int tile_row,
1515 int tile_col, int mi_row) {
1516 AV1_COMMON *const cm = &cpi->common;
1517 const int tile_cols = cm->tiles.cols;
1518 TileDataEnc *this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col];
1519 const TileInfo *const tile_info = &this_tile->tile_info;
1520 TokenExtra *tok = NULL((void*)0);
16
'tok' initialized to a null pointer value
1521
1522 get_token_start(cpi, tile_info, tile_row, tile_col, mi_row, &tok);
17
Calling 'get_token_start'
20
Returning from 'get_token_start'
1523
1524 encode_sb_row(cpi, td, this_tile, mi_row, &tok);
21
Calling 'encode_sb_row'
29
Returning from 'encode_sb_row'
1525
1526 populate_token_count(cpi, tile_info, tile_row, tile_col, mi_row, tok);
30
Passing null pointer value via 6th parameter 'tok'
31
Calling 'populate_token_count'
1527}
1528
1529/*!\brief Encode a tile
1530 *
1531 * \ingroup partition_search
1532 */
1533void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
1534 int tile_col) {
1535 AV1_COMMON *const cm = &cpi->common;
1536 TileDataEnc *const this_tile =
1537 &cpi->tile_data[tile_row * cm->tiles.cols + tile_col];
1538 const TileInfo *const tile_info = &this_tile->tile_info;
1539
1540 if (!cpi->sf.rt_sf.use_nonrd_pick_mode) av1_inter_mode_data_init(this_tile);
7
Assuming field 'use_nonrd_pick_mode' is not equal to 0
8
Taking false branch
1541
1542 av1_zero_above_context(cm, &td->mb.e_mbd, tile_info->mi_col_start,
1543 tile_info->mi_col_end, tile_row);
1544 av1_init_above_context(&cm->above_contexts, av1_num_planes(cm), tile_row,
1545 &td->mb.e_mbd);
1546
1547#if !CONFIG_REALTIME_ONLY0
1548 if (cpi->oxcf.intra_mode_cfg.enable_cfl_intra)
9
Assuming field 'enable_cfl_intra' is false
10
Taking false branch
1549 cfl_init(&td->mb.e_mbd.cfl, cm->seq_params);
1550#endif
1551
1552 if (td->mb.txfm_search_info.mb_rd_record != NULL((void*)0)) {
11
Assuming field 'mb_rd_record' is equal to NULL
12
Taking false branch
1553 av1_crc32c_calculator_init(
1554 &td->mb.txfm_search_info.mb_rd_record->crc_calculator);
1555 }
1556
1557 for (int mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
13
Assuming 'mi_row' is < field 'mi_row_end'
14
Loop condition is true. Entering loop body
1558 mi_row += cm->seq_params->mib_size) {
1559 av1_encode_sb_row(cpi, td, tile_row, tile_col, mi_row);
15
Calling 'av1_encode_sb_row'
1560 }
1561 this_tile->abs_sum_level = td->abs_sum_level;
1562}
1563
1564/*!\brief Break one frame into tiles and encode the tiles
1565 *
1566 * \ingroup partition_search
1567 *
1568 * \param[in] cpi Top-level encoder structure
1569 */
1570static inline void encode_tiles(AV1_COMP *cpi) {
1571 AV1_COMMON *const cm = &cpi->common;
1572 const int tile_cols = cm->tiles.cols;
1573 const int tile_rows = cm->tiles.rows;
1574 int tile_col, tile_row;
1575
1576 MACROBLOCK *const mb = &cpi->td.mb;
1577 assert(IMPLIES(cpi->tile_data == NULL, cpi->allocated_tiles == 0))((void) sizeof (((!(cpi->tile_data == ((void*)0)) || (cpi->
allocated_tiles == 0))) ? 1 : 0), __extension__ ({ if ((!(cpi
->tile_data == ((void*)0)) || (cpi->allocated_tiles == 0
))) ; else __assert_fail ("IMPLIES(cpi->tile_data == NULL, cpi->allocated_tiles == 0)"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1577, __extension__ __PRETTY_FUNCTION__); }))
;
1
Assuming field 'tile_data' is not equal to null
1578 if (cpi->allocated_tiles != tile_cols * tile_rows) av1_alloc_tile_data(cpi);
2
Assuming the condition is false
3
Taking false branch
1579
1580 av1_init_tile_data(cpi);
1581 av1_alloc_mb_data(cpi, mb);
1582
1583 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
4
Loop condition is true. Entering loop body
1584 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
5
Loop condition is true. Entering loop body
1585 TileDataEnc *const this_tile =
1586 &cpi->tile_data[tile_row * cm->tiles.cols + tile_col];
1587 cpi->td.intrabc_used = 0;
1588 cpi->td.deltaq_used = 0;
1589 cpi->td.abs_sum_level = 0;
1590 cpi->td.rd_counts.seg_tmp_pred_cost[0] = 0;
1591 cpi->td.rd_counts.seg_tmp_pred_cost[1] = 0;
1592 cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx;
1593 cpi->td.mb.tile_pb_ctx = &this_tile->tctx;
1594 av1_init_rtc_counters(&cpi->td.mb);
1595 cpi->td.mb.palette_pixels = 0;
1596 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
6
Calling 'av1_encode_tile'
1597 if (!frame_is_intra_only(&cpi->common))
1598 av1_accumulate_rtc_counters(cpi, &cpi->td.mb);
1599 cpi->palette_pixel_num += cpi->td.mb.palette_pixels;
1600 cpi->intrabc_used |= cpi->td.intrabc_used;
1601 cpi->deltaq_used |= cpi->td.deltaq_used;
1602 }
1603 }
1604
1605 av1_dealloc_mb_data(mb, av1_num_planes(cm));
1606}
1607
1608// Set the relative distance of a reference frame w.r.t. current frame
1609static inline void set_rel_frame_dist(
1610 const AV1_COMMON *const cm, RefFrameDistanceInfo *const ref_frame_dist_info,
1611 const int ref_frame_flags) {
1612 MV_REFERENCE_FRAME ref_frame;
1613 int min_past_dist = INT32_MAX(2147483647), min_future_dist = INT32_MAX(2147483647);
1614 ref_frame_dist_info->nearest_past_ref = NONE_FRAME;
1615 ref_frame_dist_info->nearest_future_ref = NONE_FRAME;
1616 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
1617 ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME] = 0;
1618 if (ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
1619 int dist = av1_encoder_get_relative_dist(
1620 cm->cur_frame->ref_display_order_hint[ref_frame - LAST_FRAME],
1621 cm->current_frame.display_order_hint);
1622 ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME] = dist;
1623 // Get the nearest ref_frame in the past
1624 if (abs(dist) < min_past_dist && dist < 0) {
1625 ref_frame_dist_info->nearest_past_ref = ref_frame;
1626 min_past_dist = abs(dist);
1627 }
1628 // Get the nearest ref_frame in the future
1629 if (dist < min_future_dist && dist > 0) {
1630 ref_frame_dist_info->nearest_future_ref = ref_frame;
1631 min_future_dist = dist;
1632 }
1633 }
1634 }
1635}
1636
1637static inline int refs_are_one_sided(const AV1_COMMON *cm) {
1638 assert(!frame_is_intra_only(cm))((void) sizeof ((!frame_is_intra_only(cm)) ? 1 : 0), __extension__
({ if (!frame_is_intra_only(cm)) ; else __assert_fail ("!frame_is_intra_only(cm)"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1638, __extension__ __PRETTY_FUNCTION__); }))
;
1639
1640 int one_sided_refs = 1;
1641 const int cur_display_order_hint = cm->current_frame.display_order_hint;
1642 for (int ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref) {
1643 const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref);
1644 if (buf == NULL((void*)0)) continue;
1645 if (av1_encoder_get_relative_dist(buf->display_order_hint,
1646 cur_display_order_hint) > 0) {
1647 one_sided_refs = 0; // bwd reference
1648 break;
1649 }
1650 }
1651 return one_sided_refs;
1652}
1653
1654static inline void get_skip_mode_ref_offsets(const AV1_COMMON *cm,
1655 int ref_order_hint[2]) {
1656 const SkipModeInfo *const skip_mode_info = &cm->current_frame.skip_mode_info;
1657 ref_order_hint[0] = ref_order_hint[1] = 0;
1658 if (!skip_mode_info->skip_mode_allowed) return;
1659
1660 const RefCntBuffer *const buf_0 =
1661 get_ref_frame_buf(cm, LAST_FRAME + skip_mode_info->ref_frame_idx_0);
1662 const RefCntBuffer *const buf_1 =
1663 get_ref_frame_buf(cm, LAST_FRAME + skip_mode_info->ref_frame_idx_1);
1664 assert(buf_0 != NULL && buf_1 != NULL)((void) sizeof ((buf_0 != ((void*)0) && buf_1 != ((void
*)0)) ? 1 : 0), __extension__ ({ if (buf_0 != ((void*)0) &&
buf_1 != ((void*)0)) ; else __assert_fail ("buf_0 != NULL && buf_1 != NULL"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1664, __extension__ __PRETTY_FUNCTION__); }))
;
1665
1666 ref_order_hint[0] = buf_0->order_hint;
1667 ref_order_hint[1] = buf_1->order_hint;
1668}
1669
1670static int check_skip_mode_enabled(AV1_COMP *const cpi) {
1671 AV1_COMMON *const cm = &cpi->common;
1672
1673 av1_setup_skip_mode_allowed(cm);
1674 if (!cm->current_frame.skip_mode_info.skip_mode_allowed) return 0;
1675
1676 // Turn off skip mode if the temporal distances of the reference pair to the
1677 // current frame are different by more than 1 frame.
1678 const int cur_offset = (int)cm->current_frame.order_hint;
1679 int ref_offset[2];
1680 get_skip_mode_ref_offsets(cm, ref_offset);
1681 const int cur_to_ref0 = get_relative_dist(&cm->seq_params->order_hint_info,
1682 cur_offset, ref_offset[0]);
1683 const int cur_to_ref1 = abs(get_relative_dist(
1684 &cm->seq_params->order_hint_info, cur_offset, ref_offset[1]));
1685 if (abs(cur_to_ref0 - cur_to_ref1) > 1) return 0;
1686
1687 // High Latency: Turn off skip mode if all refs are fwd.
1688 if (cpi->all_one_sided_refs && cpi->oxcf.gf_cfg.lag_in_frames > 0) return 0;
1689
1690 const int ref_frame[2] = {
1691 cm->current_frame.skip_mode_info.ref_frame_idx_0 + LAST_FRAME,
1692 cm->current_frame.skip_mode_info.ref_frame_idx_1 + LAST_FRAME
1693 };
1694 if (!(cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame[0]]) ||
1695 !(cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame[1]]))
1696 return 0;
1697
1698 return 1;
1699}
1700
1701static inline void set_default_interp_skip_flags(
1702 const AV1_COMMON *cm, InterpSearchFlags *interp_search_flags) {
1703 const int num_planes = av1_num_planes(cm);
1704 interp_search_flags->default_interp_skip_flags =
1705 (num_planes == 1) ? INTERP_SKIP_LUMA_EVAL_CHROMA
1706 : INTERP_SKIP_LUMA_SKIP_CHROMA;
1707}
1708
1709/*!\cond */
1710typedef struct {
1711 // Scoring function for usefulness of references (the lower score, the more
1712 // useful)
1713 int score;
1714 // Index in the reference buffer
1715 int index;
1716} RefScoreData;
1717/*!\endcond */
1718
1719// Comparison function to sort reference frames in ascending score order.
1720static int compare_score_data_asc(const void *a, const void *b) {
1721 const RefScoreData *ra = (const RefScoreData *)a;
1722 const RefScoreData *rb = (const RefScoreData *)b;
1723
1724 const int score_diff = ra->score - rb->score;
1725 if (score_diff != 0) return score_diff;
1726
1727 return ra->index - rb->index;
1728}
1729
1730// Determines whether a given reference frame is "good" based on temporal
1731// distance and base_qindex. The "good" reference frames are not allowed to be
1732// pruned by the speed feature "prune_single_ref" and "prune_comp_ref_frames"
1733// at block level.
1734static inline void setup_keep_ref_frame_mask(AV1_COMP *cpi) {
1735 const int prune_single_ref = cpi->sf.inter_sf.prune_single_ref;
1736 const int prune_comp_ref_frames = cpi->sf.inter_sf.prune_comp_ref_frames;
1737 const AV1_COMMON *const cm = &cpi->common;
1738 cpi->keep_single_ref_frame_mask = 0;
1739 cpi->keep_comp_ref_frame_mask = 0;
1740 if (frame_is_intra_only(cm)) return;
1741
1742 RefScoreData ref_score_data[INTER_REFS_PER_FRAME];
1743 for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
1744 ref_score_data[i].score = INT_MAX2147483647;
1745 ref_score_data[i].index = i;
1746 }
1747
1748 // Calculate score for each reference frame based on relative distance to
1749 // the current frame and its base_qindex. A lower score means that the
1750 // reference is potentially more useful.
1751 for (MV_REFERENCE_FRAME ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME;
1752 ++ref_frame) {
1753 if (cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
1754 const RefFrameDistanceInfo *const ref_frame_dist_info =
1755 &cpi->ref_frame_dist_info;
1756 const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
1757 ref_score_data[ref_frame - LAST_FRAME].score =
1758 abs(ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME]) +
1759 buf->base_qindex;
1760 }
1761 }
1762
1763 qsort(ref_score_data, INTER_REFS_PER_FRAME, sizeof(ref_score_data[0]),
1764 compare_score_data_asc);
1765
1766 // Decide the number of reference frames for which pruning via the speed
1767 // feature prune_single_ref is disallowed.
1768 // prune_single_ref = 0 => None of the 7 reference frames are pruned.
1769 // prune_single_ref = 1 => The best 5 reference frames are not pruned.
1770 // prune_single_ref = 2 => The best 3 reference frames are not pruned.
1771 // prune_single_ref = 3, 4 => All the 7 references are allowed to be pruned.
1772 static const int num_single_ref_to_keep_lookup[5] = { INTER_REFS_PER_FRAME, 5,
1773 3, 0, 0 };
1774 assert(prune_single_ref >= 0 && prune_single_ref <= 4)((void) sizeof ((prune_single_ref >= 0 && prune_single_ref
<= 4) ? 1 : 0), __extension__ ({ if (prune_single_ref >=
0 && prune_single_ref <= 4) ; else __assert_fail (
"prune_single_ref >= 0 && prune_single_ref <= 4"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1774, __extension__ __PRETTY_FUNCTION__); }))
;
1775 const int num_single_ref_to_keep =
1776 num_single_ref_to_keep_lookup[prune_single_ref];
1777 for (int i = 0; i < num_single_ref_to_keep; ++i) {
1778 const int idx = ref_score_data[i].index;
1779 cpi->keep_single_ref_frame_mask |= 1 << idx;
1780 }
1781
1782 // Decide the number of reference frame pairs for which pruning via the speed
1783 // feature "prune_comp_ref_frames" is disallowed.
1784 // prune_comp_ref_frames = 0 => None of the allowed reference frame pairs
1785 // are pruned.
1786 // prune_comp_ref_frames = 1 => The best 3 reference frame pairs are not
1787 // allowed to be pruned, i.e, reference frame
1788 // pairs with rank (1, 2), (1, 3), (2, 3) are
1789 // not pruned.
1790 // prune_comp_ref_frames = 2, 3 => All the reference frame pairs are allowed
1791 // to be pruned.
1792 static const int num_comp_ref_to_keep_lookup[4] = { INTER_REFS_PER_FRAME, 3,
1793 0, 0 };
1794 assert(prune_comp_ref_frames >= 0 && prune_comp_ref_frames <= 3)((void) sizeof ((prune_comp_ref_frames >= 0 && prune_comp_ref_frames
<= 3) ? 1 : 0), __extension__ ({ if (prune_comp_ref_frames
>= 0 && prune_comp_ref_frames <= 3) ; else __assert_fail
("prune_comp_ref_frames >= 0 && prune_comp_ref_frames <= 3"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 1794, __extension__ __PRETTY_FUNCTION__); }))
;
1795 const int num_comp_ref_to_keep =
1796 num_comp_ref_to_keep_lookup[prune_comp_ref_frames];
1797 for (int i = 0; i < num_comp_ref_to_keep; ++i) {
1798 const int idx = ref_score_data[i].index;
1799 cpi->keep_comp_ref_frame_mask |= 1 << idx;
1800 }
1801}
1802
1803static inline void setup_prune_ref_frame_mask(AV1_COMP *cpi) {
1804 if ((!cpi->oxcf.ref_frm_cfg.enable_onesided_comp ||
1805 cpi->sf.inter_sf.disable_onesided_comp) &&
1806 cpi->all_one_sided_refs) {
1807 // Disable all compound references
1808 cpi->prune_ref_frame_mask = (1 << MODE_CTX_REF_FRAMES(REF_FRAMES + (FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS))) - (1 << REF_FRAMES);
1809 } else if (!cpi->sf.rt_sf.use_nonrd_pick_mode &&
1810 cpi->sf.inter_sf.selective_ref_frame >= 1) {
1811 AV1_COMMON *const cm = &cpi->common;
1812 const int cur_frame_display_order_hint =
1813 cm->current_frame.display_order_hint;
1814 unsigned int *ref_display_order_hint =
1815 cm->cur_frame->ref_display_order_hint;
1816 const int arf2_dist = av1_encoder_get_relative_dist(
1817 ref_display_order_hint[ALTREF2_FRAME - LAST_FRAME],
1818 cur_frame_display_order_hint);
1819 const int bwd_dist = av1_encoder_get_relative_dist(
1820 ref_display_order_hint[BWDREF_FRAME - LAST_FRAME],
1821 cur_frame_display_order_hint);
1822
1823 for (int ref_idx = REF_FRAMES; ref_idx < MODE_CTX_REF_FRAMES(REF_FRAMES + (FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS)); ++ref_idx) {
1824 MV_REFERENCE_FRAME rf[2];
1825 av1_set_ref_frame(rf, ref_idx);
1826 if (!(cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[0]]) ||
1827 !(cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[1]])) {
1828 continue;
1829 }
1830
1831 if (!cpi->all_one_sided_refs) {
1832 int ref_dist[2];
1833 for (int i = 0; i < 2; ++i) {
1834 ref_dist[i] = av1_encoder_get_relative_dist(
1835 ref_display_order_hint[rf[i] - LAST_FRAME],
1836 cur_frame_display_order_hint);
1837 }
1838
1839 // One-sided compound is used only when all reference frames are
1840 // one-sided.
1841 if ((ref_dist[0] > 0) == (ref_dist[1] > 0)) {
1842 cpi->prune_ref_frame_mask |= 1 << ref_idx;
1843 }
1844 }
1845
1846 if (cpi->sf.inter_sf.selective_ref_frame >= 4 &&
1847 (rf[0] == ALTREF2_FRAME || rf[1] == ALTREF2_FRAME) &&
1848 (cpi->ref_frame_flags & av1_ref_frame_flag_list[BWDREF_FRAME])) {
1849 // Check if both ALTREF2_FRAME and BWDREF_FRAME are future references.
1850 if (arf2_dist > 0 && bwd_dist > 0 && bwd_dist <= arf2_dist) {
1851 // Drop ALTREF2_FRAME as a reference if BWDREF_FRAME is a closer
1852 // reference to the current frame than ALTREF2_FRAME
1853 cpi->prune_ref_frame_mask |= 1 << ref_idx;
1854 }
1855 }
1856 }
1857 }
1858}
1859
1860static int allow_deltaq_mode(AV1_COMP *cpi) {
1861#if !CONFIG_REALTIME_ONLY0
1862 AV1_COMMON *const cm = &cpi->common;
1863 BLOCK_SIZE sb_size = cm->seq_params->sb_size;
1864 int sbs_wide = mi_size_wide[sb_size];
1865 int sbs_high = mi_size_high[sb_size];
1866
1867 int64_t delta_rdcost = 0;
1868 for (int mi_row = 0; mi_row < cm->mi_params.mi_rows; mi_row += sbs_high) {
1869 for (int mi_col = 0; mi_col < cm->mi_params.mi_cols; mi_col += sbs_wide) {
1870 int64_t this_delta_rdcost = 0;
1871 av1_get_q_for_deltaq_objective(cpi, &cpi->td, &this_delta_rdcost, sb_size,
1872 mi_row, mi_col);
1873 delta_rdcost += this_delta_rdcost;
1874 }
1875 }
1876 return delta_rdcost < 0;
1877#else
1878 (void)cpi;
1879 return 1;
1880#endif // !CONFIG_REALTIME_ONLY
1881}
1882
1883static inline int disable_deltaq_for_intl_arfs(const AV1_COMP *cpi) {
1884 if (cpi->oxcf.mode == GOOD && is_stat_consumption_stage_twopass(cpi) &&
1885 cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_OBJECTIVE &&
1886 cpi->oxcf.algo_cfg.enable_tpl_model && cpi->oxcf.q_cfg.aq_mode == NO_AQ &&
1887 !cpi->common.seg.enabled && !cpi->roi.enabled && !cpi->oxcf.sb_qp_sweep &&
1888 !cpi->use_ducky_encode) {
1889 return 1;
1890 }
1891 return 0;
1892}
1893
1894static inline int enable_delta_rdmult(const AV1_COMP *cpi) {
1895 if (!disable_deltaq_for_intl_arfs(cpi))
1896 return cpi->common.delta_q_info.delta_q_present_flag;
1897
1898 const GF_GROUP *gf_group = &cpi->ppi->gf_group;
1899 return gf_group->update_type[cpi->gf_frame_index] != LF_UPDATE;
1900}
1901
1902static inline int enable_delta_q(const AV1_COMP *cpi) {
1903 const GF_GROUP *gf_group = &cpi->ppi->gf_group;
1904 if (!disable_deltaq_for_intl_arfs(cpi))
1905 return gf_group->update_type[cpi->gf_frame_index] != LF_UPDATE;
1906
1907 return cpi->common.current_frame.pyramid_level <= 1;
1908}
1909
1910#define FORCE_ZMV_SKIP_128X128_BLK_DIFF10000 10000
1911#define FORCE_ZMV_SKIP_MAX_PER_PIXEL_DIFF4 4
1912
1913// Populates block level thresholds for force zeromv-skip decision
1914static void populate_thresh_to_force_zeromv_skip(AV1_COMP *cpi) {
1915 if (cpi->sf.rt_sf.part_early_exit_zeromv == 0) return;
1916
1917 // Threshold for forcing zeromv-skip decision is as below:
1918 // For 128x128 blocks, threshold is 10000 and per pixel threshold is 0.6103.
1919 // For 64x64 blocks, threshold is 5000 and per pixel threshold is 1.221
1920 // allowing slightly higher error for smaller blocks.
1921 // Per Pixel Threshold of 64x64 block Area of 64x64 block 1 1
1922 // ------------------------------------=sqrt(---------------------)=sqrt(-)=-
1923 // Per Pixel Threshold of 128x128 block Area of 128x128 block 4 2
1924 // Thus, per pixel thresholds for blocks of size 32x32, 16x16,... can be
1925 // chosen as 2.442, 4.884,.... As the per pixel error tends to be higher for
1926 // small blocks, the same is clipped to 4.
1927 const unsigned int thresh_exit_128x128_part = FORCE_ZMV_SKIP_128X128_BLK_DIFF10000;
1928 const int num_128x128_pix =
1929 block_size_wide[BLOCK_128X128] * block_size_high[BLOCK_128X128];
1930
1931 for (BLOCK_SIZE bsize = BLOCK_4X4; bsize < BLOCK_SIZES_ALL; bsize++) {
1932 const int num_block_pix = block_size_wide[bsize] * block_size_high[bsize];
1933
1934 // Calculate the threshold for zeromv-skip decision based on area of the
1935 // partition
1936 unsigned int thresh_exit_part_blk =
1937 (unsigned int)(thresh_exit_128x128_part *
1938 sqrt((double)num_block_pix / num_128x128_pix) +
1939 0.5);
1940 thresh_exit_part_blk = AOMMIN((((thresh_exit_part_blk) < ((unsigned int)(4 * num_block_pix
))) ? (thresh_exit_part_blk) : ((unsigned int)(4 * num_block_pix
)))
1941 thresh_exit_part_blk,(((thresh_exit_part_blk) < ((unsigned int)(4 * num_block_pix
))) ? (thresh_exit_part_blk) : ((unsigned int)(4 * num_block_pix
)))
1942 (unsigned int)(FORCE_ZMV_SKIP_MAX_PER_PIXEL_DIFF * num_block_pix))(((thresh_exit_part_blk) < ((unsigned int)(4 * num_block_pix
))) ? (thresh_exit_part_blk) : ((unsigned int)(4 * num_block_pix
)))
;
1943 cpi->zeromv_skip_thresh_exit_part[bsize] = thresh_exit_part_blk;
1944 }
1945}
1946
1947static void free_block_hash_buffers(uint32_t *block_hash_values[2]) {
1948 for (int j = 0; j < 2; ++j) {
1949 aom_free(block_hash_values[j]);
1950 }
1951}
1952
1953/*!\brief Determines delta_q_res value for Variance Boost modulation.
1954 */
1955static int aom_get_variance_boost_delta_q_res(int qindex) {
1956 // Signaling delta_q changes across superblocks comes with inherent syntax
1957 // element overhead, which adds up to total payload size. This overhead
1958 // becomes proportionally bigger the higher the base qindex (i.e. lower
1959 // quality, smaller file size), so a balance needs to be struck.
1960 // - Smaller delta_q_res: more granular delta_q control, more bits spent
1961 // signaling deltas.
1962 // - Larger delta_q_res: coarser delta_q control, less bits spent signaling
1963 // deltas.
1964 //
1965 // At the same time, SB qindex fluctuations become larger the higher
1966 // the base qindex (between lowest and highest-variance regions):
1967 // - For QP 5: up to 8 qindexes
1968 // - For QP 60: up to 52 qindexes
1969 //
1970 // With these factors in mind, it was found that the best strategy that
1971 // maximizes quality per bitrate is by having very finely-grained delta_q
1972 // values for the lowest picture qindexes (to preserve tiny qindex SB deltas),
1973 // and progressively making them coarser as base qindex increases (to reduce
1974 // total signaling overhead).
1975 int delta_q_res = 1;
1976
1977 if (qindex >= 160) {
1978 delta_q_res = 8;
1979 } else if (qindex >= 120) {
1980 delta_q_res = 4;
1981 } else if (qindex >= 80) {
1982 delta_q_res = 2;
1983 } else {
1984 delta_q_res = 1;
1985 }
1986
1987 return delta_q_res;
1988}
1989
1990#if !CONFIG_REALTIME_ONLY0
1991static float get_thresh_based_on_q(int qindex, int speed) {
1992 const float min_threshold_arr[3] = { 0.084f, 0.087f, 0.126f };
1993 const float max_threshold_arr[3] = { 0.140f, 0.150f, 0.182f };
1994 const int idx = (speed >= 3) ? 2 : (speed - 1);
1995 const float min_thresh = min_threshold_arr[idx];
1996 const float max_thresh = max_threshold_arr[idx];
1997 const float thresh = min_thresh + (max_thresh - min_thresh) *
1998 ((float)MAXQ255 - (float)qindex) /
1999 (float)(MAXQ255 - MINQ0);
2000 return thresh;
2001}
2002
2003static int get_mv_err(MV cur_mv, MV ref_mv) {
2004 const MV diff = { cur_mv.row - ref_mv.row, cur_mv.col - ref_mv.col };
2005 const MV abs_diff = { abs(diff.row), abs(diff.col) };
2006 const int mv_err = (abs_diff.row + abs_diff.col);
2007 return mv_err;
2008}
2009
2010static void check_mv_err_and_update(MV cur_mv, MV ref_mv, int *best_mv_err) {
2011 const int mv_err = get_mv_err(cur_mv, ref_mv);
2012 *best_mv_err = AOMMIN(mv_err, *best_mv_err)(((mv_err) < (*best_mv_err)) ? (mv_err) : (*best_mv_err));
2013}
2014
2015static int is_inside_frame_border(int mi_row, int mi_col, int row_offset,
2016 int col_offset, int num_mi_rows,
2017 int num_mi_cols) {
2018 if (mi_row + row_offset < 0 || mi_row + row_offset >= num_mi_rows ||
2019 mi_col + col_offset < 0 || mi_col + col_offset >= num_mi_cols)
2020 return 0;
2021
2022 return 1;
2023}
2024
2025// Compute the minimum MV error between current MV and spatial MV predictors.
2026static int get_spatial_mvpred_err(AV1_COMMON *cm, TplParams *const tpl_data,
2027 int tpl_idx, int mi_row, int mi_col,
2028 int ref_idx, int_mv cur_mv, int allow_hp,
2029 int is_integer) {
2030 const TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
2031 TplDepStats *tpl_ptr = tpl_frame->tpl_stats_ptr;
2032 const uint8_t block_mis_log2 = tpl_data->tpl_stats_block_mis_log2;
2033
2034 int mv_err = INT32_MAX(2147483647);
2035 const int step = 1 << block_mis_log2;
2036 const int mv_pred_pos_in_mis[8][2] = {
2037 { -step, 0 }, { 0, -step }, { -step, step }, { -step, -step },
2038 { -2 * step, 0 }, { 0, -2 * step }, { -3 * step, 0 }, { 0, -3 * step },
2039 };
2040
2041 for (int i = 0; i < 8; i++) {
2042 int row_offset = mv_pred_pos_in_mis[i][0];
2043 int col_offset = mv_pred_pos_in_mis[i][1];
2044 if (!is_inside_frame_border(mi_row, mi_col, row_offset, col_offset,
2045 tpl_frame->mi_rows, tpl_frame->mi_cols)) {
2046 continue;
2047 }
2048
2049 const TplDepStats *tpl_stats =
2050 &tpl_ptr[av1_tpl_ptr_pos(mi_row + row_offset, mi_col + col_offset,
2051 tpl_frame->stride, block_mis_log2)];
2052 int_mv this_refmv = tpl_stats->mv[ref_idx];
2053 lower_mv_precision(&this_refmv.as_mv, allow_hp, is_integer);
2054 check_mv_err_and_update(cur_mv.as_mv, this_refmv.as_mv, &mv_err);
2055 }
2056
2057 // Check MV error w.r.t. Global MV / Zero MV
2058 int_mv gm_mv = { 0 };
2059 if (cm->global_motion[ref_idx + LAST_FRAME].wmtype > TRANSLATION) {
2060 const BLOCK_SIZE bsize = convert_length_to_bsize(tpl_data->tpl_bsize_1d);
2061 gm_mv = gm_get_motion_vector(&cm->global_motion[ref_idx + LAST_FRAME],
2062 allow_hp, bsize, mi_col, mi_row, is_integer);
2063 }
2064 check_mv_err_and_update(cur_mv.as_mv, gm_mv.as_mv, &mv_err);
2065
2066 return mv_err;
2067}
2068
2069// Compute the minimum MV error between current MV and temporal MV predictors.
2070static int get_temporal_mvpred_err(AV1_COMMON *cm, int mi_row, int mi_col,
2071 int num_mi_rows, int num_mi_cols,
2072 int ref_idx, int_mv cur_mv, int allow_hp,
2073 int is_integer) {
2074 const RefCntBuffer *ref_buf = get_ref_frame_buf(cm, ref_idx + LAST_FRAME);
2075 if (ref_buf == NULL((void*)0)) return INT32_MAX(2147483647);
2076 int cur_to_ref_dist =
2077 get_relative_dist(&cm->seq_params->order_hint_info,
2078 cm->cur_frame->order_hint, ref_buf->order_hint);
2079
2080 int mv_err = INT32_MAX(2147483647);
2081 const int mv_pred_pos_in_mis[7][2] = {
2082 { 0, 0 }, { 0, 2 }, { 2, 0 }, { 2, 2 }, { 4, -2 }, { 4, 4 }, { 2, 4 },
2083 };
2084
2085 for (int i = 0; i < 7; i++) {
2086 int row_offset = mv_pred_pos_in_mis[i][0];
2087 int col_offset = mv_pred_pos_in_mis[i][1];
2088 if (!is_inside_frame_border(mi_row, mi_col, row_offset, col_offset,
2089 num_mi_rows, num_mi_cols)) {
2090 continue;
2091 }
2092 const TPL_MV_REF *ref_mvs =
2093 cm->tpl_mvs +
2094 ((mi_row + row_offset) >> 1) * (cm->mi_params.mi_stride >> 1) +
2095 ((mi_col + col_offset) >> 1);
2096 if (ref_mvs->mfmv0.as_int == INVALID_MV0x80008000) continue;
2097
2098 int_mv this_refmv;
2099 av1_get_mv_projection(&this_refmv.as_mv, ref_mvs->mfmv0.as_mv,
2100 cur_to_ref_dist, ref_mvs->ref_frame_offset);
2101 lower_mv_precision(&this_refmv.as_mv, allow_hp, is_integer);
2102 check_mv_err_and_update(cur_mv.as_mv, this_refmv.as_mv, &mv_err);
2103 }
2104
2105 return mv_err;
2106}
2107
2108// Determine whether to disable temporal MV prediction for the current frame
2109// based on TPL and motion field data. Temporal MV prediction is disabled if the
2110// reduction in MV error by including temporal MVs as MV predictors is small.
2111static void check_to_disable_ref_frame_mvs(AV1_COMP *cpi) {
2112 AV1_COMMON *cm = &cpi->common;
2113 if (!cm->features.allow_ref_frame_mvs || cpi->sf.hl_sf.ref_frame_mvs_lvl != 1)
2114 return;
2115
2116 const int tpl_idx = cpi->gf_frame_index;
2117 TplParams *const tpl_data = &cpi->ppi->tpl_data;
2118 if (!av1_tpl_stats_ready(tpl_data, tpl_idx)) return;
2119
2120 const SUBPEL_FORCE_STOP tpl_subpel_precision =
2121 cpi->sf.tpl_sf.subpel_force_stop;
2122 const int allow_high_precision_mv = tpl_subpel_precision == EIGHTH_PEL &&
2123 cm->features.allow_high_precision_mv;
2124 const int force_integer_mv = tpl_subpel_precision == FULL_PEL ||
2125 cm->features.cur_frame_force_integer_mv;
2126
2127 const TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
2128 TplDepStats *tpl_ptr = tpl_frame->tpl_stats_ptr;
2129 const uint8_t block_mis_log2 = tpl_data->tpl_stats_block_mis_log2;
2130 const int step = 1 << block_mis_log2;
2131
2132 uint64_t accum_spatial_mvpred_err = 0;
2133 uint64_t accum_best_err = 0;
2134
2135 for (int mi_row = 0; mi_row < tpl_frame->mi_rows; mi_row += step) {
2136 for (int mi_col = 0; mi_col < tpl_frame->mi_cols; mi_col += step) {
2137 TplDepStats *tpl_stats_ptr = &tpl_ptr[av1_tpl_ptr_pos(
2138 mi_row, mi_col, tpl_frame->stride, block_mis_log2)];
2139 const int cur_best_ref_idx = tpl_stats_ptr->ref_frame_index[0];
2140 if (cur_best_ref_idx == NONE_FRAME) continue;
2141
2142 int_mv cur_mv = tpl_stats_ptr->mv[cur_best_ref_idx];
2143 lower_mv_precision(&cur_mv.as_mv, allow_high_precision_mv,
2144 force_integer_mv);
2145
2146 const int cur_spatial_mvpred_err = get_spatial_mvpred_err(
2147 cm, tpl_data, tpl_idx, mi_row, mi_col, cur_best_ref_idx, cur_mv,
2148 allow_high_precision_mv, force_integer_mv);
2149
2150 const int cur_temporal_mvpred_err = get_temporal_mvpred_err(
2151 cm, mi_row, mi_col, tpl_frame->mi_rows, tpl_frame->mi_cols,
2152 cur_best_ref_idx, cur_mv, allow_high_precision_mv, force_integer_mv);
2153
2154 const int cur_best_err =
2155 AOMMIN(cur_spatial_mvpred_err, cur_temporal_mvpred_err)(((cur_spatial_mvpred_err) < (cur_temporal_mvpred_err)) ? (
cur_spatial_mvpred_err) : (cur_temporal_mvpred_err))
;
2156 accum_spatial_mvpred_err += cur_spatial_mvpred_err;
2157 accum_best_err += cur_best_err;
2158 }
2159 }
2160
2161 const float threshold =
2162 get_thresh_based_on_q(cm->quant_params.base_qindex, cpi->oxcf.speed);
2163 const float mv_err_reduction =
2164 (float)(accum_spatial_mvpred_err - accum_best_err);
2165
2166 if (mv_err_reduction <= threshold * accum_spatial_mvpred_err)
2167 cm->features.allow_ref_frame_mvs = 0;
2168}
2169#endif // !CONFIG_REALTIME_ONLY
2170
2171/*!\brief Encoder setup(only for the current frame), encoding, and recontruction
2172 * for a single frame
2173 *
2174 * \ingroup high_level_algo
2175 */
2176static inline void encode_frame_internal(AV1_COMP *cpi) {
2177 ThreadData *const td = &cpi->td;
2178 MACROBLOCK *const x = &td->mb;
2179 AV1_COMMON *const cm = &cpi->common;
2180 CommonModeInfoParams *const mi_params = &cm->mi_params;
2181 FeatureFlags *const features = &cm->features;
2182 MACROBLOCKD *const xd = &x->e_mbd;
2183 RD_COUNTS *const rdc = &cpi->td.rd_counts;
2184#if CONFIG_FPMT_TEST0
2185 FrameProbInfo *const temp_frame_probs = &cpi->ppi->temp_frame_probs;
2186 FrameProbInfo *const temp_frame_probs_simulation =
2187 &cpi->ppi->temp_frame_probs_simulation;
2188#endif
2189 FrameProbInfo *const frame_probs = &cpi->ppi->frame_probs;
2190 IntraBCHashInfo *const intrabc_hash_info = &x->intrabc_hash_info;
2191 MultiThreadInfo *const mt_info = &cpi->mt_info;
2192 AV1EncRowMultiThreadInfo *const enc_row_mt = &mt_info->enc_row_mt;
2193 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
2194 const DELTAQ_MODE deltaq_mode = oxcf->q_cfg.deltaq_mode;
2195 int i;
2196
2197 if (!cpi->sf.rt_sf.use_nonrd_pick_mode) {
2198 mi_params->setup_mi(mi_params);
2199 }
2200
2201 set_mi_offsets(mi_params, xd, 0, 0);
2202
2203 av1_zero(*td->counts)memset(&(*td->counts), 0, sizeof(*td->counts));
2204 av1_zero(rdc->tx_type_used)memset(&(rdc->tx_type_used), 0, sizeof(rdc->tx_type_used
))
;
2205 av1_zero(rdc->obmc_used)memset(&(rdc->obmc_used), 0, sizeof(rdc->obmc_used)
)
;
2206 av1_zero(rdc->warped_used)memset(&(rdc->warped_used), 0, sizeof(rdc->warped_used
))
;
2207 av1_zero(rdc->seg_tmp_pred_cost)memset(&(rdc->seg_tmp_pred_cost), 0, sizeof(rdc->seg_tmp_pred_cost
))
;
2208
2209 // Reset the flag.
2210 cpi->intrabc_used = 0;
2211 // Need to disable intrabc when superres is selected
2212 if (av1_superres_scaled(cm)) {
2213 features->allow_intrabc = 0;
2214 }
2215
2216 features->allow_intrabc &= (oxcf->kf_cfg.enable_intrabc);
2217
2218 if (features->allow_warped_motion &&
2219 cpi->sf.inter_sf.prune_warped_prob_thresh > 0) {
2220 const FRAME_UPDATE_TYPE update_type =
2221 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2222 int warped_probability =
2223#if CONFIG_FPMT_TEST0
2224 cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE
2225 ? temp_frame_probs->warped_probs[update_type]
2226 :
2227#endif // CONFIG_FPMT_TEST
2228 frame_probs->warped_probs[update_type];
2229 if (warped_probability < cpi->sf.inter_sf.prune_warped_prob_thresh)
2230 features->allow_warped_motion = 0;
2231 }
2232
2233 int hash_table_created = 0;
2234 if (!is_stat_generation_stage(cpi) && av1_use_hash_me(cpi) &&
2235 (!cpi->sf.rt_sf.use_nonrd_pick_mode || cpi->sf.rt_sf.rt_use_intrabc)) {
2236 // TODO(any): move this outside of the recoding loop to avoid recalculating
2237 // the hash table.
2238 // add to hash table
2239 const int pic_width = cpi->source->y_crop_width;
2240 const int pic_height = cpi->source->y_crop_height;
2241 uint32_t *block_hash_values[2] = { NULL((void*)0) }; // two buffers used ping-pong
2242 bool_Bool error = false0;
2243
2244 for (int j = 0; j < 2; ++j) {
2245 block_hash_values[j] = (uint32_t *)aom_malloc(
2246 sizeof(*block_hash_values[j]) * pic_width * pic_height);
2247 if (!block_hash_values[j]) {
2248 error = true1;
2249 break;
2250 }
2251 }
2252
2253 av1_hash_table_init(intrabc_hash_info);
2254 if (error ||
2255 !av1_hash_table_create(&intrabc_hash_info->intrabc_hash_table)) {
2256 free_block_hash_buffers(block_hash_values);
2257 aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
2258 "Error allocating intrabc_hash_table and buffers");
2259 }
2260 hash_table_created = 1;
2261 av1_generate_block_2x2_hash_value(cpi->source, block_hash_values[0]);
2262 // Hash data generated for screen contents is used for intraBC ME
2263 const int min_alloc_size = block_size_wide[mi_params->mi_alloc_bsize];
2264 int max_sb_size = (1 << (cm->seq_params->mib_size_log2 + MI_SIZE_LOG22));
2265
2266 if (cpi->sf.mv_sf.hash_max_8x8_intrabc_blocks) {
2267 max_sb_size = AOMMIN(8, max_sb_size)(((8) < (max_sb_size)) ? (8) : (max_sb_size));
2268 }
2269
2270 int src_idx = 0;
2271 for (int size = 4; size <= max_sb_size; size *= 2, src_idx = !src_idx) {
2272 const int dst_idx = !src_idx;
2273 av1_generate_block_hash_value(intrabc_hash_info, cpi->source, size,
2274 block_hash_values[src_idx],
2275 block_hash_values[dst_idx]);
2276 if (size >= min_alloc_size &&
2277 !av1_add_to_hash_map_by_row_with_precal_data(
2278 &intrabc_hash_info->intrabc_hash_table,
2279 block_hash_values[dst_idx], pic_width, pic_height, size)) {
2280 error = true1;
2281 break;
2282 }
2283 }
2284
2285 free_block_hash_buffers(block_hash_values);
2286
2287 if (error) {
2288 aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
2289 "Error adding data to intrabc_hash_table");
2290 }
2291 }
2292
2293 const CommonQuantParams *quant_params = &cm->quant_params;
2294 for (i = 0; i < MAX_SEGMENTS8; ++i) {
2295 const int qindex =
2296 cm->seg.enabled ? av1_get_qindex(&cm->seg, i, quant_params->base_qindex)
2297 : quant_params->base_qindex;
2298 xd->lossless[i] =
2299 qindex == 0 && quant_params->y_dc_delta_q == 0 &&
2300 quant_params->u_dc_delta_q == 0 && quant_params->u_ac_delta_q == 0 &&
2301 quant_params->v_dc_delta_q == 0 && quant_params->v_ac_delta_q == 0;
2302 if (xd->lossless[i]) cpi->enc_seg.has_lossless_segment = 1;
2303 xd->qindex[i] = qindex;
2304 if (xd->lossless[i]) {
2305 cpi->optimize_seg_arr[i] = NO_TRELLIS_OPT;
2306 } else {
2307 cpi->optimize_seg_arr[i] = cpi->sf.rd_sf.optimize_coefficients;
2308 }
2309 }
2310 features->coded_lossless = is_coded_lossless(cm, xd);
2311 features->all_lossless = features->coded_lossless && !av1_superres_scaled(cm);
2312
2313 // Fix delta q resolution for the moment
2314
2315 cm->delta_q_info.delta_q_res = 0;
2316 if (cpi->use_ducky_encode) {
2317 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_DUCKY_ENCODE4;
2318 } else if (cpi->oxcf.q_cfg.aq_mode != CYCLIC_REFRESH_AQ &&
2319 !cpi->roi.enabled) {
2320 if (deltaq_mode == DELTA_Q_OBJECTIVE)
2321 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_OBJECTIVE4;
2322 else if (deltaq_mode == DELTA_Q_PERCEPTUAL)
2323 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL4;
2324 else if (deltaq_mode == DELTA_Q_PERCEPTUAL_AI)
2325 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL4;
2326 else if (deltaq_mode == DELTA_Q_USER_RATING_BASED)
2327 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL4;
2328 else if (deltaq_mode == DELTA_Q_HDR)
2329 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL4;
2330 else if (deltaq_mode == DELTA_Q_VARIANCE_BOOST)
2331 cm->delta_q_info.delta_q_res =
2332 aom_get_variance_boost_delta_q_res(quant_params->base_qindex);
2333 // Set delta_q_present_flag before it is used for the first time
2334 cm->delta_q_info.delta_lf_res = DEFAULT_DELTA_LF_RES2;
2335 cm->delta_q_info.delta_q_present_flag = deltaq_mode != NO_DELTA_Q;
2336
2337 // Turn off cm->delta_q_info.delta_q_present_flag if objective delta_q
2338 // is used for ineligible frames. That effectively will turn off row_mt
2339 // usage. Note objective delta_q and tpl eligible frames are only altref
2340 // frames currently.
2341 if (cm->delta_q_info.delta_q_present_flag) {
2342 if (deltaq_mode == DELTA_Q_OBJECTIVE && !enable_delta_q(cpi))
2343 cm->delta_q_info.delta_q_present_flag = 0;
2344
2345 if (deltaq_mode == DELTA_Q_OBJECTIVE &&
2346 cm->delta_q_info.delta_q_present_flag) {
2347 cm->delta_q_info.delta_q_present_flag &= allow_deltaq_mode(cpi);
2348 }
2349 }
2350
2351 // Reset delta_q_used flag
2352 cpi->deltaq_used = 0;
2353
2354 cm->delta_q_info.delta_lf_present_flag =
2355 cm->delta_q_info.delta_q_present_flag &&
2356 oxcf->tool_cfg.enable_deltalf_mode;
2357 cm->delta_q_info.delta_lf_multi = DEFAULT_DELTA_LF_MULTI0;
2358
2359 // update delta_q_present_flag and delta_lf_present_flag based on
2360 // base_qindex
2361 cm->delta_q_info.delta_q_present_flag &= quant_params->base_qindex > 0;
2362 cm->delta_q_info.delta_lf_present_flag &= quant_params->base_qindex > 0;
2363 } else if (cpi->cyclic_refresh->apply_cyclic_refresh ||
2364 cpi->svc.number_temporal_layers == 1) {
2365 cpi->cyclic_refresh->actual_num_seg1_blocks = 0;
2366 cpi->cyclic_refresh->actual_num_seg2_blocks = 0;
2367 }
2368 cpi->rc.cnt_zeromv = 0;
2369 cpi->cb_delta_rdmult_enabled = enable_delta_rdmult(cpi);
2370
2371 av1_frame_init_quantizer(cpi);
2372 init_encode_frame_mb_context(cpi);
2373 set_default_interp_skip_flags(cm, &cpi->interp_search_flags);
2374
2375 if (cm->prev_frame && cm->prev_frame->seg.enabled &&
2376 cpi->svc.number_spatial_layers == 1)
2377 cm->last_frame_seg_map = cm->prev_frame->seg_map;
2378 else
2379 cm->last_frame_seg_map = NULL((void*)0);
2380 if (features->allow_intrabc || features->coded_lossless) {
2381 av1_set_default_ref_deltas(cm->lf.ref_deltas);
2382 av1_set_default_mode_deltas(cm->lf.mode_deltas);
2383 } else if (cm->prev_frame) {
2384 memcpy(cm->lf.ref_deltas, cm->prev_frame->ref_deltas, REF_FRAMES);
2385 memcpy(cm->lf.mode_deltas, cm->prev_frame->mode_deltas, MAX_MODE_LF_DELTAS2);
2386 }
2387 cm->lf.mode_ref_delta_enabled = oxcf->algo_cfg.mode_ref_delta_enabled;
2388 memcpy(cm->cur_frame->ref_deltas, cm->lf.ref_deltas, REF_FRAMES);
2389 memcpy(cm->cur_frame->mode_deltas, cm->lf.mode_deltas, MAX_MODE_LF_DELTAS2);
2390
2391 cpi->all_one_sided_refs =
2392 frame_is_intra_only(cm) ? 0 : refs_are_one_sided(cm);
2393
2394 cpi->prune_ref_frame_mask = 0;
2395 // Figure out which ref frames can be skipped at frame level.
2396 setup_prune_ref_frame_mask(cpi);
2397 // Disable certain reference frame pruning based on temporal distance and
2398 // quality of that reference frame.
2399 setup_keep_ref_frame_mask(cpi);
2400
2401 x->txfm_search_info.txb_split_count = 0;
2402#if CONFIG_SPEED_STATS0
2403 x->txfm_search_info.tx_search_count = 0;
2404#endif // CONFIG_SPEED_STATS
2405
2406#if !CONFIG_REALTIME_ONLY0
2407#if CONFIG_COLLECT_COMPONENT_TIMING0
2408 start_timing(cpi, av1_compute_global_motion_time);
2409#endif
2410 av1_compute_global_motion_facade(cpi);
2411#if CONFIG_COLLECT_COMPONENT_TIMING0
2412 end_timing(cpi, av1_compute_global_motion_time);
2413#endif
2414#endif // !CONFIG_REALTIME_ONLY
2415
2416#if CONFIG_COLLECT_COMPONENT_TIMING0
2417 start_timing(cpi, av1_setup_motion_field_time);
2418#endif
2419 av1_calculate_ref_frame_side(cm);
2420
2421 features->allow_ref_frame_mvs &= !(cpi->sf.hl_sf.ref_frame_mvs_lvl == 2);
2422 if (features->allow_ref_frame_mvs) av1_setup_motion_field(cm);
2423#if !CONFIG_REALTIME_ONLY0
2424 check_to_disable_ref_frame_mvs(cpi);
2425#endif // !CONFIG_REALTIME_ONLY
2426
2427#if CONFIG_COLLECT_COMPONENT_TIMING0
2428 end_timing(cpi, av1_setup_motion_field_time);
2429#endif
2430
2431 cm->current_frame.skip_mode_info.skip_mode_flag =
2432 check_skip_mode_enabled(cpi);
2433
2434 // Initialization of skip mode cost depends on the value of
2435 // 'skip_mode_flag'. This initialization happens in the function
2436 // av1_fill_mode_rates(), which is in turn called in
2437 // av1_initialize_rd_consts(). Thus, av1_initialize_rd_consts()
2438 // has to be called after 'skip_mode_flag' is initialized.
2439 av1_initialize_rd_consts(cpi);
2440 av1_set_sad_per_bit(cpi, &x->sadperbit, quant_params->base_qindex);
2441 populate_thresh_to_force_zeromv_skip(cpi);
2442
2443 enc_row_mt->sync_read_ptr = av1_row_mt_sync_read_dummy;
2444 enc_row_mt->sync_write_ptr = av1_row_mt_sync_write_dummy;
2445 mt_info->row_mt_enabled = 0;
2446 mt_info->pack_bs_mt_enabled = AOMMIN(mt_info->num_mod_workers[MOD_PACK_BS],(((mt_info->num_mod_workers[MOD_PACK_BS]) < (cm->tiles
.cols * cm->tiles.rows)) ? (mt_info->num_mod_workers[MOD_PACK_BS
]) : (cm->tiles.cols * cm->tiles.rows))
2447 cm->tiles.cols * cm->tiles.rows)(((mt_info->num_mod_workers[MOD_PACK_BS]) < (cm->tiles
.cols * cm->tiles.rows)) ? (mt_info->num_mod_workers[MOD_PACK_BS
]) : (cm->tiles.cols * cm->tiles.rows))
> 1;
2448
2449 if (oxcf->row_mt && (mt_info->num_workers > 1)) {
2450 mt_info->row_mt_enabled = 1;
2451 enc_row_mt->sync_read_ptr = av1_row_mt_sync_read;
2452 enc_row_mt->sync_write_ptr = av1_row_mt_sync_write;
2453 av1_encode_tiles_row_mt(cpi);
2454 } else {
2455 if (AOMMIN(mt_info->num_workers, cm->tiles.cols * cm->tiles.rows)(((mt_info->num_workers) < (cm->tiles.cols * cm->
tiles.rows)) ? (mt_info->num_workers) : (cm->tiles.cols
* cm->tiles.rows))
> 1) {
2456 av1_encode_tiles_mt(cpi);
2457 } else {
2458 // Preallocate the pc_tree for realtime coding to reduce the cost of
2459 // memory allocation.
2460 const int use_nonrd_mode = cpi->sf.rt_sf.use_nonrd_pick_mode;
2461 if (use_nonrd_mode) {
2462 td->pc_root = av1_alloc_pc_tree_node(cm->seq_params->sb_size);
2463 if (!td->pc_root)
2464 aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
2465 "Failed to allocate PC_TREE");
2466 } else {
2467 td->pc_root = NULL((void*)0);
2468 }
2469
2470 encode_tiles(cpi);
2471 av1_free_pc_tree_recursive(td->pc_root, av1_num_planes(cm), 0, 0,
2472 cpi->sf.part_sf.partition_search_type);
2473 td->pc_root = NULL((void*)0);
2474 }
2475 }
2476
2477 // If intrabc is allowed but never selected, reset the allow_intrabc flag.
2478 if (features->allow_intrabc && !cpi->intrabc_used) {
2479 features->allow_intrabc = 0;
2480 }
2481 if (features->allow_intrabc) {
2482 cm->delta_q_info.delta_lf_present_flag = 0;
2483 }
2484
2485 if (cm->delta_q_info.delta_q_present_flag && cpi->deltaq_used == 0) {
2486 cm->delta_q_info.delta_q_present_flag = 0;
2487 }
2488
2489 // Set the transform size appropriately before bitstream creation
2490 const MODE_EVAL_TYPE eval_type =
2491 cpi->sf.winner_mode_sf.enable_winner_mode_for_tx_size_srch
2492 ? WINNER_MODE_EVAL
2493 : DEFAULT_EVAL;
2494 const TX_SIZE_SEARCH_METHOD tx_search_type =
2495 cpi->winner_mode_params.tx_size_search_methods[eval_type];
2496 assert(oxcf->txfm_cfg.enable_tx64 || tx_search_type != USE_LARGESTALL)((void) sizeof ((oxcf->txfm_cfg.enable_tx64 || tx_search_type
!= USE_LARGESTALL) ? 1 : 0), __extension__ ({ if (oxcf->txfm_cfg
.enable_tx64 || tx_search_type != USE_LARGESTALL) ; else __assert_fail
("oxcf->txfm_cfg.enable_tx64 || tx_search_type != USE_LARGESTALL"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 2496, __extension__ __PRETTY_FUNCTION__); }))
;
2497 features->tx_mode = select_tx_mode(cm, tx_search_type);
2498
2499 // Retain the frame level probability update conditions for parallel frames.
2500 // These conditions will be consumed during postencode stage to update the
2501 // probability.
2502 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2503 cpi->do_update_frame_probs_txtype[cpi->num_frame_recode] =
2504 cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats;
2505 cpi->do_update_frame_probs_obmc[cpi->num_frame_recode] =
2506 (cpi->sf.inter_sf.prune_obmc_prob_thresh > 0 &&
2507 cpi->sf.inter_sf.prune_obmc_prob_thresh < INT_MAX2147483647);
2508 cpi->do_update_frame_probs_warp[cpi->num_frame_recode] =
2509 (features->allow_warped_motion &&
2510 cpi->sf.inter_sf.prune_warped_prob_thresh > 0);
2511 cpi->do_update_frame_probs_interpfilter[cpi->num_frame_recode] =
2512 (cm->current_frame.frame_type != KEY_FRAME &&
2513 cpi->sf.interp_sf.adaptive_interp_filter_search == 2 &&
2514 features->interp_filter == SWITCHABLE);
2515 }
2516
2517 if (cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats ||
2518 ((cpi->sf.tx_sf.tx_type_search.fast_inter_tx_type_prob_thresh !=
2519 INT_MAX2147483647) &&
2520 (cpi->sf.tx_sf.tx_type_search.fast_inter_tx_type_prob_thresh != 0))) {
2521 const FRAME_UPDATE_TYPE update_type =
2522 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2523 for (i = 0; i < TX_SIZES_ALL; i++) {
2524 int sum = 0;
2525 int j;
2526 int left = MAX_TX_TYPE_PROB1024;
2527
2528 for (j = 0; j < TX_TYPES; j++)
2529 sum += cpi->td.rd_counts.tx_type_used[i][j];
2530
2531 for (j = TX_TYPES - 1; j >= 0; j--) {
2532 int update_txtype_frameprobs = 1;
2533 const int new_prob =
2534 sum ? (int)((int64_t)MAX_TX_TYPE_PROB1024 *
2535 cpi->td.rd_counts.tx_type_used[i][j] / sum)
2536 : (j ? 0 : MAX_TX_TYPE_PROB1024);
2537#if CONFIG_FPMT_TEST0
2538 if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2539 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] ==
2540 0) {
2541 int prob =
2542 (temp_frame_probs_simulation->tx_type_probs[update_type][i][j] +
2543 new_prob) >>
2544 1;
2545 left -= prob;
2546 if (j == 0) prob += left;
2547 temp_frame_probs_simulation->tx_type_probs[update_type][i][j] =
2548 prob;
2549 // Copy temp_frame_probs_simulation to temp_frame_probs
2550 for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2551 update_type_idx++) {
2552 temp_frame_probs->tx_type_probs[update_type_idx][i][j] =
2553 temp_frame_probs_simulation
2554 ->tx_type_probs[update_type_idx][i][j];
2555 }
2556 }
2557 update_txtype_frameprobs = 0;
2558 }
2559#endif // CONFIG_FPMT_TEST
2560 // Track the frame probabilities of parallel encode frames to update
2561 // during postencode stage.
2562 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2563 update_txtype_frameprobs = 0;
2564 cpi->frame_new_probs[cpi->num_frame_recode]
2565 .tx_type_probs[update_type][i][j] = new_prob;
2566 }
2567 if (update_txtype_frameprobs) {
2568 int prob =
2569 (frame_probs->tx_type_probs[update_type][i][j] + new_prob) >> 1;
2570 left -= prob;
2571 if (j == 0) prob += left;
2572 frame_probs->tx_type_probs[update_type][i][j] = prob;
2573 }
2574 }
2575 }
2576 }
2577
2578 if (cm->seg.enabled) {
2579 cm->seg.temporal_update = 1;
2580 if (rdc->seg_tmp_pred_cost[0] < rdc->seg_tmp_pred_cost[1])
2581 cm->seg.temporal_update = 0;
2582 }
2583
2584 if (cpi->sf.inter_sf.prune_obmc_prob_thresh > 0 &&
2585 cpi->sf.inter_sf.prune_obmc_prob_thresh < INT_MAX2147483647) {
2586 const FRAME_UPDATE_TYPE update_type =
2587 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2588
2589 for (i = 0; i < BLOCK_SIZES_ALL; i++) {
2590 int sum = 0;
2591 int update_obmc_frameprobs = 1;
2592 for (int j = 0; j < 2; j++) sum += cpi->td.rd_counts.obmc_used[i][j];
2593
2594 const int new_prob =
2595 sum ? 128 * cpi->td.rd_counts.obmc_used[i][1] / sum : 0;
2596#if CONFIG_FPMT_TEST0
2597 if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2598 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 0) {
2599 temp_frame_probs_simulation->obmc_probs[update_type][i] =
2600 (temp_frame_probs_simulation->obmc_probs[update_type][i] +
2601 new_prob) >>
2602 1;
2603 // Copy temp_frame_probs_simulation to temp_frame_probs
2604 for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2605 update_type_idx++) {
2606 temp_frame_probs->obmc_probs[update_type_idx][i] =
2607 temp_frame_probs_simulation->obmc_probs[update_type_idx][i];
2608 }
2609 }
2610 update_obmc_frameprobs = 0;
2611 }
2612#endif // CONFIG_FPMT_TEST
2613 // Track the frame probabilities of parallel encode frames to update
2614 // during postencode stage.
2615 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2616 update_obmc_frameprobs = 0;
2617 cpi->frame_new_probs[cpi->num_frame_recode].obmc_probs[update_type][i] =
2618 new_prob;
2619 }
2620 if (update_obmc_frameprobs) {
2621 frame_probs->obmc_probs[update_type][i] =
2622 (frame_probs->obmc_probs[update_type][i] + new_prob) >> 1;
2623 }
2624 }
2625 }
2626
2627 if (features->allow_warped_motion &&
2628 cpi->sf.inter_sf.prune_warped_prob_thresh > 0) {
2629 const FRAME_UPDATE_TYPE update_type =
2630 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2631 int update_warp_frameprobs = 1;
2632 int sum = 0;
2633 for (i = 0; i < 2; i++) sum += cpi->td.rd_counts.warped_used[i];
2634 const int new_prob = sum ? 128 * cpi->td.rd_counts.warped_used[1] / sum : 0;
2635#if CONFIG_FPMT_TEST0
2636 if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2637 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 0) {
2638 temp_frame_probs_simulation->warped_probs[update_type] =
2639 (temp_frame_probs_simulation->warped_probs[update_type] +
2640 new_prob) >>
2641 1;
2642 // Copy temp_frame_probs_simulation to temp_frame_probs
2643 for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2644 update_type_idx++) {
2645 temp_frame_probs->warped_probs[update_type_idx] =
2646 temp_frame_probs_simulation->warped_probs[update_type_idx];
2647 }
2648 }
2649 update_warp_frameprobs = 0;
2650 }
2651#endif // CONFIG_FPMT_TEST
2652 // Track the frame probabilities of parallel encode frames to update
2653 // during postencode stage.
2654 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2655 update_warp_frameprobs = 0;
2656 cpi->frame_new_probs[cpi->num_frame_recode].warped_probs[update_type] =
2657 new_prob;
2658 }
2659 if (update_warp_frameprobs) {
2660 frame_probs->warped_probs[update_type] =
2661 (frame_probs->warped_probs[update_type] + new_prob) >> 1;
2662 }
2663 }
2664
2665 if (cm->current_frame.frame_type != KEY_FRAME &&
2666 cpi->sf.interp_sf.adaptive_interp_filter_search == 2 &&
2667 features->interp_filter == SWITCHABLE) {
2668 const FRAME_UPDATE_TYPE update_type =
2669 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2670
2671 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS((SWITCHABLE_FILTERS + 1) * 4); i++) {
2672 int sum = 0;
2673 int j;
2674 int left = 1536;
2675
2676 for (j = 0; j < SWITCHABLE_FILTERS; j++) {
2677 sum += cpi->td.counts->switchable_interp[i][j];
2678 }
2679
2680 for (j = SWITCHABLE_FILTERS - 1; j >= 0; j--) {
2681 int update_interpfilter_frameprobs = 1;
2682 const int new_prob =
2683 sum ? 1536 * cpi->td.counts->switchable_interp[i][j] / sum
2684 : (j ? 0 : 1536);
2685#if CONFIG_FPMT_TEST0
2686 if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2687 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] ==
2688 0) {
2689 int prob = (temp_frame_probs_simulation
2690 ->switchable_interp_probs[update_type][i][j] +
2691 new_prob) >>
2692 1;
2693 left -= prob;
2694 if (j == 0) prob += left;
2695 temp_frame_probs_simulation
2696 ->switchable_interp_probs[update_type][i][j] = prob;
2697 // Copy temp_frame_probs_simulation to temp_frame_probs
2698 for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2699 update_type_idx++) {
2700 temp_frame_probs->switchable_interp_probs[update_type_idx][i][j] =
2701 temp_frame_probs_simulation
2702 ->switchable_interp_probs[update_type_idx][i][j];
2703 }
2704 }
2705 update_interpfilter_frameprobs = 0;
2706 }
2707#endif // CONFIG_FPMT_TEST
2708 // Track the frame probabilities of parallel encode frames to update
2709 // during postencode stage.
2710 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2711 update_interpfilter_frameprobs = 0;
2712 cpi->frame_new_probs[cpi->num_frame_recode]
2713 .switchable_interp_probs[update_type][i][j] = new_prob;
2714 }
2715 if (update_interpfilter_frameprobs) {
2716 int prob = (frame_probs->switchable_interp_probs[update_type][i][j] +
2717 new_prob) >>
2718 1;
2719 left -= prob;
2720 if (j == 0) prob += left;
2721 frame_probs->switchable_interp_probs[update_type][i][j] = prob;
2722 }
2723 }
2724 }
2725 }
2726 if (hash_table_created) {
2727 av1_hash_table_destroy(&intrabc_hash_info->intrabc_hash_table);
2728 }
2729}
2730
2731/*!\brief Setup reference frame buffers and encode a frame
2732 *
2733 * \ingroup high_level_algo
2734 * \callgraph
2735 * \callergraph
2736 *
2737 * \param[in] cpi Top-level encoder structure
2738 */
2739void av1_encode_frame(AV1_COMP *cpi) {
2740 AV1_COMMON *const cm = &cpi->common;
2741 CurrentFrame *const current_frame = &cm->current_frame;
2742 FeatureFlags *const features = &cm->features;
2743 RD_COUNTS *const rdc = &cpi->td.rd_counts;
2744 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
2745 // Indicates whether or not to use a default reduced set for ext-tx
2746 // rather than the potential full set of 16 transforms
2747 features->reduced_tx_set_used = oxcf->txfm_cfg.reduced_tx_type_set;
2748
2749 // Make sure segment_id is no larger than last_active_segid.
2750 if (cm->seg.enabled && cm->seg.update_map) {
2751 const int mi_rows = cm->mi_params.mi_rows;
2752 const int mi_cols = cm->mi_params.mi_cols;
2753 const int last_active_segid = cm->seg.last_active_segid;
2754 uint8_t *map = cpi->enc_seg.map;
2755 for (int mi_row = 0; mi_row < mi_rows; ++mi_row) {
2756 for (int mi_col = 0; mi_col < mi_cols; ++mi_col) {
2757 map[mi_col] = AOMMIN(map[mi_col], last_active_segid)(((map[mi_col]) < (last_active_segid)) ? (map[mi_col]) : (
last_active_segid))
;
2758 }
2759 map += mi_cols;
2760 }
2761 }
2762
2763 av1_setup_frame_buf_refs(cm);
2764 enforce_max_ref_frames(cpi, &cpi->ref_frame_flags,
2765 cm->cur_frame->ref_display_order_hint,
2766 cm->current_frame.display_order_hint);
2767 set_rel_frame_dist(&cpi->common, &cpi->ref_frame_dist_info,
2768 cpi->ref_frame_flags);
2769 av1_setup_frame_sign_bias(cm);
2770
2771 // If global motion is enabled, then every buffer which is used as either
2772 // a source or a ref frame should have an image pyramid allocated.
2773 // Check here so that issues can be caught early in debug mode
2774#if !defined(NDEBUG) && !CONFIG_REALTIME_ONLY0
2775 if (cpi->alloc_pyramid) {
2776 assert(cpi->source->y_pyramid)((void) sizeof ((cpi->source->y_pyramid) ? 1 : 0), __extension__
({ if (cpi->source->y_pyramid) ; else __assert_fail ("cpi->source->y_pyramid"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 2776, __extension__ __PRETTY_FUNCTION__); }))
;
2777 for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
2778 const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
2779 if (buf != NULL((void*)0)) {
2780 assert(buf->buf.y_pyramid)((void) sizeof ((buf->buf.y_pyramid) ? 1 : 0), __extension__
({ if (buf->buf.y_pyramid) ; else __assert_fail ("buf->buf.y_pyramid"
, "/root/firefox-clang/third_party/aom/av1/encoder/encodeframe.c"
, 2780, __extension__ __PRETTY_FUNCTION__); }))
;
2781 }
2782 }
2783 }
2784#endif // !defined(NDEBUG) && !CONFIG_REALTIME_ONLY
2785
2786#if CONFIG_MISMATCH_DEBUG0
2787 mismatch_reset_frame(av1_num_planes(cm));
2788#endif
2789
2790 rdc->newmv_or_intra_blocks = 0;
2791 cpi->palette_pixel_num = 0;
2792
2793 if (cpi->sf.hl_sf.frame_parameter_update ||
2794 cpi->sf.rt_sf.use_comp_ref_nonrd) {
2795 if (frame_is_intra_only(cm))
2796 current_frame->reference_mode = SINGLE_REFERENCE;
2797 else
2798 current_frame->reference_mode = REFERENCE_MODE_SELECT;
2799
2800 features->interp_filter = SWITCHABLE;
2801 if (cm->tiles.large_scale) features->interp_filter = EIGHTTAP_REGULAR;
2802
2803 features->switchable_motion_mode = is_switchable_motion_mode_allowed(
2804 features->allow_warped_motion, oxcf->motion_mode_cfg.enable_obmc);
2805
2806 rdc->compound_ref_used_flag = 0;
2807 rdc->skip_mode_used_flag = 0;
2808
2809 encode_frame_internal(cpi);
2810
2811 if (current_frame->reference_mode == REFERENCE_MODE_SELECT) {
2812 // Use a flag that includes 4x4 blocks
2813 if (rdc->compound_ref_used_flag == 0) {
2814 current_frame->reference_mode = SINGLE_REFERENCE;
2815#if CONFIG_ENTROPY_STATS0
2816 av1_zero(cpi->td.counts->comp_inter)memset(&(cpi->td.counts->comp_inter), 0, sizeof(cpi
->td.counts->comp_inter))
;
2817#endif // CONFIG_ENTROPY_STATS
2818 }
2819 }
2820 // Re-check on the skip mode status as reference mode may have been
2821 // changed.
2822 SkipModeInfo *const skip_mode_info = &current_frame->skip_mode_info;
2823 if (frame_is_intra_only(cm) ||
2824 current_frame->reference_mode == SINGLE_REFERENCE) {
2825 skip_mode_info->skip_mode_allowed = 0;
2826 skip_mode_info->skip_mode_flag = 0;
2827 }
2828 if (skip_mode_info->skip_mode_flag && rdc->skip_mode_used_flag == 0)
2829 skip_mode_info->skip_mode_flag = 0;
2830
2831 if (!cm->tiles.large_scale) {
2832 if (features->tx_mode == TX_MODE_SELECT &&
2833 cpi->td.mb.txfm_search_info.txb_split_count == 0)
2834 features->tx_mode = TX_MODE_LARGEST;
2835 }
2836 } else {
2837 // This is needed if real-time speed setting is changed on the fly
2838 // from one using compound prediction to one using single reference.
2839 if (current_frame->reference_mode == REFERENCE_MODE_SELECT)
2840 current_frame->reference_mode = SINGLE_REFERENCE;
2841 encode_frame_internal(cpi);
2842 }
2843}