Bug Summary

File:root/firefox-clang/third_party/aom/av1/encoder/rdopt.c
Warning:line 4697, column 45
The result of left shift is undefined because the right operand is negative

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name rdopt.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-21/lib/clang/21 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -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-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -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-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 -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-06-27-100320-3286336-1 -x c /root/firefox-clang/third_party/aom/av1/encoder/rdopt.c

/root/firefox-clang/third_party/aom/av1/encoder/rdopt.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 <assert.h>
13#include <math.h>
14#include <stdbool.h>
15#include <stdint.h>
16#include <string.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/blend.h"
24#include "aom_mem/aom_mem.h"
25#include "aom_ports/aom_timer.h"
26#include "aom_ports/mem.h"
27
28#include "av1/common/av1_common_int.h"
29#include "av1/common/cfl.h"
30#include "av1/common/blockd.h"
31#include "av1/common/common.h"
32#include "av1/common/common_data.h"
33#include "av1/common/entropy.h"
34#include "av1/common/entropymode.h"
35#include "av1/common/enums.h"
36#include "av1/common/idct.h"
37#include "av1/common/mvref_common.h"
38#include "av1/common/obmc.h"
39#include "av1/common/pred_common.h"
40#include "av1/common/quant_common.h"
41#include "av1/common/reconinter.h"
42#include "av1/common/reconintra.h"
43#include "av1/common/scan.h"
44#include "av1/common/seg_common.h"
45#include "av1/common/txb_common.h"
46#include "av1/common/warped_motion.h"
47
48#include "av1/encoder/aq_variance.h"
49#include "av1/encoder/av1_quantize.h"
50#include "av1/encoder/block.h"
51#include "av1/encoder/cost.h"
52#include "av1/encoder/compound_type.h"
53#include "av1/encoder/encodemb.h"
54#include "av1/encoder/encodemv.h"
55#include "av1/encoder/encoder.h"
56#include "av1/encoder/encodetxb.h"
57#include "av1/encoder/hybrid_fwd_txfm.h"
58#include "av1/encoder/interp_search.h"
59#include "av1/encoder/intra_mode_search.h"
60#include "av1/encoder/intra_mode_search_utils.h"
61#include "av1/encoder/mcomp.h"
62#include "av1/encoder/ml.h"
63#include "av1/encoder/mode_prune_model_weights.h"
64#include "av1/encoder/model_rd.h"
65#include "av1/encoder/motion_search_facade.h"
66#include "av1/encoder/palette.h"
67#include "av1/encoder/pustats.h"
68#include "av1/encoder/random.h"
69#include "av1/encoder/ratectrl.h"
70#include "av1/encoder/rd.h"
71#include "av1/encoder/rdopt.h"
72#include "av1/encoder/reconinter_enc.h"
73#include "av1/encoder/tokenize.h"
74#include "av1/encoder/tpl_model.h"
75#include "av1/encoder/tx_search.h"
76#include "av1/encoder/var_based_part.h"
77
78#define LAST_NEW_MV_INDEX6 6
79
80// Mode_threshold multiplication factor table for prune_inter_modes_if_skippable
81// The values are kept in Q12 format and equation used to derive is
82// (2.5 - ((float)x->qindex / MAXQ) * 1.5)
83#define MODE_THRESH_QBITS12 12
84static const int mode_threshold_mul_factor[QINDEX_RANGE(255 - 0 + 1)] = {
85 10240, 10216, 10192, 10168, 10144, 10120, 10095, 10071, 10047, 10023, 9999,
86 9975, 9951, 9927, 9903, 9879, 9854, 9830, 9806, 9782, 9758, 9734,
87 9710, 9686, 9662, 9638, 9614, 9589, 9565, 9541, 9517, 9493, 9469,
88 9445, 9421, 9397, 9373, 9349, 9324, 9300, 9276, 9252, 9228, 9204,
89 9180, 9156, 9132, 9108, 9083, 9059, 9035, 9011, 8987, 8963, 8939,
90 8915, 8891, 8867, 8843, 8818, 8794, 8770, 8746, 8722, 8698, 8674,
91 8650, 8626, 8602, 8578, 8553, 8529, 8505, 8481, 8457, 8433, 8409,
92 8385, 8361, 8337, 8312, 8288, 8264, 8240, 8216, 8192, 8168, 8144,
93 8120, 8096, 8072, 8047, 8023, 7999, 7975, 7951, 7927, 7903, 7879,
94 7855, 7831, 7806, 7782, 7758, 7734, 7710, 7686, 7662, 7638, 7614,
95 7590, 7566, 7541, 7517, 7493, 7469, 7445, 7421, 7397, 7373, 7349,
96 7325, 7301, 7276, 7252, 7228, 7204, 7180, 7156, 7132, 7108, 7084,
97 7060, 7035, 7011, 6987, 6963, 6939, 6915, 6891, 6867, 6843, 6819,
98 6795, 6770, 6746, 6722, 6698, 6674, 6650, 6626, 6602, 6578, 6554,
99 6530, 6505, 6481, 6457, 6433, 6409, 6385, 6361, 6337, 6313, 6289,
100 6264, 6240, 6216, 6192, 6168, 6144, 6120, 6096, 6072, 6048, 6024,
101 5999, 5975, 5951, 5927, 5903, 5879, 5855, 5831, 5807, 5783, 5758,
102 5734, 5710, 5686, 5662, 5638, 5614, 5590, 5566, 5542, 5518, 5493,
103 5469, 5445, 5421, 5397, 5373, 5349, 5325, 5301, 5277, 5253, 5228,
104 5204, 5180, 5156, 5132, 5108, 5084, 5060, 5036, 5012, 4987, 4963,
105 4939, 4915, 4891, 4867, 4843, 4819, 4795, 4771, 4747, 4722, 4698,
106 4674, 4650, 4626, 4602, 4578, 4554, 4530, 4506, 4482, 4457, 4433,
107 4409, 4385, 4361, 4337, 4313, 4289, 4265, 4241, 4216, 4192, 4168,
108 4144, 4120, 4096
109};
110
111static const THR_MODES av1_default_mode_order[MAX_MODES] = {
112 THR_NEARESTMV,
113 THR_NEARESTL2,
114 THR_NEARESTL3,
115 THR_NEARESTB,
116 THR_NEARESTA2,
117 THR_NEARESTA,
118 THR_NEARESTG,
119
120 THR_NEWMV,
121 THR_NEWL2,
122 THR_NEWL3,
123 THR_NEWB,
124 THR_NEWA2,
125 THR_NEWA,
126 THR_NEWG,
127
128 THR_NEARMV,
129 THR_NEARL2,
130 THR_NEARL3,
131 THR_NEARB,
132 THR_NEARA2,
133 THR_NEARA,
134 THR_NEARG,
135
136 THR_GLOBALMV,
137 THR_GLOBALL2,
138 THR_GLOBALL3,
139 THR_GLOBALB,
140 THR_GLOBALA2,
141 THR_GLOBALA,
142 THR_GLOBALG,
143
144 THR_COMP_NEAREST_NEARESTLA,
145 THR_COMP_NEAREST_NEARESTL2A,
146 THR_COMP_NEAREST_NEARESTL3A,
147 THR_COMP_NEAREST_NEARESTGA,
148 THR_COMP_NEAREST_NEARESTLB,
149 THR_COMP_NEAREST_NEARESTL2B,
150 THR_COMP_NEAREST_NEARESTL3B,
151 THR_COMP_NEAREST_NEARESTGB,
152 THR_COMP_NEAREST_NEARESTLA2,
153 THR_COMP_NEAREST_NEARESTL2A2,
154 THR_COMP_NEAREST_NEARESTL3A2,
155 THR_COMP_NEAREST_NEARESTGA2,
156 THR_COMP_NEAREST_NEARESTLL2,
157 THR_COMP_NEAREST_NEARESTLL3,
158 THR_COMP_NEAREST_NEARESTLG,
159 THR_COMP_NEAREST_NEARESTBA,
160
161 THR_COMP_NEAR_NEARLB,
162 THR_COMP_NEW_NEWLB,
163 THR_COMP_NEW_NEARESTLB,
164 THR_COMP_NEAREST_NEWLB,
165 THR_COMP_NEW_NEARLB,
166 THR_COMP_NEAR_NEWLB,
167 THR_COMP_GLOBAL_GLOBALLB,
168
169 THR_COMP_NEAR_NEARLA,
170 THR_COMP_NEW_NEWLA,
171 THR_COMP_NEW_NEARESTLA,
172 THR_COMP_NEAREST_NEWLA,
173 THR_COMP_NEW_NEARLA,
174 THR_COMP_NEAR_NEWLA,
175 THR_COMP_GLOBAL_GLOBALLA,
176
177 THR_COMP_NEAR_NEARL2A,
178 THR_COMP_NEW_NEWL2A,
179 THR_COMP_NEW_NEARESTL2A,
180 THR_COMP_NEAREST_NEWL2A,
181 THR_COMP_NEW_NEARL2A,
182 THR_COMP_NEAR_NEWL2A,
183 THR_COMP_GLOBAL_GLOBALL2A,
184
185 THR_COMP_NEAR_NEARL3A,
186 THR_COMP_NEW_NEWL3A,
187 THR_COMP_NEW_NEARESTL3A,
188 THR_COMP_NEAREST_NEWL3A,
189 THR_COMP_NEW_NEARL3A,
190 THR_COMP_NEAR_NEWL3A,
191 THR_COMP_GLOBAL_GLOBALL3A,
192
193 THR_COMP_NEAR_NEARGA,
194 THR_COMP_NEW_NEWGA,
195 THR_COMP_NEW_NEARESTGA,
196 THR_COMP_NEAREST_NEWGA,
197 THR_COMP_NEW_NEARGA,
198 THR_COMP_NEAR_NEWGA,
199 THR_COMP_GLOBAL_GLOBALGA,
200
201 THR_COMP_NEAR_NEARL2B,
202 THR_COMP_NEW_NEWL2B,
203 THR_COMP_NEW_NEARESTL2B,
204 THR_COMP_NEAREST_NEWL2B,
205 THR_COMP_NEW_NEARL2B,
206 THR_COMP_NEAR_NEWL2B,
207 THR_COMP_GLOBAL_GLOBALL2B,
208
209 THR_COMP_NEAR_NEARL3B,
210 THR_COMP_NEW_NEWL3B,
211 THR_COMP_NEW_NEARESTL3B,
212 THR_COMP_NEAREST_NEWL3B,
213 THR_COMP_NEW_NEARL3B,
214 THR_COMP_NEAR_NEWL3B,
215 THR_COMP_GLOBAL_GLOBALL3B,
216
217 THR_COMP_NEAR_NEARGB,
218 THR_COMP_NEW_NEWGB,
219 THR_COMP_NEW_NEARESTGB,
220 THR_COMP_NEAREST_NEWGB,
221 THR_COMP_NEW_NEARGB,
222 THR_COMP_NEAR_NEWGB,
223 THR_COMP_GLOBAL_GLOBALGB,
224
225 THR_COMP_NEAR_NEARLA2,
226 THR_COMP_NEW_NEWLA2,
227 THR_COMP_NEW_NEARESTLA2,
228 THR_COMP_NEAREST_NEWLA2,
229 THR_COMP_NEW_NEARLA2,
230 THR_COMP_NEAR_NEWLA2,
231 THR_COMP_GLOBAL_GLOBALLA2,
232
233 THR_COMP_NEAR_NEARL2A2,
234 THR_COMP_NEW_NEWL2A2,
235 THR_COMP_NEW_NEARESTL2A2,
236 THR_COMP_NEAREST_NEWL2A2,
237 THR_COMP_NEW_NEARL2A2,
238 THR_COMP_NEAR_NEWL2A2,
239 THR_COMP_GLOBAL_GLOBALL2A2,
240
241 THR_COMP_NEAR_NEARL3A2,
242 THR_COMP_NEW_NEWL3A2,
243 THR_COMP_NEW_NEARESTL3A2,
244 THR_COMP_NEAREST_NEWL3A2,
245 THR_COMP_NEW_NEARL3A2,
246 THR_COMP_NEAR_NEWL3A2,
247 THR_COMP_GLOBAL_GLOBALL3A2,
248
249 THR_COMP_NEAR_NEARGA2,
250 THR_COMP_NEW_NEWGA2,
251 THR_COMP_NEW_NEARESTGA2,
252 THR_COMP_NEAREST_NEWGA2,
253 THR_COMP_NEW_NEARGA2,
254 THR_COMP_NEAR_NEWGA2,
255 THR_COMP_GLOBAL_GLOBALGA2,
256
257 THR_COMP_NEAR_NEARLL2,
258 THR_COMP_NEW_NEWLL2,
259 THR_COMP_NEW_NEARESTLL2,
260 THR_COMP_NEAREST_NEWLL2,
261 THR_COMP_NEW_NEARLL2,
262 THR_COMP_NEAR_NEWLL2,
263 THR_COMP_GLOBAL_GLOBALLL2,
264
265 THR_COMP_NEAR_NEARLL3,
266 THR_COMP_NEW_NEWLL3,
267 THR_COMP_NEW_NEARESTLL3,
268 THR_COMP_NEAREST_NEWLL3,
269 THR_COMP_NEW_NEARLL3,
270 THR_COMP_NEAR_NEWLL3,
271 THR_COMP_GLOBAL_GLOBALLL3,
272
273 THR_COMP_NEAR_NEARLG,
274 THR_COMP_NEW_NEWLG,
275 THR_COMP_NEW_NEARESTLG,
276 THR_COMP_NEAREST_NEWLG,
277 THR_COMP_NEW_NEARLG,
278 THR_COMP_NEAR_NEWLG,
279 THR_COMP_GLOBAL_GLOBALLG,
280
281 THR_COMP_NEAR_NEARBA,
282 THR_COMP_NEW_NEWBA,
283 THR_COMP_NEW_NEARESTBA,
284 THR_COMP_NEAREST_NEWBA,
285 THR_COMP_NEW_NEARBA,
286 THR_COMP_NEAR_NEWBA,
287 THR_COMP_GLOBAL_GLOBALBA,
288
289 THR_DC,
290 THR_PAETH,
291 THR_SMOOTH,
292 THR_SMOOTH_V,
293 THR_SMOOTH_H,
294 THR_H_PRED,
295 THR_V_PRED,
296 THR_D135_PRED,
297 THR_D203_PRED,
298 THR_D157_PRED,
299 THR_D67_PRED,
300 THR_D113_PRED,
301 THR_D45_PRED,
302};
303
304/*!\cond */
305typedef struct SingleInterModeState {
306 int64_t rd;
307 MV_REFERENCE_FRAME ref_frame;
308 int valid;
309} SingleInterModeState;
310
311typedef struct InterModeSearchState {
312 int64_t best_rd;
313 int64_t best_skip_rd[2];
314 MB_MODE_INFO best_mbmode;
315 int best_rate_y;
316 int best_rate_uv;
317 int best_mode_skippable;
318 int best_skip2;
319 THR_MODES best_mode_index;
320 int num_available_refs;
321 int64_t dist_refs[REF_FRAMES];
322 int dist_order_refs[REF_FRAMES];
323 int64_t mode_threshold[MAX_MODES];
324 int64_t best_intra_rd;
325 unsigned int best_pred_sse;
326
327 /*!
328 * \brief Keep track of best intra rd for use in compound mode.
329 */
330 int64_t best_pred_rd[REFERENCE_MODES];
331 // Save a set of single_newmv for each checked ref_mv.
332 int_mv single_newmv[MAX_REF_MV_SEARCH3][REF_FRAMES];
333 int single_newmv_rate[MAX_REF_MV_SEARCH3][REF_FRAMES];
334 int single_newmv_valid[MAX_REF_MV_SEARCH3][REF_FRAMES];
335 int64_t modelled_rd[MB_MODE_COUNT][MAX_REF_MV_SEARCH3][REF_FRAMES];
336 // The rd of simple translation in single inter modes
337 int64_t simple_rd[MB_MODE_COUNT][MAX_REF_MV_SEARCH3][REF_FRAMES];
338 int64_t best_single_rd[REF_FRAMES];
339 PREDICTION_MODE best_single_mode[REF_FRAMES];
340
341 // Single search results by [directions][modes][reference frames]
342 SingleInterModeState single_state[2][SINGLE_INTER_MODE_NUM][FWD_REFS];
343 int single_state_cnt[2][SINGLE_INTER_MODE_NUM];
344 SingleInterModeState single_state_modelled[2][SINGLE_INTER_MODE_NUM]
345 [FWD_REFS];
346 int single_state_modelled_cnt[2][SINGLE_INTER_MODE_NUM];
347 MV_REFERENCE_FRAME single_rd_order[2][SINGLE_INTER_MODE_NUM][FWD_REFS];
348 IntraModeSearchState intra_search_state;
349 RD_STATS best_y_rdcost;
350} InterModeSearchState;
351/*!\endcond */
352
353void av1_inter_mode_data_init(TileDataEnc *tile_data) {
354 for (int i = 0; i < BLOCK_SIZES_ALL; ++i) {
355 InterModeRdModel *md = &tile_data->inter_mode_rd_models[i];
356 md->ready = 0;
357 md->num = 0;
358 md->dist_sum = 0;
359 md->ld_sum = 0;
360 md->sse_sum = 0;
361 md->sse_sse_sum = 0;
362 md->sse_ld_sum = 0;
363 }
364}
365
366static int get_est_rate_dist(const TileDataEnc *tile_data, BLOCK_SIZE bsize,
367 int64_t sse, int *est_residue_cost,
368 int64_t *est_dist) {
369 const InterModeRdModel *md = &tile_data->inter_mode_rd_models[bsize];
370 if (md->ready) {
371 if (sse < md->dist_mean) {
372 *est_residue_cost = 0;
373 *est_dist = sse;
374 } else {
375 *est_dist = (int64_t)round(md->dist_mean);
376 const double est_ld = md->a * sse + md->b;
377 // Clamp estimated rate cost by INT_MAX / 2.
378 // TODO(angiebird@google.com): find better solution than clamping.
379 if (fabs(est_ld) < 1e-2) {
380 *est_residue_cost = INT_MAX2147483647 / 2;
381 } else {
382 double est_residue_cost_dbl = ((sse - md->dist_mean) / est_ld);
383 if (est_residue_cost_dbl < 0) {
384 *est_residue_cost = 0;
385 } else {
386 *est_residue_cost =
387 (int)AOMMIN((int64_t)round(est_residue_cost_dbl), INT_MAX / 2)((((int64_t)round(est_residue_cost_dbl)) < (2147483647 / 2
)) ? ((int64_t)round(est_residue_cost_dbl)) : (2147483647 / 2
))
;
388 }
389 }
390 if (*est_residue_cost <= 0) {
391 *est_residue_cost = 0;
392 *est_dist = sse;
393 }
394 }
395 return 1;
396 }
397 return 0;
398}
399
400void av1_inter_mode_data_fit(TileDataEnc *tile_data, int rdmult) {
401 for (int bsize = 0; bsize < BLOCK_SIZES_ALL; ++bsize) {
402 const int block_idx = inter_mode_data_block_idx(bsize);
403 InterModeRdModel *md = &tile_data->inter_mode_rd_models[bsize];
404 if (block_idx == -1) continue;
405 if ((md->ready == 0 && md->num < 200) || (md->ready == 1 && md->num < 64)) {
406 continue;
407 } else {
408 if (md->ready == 0) {
409 md->dist_mean = md->dist_sum / md->num;
410 md->ld_mean = md->ld_sum / md->num;
411 md->sse_mean = md->sse_sum / md->num;
412 md->sse_sse_mean = md->sse_sse_sum / md->num;
413 md->sse_ld_mean = md->sse_ld_sum / md->num;
414 } else {
415 const double factor = 3;
416 md->dist_mean =
417 (md->dist_mean * factor + (md->dist_sum / md->num)) / (factor + 1);
418 md->ld_mean =
419 (md->ld_mean * factor + (md->ld_sum / md->num)) / (factor + 1);
420 md->sse_mean =
421 (md->sse_mean * factor + (md->sse_sum / md->num)) / (factor + 1);
422 md->sse_sse_mean =
423 (md->sse_sse_mean * factor + (md->sse_sse_sum / md->num)) /
424 (factor + 1);
425 md->sse_ld_mean =
426 (md->sse_ld_mean * factor + (md->sse_ld_sum / md->num)) /
427 (factor + 1);
428 }
429
430 const double my = md->ld_mean;
431 const double mx = md->sse_mean;
432 const double dx = sqrt(md->sse_sse_mean);
433 const double dxy = md->sse_ld_mean;
434
435 md->a = (dxy - mx * my) / (dx * dx - mx * mx);
436 md->b = my - md->a * mx;
437 md->ready = 1;
438
439 md->num = 0;
440 md->dist_sum = 0;
441 md->ld_sum = 0;
442 md->sse_sum = 0;
443 md->sse_sse_sum = 0;
444 md->sse_ld_sum = 0;
445 }
446 (void)rdmult;
447 }
448}
449
450static inline void inter_mode_data_push(TileDataEnc *tile_data,
451 BLOCK_SIZE bsize, int64_t sse,
452 int64_t dist, int residue_cost) {
453 if (residue_cost == 0 || sse == dist) return;
454 const int block_idx = inter_mode_data_block_idx(bsize);
455 if (block_idx == -1) return;
456 InterModeRdModel *rd_model = &tile_data->inter_mode_rd_models[bsize];
457 if (rd_model->num < INTER_MODE_RD_DATA_OVERALL_SIZE6400) {
458 const double ld = (sse - dist) * 1. / residue_cost;
459 ++rd_model->num;
460 rd_model->dist_sum += dist;
461 rd_model->ld_sum += ld;
462 rd_model->sse_sum += sse;
463 rd_model->sse_sse_sum += (double)sse * (double)sse;
464 rd_model->sse_ld_sum += sse * ld;
465 }
466}
467
468static inline void inter_modes_info_push(InterModesInfo *inter_modes_info,
469 int mode_rate, int64_t sse, int64_t rd,
470 RD_STATS *rd_cost, RD_STATS *rd_cost_y,
471 RD_STATS *rd_cost_uv,
472 const MB_MODE_INFO *mbmi) {
473 const int num = inter_modes_info->num;
474 assert(num < MAX_INTER_MODES)((void) sizeof ((num < 1024) ? 1 : 0), __extension__ ({ if
(num < 1024) ; else __assert_fail ("num < MAX_INTER_MODES"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 474
, __extension__ __PRETTY_FUNCTION__); }))
;
475 inter_modes_info->mbmi_arr[num] = *mbmi;
476 inter_modes_info->mode_rate_arr[num] = mode_rate;
477 inter_modes_info->sse_arr[num] = sse;
478 inter_modes_info->est_rd_arr[num] = rd;
479 inter_modes_info->rd_cost_arr[num] = *rd_cost;
480 inter_modes_info->rd_cost_y_arr[num] = *rd_cost_y;
481 inter_modes_info->rd_cost_uv_arr[num] = *rd_cost_uv;
482 ++inter_modes_info->num;
483}
484
485static int compare_rd_idx_pair(const void *a, const void *b) {
486 if (((RdIdxPair *)a)->rd == ((RdIdxPair *)b)->rd) {
487 // To avoid inconsistency in qsort() ordering when two elements are equal,
488 // using idx as tie breaker. Refer aomedia:2928
489 if (((RdIdxPair *)a)->idx == ((RdIdxPair *)b)->idx)
490 return 0;
491 else if (((RdIdxPair *)a)->idx > ((RdIdxPair *)b)->idx)
492 return 1;
493 else
494 return -1;
495 } else if (((const RdIdxPair *)a)->rd > ((const RdIdxPair *)b)->rd) {
496 return 1;
497 } else {
498 return -1;
499 }
500}
501
502static inline void inter_modes_info_sort(const InterModesInfo *inter_modes_info,
503 RdIdxPair *rd_idx_pair_arr) {
504 if (inter_modes_info->num == 0) {
505 return;
506 }
507 for (int i = 0; i < inter_modes_info->num; ++i) {
508 rd_idx_pair_arr[i].idx = i;
509 rd_idx_pair_arr[i].rd = inter_modes_info->est_rd_arr[i];
510 }
511 qsort(rd_idx_pair_arr, inter_modes_info->num, sizeof(rd_idx_pair_arr[0]),
512 compare_rd_idx_pair);
513}
514
515// Similar to get_horver_correlation, but also takes into account first
516// row/column, when computing horizontal/vertical correlation.
517void av1_get_horver_correlation_full_c(const int16_t *diff, int stride,
518 int width, int height, float *hcorr,
519 float *vcorr) {
520 // The following notation is used:
521 // x - current pixel
522 // y - left neighbor pixel
523 // z - top neighbor pixel
524 int64_t x_sum = 0, x2_sum = 0, xy_sum = 0, xz_sum = 0;
525 int64_t x_firstrow = 0, x_finalrow = 0, x_firstcol = 0, x_finalcol = 0;
526 int64_t x2_firstrow = 0, x2_finalrow = 0, x2_firstcol = 0, x2_finalcol = 0;
527
528 // First, process horizontal correlation on just the first row
529 x_sum += diff[0];
530 x2_sum += diff[0] * diff[0];
531 x_firstrow += diff[0];
532 x2_firstrow += diff[0] * diff[0];
533 for (int j = 1; j < width; ++j) {
534 const int16_t x = diff[j];
535 const int16_t y = diff[j - 1];
536 x_sum += x;
537 x_firstrow += x;
538 x2_sum += x * x;
539 x2_firstrow += x * x;
540 xy_sum += x * y;
541 }
542
543 // Process vertical correlation in the first column
544 x_firstcol += diff[0];
545 x2_firstcol += diff[0] * diff[0];
546 for (int i = 1; i < height; ++i) {
547 const int16_t x = diff[i * stride];
548 const int16_t z = diff[(i - 1) * stride];
549 x_sum += x;
550 x_firstcol += x;
551 x2_sum += x * x;
552 x2_firstcol += x * x;
553 xz_sum += x * z;
554 }
555
556 // Now process horiz and vert correlation through the rest unit
557 for (int i = 1; i < height; ++i) {
558 for (int j = 1; j < width; ++j) {
559 const int16_t x = diff[i * stride + j];
560 const int16_t y = diff[i * stride + j - 1];
561 const int16_t z = diff[(i - 1) * stride + j];
562 x_sum += x;
563 x2_sum += x * x;
564 xy_sum += x * y;
565 xz_sum += x * z;
566 }
567 }
568
569 for (int j = 0; j < width; ++j) {
570 x_finalrow += diff[(height - 1) * stride + j];
571 x2_finalrow +=
572 diff[(height - 1) * stride + j] * diff[(height - 1) * stride + j];
573 }
574 for (int i = 0; i < height; ++i) {
575 x_finalcol += diff[i * stride + width - 1];
576 x2_finalcol += diff[i * stride + width - 1] * diff[i * stride + width - 1];
577 }
578
579 int64_t xhor_sum = x_sum - x_finalcol;
580 int64_t xver_sum = x_sum - x_finalrow;
581 int64_t y_sum = x_sum - x_firstcol;
582 int64_t z_sum = x_sum - x_firstrow;
583 int64_t x2hor_sum = x2_sum - x2_finalcol;
584 int64_t x2ver_sum = x2_sum - x2_finalrow;
585 int64_t y2_sum = x2_sum - x2_firstcol;
586 int64_t z2_sum = x2_sum - x2_firstrow;
587
588 const float num_hor = (float)(height * (width - 1));
589 const float num_ver = (float)((height - 1) * width);
590
591 const float xhor_var_n = x2hor_sum - (xhor_sum * xhor_sum) / num_hor;
592 const float xver_var_n = x2ver_sum - (xver_sum * xver_sum) / num_ver;
593
594 const float y_var_n = y2_sum - (y_sum * y_sum) / num_hor;
595 const float z_var_n = z2_sum - (z_sum * z_sum) / num_ver;
596
597 const float xy_var_n = xy_sum - (xhor_sum * y_sum) / num_hor;
598 const float xz_var_n = xz_sum - (xver_sum * z_sum) / num_ver;
599
600 if (xhor_var_n > 0 && y_var_n > 0) {
601 *hcorr = xy_var_n / sqrtf(xhor_var_n * y_var_n);
602 *hcorr = *hcorr < 0 ? 0 : *hcorr;
603 } else {
604 *hcorr = 1.0;
605 }
606 if (xver_var_n > 0 && z_var_n > 0) {
607 *vcorr = xz_var_n / sqrtf(xver_var_n * z_var_n);
608 *vcorr = *vcorr < 0 ? 0 : *vcorr;
609 } else {
610 *vcorr = 1.0;
611 }
612}
613
614static void get_variance_stats_hbd(const MACROBLOCK *x, int64_t *src_var,
615 int64_t *rec_var) {
616 const MACROBLOCKD *xd = &x->e_mbd;
617 const MB_MODE_INFO *mbmi = xd->mi[0];
618 const struct macroblockd_plane *const pd = &xd->plane[AOM_PLANE_Y0];
619 const struct macroblock_plane *const p = &x->plane[AOM_PLANE_Y0];
620
621 BLOCK_SIZE bsize = mbmi->bsize;
622 int bw = block_size_wide[bsize];
623 int bh = block_size_high[bsize];
624
625 static const int gau_filter[3][3] = {
626 { 1, 2, 1 },
627 { 2, 4, 2 },
628 { 1, 2, 1 },
629 };
630
631 DECLARE_ALIGNED(16, uint16_t, dclevel[(MAX_SB_SIZE + 2) * (MAX_SB_SIZE + 2)])uint16_t dclevel[((1 << 7) + 2) * ((1 << 7) + 2)]
__attribute__((aligned(16)))
;
632
633 uint16_t *pred_ptr = &dclevel[bw + 1];
634 int pred_stride = xd->plane[0].dst.stride;
635
636 for (int idy = -1; idy < bh + 1; ++idy) {
637 for (int idx = -1; idx < bw + 1; ++idx) {
638 int offset_idy = idy;
639 int offset_idx = idx;
640 if (idy == -1) offset_idy = 0;
641 if (idy == bh) offset_idy = bh - 1;
642 if (idx == -1) offset_idx = 0;
643 if (idx == bw) offset_idx = bw - 1;
644
645 int offset = offset_idy * pred_stride + offset_idx;
646 pred_ptr[idy * bw + idx] = CONVERT_TO_SHORTPTR(pd->dst.buf)((uint16_t *)(((uintptr_t)(pd->dst.buf)) << 1))[offset];
647 }
648 }
649
650 *rec_var = 0;
651 for (int idy = 0; idy < bh; ++idy) {
652 for (int idx = 0; idx < bw; ++idx) {
653 int sum = 0;
654 for (int iy = 0; iy < 3; ++iy)
655 for (int ix = 0; ix < 3; ++ix)
656 sum += pred_ptr[(idy + iy - 1) * bw + (idx + ix - 1)] *
657 gau_filter[iy][ix];
658
659 sum = sum >> 4;
660
661 int64_t diff = pred_ptr[idy * bw + idx] - sum;
662 *rec_var += diff * diff;
663 }
664 }
665 *rec_var <<= 4;
666
667 int src_stride = p->src.stride;
668 for (int idy = -1; idy < bh + 1; ++idy) {
669 for (int idx = -1; idx < bw + 1; ++idx) {
670 int offset_idy = idy;
671 int offset_idx = idx;
672 if (idy == -1) offset_idy = 0;
673 if (idy == bh) offset_idy = bh - 1;
674 if (idx == -1) offset_idx = 0;
675 if (idx == bw) offset_idx = bw - 1;
676
677 int offset = offset_idy * src_stride + offset_idx;
678 pred_ptr[idy * bw + idx] = CONVERT_TO_SHORTPTR(p->src.buf)((uint16_t *)(((uintptr_t)(p->src.buf)) << 1))[offset];
679 }
680 }
681
682 *src_var = 0;
683 for (int idy = 0; idy < bh; ++idy) {
684 for (int idx = 0; idx < bw; ++idx) {
685 int sum = 0;
686 for (int iy = 0; iy < 3; ++iy)
687 for (int ix = 0; ix < 3; ++ix)
688 sum += pred_ptr[(idy + iy - 1) * bw + (idx + ix - 1)] *
689 gau_filter[iy][ix];
690
691 sum = sum >> 4;
692
693 int64_t diff = pred_ptr[idy * bw + idx] - sum;
694 *src_var += diff * diff;
695 }
696 }
697 *src_var <<= 4;
698}
699
700static void get_variance_stats(const MACROBLOCK *x, int64_t *src_var,
701 int64_t *rec_var) {
702 const MACROBLOCKD *xd = &x->e_mbd;
703 const MB_MODE_INFO *mbmi = xd->mi[0];
704 const struct macroblockd_plane *const pd = &xd->plane[AOM_PLANE_Y0];
705 const struct macroblock_plane *const p = &x->plane[AOM_PLANE_Y0];
706
707 BLOCK_SIZE bsize = mbmi->bsize;
708 int bw = block_size_wide[bsize];
709 int bh = block_size_high[bsize];
710
711 static const int gau_filter[3][3] = {
712 { 1, 2, 1 },
713 { 2, 4, 2 },
714 { 1, 2, 1 },
715 };
716
717 DECLARE_ALIGNED(16, uint8_t, dclevel[(MAX_SB_SIZE + 2) * (MAX_SB_SIZE + 2)])uint8_t dclevel[((1 << 7) + 2) * ((1 << 7) + 2)] __attribute__
((aligned(16)))
;
718
719 uint8_t *pred_ptr = &dclevel[bw + 1];
720 int pred_stride = xd->plane[0].dst.stride;
721
722 for (int idy = -1; idy < bh + 1; ++idy) {
723 for (int idx = -1; idx < bw + 1; ++idx) {
724 int offset_idy = idy;
725 int offset_idx = idx;
726 if (idy == -1) offset_idy = 0;
727 if (idy == bh) offset_idy = bh - 1;
728 if (idx == -1) offset_idx = 0;
729 if (idx == bw) offset_idx = bw - 1;
730
731 int offset = offset_idy * pred_stride + offset_idx;
732 pred_ptr[idy * bw + idx] = pd->dst.buf[offset];
733 }
734 }
735
736 *rec_var = 0;
737 for (int idy = 0; idy < bh; ++idy) {
738 for (int idx = 0; idx < bw; ++idx) {
739 int sum = 0;
740 for (int iy = 0; iy < 3; ++iy)
741 for (int ix = 0; ix < 3; ++ix)
742 sum += pred_ptr[(idy + iy - 1) * bw + (idx + ix - 1)] *
743 gau_filter[iy][ix];
744
745 sum = sum >> 4;
746
747 int64_t diff = pred_ptr[idy * bw + idx] - sum;
748 *rec_var += diff * diff;
749 }
750 }
751 *rec_var <<= 4;
752
753 int src_stride = p->src.stride;
754 for (int idy = -1; idy < bh + 1; ++idy) {
755 for (int idx = -1; idx < bw + 1; ++idx) {
756 int offset_idy = idy;
757 int offset_idx = idx;
758 if (idy == -1) offset_idy = 0;
759 if (idy == bh) offset_idy = bh - 1;
760 if (idx == -1) offset_idx = 0;
761 if (idx == bw) offset_idx = bw - 1;
762
763 int offset = offset_idy * src_stride + offset_idx;
764 pred_ptr[idy * bw + idx] = p->src.buf[offset];
765 }
766 }
767
768 *src_var = 0;
769 for (int idy = 0; idy < bh; ++idy) {
770 for (int idx = 0; idx < bw; ++idx) {
771 int sum = 0;
772 for (int iy = 0; iy < 3; ++iy)
773 for (int ix = 0; ix < 3; ++ix)
774 sum += pred_ptr[(idy + iy - 1) * bw + (idx + ix - 1)] *
775 gau_filter[iy][ix];
776
777 sum = sum >> 4;
778
779 int64_t diff = pred_ptr[idy * bw + idx] - sum;
780 *src_var += diff * diff;
781 }
782 }
783 *src_var <<= 4;
784}
785
786static void adjust_rdcost(const AV1_COMP *cpi, const MACROBLOCK *x,
787 RD_STATS *rd_cost) {
788 if (cpi->oxcf.algo_cfg.sharpness != 3) return;
789
790 if (frame_is_kf_gf_arf(cpi)) return;
791
792 int64_t src_var, rec_var;
793
794 const bool_Bool is_hbd = is_cur_buf_hbd(&x->e_mbd);
795 if (is_hbd)
796 get_variance_stats_hbd(x, &src_var, &rec_var);
797 else
798 get_variance_stats(x, &src_var, &rec_var);
799
800 if (src_var <= rec_var) return;
801
802 int64_t var_offset = src_var - rec_var;
803
804 rd_cost->dist += var_offset;
805
806 rd_cost->rdcost = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist)((((((int64_t)(rd_cost->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_cost->dist) * (1 <<
7)))
;
807}
808
809static void adjust_cost(const AV1_COMP *cpi, const MACROBLOCK *x,
810 int64_t *rd_cost) {
811 if (cpi->oxcf.algo_cfg.sharpness != 3) return;
812
813 if (frame_is_kf_gf_arf(cpi)) return;
814
815 int64_t src_var, rec_var;
816 const bool_Bool is_hbd = is_cur_buf_hbd(&x->e_mbd);
817
818 if (is_hbd)
819 get_variance_stats_hbd(x, &src_var, &rec_var);
820 else
821 get_variance_stats(x, &src_var, &rec_var);
822
823 if (src_var <= rec_var) return;
824
825 int64_t var_offset = src_var - rec_var;
826
827 *rd_cost += RDCOST(x->rdmult, 0, var_offset)((((((int64_t)(0)) * (x->rdmult)) + (((1 << (9)) >>
1))) >> (9)) + ((var_offset) * (1 << 7)))
;
828}
829
830static int64_t get_sse(const AV1_COMP *cpi, const MACROBLOCK *x,
831 int64_t *sse_y) {
832 const AV1_COMMON *cm = &cpi->common;
833 const int num_planes = av1_num_planes(cm);
834 const MACROBLOCKD *xd = &x->e_mbd;
835 const MB_MODE_INFO *mbmi = xd->mi[0];
836 int64_t total_sse = 0;
837 for (int plane = 0; plane < num_planes; ++plane) {
838 if (plane && !xd->is_chroma_ref) break;
839 const struct macroblock_plane *const p = &x->plane[plane];
840 const struct macroblockd_plane *const pd = &xd->plane[plane];
841 const BLOCK_SIZE bs =
842 get_plane_block_size(mbmi->bsize, pd->subsampling_x, pd->subsampling_y);
843 unsigned int sse;
844
845 cpi->ppi->fn_ptr[bs].vf(p->src.buf, p->src.stride, pd->dst.buf,
846 pd->dst.stride, &sse);
847 total_sse += sse;
848 if (!plane && sse_y) *sse_y = sse;
849 }
850 total_sse <<= 4;
851 return total_sse;
852}
853
854int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
855 intptr_t block_size, int64_t *ssz) {
856 int i;
857 int64_t error = 0, sqcoeff = 0;
858
859 for (i = 0; i < block_size; i++) {
860 const int diff = coeff[i] - dqcoeff[i];
861 error += diff * diff;
862 sqcoeff += coeff[i] * coeff[i];
863 }
864
865 *ssz = sqcoeff;
866 return error;
867}
868
869int64_t av1_block_error_lp_c(const int16_t *coeff, const int16_t *dqcoeff,
870 intptr_t block_size) {
871 int64_t error = 0;
872
873 for (int i = 0; i < block_size; i++) {
874 const int diff = coeff[i] - dqcoeff[i];
875 error += diff * diff;
876 }
877
878 return error;
879}
880
881#if CONFIG_AV1_HIGHBITDEPTH1
882int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
883 const tran_low_t *dqcoeff, intptr_t block_size,
884 int64_t *ssz, int bd) {
885 int i;
886 int64_t error = 0, sqcoeff = 0;
887 int shift = 2 * (bd - 8);
888 int rounding = (1 << shift) >> 1;
889
890 for (i = 0; i < block_size; i++) {
891 const int64_t diff = coeff[i] - dqcoeff[i];
892 error += diff * diff;
893 sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
894 }
895 error = (error + rounding) >> shift;
896 sqcoeff = (sqcoeff + rounding) >> shift;
897
898 *ssz = sqcoeff;
899 return error;
900}
901#endif
902
903static int conditional_skipintra(PREDICTION_MODE mode,
904 PREDICTION_MODE best_intra_mode) {
905 if (mode == D113_PRED && best_intra_mode != V_PRED &&
906 best_intra_mode != D135_PRED)
907 return 1;
908 if (mode == D67_PRED && best_intra_mode != V_PRED &&
909 best_intra_mode != D45_PRED)
910 return 1;
911 if (mode == D203_PRED && best_intra_mode != H_PRED &&
912 best_intra_mode != D45_PRED)
913 return 1;
914 if (mode == D157_PRED && best_intra_mode != H_PRED &&
915 best_intra_mode != D135_PRED)
916 return 1;
917 return 0;
918}
919
920static int cost_mv_ref(const ModeCosts *const mode_costs, PREDICTION_MODE mode,
921 int16_t mode_context) {
922 if (is_inter_compound_mode(mode)) {
923 return mode_costs
924 ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)(uint8_t)((mode)-NEAREST_NEARESTMV)];
925 }
926
927 int mode_cost = 0;
928 int16_t mode_ctx = mode_context & NEWMV_CTX_MASK((1 << 3) - 1);
929
930 assert(is_inter_mode(mode))((void) sizeof ((is_inter_mode(mode)) ? 1 : 0), __extension__
({ if (is_inter_mode(mode)) ; else __assert_fail ("is_inter_mode(mode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 930
, __extension__ __PRETTY_FUNCTION__); }))
;
931
932 if (mode == NEWMV) {
933 mode_cost = mode_costs->newmv_mode_cost[mode_ctx][0];
934 return mode_cost;
935 } else {
936 mode_cost = mode_costs->newmv_mode_cost[mode_ctx][1];
937 mode_ctx = (mode_context >> GLOBALMV_OFFSET3) & GLOBALMV_CTX_MASK((1 << (4 - 3)) - 1);
938
939 if (mode == GLOBALMV) {
940 mode_cost += mode_costs->zeromv_mode_cost[mode_ctx][0];
941 return mode_cost;
942 } else {
943 mode_cost += mode_costs->zeromv_mode_cost[mode_ctx][1];
944 mode_ctx = (mode_context >> REFMV_OFFSET4) & REFMV_CTX_MASK((1 << (8 - 4)) - 1);
945 mode_cost += mode_costs->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
946 return mode_cost;
947 }
948 }
949}
950
951static inline PREDICTION_MODE get_single_mode(PREDICTION_MODE this_mode,
952 int ref_idx) {
953 return ref_idx ? compound_ref1_mode(this_mode)
954 : compound_ref0_mode(this_mode);
955}
956
957static inline void estimate_ref_frame_costs(
958 const AV1_COMMON *cm, const MACROBLOCKD *xd, const ModeCosts *mode_costs,
959 int segment_id, unsigned int *ref_costs_single,
960 unsigned int (*ref_costs_comp)[REF_FRAMES]) {
961 int seg_ref_active =
962 segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
963 if (seg_ref_active) {
964 memset(ref_costs_single, 0, REF_FRAMES * sizeof(*ref_costs_single));
965 int ref_frame;
966 for (ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame)
967 memset(ref_costs_comp[ref_frame], 0,
968 REF_FRAMES * sizeof((*ref_costs_comp)[0]));
969 } else {
970 int intra_inter_ctx = av1_get_intra_inter_context(xd);
971 ref_costs_single[INTRA_FRAME] =
972 mode_costs->intra_inter_cost[intra_inter_ctx][0];
973 unsigned int base_cost = mode_costs->intra_inter_cost[intra_inter_ctx][1];
974
975 for (int i = LAST_FRAME; i <= ALTREF_FRAME; ++i)
976 ref_costs_single[i] = base_cost;
977
978 const int ctx_p1 = av1_get_pred_context_single_ref_p1(xd);
979 const int ctx_p2 = av1_get_pred_context_single_ref_p2(xd);
980 const int ctx_p3 = av1_get_pred_context_single_ref_p3(xd);
981 const int ctx_p4 = av1_get_pred_context_single_ref_p4(xd);
982 const int ctx_p5 = av1_get_pred_context_single_ref_p5(xd);
983 const int ctx_p6 = av1_get_pred_context_single_ref_p6(xd);
984
985 // Determine cost of a single ref frame, where frame types are represented
986 // by a tree:
987 // Level 0: add cost whether this ref is a forward or backward ref
988 ref_costs_single[LAST_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][0];
989 ref_costs_single[LAST2_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][0];
990 ref_costs_single[LAST3_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][0];
991 ref_costs_single[GOLDEN_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][0];
992 ref_costs_single[BWDREF_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][1];
993 ref_costs_single[ALTREF2_FRAME] +=
994 mode_costs->single_ref_cost[ctx_p1][0][1];
995 ref_costs_single[ALTREF_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][1];
996
997 // Level 1: if this ref is forward ref,
998 // add cost whether it is last/last2 or last3/golden
999 ref_costs_single[LAST_FRAME] += mode_costs->single_ref_cost[ctx_p3][2][0];
1000 ref_costs_single[LAST2_FRAME] += mode_costs->single_ref_cost[ctx_p3][2][0];
1001 ref_costs_single[LAST3_FRAME] += mode_costs->single_ref_cost[ctx_p3][2][1];
1002 ref_costs_single[GOLDEN_FRAME] += mode_costs->single_ref_cost[ctx_p3][2][1];
1003
1004 // Level 1: if this ref is backward ref
1005 // then add cost whether this ref is altref or backward ref
1006 ref_costs_single[BWDREF_FRAME] += mode_costs->single_ref_cost[ctx_p2][1][0];
1007 ref_costs_single[ALTREF2_FRAME] +=
1008 mode_costs->single_ref_cost[ctx_p2][1][0];
1009 ref_costs_single[ALTREF_FRAME] += mode_costs->single_ref_cost[ctx_p2][1][1];
1010
1011 // Level 2: further add cost whether this ref is last or last2
1012 ref_costs_single[LAST_FRAME] += mode_costs->single_ref_cost[ctx_p4][3][0];
1013 ref_costs_single[LAST2_FRAME] += mode_costs->single_ref_cost[ctx_p4][3][1];
1014
1015 // Level 2: last3 or golden
1016 ref_costs_single[LAST3_FRAME] += mode_costs->single_ref_cost[ctx_p5][4][0];
1017 ref_costs_single[GOLDEN_FRAME] += mode_costs->single_ref_cost[ctx_p5][4][1];
1018
1019 // Level 2: bwdref or altref2
1020 ref_costs_single[BWDREF_FRAME] += mode_costs->single_ref_cost[ctx_p6][5][0];
1021 ref_costs_single[ALTREF2_FRAME] +=
1022 mode_costs->single_ref_cost[ctx_p6][5][1];
1023
1024 if (cm->current_frame.reference_mode != SINGLE_REFERENCE) {
1025 // Similar to single ref, determine cost of compound ref frames.
1026 // cost_compound_refs = cost_first_ref + cost_second_ref
1027 const int bwdref_comp_ctx_p = av1_get_pred_context_comp_bwdref_p(xd);
1028 const int bwdref_comp_ctx_p1 = av1_get_pred_context_comp_bwdref_p1(xd);
1029 const int ref_comp_ctx_p = av1_get_pred_context_comp_ref_p(xd);
1030 const int ref_comp_ctx_p1 = av1_get_pred_context_comp_ref_p1(xd);
1031 const int ref_comp_ctx_p2 = av1_get_pred_context_comp_ref_p2(xd);
1032
1033 const int comp_ref_type_ctx = av1_get_comp_reference_type_context(xd);
1034 unsigned int ref_bicomp_costs[REF_FRAMES] = { 0 };
1035
1036 ref_bicomp_costs[LAST_FRAME] = ref_bicomp_costs[LAST2_FRAME] =
1037 ref_bicomp_costs[LAST3_FRAME] = ref_bicomp_costs[GOLDEN_FRAME] =
1038 base_cost + mode_costs->comp_ref_type_cost[comp_ref_type_ctx][1];
1039 ref_bicomp_costs[BWDREF_FRAME] = ref_bicomp_costs[ALTREF2_FRAME] = 0;
1040 ref_bicomp_costs[ALTREF_FRAME] = 0;
1041
1042 // cost of first ref frame
1043 ref_bicomp_costs[LAST_FRAME] +=
1044 mode_costs->comp_ref_cost[ref_comp_ctx_p][0][0];
1045 ref_bicomp_costs[LAST2_FRAME] +=
1046 mode_costs->comp_ref_cost[ref_comp_ctx_p][0][0];
1047 ref_bicomp_costs[LAST3_FRAME] +=
1048 mode_costs->comp_ref_cost[ref_comp_ctx_p][0][1];
1049 ref_bicomp_costs[GOLDEN_FRAME] +=
1050 mode_costs->comp_ref_cost[ref_comp_ctx_p][0][1];
1051
1052 ref_bicomp_costs[LAST_FRAME] +=
1053 mode_costs->comp_ref_cost[ref_comp_ctx_p1][1][0];
1054 ref_bicomp_costs[LAST2_FRAME] +=
1055 mode_costs->comp_ref_cost[ref_comp_ctx_p1][1][1];
1056
1057 ref_bicomp_costs[LAST3_FRAME] +=
1058 mode_costs->comp_ref_cost[ref_comp_ctx_p2][2][0];
1059 ref_bicomp_costs[GOLDEN_FRAME] +=
1060 mode_costs->comp_ref_cost[ref_comp_ctx_p2][2][1];
1061
1062 // cost of second ref frame
1063 ref_bicomp_costs[BWDREF_FRAME] +=
1064 mode_costs->comp_bwdref_cost[bwdref_comp_ctx_p][0][0];
1065 ref_bicomp_costs[ALTREF2_FRAME] +=
1066 mode_costs->comp_bwdref_cost[bwdref_comp_ctx_p][0][0];
1067 ref_bicomp_costs[ALTREF_FRAME] +=
1068 mode_costs->comp_bwdref_cost[bwdref_comp_ctx_p][0][1];
1069
1070 ref_bicomp_costs[BWDREF_FRAME] +=
1071 mode_costs->comp_bwdref_cost[bwdref_comp_ctx_p1][1][0];
1072 ref_bicomp_costs[ALTREF2_FRAME] +=
1073 mode_costs->comp_bwdref_cost[bwdref_comp_ctx_p1][1][1];
1074
1075 // cost: if one ref frame is forward ref, the other ref is backward ref
1076 int ref0, ref1;
1077 for (ref0 = LAST_FRAME; ref0 <= GOLDEN_FRAME; ++ref0) {
1078 for (ref1 = BWDREF_FRAME; ref1 <= ALTREF_FRAME; ++ref1) {
1079 ref_costs_comp[ref0][ref1] =
1080 ref_bicomp_costs[ref0] + ref_bicomp_costs[ref1];
1081 }
1082 }
1083
1084 // cost: if both ref frames are the same side.
1085 const int uni_comp_ref_ctx_p = av1_get_pred_context_uni_comp_ref_p(xd);
1086 const int uni_comp_ref_ctx_p1 = av1_get_pred_context_uni_comp_ref_p1(xd);
1087 const int uni_comp_ref_ctx_p2 = av1_get_pred_context_uni_comp_ref_p2(xd);
1088 ref_costs_comp[LAST_FRAME][LAST2_FRAME] =
1089 base_cost + mode_costs->comp_ref_type_cost[comp_ref_type_ctx][0] +
1090 mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p][0][0] +
1091 mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p1][1][0];
1092 ref_costs_comp[LAST_FRAME][LAST3_FRAME] =
1093 base_cost + mode_costs->comp_ref_type_cost[comp_ref_type_ctx][0] +
1094 mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p][0][0] +
1095 mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p1][1][1] +
1096 mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p2][2][0];
1097 ref_costs_comp[LAST_FRAME][GOLDEN_FRAME] =
1098 base_cost + mode_costs->comp_ref_type_cost[comp_ref_type_ctx][0] +
1099 mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p][0][0] +
1100 mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p1][1][1] +
1101 mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p2][2][1];
1102 ref_costs_comp[BWDREF_FRAME][ALTREF_FRAME] =
1103 base_cost + mode_costs->comp_ref_type_cost[comp_ref_type_ctx][0] +
1104 mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p][0][1];
1105 } else {
1106 int ref0, ref1;
1107 for (ref0 = LAST_FRAME; ref0 <= GOLDEN_FRAME; ++ref0) {
1108 for (ref1 = BWDREF_FRAME; ref1 <= ALTREF_FRAME; ++ref1)
1109 ref_costs_comp[ref0][ref1] = 512;
1110 }
1111 ref_costs_comp[LAST_FRAME][LAST2_FRAME] = 512;
1112 ref_costs_comp[LAST_FRAME][LAST3_FRAME] = 512;
1113 ref_costs_comp[LAST_FRAME][GOLDEN_FRAME] = 512;
1114 ref_costs_comp[BWDREF_FRAME][ALTREF_FRAME] = 512;
1115 }
1116 }
1117}
1118
1119static inline void store_coding_context(
1120#if CONFIG_INTERNAL_STATS0
1121 MACROBLOCK *x, PICK_MODE_CONTEXT *ctx, int mode_index,
1122#else
1123 MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
1124#endif // CONFIG_INTERNAL_STATS
1125 int skippable) {
1126 MACROBLOCKD *const xd = &x->e_mbd;
1127
1128 // Take a snapshot of the coding context so it can be
1129 // restored if we decide to encode this way
1130 ctx->rd_stats.skip_txfm = x->txfm_search_info.skip_txfm;
1131 ctx->skippable = skippable;
1132#if CONFIG_INTERNAL_STATS0
1133 ctx->best_mode_index = mode_index;
1134#endif // CONFIG_INTERNAL_STATS
1135 ctx->mic = *xd->mi[0];
1136 av1_copy_mbmi_ext_to_mbmi_ext_frame(&ctx->mbmi_ext_best, &x->mbmi_ext,
1137 av1_ref_frame_type(xd->mi[0]->ref_frame));
1138}
1139
1140static inline void setup_buffer_ref_mvs_inter(
1141 const AV1_COMP *const cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
1142 BLOCK_SIZE block_size, struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE3]) {
1143 const AV1_COMMON *cm = &cpi->common;
1144 const int num_planes = av1_num_planes(cm);
1145 const YV12_BUFFER_CONFIG *scaled_ref_frame =
1146 av1_get_scaled_ref_frame(cpi, ref_frame);
1147 MACROBLOCKD *const xd = &x->e_mbd;
1148 MB_MODE_INFO *const mbmi = xd->mi[0];
1149 MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
1150 const struct scale_factors *const sf =
1151 get_ref_scale_factors_const(cm, ref_frame);
1152 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_yv12_buf(cm, ref_frame);
1153 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/rdopt.c", 1153
, __extension__ __PRETTY_FUNCTION__); }))
;
1154
1155 if (scaled_ref_frame) {
1156 // Setup pred block based on scaled reference, because av1_mv_pred() doesn't
1157 // support scaling.
1158 av1_setup_pred_block(xd, yv12_mb[ref_frame], scaled_ref_frame, NULL((void*)0), NULL((void*)0),
1159 num_planes);
1160 } else {
1161 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, sf, sf, num_planes);
1162 }
1163
1164 // Gets an initial list of candidate vectors from neighbours and orders them
1165 av1_find_mv_refs(cm, xd, mbmi, ref_frame, mbmi_ext->ref_mv_count,
1166 xd->ref_mv_stack, xd->weight, NULL((void*)0), mbmi_ext->global_mvs,
1167 mbmi_ext->mode_context);
1168 // TODO(Ravi): Populate mbmi_ext->ref_mv_stack[ref_frame][4] and
1169 // mbmi_ext->weight[ref_frame][4] inside av1_find_mv_refs.
1170 av1_copy_usable_ref_mv_stack_and_weight(xd, mbmi_ext, ref_frame);
1171 // Further refinement that is encode side only to test the top few candidates
1172 // in full and choose the best as the center point for subsequent searches.
1173 // The current implementation doesn't support scaling.
1174 av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12_mb[ref_frame][0].stride,
1175 ref_frame, block_size);
1176
1177 // Go back to unscaled reference.
1178 if (scaled_ref_frame) {
1179 // We had temporarily setup pred block based on scaled reference above. Go
1180 // back to unscaled reference now, for subsequent use.
1181 av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, sf, sf, num_planes);
1182 }
1183}
1184
1185#define LEFT_TOP_MARGIN((288 - 4) << 3) ((AOM_BORDER_IN_PIXELS288 - AOM_INTERP_EXTEND4) << 3)
1186#define RIGHT_BOTTOM_MARGIN((288 - 4) << 3) ((AOM_BORDER_IN_PIXELS288 - AOM_INTERP_EXTEND4) << 3)
1187
1188// TODO(jingning): this mv clamping function should be block size dependent.
1189static inline void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
1190 const SubpelMvLimits mv_limits = { xd->mb_to_left_edge - LEFT_TOP_MARGIN((288 - 4) << 3),
1191 xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN((288 - 4) << 3),
1192 xd->mb_to_top_edge - LEFT_TOP_MARGIN((288 - 4) << 3),
1193 xd->mb_to_bottom_edge +
1194 RIGHT_BOTTOM_MARGIN((288 - 4) << 3) };
1195 clamp_mv(mv, &mv_limits);
1196}
1197
1198/* If the current mode shares the same mv with other modes with higher cost,
1199 * skip this mode. */
1200static int skip_repeated_mv(const AV1_COMMON *const cm,
1201 const MACROBLOCK *const x,
1202 PREDICTION_MODE this_mode,
1203 const MV_REFERENCE_FRAME ref_frames[2],
1204 InterModeSearchState *search_state) {
1205 const int is_comp_pred = ref_frames[1] > INTRA_FRAME;
1206 const uint8_t ref_frame_type = av1_ref_frame_type(ref_frames);
1207 const MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
1208 const int ref_mv_count = mbmi_ext->ref_mv_count[ref_frame_type];
1209 PREDICTION_MODE compare_mode = MB_MODE_COUNT;
1210 if (!is_comp_pred) {
1211 if (this_mode == NEARMV) {
1212 if (ref_mv_count == 0) {
1213 // NEARMV has the same motion vector as NEARESTMV
1214 compare_mode = NEARESTMV;
1215 }
1216 if (ref_mv_count == 1 &&
1217 cm->global_motion[ref_frames[0]].wmtype <= TRANSLATION) {
1218 // NEARMV has the same motion vector as GLOBALMV
1219 compare_mode = GLOBALMV;
1220 }
1221 }
1222 if (this_mode == GLOBALMV) {
1223 if (ref_mv_count == 0 &&
1224 cm->global_motion[ref_frames[0]].wmtype <= TRANSLATION) {
1225 // GLOBALMV has the same motion vector as NEARESTMV
1226 compare_mode = NEARESTMV;
1227 }
1228 if (ref_mv_count == 1) {
1229 // GLOBALMV has the same motion vector as NEARMV
1230 compare_mode = NEARMV;
1231 }
1232 }
1233
1234 if (compare_mode != MB_MODE_COUNT) {
1235 // Use modelled_rd to check whether compare mode was searched
1236 if (search_state->modelled_rd[compare_mode][0][ref_frames[0]] !=
1237 INT64_MAX(9223372036854775807L)) {
1238 const int16_t mode_ctx =
1239 av1_mode_context_analyzer(mbmi_ext->mode_context, ref_frames);
1240 const int compare_cost =
1241 cost_mv_ref(&x->mode_costs, compare_mode, mode_ctx);
1242 const int this_cost = cost_mv_ref(&x->mode_costs, this_mode, mode_ctx);
1243
1244 // Only skip if the mode cost is larger than compare mode cost
1245 if (this_cost > compare_cost) {
1246 search_state->modelled_rd[this_mode][0][ref_frames[0]] =
1247 search_state->modelled_rd[compare_mode][0][ref_frames[0]];
1248 return 1;
1249 }
1250 }
1251 }
1252 }
1253 return 0;
1254}
1255
1256static inline int clamp_and_check_mv(int_mv *out_mv, int_mv in_mv,
1257 const AV1_COMMON *cm,
1258 const MACROBLOCK *x) {
1259 const MACROBLOCKD *const xd = &x->e_mbd;
1260 *out_mv = in_mv;
1261 lower_mv_precision(&out_mv->as_mv, cm->features.allow_high_precision_mv,
1262 cm->features.cur_frame_force_integer_mv);
1263 clamp_mv2(&out_mv->as_mv, xd);
1264 return av1_is_fullmv_in_range(&x->mv_limits,
1265 get_fullmv_from_mv(&out_mv->as_mv));
1266}
1267
1268// To use single newmv directly for compound modes, need to clamp the mv to the
1269// valid mv range. Without this, encoder would generate out of range mv, and
1270// this is seen in 8k encoding.
1271static inline void clamp_mv_in_range(MACROBLOCK *const x, int_mv *mv,
1272 int ref_idx) {
1273 const int_mv ref_mv = av1_get_ref_mv(x, ref_idx);
1274 SubpelMvLimits mv_limits;
1275
1276 av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, &ref_mv.as_mv);
1277 clamp_mv(&mv->as_mv, &mv_limits);
1278}
1279
1280static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
1281 const BLOCK_SIZE bsize, int_mv *cur_mv,
1282 int *const rate_mv, HandleInterModeArgs *const args,
1283 inter_mode_info *mode_info) {
1284 MACROBLOCKD *const xd = &x->e_mbd;
1285 MB_MODE_INFO *const mbmi = xd->mi[0];
1286 const int is_comp_pred = has_second_ref(mbmi);
1287 const PREDICTION_MODE this_mode = mbmi->mode;
1288 const int refs[2] = { mbmi->ref_frame[0],
1289 mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
1290 const int ref_mv_idx = mbmi->ref_mv_idx;
1291
1292 if (is_comp_pred) {
1293 const int valid_mv0 = args->single_newmv_valid[ref_mv_idx][refs[0]];
1294 const int valid_mv1 = args->single_newmv_valid[ref_mv_idx][refs[1]];
1295 if (this_mode == NEW_NEWMV) {
1296 if (valid_mv0) {
1297 cur_mv[0].as_int = args->single_newmv[ref_mv_idx][refs[0]].as_int;
1298 clamp_mv_in_range(x, &cur_mv[0], 0);
1299 }
1300 if (valid_mv1) {
1301 cur_mv[1].as_int = args->single_newmv[ref_mv_idx][refs[1]].as_int;
1302 clamp_mv_in_range(x, &cur_mv[1], 1);
1303 }
1304 *rate_mv = 0;
1305 for (int i = 0; i < 2; ++i) {
1306 const int_mv ref_mv = av1_get_ref_mv(x, i);
1307 *rate_mv += av1_mv_bit_cost(&cur_mv[i].as_mv, &ref_mv.as_mv,
1308 x->mv_costs->nmv_joint_cost,
1309 x->mv_costs->mv_cost_stack, MV_COST_WEIGHT108);
1310 }
1311 } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
1312 if (valid_mv1) {
1313 cur_mv[1].as_int = args->single_newmv[ref_mv_idx][refs[1]].as_int;
1314 clamp_mv_in_range(x, &cur_mv[1], 1);
1315 }
1316 const int_mv ref_mv = av1_get_ref_mv(x, 1);
1317 *rate_mv = av1_mv_bit_cost(&cur_mv[1].as_mv, &ref_mv.as_mv,
1318 x->mv_costs->nmv_joint_cost,
1319 x->mv_costs->mv_cost_stack, MV_COST_WEIGHT108);
1320 } else {
1321 assert(this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV)((void) sizeof ((this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV
) ? 1 : 0), __extension__ ({ if (this_mode == NEW_NEARESTMV ||
this_mode == NEW_NEARMV) ; else __assert_fail ("this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 1321
, __extension__ __PRETTY_FUNCTION__); }))
;
1322 if (valid_mv0) {
1323 cur_mv[0].as_int = args->single_newmv[ref_mv_idx][refs[0]].as_int;
1324 clamp_mv_in_range(x, &cur_mv[0], 0);
1325 }
1326 const int_mv ref_mv = av1_get_ref_mv(x, 0);
1327 *rate_mv = av1_mv_bit_cost(&cur_mv[0].as_mv, &ref_mv.as_mv,
1328 x->mv_costs->nmv_joint_cost,
1329 x->mv_costs->mv_cost_stack, MV_COST_WEIGHT108);
1330 }
1331 } else {
1332 // Single ref case.
1333 const int ref_idx = 0;
1334 int search_range = INT_MAX2147483647;
1335
1336 if (cpi->sf.mv_sf.reduce_search_range && mbmi->ref_mv_idx > 0) {
1337 const MV ref_mv = av1_get_ref_mv(x, ref_idx).as_mv;
1338 int min_mv_diff = INT_MAX2147483647;
1339 int best_match = -1;
1340 MV prev_ref_mv[2] = { { 0 } };
1341 for (int idx = 0; idx < mbmi->ref_mv_idx; ++idx) {
1342 prev_ref_mv[idx] = av1_get_ref_mv_from_stack(ref_idx, mbmi->ref_frame,
1343 idx, &x->mbmi_ext)
1344 .as_mv;
1345 const int ref_mv_diff = AOMMAX(abs(ref_mv.row - prev_ref_mv[idx].row),(((abs(ref_mv.row - prev_ref_mv[idx].row)) > (abs(ref_mv.col
- prev_ref_mv[idx].col))) ? (abs(ref_mv.row - prev_ref_mv[idx
].row)) : (abs(ref_mv.col - prev_ref_mv[idx].col)))
1346 abs(ref_mv.col - prev_ref_mv[idx].col))(((abs(ref_mv.row - prev_ref_mv[idx].row)) > (abs(ref_mv.col
- prev_ref_mv[idx].col))) ? (abs(ref_mv.row - prev_ref_mv[idx
].row)) : (abs(ref_mv.col - prev_ref_mv[idx].col)))
;
1347
1348 if (min_mv_diff > ref_mv_diff) {
1349 min_mv_diff = ref_mv_diff;
1350 best_match = idx;
1351 }
1352 }
1353
1354 if (min_mv_diff < (16 << 3)) {
1355 if (args->single_newmv_valid[best_match][refs[0]]) {
1356 search_range = min_mv_diff;
1357 search_range +=
1358 AOMMAX(abs(args->single_newmv[best_match][refs[0]].as_mv.row -(((abs(args->single_newmv[best_match][refs[0]].as_mv.row -
prev_ref_mv[best_match].row)) > (abs(args->single_newmv
[best_match][refs[0]].as_mv.col - prev_ref_mv[best_match].col
))) ? (abs(args->single_newmv[best_match][refs[0]].as_mv.row
- prev_ref_mv[best_match].row)) : (abs(args->single_newmv
[best_match][refs[0]].as_mv.col - prev_ref_mv[best_match].col
)))
1359 prev_ref_mv[best_match].row),(((abs(args->single_newmv[best_match][refs[0]].as_mv.row -
prev_ref_mv[best_match].row)) > (abs(args->single_newmv
[best_match][refs[0]].as_mv.col - prev_ref_mv[best_match].col
))) ? (abs(args->single_newmv[best_match][refs[0]].as_mv.row
- prev_ref_mv[best_match].row)) : (abs(args->single_newmv
[best_match][refs[0]].as_mv.col - prev_ref_mv[best_match].col
)))
1360 abs(args->single_newmv[best_match][refs[0]].as_mv.col -(((abs(args->single_newmv[best_match][refs[0]].as_mv.row -
prev_ref_mv[best_match].row)) > (abs(args->single_newmv
[best_match][refs[0]].as_mv.col - prev_ref_mv[best_match].col
))) ? (abs(args->single_newmv[best_match][refs[0]].as_mv.row
- prev_ref_mv[best_match].row)) : (abs(args->single_newmv
[best_match][refs[0]].as_mv.col - prev_ref_mv[best_match].col
)))
1361 prev_ref_mv[best_match].col))(((abs(args->single_newmv[best_match][refs[0]].as_mv.row -
prev_ref_mv[best_match].row)) > (abs(args->single_newmv
[best_match][refs[0]].as_mv.col - prev_ref_mv[best_match].col
))) ? (abs(args->single_newmv[best_match][refs[0]].as_mv.row
- prev_ref_mv[best_match].row)) : (abs(args->single_newmv
[best_match][refs[0]].as_mv.col - prev_ref_mv[best_match].col
)))
;
1362 // Get full pixel search range.
1363 search_range = (search_range + 4) >> 3;
1364 }
1365 }
1366 }
1367
1368 int_mv best_mv;
1369 av1_single_motion_search(cpi, x, bsize, ref_idx, rate_mv, search_range,
1370 mode_info, &best_mv, args);
1371 if (best_mv.as_int == INVALID_MV0x80008000) return INT64_MAX(9223372036854775807L);
1372
1373 args->single_newmv[ref_mv_idx][refs[0]] = best_mv;
1374 args->single_newmv_rate[ref_mv_idx][refs[0]] = *rate_mv;
1375 args->single_newmv_valid[ref_mv_idx][refs[0]] = 1;
1376 cur_mv[0].as_int = best_mv.as_int;
1377
1378 // Return after single_newmv is set.
1379 if (mode_info[mbmi->ref_mv_idx].skip) return INT64_MAX(9223372036854775807L);
1380 }
1381
1382 return 0;
1383}
1384
1385static inline void update_mode_start_end_index(
1386 const AV1_COMP *const cpi, const MB_MODE_INFO *const mbmi,
1387 int *mode_index_start, int *mode_index_end, int last_motion_mode_allowed,
1388 int interintra_allowed, int eval_motion_mode) {
1389 *mode_index_start = (int)SIMPLE_TRANSLATION;
1390 *mode_index_end = (int)last_motion_mode_allowed + interintra_allowed;
1391 if (cpi->sf.winner_mode_sf.motion_mode_for_winner_cand) {
1392 if (!eval_motion_mode) {
1393 *mode_index_end = (int)SIMPLE_TRANSLATION;
1394 } else {
1395 // Set the start index appropriately to process motion modes other than
1396 // simple translation
1397 *mode_index_start = 1;
1398 }
1399 }
1400 if (cpi->sf.inter_sf.extra_prune_warped && mbmi->bsize > BLOCK_16X16)
1401 *mode_index_end = SIMPLE_TRANSLATION;
1402}
1403
1404// Increase rd cost of warp mode for low complexity decoding.
1405static inline void increase_warp_mode_rd(const MB_MODE_INFO *const best_mbmi,
1406 const MB_MODE_INFO *const this_mbmi,
1407 int64_t *const best_scaled_rd,
1408 int64_t *const this_scaled_rd,
1409 int rd_bias_scale_pct) {
1410 // Check rd bias percentage is non-zero.
1411 if (!rd_bias_scale_pct) return;
1412 if (*best_scaled_rd == INT64_MAX(9223372036854775807L) || *this_scaled_rd == INT64_MAX(9223372036854775807L)) return;
1413
1414 // Experiments have been performed with increasing the RD cost of warp mode at
1415 // the below locations of inter mode evaluation.
1416 // (1). Inter mode evaluation loop in av1_rd_pick_inter_mode().
1417 // (2). Motion mode evaluation during handle_inter_mode() call.
1418 // (3). Motion mode evaluation for winner motion modes.
1419 // (4). Tx search for best inter candidates.
1420 // Based on the speed quality trade-off results of this speed feature, the rd
1421 // bias logic is enabled only at (2), (3) and (4).
1422 const double rd_bias_scale = rd_bias_scale_pct / 100.0;
1423 if (best_mbmi->motion_mode == WARPED_CAUSAL)
1424 *best_scaled_rd += (int64_t)(rd_bias_scale * *best_scaled_rd);
1425 if (this_mbmi->motion_mode == WARPED_CAUSAL)
1426 *this_scaled_rd += (int64_t)(rd_bias_scale * *this_scaled_rd);
1427}
1428
1429/*!\brief AV1 motion mode search
1430 *
1431 * \ingroup inter_mode_search
1432 * Function to search over and determine the motion mode. It will update
1433 * mbmi->motion_mode to one of SIMPLE_TRANSLATION, OBMC_CAUSAL, or
1434 * WARPED_CAUSAL and determine any necessary side information for the selected
1435 * motion mode. It will also perform the full transform search, unless the
1436 * input parameter do_tx_search indicates to do an estimation of the RD rather
1437 * than an RD corresponding to a full transform search. It will return the
1438 * RD for the final motion_mode.
1439 * Do the RD search for a given inter mode and compute all information relevant
1440 * to the input mode. It will compute the best MV,
1441 * compound parameters (if the mode is a compound mode) and interpolation filter
1442 * parameters.
1443 *
1444 * \param[in] cpi Top-level encoder structure.
1445 * \param[in] tile_data Pointer to struct holding adaptive
1446 * data/contexts/models for the tile during
1447 * encoding.
1448 * \param[in] x Pointer to struct holding all the data for
1449 * the current macroblock.
1450 * \param[in] bsize Current block size.
1451 * \param[in,out] rd_stats Struct to keep track of the overall RD
1452 * information.
1453 * \param[in,out] rd_stats_y Struct to keep track of the RD information
1454 * for only the Y plane.
1455 * \param[in,out] rd_stats_uv Struct to keep track of the RD information
1456 * for only the UV planes.
1457 * \param[in] args HandleInterModeArgs struct holding
1458 * miscellaneous arguments for inter mode
1459 * search. See the documentation for this
1460 * struct for a description of each member.
1461 * \param[in] ref_best_rd Best RD found so far for this block.
1462 * It is used for early termination of this
1463 * search if the RD exceeds this value.
1464 * \param[in,out] ref_skip_rd A length 2 array, where skip_rd[0] is the
1465 * best total RD for a skip mode so far, and
1466 * skip_rd[1] is the best RD for a skip mode so
1467 * far in luma. This is used as a speed feature
1468 * to skip the transform search if the computed
1469 * skip RD for the current mode is not better
1470 * than the best skip_rd so far.
1471 * \param[in,out] rate_mv The rate associated with the motion vectors.
1472 * This will be modified if a motion search is
1473 * done in the motion mode search.
1474 * \param[in,out] orig_dst A prediction buffer to hold a computed
1475 * prediction. This will eventually hold the
1476 * final prediction, and the tmp_dst info will
1477 * be copied here.
1478 * \param[in,out] best_est_rd Estimated RD for motion mode search if
1479 * do_tx_search (see below) is 0.
1480 * \param[in] do_tx_search Parameter to indicate whether or not to do
1481 * a full transform search. This will compute
1482 * an estimated RD for the modes without the
1483 * transform search and later perform the full
1484 * transform search on the best candidates.
1485 * \param[in] inter_modes_info InterModesInfo struct to hold inter mode
1486 * information to perform a full transform
1487 * search only on winning candidates searched
1488 * with an estimate for transform coding RD.
1489 * \param[in] eval_motion_mode Boolean whether or not to evaluate motion
1490 * motion modes other than SIMPLE_TRANSLATION.
1491 * \param[out] yrd Stores the rdcost corresponding to encoding
1492 * the luma plane.
1493 * \return Returns INT64_MAX if the determined motion mode is invalid and the
1494 * current motion mode being tested should be skipped. It returns 0 if the
1495 * motion mode search is a success.
1496 */
1497static int64_t motion_mode_rd(
1498 const AV1_COMP *const cpi, TileDataEnc *tile_data, MACROBLOCK *const x,
1499 BLOCK_SIZE bsize, RD_STATS *rd_stats, RD_STATS *rd_stats_y,
1500 RD_STATS *rd_stats_uv, HandleInterModeArgs *const args, int64_t ref_best_rd,
1501 int64_t *ref_skip_rd, int *rate_mv, const BUFFER_SET *orig_dst,
1502 int64_t *best_est_rd, int do_tx_search, InterModesInfo *inter_modes_info,
1503 int eval_motion_mode, int64_t *yrd) {
1504 const AV1_COMMON *const cm = &cpi->common;
1505 const FeatureFlags *const features = &cm->features;
1506 TxfmSearchInfo *txfm_info = &x->txfm_search_info;
1507 const int num_planes = av1_num_planes(cm);
1508 MACROBLOCKD *xd = &x->e_mbd;
1509 MB_MODE_INFO *mbmi = xd->mi[0];
1510 const int is_comp_pred = has_second_ref(mbmi);
1511 const PREDICTION_MODE this_mode = mbmi->mode;
1512 const int rate2_nocoeff = rd_stats->rate;
1513 int best_xskip_txfm = 0;
1514 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
1515 uint8_t best_blk_skip[MAX_MIB_SIZE(1 << (7 - 2)) * MAX_MIB_SIZE(1 << (7 - 2))];
1516 uint8_t best_tx_type_map[MAX_MIB_SIZE(1 << (7 - 2)) * MAX_MIB_SIZE(1 << (7 - 2))];
1517 const int rate_mv0 = *rate_mv;
1518 const int interintra_allowed = cm->seq_params->enable_interintra_compound &&
1519 is_interintra_allowed(mbmi) &&
1520 mbmi->compound_idx;
1521 WARP_SAMPLE_INFO *const warp_sample_info =
1522 &x->warp_sample_info[mbmi->ref_frame[0]];
1523 int *pts0 = warp_sample_info->pts;
1524 int *pts_inref0 = warp_sample_info->pts_inref;
1525
1526 assert(mbmi->ref_frame[1] != INTRA_FRAME)((void) sizeof ((mbmi->ref_frame[1] != INTRA_FRAME) ? 1 : 0
), __extension__ ({ if (mbmi->ref_frame[1] != INTRA_FRAME)
; else __assert_fail ("mbmi->ref_frame[1] != INTRA_FRAME"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 1526
, __extension__ __PRETTY_FUNCTION__); }))
;
1527 const MV_REFERENCE_FRAME ref_frame_1 = mbmi->ref_frame[1];
1528 av1_invalid_rd_stats(&best_rd_stats);
1529 mbmi->num_proj_ref = 1; // assume num_proj_ref >=1
1530 MOTION_MODE last_motion_mode_allowed = SIMPLE_TRANSLATION;
1531 *yrd = INT64_MAX(9223372036854775807L);
1532 if (features->switchable_motion_mode) {
1533 // Determine which motion modes to search if more than SIMPLE_TRANSLATION
1534 // is allowed.
1535 last_motion_mode_allowed = motion_mode_allowed(
1536 xd->global_motion, xd, mbmi, features->allow_warped_motion);
1537 }
1538
1539 if (last_motion_mode_allowed == WARPED_CAUSAL) {
1540 // Collect projection samples used in least squares approximation of
1541 // the warped motion parameters if WARPED_CAUSAL is going to be searched.
1542 if (warp_sample_info->num < 0) {
1543 warp_sample_info->num = av1_findSamples(cm, xd, pts0, pts_inref0);
1544 }
1545 mbmi->num_proj_ref = warp_sample_info->num;
1546 }
1547 const int total_samples = mbmi->num_proj_ref;
1548 if (total_samples == 0) {
1549 // Do not search WARPED_CAUSAL if there are no samples to use to determine
1550 // warped parameters.
1551 last_motion_mode_allowed = OBMC_CAUSAL;
1552 }
1553
1554 const MB_MODE_INFO base_mbmi = *mbmi;
1555 MB_MODE_INFO best_mbmi;
1556 const int interp_filter = features->interp_filter;
1557 const int switchable_rate =
1558 av1_is_interp_needed(xd)
1559 ? av1_get_switchable_rate(x, xd, interp_filter,
1560 cm->seq_params->enable_dual_filter)
1561 : 0;
1562 int64_t best_rd = INT64_MAX(9223372036854775807L);
1563 int best_rate_mv = rate_mv0;
1564 const int mi_row = xd->mi_row;
1565 const int mi_col = xd->mi_col;
1566 int mode_index_start, mode_index_end;
1567 const int txfm_rd_gate_level =
1568 get_txfm_rd_gate_level(cm->seq_params->enable_masked_compound,
1569 cpi->sf.inter_sf.txfm_rd_gate_level, bsize,
1570 TX_SEARCH_MOTION_MODE, eval_motion_mode);
1571
1572 // Modify the start and end index according to speed features. For example,
1573 // if SIMPLE_TRANSLATION has already been searched according to
1574 // the motion_mode_for_winner_cand speed feature, update the mode_index_start
1575 // to avoid searching it again.
1576 update_mode_start_end_index(cpi, mbmi, &mode_index_start, &mode_index_end,
1577 last_motion_mode_allowed, interintra_allowed,
1578 eval_motion_mode);
1579 // Main function loop. This loops over all of the possible motion modes and
1580 // computes RD to determine the best one. This process includes computing
1581 // any necessary side information for the motion mode and performing the
1582 // transform search.
1583 for (int mode_index = mode_index_start; mode_index <= mode_index_end;
1584 mode_index++) {
1585 if (args->skip_motion_mode && mode_index) continue;
1586 int tmp_rate2 = rate2_nocoeff;
1587 const int is_interintra_mode = mode_index > (int)last_motion_mode_allowed;
1588 int tmp_rate_mv = rate_mv0;
1589
1590 *mbmi = base_mbmi;
1591 if (is_interintra_mode) {
1592 // Only use SIMPLE_TRANSLATION for interintra
1593 mbmi->motion_mode = SIMPLE_TRANSLATION;
1594 } else {
1595 mbmi->motion_mode = (MOTION_MODE)mode_index;
1596 assert(mbmi->ref_frame[1] != INTRA_FRAME)((void) sizeof ((mbmi->ref_frame[1] != INTRA_FRAME) ? 1 : 0
), __extension__ ({ if (mbmi->ref_frame[1] != INTRA_FRAME)
; else __assert_fail ("mbmi->ref_frame[1] != INTRA_FRAME"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 1596
, __extension__ __PRETTY_FUNCTION__); }))
;
1597 }
1598
1599 if (cpi->oxcf.algo_cfg.sharpness == 3 &&
1600 (mbmi->motion_mode == OBMC_CAUSAL ||
1601 mbmi->motion_mode == WARPED_CAUSAL))
1602 continue;
1603
1604 // Do not search OBMC if the probability of selecting it is below a
1605 // predetermined threshold for this update_type and block size.
1606 const FRAME_UPDATE_TYPE update_type =
1607 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
1608 int use_actual_frame_probs = 1;
1609 int prune_obmc;
1610#if CONFIG_FPMT_TEST0
1611 use_actual_frame_probs =
1612 (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) ? 0 : 1;
1613 if (!use_actual_frame_probs) {
1614 prune_obmc = cpi->ppi->temp_frame_probs.obmc_probs[update_type][bsize] <
1615 cpi->sf.inter_sf.prune_obmc_prob_thresh;
1616 }
1617#endif
1618 if (use_actual_frame_probs) {
1619 prune_obmc = cpi->ppi->frame_probs.obmc_probs[update_type][bsize] <
1620 cpi->sf.inter_sf.prune_obmc_prob_thresh;
1621 }
1622 if ((!cpi->oxcf.motion_mode_cfg.enable_obmc || prune_obmc) &&
1623 mbmi->motion_mode == OBMC_CAUSAL)
1624 continue;
1625
1626 if (mbmi->motion_mode == SIMPLE_TRANSLATION && !is_interintra_mode) {
1627 // SIMPLE_TRANSLATION mode: no need to recalculate.
1628 // The prediction is calculated before motion_mode_rd() is called in
1629 // handle_inter_mode()
1630 } else if (mbmi->motion_mode == OBMC_CAUSAL) {
1631 const uint32_t cur_mv = mbmi->mv[0].as_int;
1632 // OBMC_CAUSAL not allowed for compound prediction
1633 assert(!is_comp_pred)((void) sizeof ((!is_comp_pred) ? 1 : 0), __extension__ ({ if
(!is_comp_pred) ; else __assert_fail ("!is_comp_pred", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 1633, __extension__ __PRETTY_FUNCTION__); }))
;
1634 if (have_newmv_in_inter_mode(this_mode)) {
1635 av1_single_motion_search(cpi, x, bsize, 0, &tmp_rate_mv, INT_MAX2147483647, NULL((void*)0),
1636 &mbmi->mv[0], NULL((void*)0));
1637 tmp_rate2 = rate2_nocoeff - rate_mv0 + tmp_rate_mv;
1638 }
1639 if ((mbmi->mv[0].as_int != cur_mv) || eval_motion_mode) {
1640 // Build the predictor according to the current motion vector if it has
1641 // not already been built
1642 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize,
1643 0, av1_num_planes(cm) - 1);
1644 }
1645 // Build the inter predictor by blending the predictor corresponding to
1646 // this MV, and the neighboring blocks using the OBMC model
1647 av1_build_obmc_inter_prediction(
1648 cm, xd, args->above_pred_buf, args->above_pred_stride,
1649 args->left_pred_buf, args->left_pred_stride);
1650#if !CONFIG_REALTIME_ONLY0
1651 } else if (mbmi->motion_mode == WARPED_CAUSAL) {
1652 int pts[SAMPLES_ARRAY_SIZE((1 << 3) * 2)], pts_inref[SAMPLES_ARRAY_SIZE((1 << 3) * 2)];
1653 mbmi->motion_mode = WARPED_CAUSAL;
1654 mbmi->wm_params.wmtype = DEFAULT_WMTYPEAFFINE;
1655 mbmi->interp_filters =
1656 av1_broadcast_interp_filter(av1_unswitchable_filter(interp_filter));
1657
1658 memcpy(pts, pts0, total_samples * 2 * sizeof(*pts0));
1659 memcpy(pts_inref, pts_inref0, total_samples * 2 * sizeof(*pts_inref0));
1660 // Select the samples according to motion vector difference
1661 if (mbmi->num_proj_ref > 1) {
1662 mbmi->num_proj_ref = av1_selectSamples(
1663 &mbmi->mv[0].as_mv, pts, pts_inref, mbmi->num_proj_ref, bsize);
1664 }
1665
1666 // Compute the warped motion parameters with a least squares fit
1667 // using the collected samples
1668 if (!av1_find_projection(mbmi->num_proj_ref, pts, pts_inref, bsize,
1669 mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
1670 &mbmi->wm_params, mi_row, mi_col)) {
1671 assert(!is_comp_pred)((void) sizeof ((!is_comp_pred) ? 1 : 0), __extension__ ({ if
(!is_comp_pred) ; else __assert_fail ("!is_comp_pred", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 1671, __extension__ __PRETTY_FUNCTION__); }))
;
1672 if (have_newmv_in_inter_mode(this_mode)) {
1673 // Refine MV for NEWMV mode
1674 const int_mv mv0 = mbmi->mv[0];
1675 const WarpedMotionParams wm_params0 = mbmi->wm_params;
1676 const int num_proj_ref0 = mbmi->num_proj_ref;
1677
1678 const int_mv ref_mv = av1_get_ref_mv(x, 0);
1679 SUBPEL_MOTION_SEARCH_PARAMS ms_params;
1680 av1_make_default_subpel_ms_params(&ms_params, cpi, x, bsize,
1681 &ref_mv.as_mv, NULL((void*)0));
1682
1683 // Refine MV in a small range.
1684 av1_refine_warped_mv(xd, cm, &ms_params, bsize, pts0, pts_inref0,
1685 total_samples, cpi->sf.mv_sf.warp_search_method,
1686 cpi->sf.mv_sf.warp_search_iters);
1687
1688 if (mv0.as_int != mbmi->mv[0].as_int) {
1689 // Keep the refined MV and WM parameters.
1690 tmp_rate_mv = av1_mv_bit_cost(
1691 &mbmi->mv[0].as_mv, &ref_mv.as_mv, x->mv_costs->nmv_joint_cost,
1692 x->mv_costs->mv_cost_stack, MV_COST_WEIGHT108);
1693 tmp_rate2 = rate2_nocoeff - rate_mv0 + tmp_rate_mv;
1694 } else {
1695 // Restore the old MV and WM parameters.
1696 mbmi->mv[0] = mv0;
1697 mbmi->wm_params = wm_params0;
1698 mbmi->num_proj_ref = num_proj_ref0;
1699 }
1700 }
1701
1702 // Build the warped predictor
1703 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL((void*)0), bsize, 0,
1704 av1_num_planes(cm) - 1);
1705 } else {
1706 continue;
1707 }
1708#endif // !CONFIG_REALTIME_ONLY
1709 } else if (is_interintra_mode) {
1710 const int ret =
1711 av1_handle_inter_intra_mode(cpi, x, bsize, mbmi, args, ref_best_rd,
1712 &tmp_rate_mv, &tmp_rate2, orig_dst);
1713 if (ret < 0) continue;
1714 }
1715
1716 // If we are searching newmv and the mv is the same as refmv, skip the
1717 // current mode
1718 if (!av1_check_newmv_joint_nonzero(cm, x)) continue;
1719
1720 // Update rd_stats for the current motion mode
1721 txfm_info->skip_txfm = 0;
1722 rd_stats->dist = 0;
1723 rd_stats->sse = 0;
1724 rd_stats->skip_txfm = 1;
1725 rd_stats->rate = tmp_rate2;
1726 const ModeCosts *mode_costs = &x->mode_costs;
1727 if (mbmi->motion_mode != WARPED_CAUSAL) rd_stats->rate += switchable_rate;
1728 if (interintra_allowed) {
1729 rd_stats->rate +=
1730 mode_costs->interintra_cost[size_group_lookup[bsize]]
1731 [mbmi->ref_frame[1] == INTRA_FRAME];
1732 }
1733 if ((last_motion_mode_allowed > SIMPLE_TRANSLATION) &&
1734 (mbmi->ref_frame[1] != INTRA_FRAME)) {
1735 if (last_motion_mode_allowed == WARPED_CAUSAL) {
1736 rd_stats->rate +=
1737 mode_costs->motion_mode_cost[bsize][mbmi->motion_mode];
1738 } else {
1739 rd_stats->rate +=
1740 mode_costs->motion_mode_cost1[bsize][mbmi->motion_mode];
1741 }
1742 }
1743
1744 int64_t this_yrd = INT64_MAX(9223372036854775807L);
1745
1746 if (!do_tx_search) {
1747 // Avoid doing a transform search here to speed up the overall mode
1748 // search. It will be done later in the mode search if the current
1749 // motion mode seems promising.
1750 int64_t curr_sse = -1;
1751 int64_t sse_y = -1;
1752 int est_residue_cost = 0;
1753 int64_t est_dist = 0;
1754 int64_t est_rd = 0;
1755 if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 1) {
1756 curr_sse = get_sse(cpi, x, &sse_y);
1757 const int has_est_rd = get_est_rate_dist(tile_data, bsize, curr_sse,
1758 &est_residue_cost, &est_dist);
1759 (void)has_est_rd;
1760 assert(has_est_rd)((void) sizeof ((has_est_rd) ? 1 : 0), __extension__ ({ if (has_est_rd
) ; else __assert_fail ("has_est_rd", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 1760, __extension__ __PRETTY_FUNCTION__); }))
;
1761 } else if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 2 ||
1762 cpi->sf.rt_sf.use_nonrd_pick_mode) {
1763 model_rd_sb_fn[MODELRD_TYPE_MOTION_MODE_RD1](
1764 cpi, bsize, x, xd, 0, num_planes - 1, &est_residue_cost, &est_dist,
1765 NULL((void*)0), &curr_sse, NULL((void*)0), NULL((void*)0), NULL((void*)0));
1766 sse_y = x->pred_sse[xd->mi[0]->ref_frame[0]];
1767 }
1768 est_rd = RDCOST(x->rdmult, rd_stats->rate + est_residue_cost, est_dist)((((((int64_t)(rd_stats->rate + est_residue_cost)) * (x->
rdmult)) + (((1 << (9)) >> 1))) >> (9)) + (
(est_dist) * (1 << 7)))
;
1769 if (est_rd * 0.80 > *best_est_rd) {
1770 mbmi->ref_frame[1] = ref_frame_1;
1771 continue;
1772 }
1773 const int mode_rate = rd_stats->rate;
1774 rd_stats->rate += est_residue_cost;
1775 rd_stats->dist = est_dist;
1776 rd_stats->rdcost = est_rd;
1777 if (rd_stats->rdcost < *best_est_rd) {
1778 *best_est_rd = rd_stats->rdcost;
1779 assert(sse_y >= 0)((void) sizeof ((sse_y >= 0) ? 1 : 0), __extension__ ({ if
(sse_y >= 0) ; else __assert_fail ("sse_y >= 0", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 1779, __extension__ __PRETTY_FUNCTION__); }))
;
1780 ref_skip_rd[1] = txfm_rd_gate_level
1781 ? RDCOST(x->rdmult, mode_rate, (sse_y << 4))((((((int64_t)(mode_rate)) * (x->rdmult)) + (((1 << (
9)) >> 1))) >> (9)) + (((sse_y << 4)) * (1 <<
7)))
1782 : INT64_MAX(9223372036854775807L);
1783 }
1784 if (cm->current_frame.reference_mode == SINGLE_REFERENCE) {
1785 if (!is_comp_pred) {
1786 assert(curr_sse >= 0)((void) sizeof ((curr_sse >= 0) ? 1 : 0), __extension__ ({
if (curr_sse >= 0) ; else __assert_fail ("curr_sse >= 0"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 1786
, __extension__ __PRETTY_FUNCTION__); }))
;
1787 inter_modes_info_push(inter_modes_info, mode_rate, curr_sse,
1788 rd_stats->rdcost, rd_stats, rd_stats_y,
1789 rd_stats_uv, mbmi);
1790 }
1791 } else {
1792 assert(curr_sse >= 0)((void) sizeof ((curr_sse >= 0) ? 1 : 0), __extension__ ({
if (curr_sse >= 0) ; else __assert_fail ("curr_sse >= 0"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 1792
, __extension__ __PRETTY_FUNCTION__); }))
;
1793 inter_modes_info_push(inter_modes_info, mode_rate, curr_sse,
1794 rd_stats->rdcost, rd_stats, rd_stats_y,
1795 rd_stats_uv, mbmi);
1796 }
1797 mbmi->skip_txfm = 0;
1798 } else {
1799 // Perform full transform search
1800 int64_t skip_rd = INT64_MAX(9223372036854775807L);
1801 int64_t skip_rdy = INT64_MAX(9223372036854775807L);
1802 if (txfm_rd_gate_level) {
1803 // Check if the mode is good enough based on skip RD
1804 int64_t sse_y = INT64_MAX(9223372036854775807L);
1805 int64_t curr_sse = get_sse(cpi, x, &sse_y);
1806 skip_rd = RDCOST(x->rdmult, rd_stats->rate, curr_sse)((((((int64_t)(rd_stats->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((curr_sse) * (1 <<
7)))
;
1807 skip_rdy = RDCOST(x->rdmult, rd_stats->rate, (sse_y << 4))((((((int64_t)(rd_stats->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + (((sse_y << 4)) * (
1 << 7)))
;
1808 int eval_txfm = check_txfm_eval(x, bsize, ref_skip_rd[0], skip_rd,
1809 txfm_rd_gate_level, 0);
1810 if (!eval_txfm) continue;
1811 }
1812
1813 // Do transform search
1814 const int mode_rate = rd_stats->rate;
1815 if (!av1_txfm_search(cpi, x, bsize, rd_stats, rd_stats_y, rd_stats_uv,
1816 rd_stats->rate, ref_best_rd)) {
1817 if (rd_stats_y->rate == INT_MAX2147483647 && mode_index == 0) {
1818 return INT64_MAX(9223372036854775807L);
1819 }
1820 continue;
1821 }
1822 const int skip_ctx = av1_get_skip_txfm_context(xd);
1823 const int y_rate =
1824 rd_stats->skip_txfm
1825 ? x->mode_costs.skip_txfm_cost[skip_ctx][1]
1826 : (rd_stats_y->rate + x->mode_costs.skip_txfm_cost[skip_ctx][0]);
1827 this_yrd = RDCOST(x->rdmult, y_rate + mode_rate, rd_stats_y->dist)((((((int64_t)(y_rate + mode_rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_stats_y->dist) * (
1 << 7)))
;
1828
1829 const int64_t curr_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist)((((((int64_t)(rd_stats->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_stats->dist) * (1
<< 7)))
;
1830 if (curr_rd < ref_best_rd) {
1831 ref_best_rd = curr_rd;
1832 ref_skip_rd[0] = skip_rd;
1833 ref_skip_rd[1] = skip_rdy;
1834 }
1835 if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 1) {
1836 inter_mode_data_push(
1837 tile_data, mbmi->bsize, rd_stats->sse, rd_stats->dist,
1838 rd_stats_y->rate + rd_stats_uv->rate +
1839 mode_costs->skip_txfm_cost[skip_ctx][mbmi->skip_txfm]);
1840 }
1841 }
1842
1843 if (this_mode == GLOBALMV || this_mode == GLOBAL_GLOBALMV) {
1844 if (is_nontrans_global_motion(xd, xd->mi[0])) {
1845 mbmi->interp_filters =
1846 av1_broadcast_interp_filter(av1_unswitchable_filter(interp_filter));
1847 }
1848 }
1849
1850 adjust_cost(cpi, x, &this_yrd);
1851 adjust_rdcost(cpi, x, rd_stats);
1852 adjust_rdcost(cpi, x, rd_stats_y);
1853
1854 const int64_t tmp_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist)((((((int64_t)(rd_stats->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_stats->dist) * (1
<< 7)))
;
1855 if (mode_index == 0) {
1856 args->simple_rd[this_mode][mbmi->ref_mv_idx][mbmi->ref_frame[0]] = tmp_rd;
1857 }
1858 int64_t best_scaled_rd = best_rd;
1859 int64_t this_scaled_rd = tmp_rd;
1860 if (mode_index != 0)
1861 increase_warp_mode_rd(&best_mbmi, mbmi, &best_scaled_rd, &this_scaled_rd,
1862 cpi->sf.inter_sf.bias_warp_mode_rd_scale_pct);
1863
1864 if (mode_index == 0 || this_scaled_rd < best_scaled_rd) {
1865 // Update best_rd data if this is the best motion mode so far
1866 best_mbmi = *mbmi;
1867 best_rd = tmp_rd;
1868 best_rd_stats = *rd_stats;
1869 best_rd_stats_y = *rd_stats_y;
1870 best_rate_mv = tmp_rate_mv;
1871 *yrd = this_yrd;
1872 if (num_planes > 1) best_rd_stats_uv = *rd_stats_uv;
1873 memcpy(best_blk_skip, txfm_info->blk_skip,
1874 sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
1875 av1_copy_array(best_tx_type_map, xd->tx_type_map, xd->height * xd->width)do { ((void) sizeof ((sizeof(*(best_tx_type_map)) == sizeof(*
(xd->tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof(
*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))) ; else
__assert_fail ("sizeof(*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 1875
, __extension__ __PRETTY_FUNCTION__); })); memcpy(best_tx_type_map
, xd->tx_type_map, xd->height * xd->width * sizeof(*
(xd->tx_type_map))); } while (0)
;
1876 best_xskip_txfm = mbmi->skip_txfm;
1877 }
1878 }
1879 // Update RD and mbmi stats for selected motion mode
1880 mbmi->ref_frame[1] = ref_frame_1;
1881 *rate_mv = best_rate_mv;
1882 if (best_rd == INT64_MAX(9223372036854775807L) || !av1_check_newmv_joint_nonzero(cm, x)) {
1883 av1_invalid_rd_stats(rd_stats);
1884 restore_dst_buf(xd, *orig_dst, num_planes);
1885 return INT64_MAX(9223372036854775807L);
1886 }
1887 *mbmi = best_mbmi;
1888 *rd_stats = best_rd_stats;
1889 *rd_stats_y = best_rd_stats_y;
1890 if (num_planes > 1) *rd_stats_uv = best_rd_stats_uv;
1891 memcpy(txfm_info->blk_skip, best_blk_skip,
1892 sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
1893 av1_copy_array(xd->tx_type_map, best_tx_type_map, xd->height * xd->width)do { ((void) sizeof ((sizeof(*(xd->tx_type_map)) == sizeof
(*(best_tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof(
*(xd->tx_type_map)) == sizeof(*(best_tx_type_map))) ; else
__assert_fail ("sizeof(*(xd->tx_type_map)) == sizeof(*(best_tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 1893
, __extension__ __PRETTY_FUNCTION__); })); memcpy(xd->tx_type_map
, best_tx_type_map, xd->height * xd->width * sizeof(*(best_tx_type_map
))); } while (0)
;
1894 txfm_info->skip_txfm = best_xskip_txfm;
1895
1896 restore_dst_buf(xd, *orig_dst, num_planes);
1897 return 0;
1898}
1899
1900static int64_t skip_mode_rd(RD_STATS *rd_stats, const AV1_COMP *const cpi,
1901 MACROBLOCK *const x, BLOCK_SIZE bsize,
1902 const BUFFER_SET *const orig_dst, int64_t best_rd) {
1903 assert(bsize < BLOCK_SIZES_ALL)((void) sizeof ((bsize < BLOCK_SIZES_ALL) ? 1 : 0), __extension__
({ if (bsize < BLOCK_SIZES_ALL) ; else __assert_fail ("bsize < BLOCK_SIZES_ALL"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 1903
, __extension__ __PRETTY_FUNCTION__); }))
;
1904 const AV1_COMMON *cm = &cpi->common;
1905 const int num_planes = av1_num_planes(cm);
1906 MACROBLOCKD *const xd = &x->e_mbd;
1907 const int mi_row = xd->mi_row;
1908 const int mi_col = xd->mi_col;
1909 int64_t total_sse = 0;
1910 int64_t this_rd = INT64_MAX(9223372036854775807L);
1911 const int skip_mode_ctx = av1_get_skip_mode_context(xd);
1912 rd_stats->rate = x->mode_costs.skip_mode_cost[skip_mode_ctx][1];
1913
1914 for (int plane = 0; plane < num_planes; ++plane) {
1915 // Call av1_enc_build_inter_predictor() for one plane at a time.
1916 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize,
1917 plane, plane);
1918 const struct macroblockd_plane *const pd = &xd->plane[plane];
1919 const BLOCK_SIZE plane_bsize =
1920 get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
1921
1922 av1_subtract_plane(x, plane_bsize, plane);
1923
1924 int64_t sse =
1925 av1_pixel_diff_dist(x, plane, 0, 0, plane_bsize, plane_bsize, NULL((void*)0));
1926 if (is_cur_buf_hbd(xd)) sse = ROUND_POWER_OF_TWO(sse, (xd->bd - 8) * 2)(((sse) + (((1 << ((xd->bd - 8) * 2)) >> 1))) >>
((xd->bd - 8) * 2))
;
1927 sse <<= 4;
1928 total_sse += sse;
1929 // When current rd cost is more than the best rd, skip evaluation of
1930 // remaining planes.
1931 this_rd = RDCOST(x->rdmult, rd_stats->rate, total_sse)((((((int64_t)(rd_stats->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((total_sse) * (1 <<
7)))
;
1932 if (this_rd > best_rd) break;
1933 }
1934
1935 rd_stats->dist = rd_stats->sse = total_sse;
1936 rd_stats->rdcost = this_rd;
1937
1938 restore_dst_buf(xd, *orig_dst, num_planes);
1939 return 0;
1940}
1941
1942// Check NEARESTMV, NEARMV, GLOBALMV ref mvs for duplicate and skip the relevant
1943// mode
1944// Note(rachelbarker): This speed feature currently does not interact correctly
1945// with global motion. The issue is that, when global motion is used, GLOBALMV
1946// produces a different prediction to NEARESTMV/NEARMV even if the motion
1947// vectors are the same. Thus GLOBALMV should not be pruned in this case.
1948static inline int check_repeat_ref_mv(const MB_MODE_INFO_EXT *mbmi_ext,
1949 int ref_idx,
1950 const MV_REFERENCE_FRAME *ref_frame,
1951 PREDICTION_MODE single_mode) {
1952 const uint8_t ref_frame_type = av1_ref_frame_type(ref_frame);
1953 const int ref_mv_count = mbmi_ext->ref_mv_count[ref_frame_type];
1954 assert(single_mode != NEWMV)((void) sizeof ((single_mode != NEWMV) ? 1 : 0), __extension__
({ if (single_mode != NEWMV) ; else __assert_fail ("single_mode != NEWMV"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 1954
, __extension__ __PRETTY_FUNCTION__); }))
;
1955 if (single_mode == NEARESTMV) {
1956 return 0;
1957 } else if (single_mode == NEARMV) {
1958 // when ref_mv_count = 0, NEARESTMV and NEARMV are same as GLOBALMV
1959 // when ref_mv_count = 1, NEARMV is same as GLOBALMV
1960 if (ref_mv_count < 2) return 1;
1961 } else if (single_mode == GLOBALMV) {
1962 // when ref_mv_count == 0, GLOBALMV is same as NEARESTMV
1963 if (ref_mv_count == 0) return 1;
1964 // when ref_mv_count == 1, NEARMV is same as GLOBALMV
1965 else if (ref_mv_count == 1)
1966 return 0;
1967
1968 int stack_size = AOMMIN(USABLE_REF_MV_STACK_SIZE, ref_mv_count)(((4) < (ref_mv_count)) ? (4) : (ref_mv_count));
1969 // Check GLOBALMV is matching with any mv in ref_mv_stack
1970 for (int ref_mv_idx = 0; ref_mv_idx < stack_size; ref_mv_idx++) {
1971 int_mv this_mv;
1972
1973 if (ref_idx == 0)
1974 this_mv = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
1975 else
1976 this_mv = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
1977
1978 if (this_mv.as_int == mbmi_ext->global_mvs[ref_frame[ref_idx]].as_int)
1979 return 1;
1980 }
1981 }
1982 return 0;
1983}
1984
1985static inline int get_this_mv(int_mv *this_mv, PREDICTION_MODE this_mode,
1986 int ref_idx, int ref_mv_idx,
1987 int skip_repeated_ref_mv,
1988 const MV_REFERENCE_FRAME *ref_frame,
1989 const MB_MODE_INFO_EXT *mbmi_ext) {
1990 const PREDICTION_MODE single_mode = get_single_mode(this_mode, ref_idx);
1991 assert(is_inter_singleref_mode(single_mode))((void) sizeof ((is_inter_singleref_mode(single_mode)) ? 1 : 0
), __extension__ ({ if (is_inter_singleref_mode(single_mode))
; else __assert_fail ("is_inter_singleref_mode(single_mode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 1991
, __extension__ __PRETTY_FUNCTION__); }))
;
1992 if (single_mode == NEWMV) {
1993 this_mv->as_int = INVALID_MV0x80008000;
1994 } else if (single_mode == GLOBALMV) {
1995 if (skip_repeated_ref_mv &&
1996 check_repeat_ref_mv(mbmi_ext, ref_idx, ref_frame, single_mode))
1997 return 0;
1998 *this_mv = mbmi_ext->global_mvs[ref_frame[ref_idx]];
1999 } else {
2000 assert(single_mode == NEARMV || single_mode == NEARESTMV)((void) sizeof ((single_mode == NEARMV || single_mode == NEARESTMV
) ? 1 : 0), __extension__ ({ if (single_mode == NEARMV || single_mode
== NEARESTMV) ; else __assert_fail ("single_mode == NEARMV || single_mode == NEARESTMV"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2000
, __extension__ __PRETTY_FUNCTION__); }))
;
2001 const uint8_t ref_frame_type = av1_ref_frame_type(ref_frame);
2002 const int ref_mv_offset = single_mode == NEARESTMV ? 0 : ref_mv_idx + 1;
2003 if (ref_mv_offset < mbmi_ext->ref_mv_count[ref_frame_type]) {
2004 assert(ref_mv_offset >= 0)((void) sizeof ((ref_mv_offset >= 0) ? 1 : 0), __extension__
({ if (ref_mv_offset >= 0) ; else __assert_fail ("ref_mv_offset >= 0"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2004
, __extension__ __PRETTY_FUNCTION__); }))
;
2005 if (ref_idx == 0) {
2006 *this_mv =
2007 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_offset].this_mv;
2008 } else {
2009 *this_mv =
2010 mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_offset].comp_mv;
2011 }
2012 } else {
2013 if (skip_repeated_ref_mv &&
2014 check_repeat_ref_mv(mbmi_ext, ref_idx, ref_frame, single_mode))
2015 return 0;
2016 *this_mv = mbmi_ext->global_mvs[ref_frame[ref_idx]];
2017 }
2018 }
2019 return 1;
2020}
2021
2022// Skip NEARESTMV and NEARMV modes based on refmv weight computed in ref mv list
2023// population
2024static inline int skip_nearest_near_mv_using_refmv_weight(
2025 const MACROBLOCK *const x, const PREDICTION_MODE this_mode,
2026 const int8_t ref_frame_type, PREDICTION_MODE best_mode) {
2027 if (this_mode != NEARESTMV && this_mode != NEARMV) return 0;
2028 // Do not skip the mode if the current block has not yet obtained a valid
2029 // inter mode.
2030 if (!is_inter_mode(best_mode)) return 0;
2031
2032 const MACROBLOCKD *xd = &x->e_mbd;
2033 // Do not skip the mode if both the top and left neighboring blocks are not
2034 // available.
2035 if (!xd->left_available || !xd->up_available) return 0;
2036 const MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
2037 const uint16_t *const ref_mv_weight = mbmi_ext->weight[ref_frame_type];
2038 const int ref_mv_count =
2039 AOMMIN(MAX_REF_MV_SEARCH, mbmi_ext->ref_mv_count[ref_frame_type])(((3) < (mbmi_ext->ref_mv_count[ref_frame_type])) ? (3)
: (mbmi_ext->ref_mv_count[ref_frame_type]))
;
2040
2041 if (ref_mv_count == 0) return 0;
2042 // If ref mv list has at least one nearest candidate do not prune NEARESTMV
2043 if (this_mode == NEARESTMV && ref_mv_weight[0] >= REF_CAT_LEVEL640) return 0;
2044
2045 // Count number of ref mvs populated from nearest candidates
2046 int nearest_refmv_count = 0;
2047 for (int ref_mv_idx = 0; ref_mv_idx < ref_mv_count; ref_mv_idx++) {
2048 if (ref_mv_weight[ref_mv_idx] >= REF_CAT_LEVEL640) nearest_refmv_count++;
2049 }
2050
2051 // nearest_refmv_count indicates the closeness of block motion characteristics
2052 // with respect to its spatial neighbor. Smaller value of nearest_refmv_count
2053 // w.r.t to ref_mv_count means less correlation with its spatial neighbors.
2054 // Hence less possibility for NEARESTMV and NEARMV modes becoming the best
2055 // mode since these modes work well for blocks that shares similar motion
2056 // characteristics with its neighbor. Thus, NEARMV mode is pruned when
2057 // nearest_refmv_count is relatively smaller than ref_mv_count and NEARESTMV
2058 // mode is pruned if none of the ref mvs are populated from nearest candidate.
2059 const int prune_thresh = 1 + (ref_mv_count >= 2);
2060 if (nearest_refmv_count < prune_thresh) return 1;
2061 return 0;
2062}
2063
2064// This function update the non-new mv for the current prediction mode
2065static inline int build_cur_mv(int_mv *cur_mv, PREDICTION_MODE this_mode,
2066 const AV1_COMMON *cm, const MACROBLOCK *x,
2067 int skip_repeated_ref_mv) {
2068 const MACROBLOCKD *xd = &x->e_mbd;
2069 const MB_MODE_INFO *mbmi = xd->mi[0];
2070 const int is_comp_pred = has_second_ref(mbmi);
2071
2072 int ret = 1;
2073 for (int i = 0; i < is_comp_pred + 1; ++i) {
2074 int_mv this_mv;
2075 this_mv.as_int = INVALID_MV0x80008000;
2076 ret = get_this_mv(&this_mv, this_mode, i, mbmi->ref_mv_idx,
2077 skip_repeated_ref_mv, mbmi->ref_frame, &x->mbmi_ext);
2078 if (!ret) return 0;
2079 const PREDICTION_MODE single_mode = get_single_mode(this_mode, i);
2080 if (single_mode == NEWMV) {
2081 const uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
2082 cur_mv[i] =
2083 (i == 0) ? x->mbmi_ext.ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
2084 .this_mv
2085 : x->mbmi_ext.ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
2086 .comp_mv;
2087 } else {
2088 ret &= clamp_and_check_mv(cur_mv + i, this_mv, cm, x);
2089 }
2090 }
2091 return ret;
2092}
2093
2094static inline int get_drl_cost(const MB_MODE_INFO *mbmi,
2095 const MB_MODE_INFO_EXT *mbmi_ext,
2096 const int (*const drl_mode_cost0)[2],
2097 int8_t ref_frame_type) {
2098 int cost = 0;
2099 if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) {
2100 for (int idx = 0; idx < 2; ++idx) {
2101 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2102 uint8_t drl_ctx = av1_drl_ctx(mbmi_ext->weight[ref_frame_type], idx);
2103 cost += drl_mode_cost0[drl_ctx][mbmi->ref_mv_idx != idx];
2104 if (mbmi->ref_mv_idx == idx) return cost;
2105 }
2106 }
2107 return cost;
2108 }
2109
2110 if (have_nearmv_in_inter_mode(mbmi->mode)) {
2111 for (int idx = 1; idx < 3; ++idx) {
2112 if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2113 uint8_t drl_ctx = av1_drl_ctx(mbmi_ext->weight[ref_frame_type], idx);
2114 cost += drl_mode_cost0[drl_ctx][mbmi->ref_mv_idx != (idx - 1)];
2115 if (mbmi->ref_mv_idx == (idx - 1)) return cost;
2116 }
2117 }
2118 return cost;
2119 }
2120 return cost;
2121}
2122
2123static inline int is_single_newmv_valid(const HandleInterModeArgs *const args,
2124 const MB_MODE_INFO *const mbmi,
2125 PREDICTION_MODE this_mode) {
2126 for (int ref_idx = 0; ref_idx < 2; ++ref_idx) {
2127 const PREDICTION_MODE single_mode = get_single_mode(this_mode, ref_idx);
2128 const MV_REFERENCE_FRAME ref = mbmi->ref_frame[ref_idx];
2129 if (single_mode == NEWMV &&
2130 args->single_newmv_valid[mbmi->ref_mv_idx][ref] == 0) {
2131 return 0;
2132 }
2133 }
2134 return 1;
2135}
2136
2137static int get_drl_refmv_count(const MACROBLOCK *const x,
2138 const MV_REFERENCE_FRAME *ref_frame,
2139 PREDICTION_MODE mode) {
2140 const MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
2141 const int8_t ref_frame_type = av1_ref_frame_type(ref_frame);
2142 const int has_nearmv = have_nearmv_in_inter_mode(mode) ? 1 : 0;
2143 const int ref_mv_count = mbmi_ext->ref_mv_count[ref_frame_type];
2144 const int only_newmv = (mode == NEWMV || mode == NEW_NEWMV);
2145 const int has_drl =
2146 (has_nearmv && ref_mv_count > 2) || (only_newmv && ref_mv_count > 1);
2147 const int ref_set =
2148 has_drl ? AOMMIN(MAX_REF_MV_SEARCH, ref_mv_count - has_nearmv)(((3) < (ref_mv_count - has_nearmv)) ? (3) : (ref_mv_count
- has_nearmv))
: 1;
2149
2150 return ref_set;
2151}
2152
2153// Checks if particular ref_mv_idx should be pruned.
2154static int prune_ref_mv_idx_using_qindex(const int reduce_inter_modes,
2155 const int qindex,
2156 const int ref_mv_idx) {
2157 if (reduce_inter_modes >= 3) return 1;
2158 // Q-index logic based pruning is enabled only for
2159 // reduce_inter_modes = 2.
2160 assert(reduce_inter_modes == 2)((void) sizeof ((reduce_inter_modes == 2) ? 1 : 0), __extension__
({ if (reduce_inter_modes == 2) ; else __assert_fail ("reduce_inter_modes == 2"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2160
, __extension__ __PRETTY_FUNCTION__); }))
;
2161 // When reduce_inter_modes=2, pruning happens as below based on q index.
2162 // For q index range between 0 and 85: prune if ref_mv_idx >= 1.
2163 // For q index range between 86 and 170: prune if ref_mv_idx == 2.
2164 // For q index range between 171 and 255: no pruning.
2165 const int min_prune_ref_mv_idx = (qindex * 3 / QINDEX_RANGE(255 - 0 + 1)) + 1;
2166 return (ref_mv_idx >= min_prune_ref_mv_idx);
2167}
2168
2169// Whether this reference motion vector can be skipped, based on initial
2170// heuristics.
2171static bool_Bool ref_mv_idx_early_breakout(
2172 const SPEED_FEATURES *const sf,
2173 const RefFrameDistanceInfo *const ref_frame_dist_info, MACROBLOCK *x,
2174 const HandleInterModeArgs *const args, int64_t ref_best_rd,
2175 int ref_mv_idx) {
2176 MACROBLOCKD *xd = &x->e_mbd;
2177 MB_MODE_INFO *mbmi = xd->mi[0];
2178 const MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
2179 const int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
2180 const int is_comp_pred = has_second_ref(mbmi);
2181 if (sf->inter_sf.reduce_inter_modes && ref_mv_idx > 0) {
2182 if (mbmi->ref_frame[0] == LAST2_FRAME ||
2183 mbmi->ref_frame[0] == LAST3_FRAME ||
2184 mbmi->ref_frame[1] == LAST2_FRAME ||
2185 mbmi->ref_frame[1] == LAST3_FRAME) {
2186 const int has_nearmv = have_nearmv_in_inter_mode(mbmi->mode) ? 1 : 0;
2187 if (mbmi_ext->weight[ref_frame_type][ref_mv_idx + has_nearmv] <
2188 REF_CAT_LEVEL640) {
2189 return true1;
2190 }
2191 }
2192 // TODO(any): Experiment with reduce_inter_modes for compound prediction
2193 if (sf->inter_sf.reduce_inter_modes >= 2 && !is_comp_pred &&
2194 have_newmv_in_inter_mode(mbmi->mode)) {
2195 if (mbmi->ref_frame[0] != ref_frame_dist_info->nearest_past_ref &&
2196 mbmi->ref_frame[0] != ref_frame_dist_info->nearest_future_ref) {
2197 const int has_nearmv = have_nearmv_in_inter_mode(mbmi->mode) ? 1 : 0;
2198 const int do_prune = prune_ref_mv_idx_using_qindex(
2199 sf->inter_sf.reduce_inter_modes, x->qindex, ref_mv_idx);
2200 if (do_prune &&
2201 (mbmi_ext->weight[ref_frame_type][ref_mv_idx + has_nearmv] <
2202 REF_CAT_LEVEL640)) {
2203 return true1;
2204 }
2205 }
2206 }
2207 }
2208
2209 mbmi->ref_mv_idx = ref_mv_idx;
2210 if (is_comp_pred && (!is_single_newmv_valid(args, mbmi, mbmi->mode))) {
2211 return true1;
2212 }
2213 size_t est_rd_rate = args->ref_frame_cost + args->single_comp_cost;
2214 const int drl_cost = get_drl_cost(
2215 mbmi, mbmi_ext, x->mode_costs.drl_mode_cost0, ref_frame_type);
2216 est_rd_rate += drl_cost;
2217 if (RDCOST(x->rdmult, est_rd_rate, 0)((((((int64_t)(est_rd_rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((0) * (1 << 7)))
> ref_best_rd &&
2218 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV) {
2219 return true1;
2220 }
2221 return false0;
2222}
2223
2224// Compute the estimated RD cost for the motion vector with simple translation.
2225static int64_t simple_translation_pred_rd(AV1_COMP *const cpi, MACROBLOCK *x,
2226 RD_STATS *rd_stats,
2227 HandleInterModeArgs *args,
2228 int ref_mv_idx, int64_t ref_best_rd,
2229 BLOCK_SIZE bsize) {
2230 MACROBLOCKD *xd = &x->e_mbd;
2231 MB_MODE_INFO *mbmi = xd->mi[0];
2232 MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
2233 const int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
2234 const AV1_COMMON *cm = &cpi->common;
2235 const int is_comp_pred = has_second_ref(mbmi);
2236 const ModeCosts *mode_costs = &x->mode_costs;
2237
2238 struct macroblockd_plane *p = xd->plane;
2239 const BUFFER_SET orig_dst = {
2240 { p[0].dst.buf, p[1].dst.buf, p[2].dst.buf },
2241 { p[0].dst.stride, p[1].dst.stride, p[2].dst.stride },
2242 };
2243 av1_init_rd_stats(rd_stats);
2244
2245 mbmi->interinter_comp.type = COMPOUND_AVERAGE;
2246 mbmi->comp_group_idx = 0;
2247 mbmi->compound_idx = 1;
2248 if (mbmi->ref_frame[1] == INTRA_FRAME) {
2249 mbmi->ref_frame[1] = NONE_FRAME;
2250 }
2251 int16_t mode_ctx =
2252 av1_mode_context_analyzer(mbmi_ext->mode_context, mbmi->ref_frame);
2253
2254 mbmi->num_proj_ref = 0;
2255 mbmi->motion_mode = SIMPLE_TRANSLATION;
2256 mbmi->ref_mv_idx = ref_mv_idx;
2257
2258 rd_stats->rate += args->ref_frame_cost + args->single_comp_cost;
2259 const int drl_cost =
2260 get_drl_cost(mbmi, mbmi_ext, mode_costs->drl_mode_cost0, ref_frame_type);
2261 rd_stats->rate += drl_cost;
2262
2263 int_mv cur_mv[2];
2264 if (!build_cur_mv(cur_mv, mbmi->mode, cm, x, 0)) {
2265 return INT64_MAX(9223372036854775807L);
2266 }
2267 assert(have_nearmv_in_inter_mode(mbmi->mode))((void) sizeof ((have_nearmv_in_inter_mode(mbmi->mode)) ? 1
: 0), __extension__ ({ if (have_nearmv_in_inter_mode(mbmi->
mode)) ; else __assert_fail ("have_nearmv_in_inter_mode(mbmi->mode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2267
, __extension__ __PRETTY_FUNCTION__); }))
;
2268 for (int i = 0; i < is_comp_pred + 1; ++i) {
2269 mbmi->mv[i].as_int = cur_mv[i].as_int;
2270 }
2271 const int ref_mv_cost = cost_mv_ref(mode_costs, mbmi->mode, mode_ctx);
2272 rd_stats->rate += ref_mv_cost;
2273
2274 if (RDCOST(x->rdmult, rd_stats->rate, 0)((((((int64_t)(rd_stats->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((0) * (1 << 7)))
> ref_best_rd) {
2275 return INT64_MAX(9223372036854775807L);
2276 }
2277
2278 mbmi->motion_mode = SIMPLE_TRANSLATION;
2279 mbmi->num_proj_ref = 0;
2280 if (is_comp_pred) {
2281 // Only compound_average
2282 mbmi->interinter_comp.type = COMPOUND_AVERAGE;
2283 mbmi->comp_group_idx = 0;
2284 mbmi->compound_idx = 1;
2285 }
2286 set_default_interp_filters(mbmi, cm->features.interp_filter);
2287
2288 const int mi_row = xd->mi_row;
2289 const int mi_col = xd->mi_col;
2290 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, &orig_dst, bsize,
2291 AOM_PLANE_Y0, AOM_PLANE_Y0);
2292 int est_rate;
2293 int64_t est_dist;
2294 model_rd_sb_fn[MODELRD_CURVFIT](cpi, bsize, x, xd, 0, 0, &est_rate, &est_dist,
2295 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0));
2296 return RDCOST(x->rdmult, rd_stats->rate + est_rate, est_dist)((((((int64_t)(rd_stats->rate + est_rate)) * (x->rdmult
)) + (((1 << (9)) >> 1))) >> (9)) + ((est_dist
) * (1 << 7)))
;
2297}
2298
2299// Represents a set of integers, from 0 to sizeof(int) * 8, as bits in
2300// an integer. 0 for the i-th bit means that integer is excluded, 1 means
2301// it is included.
2302static inline void mask_set_bit(int *mask, int index) { *mask |= (1 << index); }
2303
2304static inline bool_Bool mask_check_bit(int mask, int index) {
2305 return (mask >> index) & 0x1;
2306}
2307
2308// Before performing the full MV search in handle_inter_mode, do a simple
2309// translation search and see if we can eliminate any motion vectors.
2310// Returns an integer where, if the i-th bit is set, it means that the i-th
2311// motion vector should be searched. This is only set for NEAR_MV.
2312static int ref_mv_idx_to_search(AV1_COMP *const cpi, MACROBLOCK *x,
2313 RD_STATS *rd_stats,
2314 HandleInterModeArgs *const args,
2315 int64_t ref_best_rd, BLOCK_SIZE bsize,
2316 const int ref_set) {
2317 // If the number of ref mv count is equal to 1, do not prune the same. It
2318 // is better to evaluate the same than to prune it.
2319 if (ref_set == 1) return 1;
2320 AV1_COMMON *const cm = &cpi->common;
2321 const MACROBLOCKD *const xd = &x->e_mbd;
2322 const MB_MODE_INFO *const mbmi = xd->mi[0];
2323 const PREDICTION_MODE this_mode = mbmi->mode;
2324
2325 // Only search indices if they have some chance of being good.
2326 int good_indices = 0;
2327 for (int i = 0; i < ref_set; ++i) {
2328 if (ref_mv_idx_early_breakout(&cpi->sf, &cpi->ref_frame_dist_info, x, args,
2329 ref_best_rd, i)) {
2330 continue;
2331 }
2332 mask_set_bit(&good_indices, i);
2333 }
2334
2335 // Only prune in NEARMV mode, if the speed feature is set, and the block size
2336 // is large enough. If these conditions are not met, return all good indices
2337 // found so far.
2338 if (!cpi->sf.inter_sf.prune_mode_search_simple_translation)
2339 return good_indices;
2340 if (!have_nearmv_in_inter_mode(this_mode)) return good_indices;
2341 if (num_pels_log2_lookup[bsize] <= 6) return good_indices;
2342 // Do not prune when there is internal resizing. TODO(elliottk) fix this
2343 // so b/2384 can be resolved.
2344 if (av1_is_scaled(get_ref_scale_factors(cm, mbmi->ref_frame[0])) ||
2345 (mbmi->ref_frame[1] > 0 &&
2346 av1_is_scaled(get_ref_scale_factors(cm, mbmi->ref_frame[1])))) {
2347 return good_indices;
2348 }
2349
2350 // Calculate the RD cost for the motion vectors using simple translation.
2351 int64_t idx_rdcost[] = { INT64_MAX(9223372036854775807L), INT64_MAX(9223372036854775807L), INT64_MAX(9223372036854775807L) };
2352 for (int ref_mv_idx = 0; ref_mv_idx < ref_set; ++ref_mv_idx) {
2353 // If this index is bad, ignore it.
2354 if (!mask_check_bit(good_indices, ref_mv_idx)) {
2355 continue;
2356 }
2357 idx_rdcost[ref_mv_idx] = simple_translation_pred_rd(
2358 cpi, x, rd_stats, args, ref_mv_idx, ref_best_rd, bsize);
2359 }
2360 // Find the index with the best RD cost.
2361 int best_idx = 0;
2362 for (int i = 1; i < MAX_REF_MV_SEARCH3; ++i) {
2363 if (idx_rdcost[i] < idx_rdcost[best_idx]) {
2364 best_idx = i;
2365 }
2366 }
2367 // Only include indices that are good and within a % of the best.
2368 const double dth = has_second_ref(mbmi) ? 1.05 : 1.001;
2369 // If the simple translation cost is not within this multiple of the
2370 // best RD, skip it. Note that the cutoff is derived experimentally.
2371 const double ref_dth = 5;
2372 int result = 0;
2373 for (int i = 0; i < ref_set; ++i) {
2374 if (mask_check_bit(good_indices, i) &&
2375 (1.0 * idx_rdcost[i]) / idx_rdcost[best_idx] < dth &&
2376 (1.0 * idx_rdcost[i]) / ref_best_rd < ref_dth) {
2377 mask_set_bit(&result, i);
2378 }
2379 }
2380 return result;
2381}
2382
2383/*!\brief Motion mode information for inter mode search speedup.
2384 *
2385 * Used in a speed feature to search motion modes other than
2386 * SIMPLE_TRANSLATION only on winning candidates.
2387 */
2388typedef struct motion_mode_candidate {
2389 /*!
2390 * Mode info for the motion mode candidate.
2391 */
2392 MB_MODE_INFO mbmi;
2393 /*!
2394 * Rate describing the cost of the motion vectors for this candidate.
2395 */
2396 int rate_mv;
2397 /*!
2398 * Rate before motion mode search and transform coding is applied.
2399 */
2400 int rate2_nocoeff;
2401 /*!
2402 * An integer value 0 or 1 which indicates whether or not to skip the motion
2403 * mode search and default to SIMPLE_TRANSLATION as a speed feature for this
2404 * candidate.
2405 */
2406 int skip_motion_mode;
2407 /*!
2408 * Total RD cost for this candidate.
2409 */
2410 int64_t rd_cost;
2411} motion_mode_candidate;
2412
2413/*!\cond */
2414typedef struct motion_mode_best_st_candidate {
2415 motion_mode_candidate motion_mode_cand[MAX_WINNER_MOTION_MODES10];
2416 int num_motion_mode_cand;
2417} motion_mode_best_st_candidate;
2418
2419// Checks if the current reference frame matches with neighbouring block's
2420// (top/left) reference frames
2421static inline int ref_match_found_in_nb_blocks(MB_MODE_INFO *cur_mbmi,
2422 MB_MODE_INFO *nb_mbmi) {
2423 MV_REFERENCE_FRAME nb_ref_frames[2] = { nb_mbmi->ref_frame[0],
2424 nb_mbmi->ref_frame[1] };
2425 MV_REFERENCE_FRAME cur_ref_frames[2] = { cur_mbmi->ref_frame[0],
2426 cur_mbmi->ref_frame[1] };
2427 const int is_cur_comp_pred = has_second_ref(cur_mbmi);
2428 int match_found = 0;
2429
2430 for (int i = 0; i < (is_cur_comp_pred + 1); i++) {
2431 if ((cur_ref_frames[i] == nb_ref_frames[0]) ||
2432 (cur_ref_frames[i] == nb_ref_frames[1]))
2433 match_found = 1;
2434 }
2435 return match_found;
2436}
2437
2438static inline int find_ref_match_in_above_nbs(const int total_mi_cols,
2439 MACROBLOCKD *xd) {
2440 if (!xd->up_available) return 1;
2441 const int mi_col = xd->mi_col;
2442 MB_MODE_INFO **cur_mbmi = xd->mi;
2443 // prev_row_mi points into the mi array, starting at the beginning of the
2444 // previous row.
2445 MB_MODE_INFO **prev_row_mi = xd->mi - mi_col - 1 * xd->mi_stride;
2446 const int end_col = AOMMIN(mi_col + xd->width, total_mi_cols)(((mi_col + xd->width) < (total_mi_cols)) ? (mi_col + xd
->width) : (total_mi_cols))
;
2447 uint8_t mi_step;
2448 for (int above_mi_col = mi_col; above_mi_col < end_col;
2449 above_mi_col += mi_step) {
2450 MB_MODE_INFO **above_mi = prev_row_mi + above_mi_col;
2451 mi_step = mi_size_wide[above_mi[0]->bsize];
2452 int match_found = 0;
2453 if (is_inter_block(*above_mi))
2454 match_found = ref_match_found_in_nb_blocks(*cur_mbmi, *above_mi);
2455 if (match_found) return 1;
2456 }
2457 return 0;
2458}
2459
2460static inline int find_ref_match_in_left_nbs(const int total_mi_rows,
2461 MACROBLOCKD *xd) {
2462 if (!xd->left_available) return 1;
2463 const int mi_row = xd->mi_row;
2464 MB_MODE_INFO **cur_mbmi = xd->mi;
2465 // prev_col_mi points into the mi array, starting at the top of the
2466 // previous column
2467 MB_MODE_INFO **prev_col_mi = xd->mi - 1 - mi_row * xd->mi_stride;
2468 const int end_row = AOMMIN(mi_row + xd->height, total_mi_rows)(((mi_row + xd->height) < (total_mi_rows)) ? (mi_row + xd
->height) : (total_mi_rows))
;
2469 uint8_t mi_step;
2470 for (int left_mi_row = mi_row; left_mi_row < end_row;
2471 left_mi_row += mi_step) {
2472 MB_MODE_INFO **left_mi = prev_col_mi + left_mi_row * xd->mi_stride;
2473 mi_step = mi_size_high[left_mi[0]->bsize];
2474 int match_found = 0;
2475 if (is_inter_block(*left_mi))
2476 match_found = ref_match_found_in_nb_blocks(*cur_mbmi, *left_mi);
2477 if (match_found) return 1;
2478 }
2479 return 0;
2480}
2481/*!\endcond */
2482
2483/*! \brief Struct used to hold TPL data to
2484 * narrow down parts of the inter mode search.
2485 */
2486typedef struct {
2487 /*!
2488 * The best inter cost out of all of the reference frames.
2489 */
2490 int64_t best_inter_cost;
2491 /*!
2492 * The inter cost for each reference frame.
2493 */
2494 int64_t ref_inter_cost[INTER_REFS_PER_FRAME];
2495} PruneInfoFromTpl;
2496
2497#if !CONFIG_REALTIME_ONLY0
2498// TODO(Remya): Check if get_tpl_stats_b() can be reused
2499static inline void get_block_level_tpl_stats(
2500 AV1_COMP *cpi, BLOCK_SIZE bsize, int mi_row, int mi_col, int *valid_refs,
2501 PruneInfoFromTpl *inter_cost_info_from_tpl) {
2502 AV1_COMMON *const cm = &cpi->common;
2503
2504 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/rdopt.c", 2505
, __extension__ __PRETTY_FUNCTION__); }))
2505 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/rdopt.c", 2505
, __extension__ __PRETTY_FUNCTION__); }))
;
2506 const int tpl_idx = cpi->gf_frame_index;
2507 TplParams *const tpl_data = &cpi->ppi->tpl_data;
2508 if (!av1_tpl_stats_ready(tpl_data, tpl_idx)) return;
2509 const TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
2510 const TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
2511 const int mi_wide = mi_size_wide[bsize];
2512 const int mi_high = mi_size_high[bsize];
2513 const int tpl_stride = tpl_frame->stride;
2514 const int step = 1 << tpl_data->tpl_stats_block_mis_log2;
2515 const int mi_col_sr =
2516 coded_to_superres_mi(mi_col, cm->superres_scale_denominator);
2517 const int mi_col_end_sr =
2518 coded_to_superres_mi(mi_col + mi_wide, cm->superres_scale_denominator);
2519 const int mi_cols_sr = av1_pixels_to_mi(cm->superres_upscaled_width);
2520
2521 const int row_step = step;
2522 const int col_step_sr =
2523 coded_to_superres_mi(step, cm->superres_scale_denominator);
2524 for (int row = mi_row; row < AOMMIN(mi_row + mi_high, cm->mi_params.mi_rows)(((mi_row + mi_high) < (cm->mi_params.mi_rows)) ? (mi_row
+ mi_high) : (cm->mi_params.mi_rows))
;
2525 row += row_step) {
2526 for (int col = mi_col_sr; col < AOMMIN(mi_col_end_sr, mi_cols_sr)(((mi_col_end_sr) < (mi_cols_sr)) ? (mi_col_end_sr) : (mi_cols_sr
))
;
2527 col += col_step_sr) {
2528 const TplDepStats *this_stats = &tpl_stats[av1_tpl_ptr_pos(
2529 row, col, tpl_stride, tpl_data->tpl_stats_block_mis_log2)];
2530
2531 // Sums up the inter cost of corresponding ref frames
2532 for (int ref_idx = 0; ref_idx < INTER_REFS_PER_FRAME; ref_idx++) {
2533 inter_cost_info_from_tpl->ref_inter_cost[ref_idx] +=
2534 this_stats->pred_error[ref_idx];
2535 }
2536 }
2537 }
2538
2539 // Computes the best inter cost (minimum inter_cost)
2540 int64_t best_inter_cost = INT64_MAX(9223372036854775807L);
2541 for (int ref_idx = 0; ref_idx < INTER_REFS_PER_FRAME; ref_idx++) {
2542 const int64_t cur_inter_cost =
2543 inter_cost_info_from_tpl->ref_inter_cost[ref_idx];
2544 // For invalid ref frames, cur_inter_cost = 0 and has to be handled while
2545 // calculating the minimum inter_cost
2546 if (cur_inter_cost != 0 && (cur_inter_cost < best_inter_cost) &&
2547 valid_refs[ref_idx])
2548 best_inter_cost = cur_inter_cost;
2549 }
2550 inter_cost_info_from_tpl->best_inter_cost = best_inter_cost;
2551}
2552#endif
2553
2554static inline int prune_modes_based_on_tpl_stats(
2555 PruneInfoFromTpl *inter_cost_info_from_tpl, const int *refs, int ref_mv_idx,
2556 const PREDICTION_MODE this_mode, int prune_mode_level) {
2557 const int have_newmv = have_newmv_in_inter_mode(this_mode);
2558 if ((prune_mode_level < 2) && have_newmv) return 0;
2559
2560 const int64_t best_inter_cost = inter_cost_info_from_tpl->best_inter_cost;
2561 if (best_inter_cost == INT64_MAX(9223372036854775807L)) return 0;
2562
2563 const int prune_level = prune_mode_level - 1;
2564 int64_t cur_inter_cost;
2565
2566 const int is_globalmv =
2567 (this_mode == GLOBALMV) || (this_mode == GLOBAL_GLOBALMV);
2568 const int prune_index = is_globalmv ? MAX_REF_MV_SEARCH3 : ref_mv_idx;
2569
2570 // Thresholds used for pruning:
2571 // Lower value indicates aggressive pruning and higher value indicates
2572 // conservative pruning which is set based on ref_mv_idx and speed feature.
2573 // 'prune_index' 0, 1, 2 corresponds to ref_mv indices 0, 1 and 2. prune_index
2574 // 3 corresponds to GLOBALMV/GLOBAL_GLOBALMV
2575 static const int tpl_inter_mode_prune_mul_factor[3][MAX_REF_MV_SEARCH3 + 1] = {
2576 { 6, 6, 6, 4 }, { 6, 4, 4, 4 }, { 5, 4, 4, 4 }
2577 };
2578
2579 const int is_comp_pred = (refs[1] > INTRA_FRAME);
2580 if (!is_comp_pred) {
2581 cur_inter_cost = inter_cost_info_from_tpl->ref_inter_cost[refs[0] - 1];
2582 } else {
2583 const int64_t inter_cost_ref0 =
2584 inter_cost_info_from_tpl->ref_inter_cost[refs[0] - 1];
2585 const int64_t inter_cost_ref1 =
2586 inter_cost_info_from_tpl->ref_inter_cost[refs[1] - 1];
2587 // Choose maximum inter_cost among inter_cost_ref0 and inter_cost_ref1 for
2588 // more aggressive pruning
2589 cur_inter_cost = AOMMAX(inter_cost_ref0, inter_cost_ref1)(((inter_cost_ref0) > (inter_cost_ref1)) ? (inter_cost_ref0
) : (inter_cost_ref1))
;
2590 }
2591
2592 // Prune the mode if cur_inter_cost is greater than threshold times
2593 // best_inter_cost
2594 if (cur_inter_cost >
2595 ((tpl_inter_mode_prune_mul_factor[prune_level][prune_index] *
2596 best_inter_cost) >>
2597 2))
2598 return 1;
2599 return 0;
2600}
2601
2602/*!\brief High level function to select parameters for compound mode.
2603 *
2604 * \ingroup inter_mode_search
2605 * The main search functionality is done in the call to av1_compound_type_rd().
2606 *
2607 * \param[in] cpi Top-level encoder structure.
2608 * \param[in] x Pointer to struct holding all the data for
2609 * the current macroblock.
2610 * \param[in] args HandleInterModeArgs struct holding
2611 * miscellaneous arguments for inter mode
2612 * search. See the documentation for this
2613 * struct for a description of each member.
2614 * \param[in] ref_best_rd Best RD found so far for this block.
2615 * It is used for early termination of this
2616 * search if the RD exceeds this value.
2617 * \param[in,out] cur_mv Current motion vector.
2618 * \param[in] bsize Current block size.
2619 * \param[in,out] compmode_interinter_cost RD of the selected interinter
2620 compound mode.
2621 * \param[in,out] rd_buffers CompoundTypeRdBuffers struct to hold all
2622 * allocated buffers for the compound
2623 * predictors and masks in the compound type
2624 * search.
2625 * \param[in,out] orig_dst A prediction buffer to hold a computed
2626 * prediction. This will eventually hold the
2627 * final prediction, and the tmp_dst info will
2628 * be copied here.
2629 * \param[in] tmp_dst A temporary prediction buffer to hold a
2630 * computed prediction.
2631 * \param[in,out] rate_mv The rate associated with the motion vectors.
2632 * This will be modified if a motion search is
2633 * done in the motion mode search.
2634 * \param[in,out] rd_stats Struct to keep track of the overall RD
2635 * information.
2636 * \param[in,out] skip_rd An array of length 2 where skip_rd[0] is the
2637 * best total RD for a skip mode so far, and
2638 * skip_rd[1] is the best RD for a skip mode so
2639 * far in luma. This is used as a speed feature
2640 * to skip the transform search if the computed
2641 * skip RD for the current mode is not better
2642 * than the best skip_rd so far.
2643 * \param[in,out] skip_build_pred Indicates whether or not to build the inter
2644 * predictor. If this is 0, the inter predictor
2645 * has already been built and thus we can avoid
2646 * repeating computation.
2647 * \return Returns 1 if this mode is worse than one already seen and 0 if it is
2648 * a viable candidate.
2649 */
2650static int process_compound_inter_mode(
2651 AV1_COMP *const cpi, MACROBLOCK *x, HandleInterModeArgs *args,
2652 int64_t ref_best_rd, int_mv *cur_mv, BLOCK_SIZE bsize,
2653 int *compmode_interinter_cost, const CompoundTypeRdBuffers *rd_buffers,
2654 const BUFFER_SET *orig_dst, const BUFFER_SET *tmp_dst, int *rate_mv,
2655 RD_STATS *rd_stats, int64_t *skip_rd, int *skip_build_pred) {
2656 MACROBLOCKD *xd = &x->e_mbd;
2657 MB_MODE_INFO *mbmi = xd->mi[0];
2658 const AV1_COMMON *cm = &cpi->common;
2659 const int masked_compound_used = is_any_masked_compound_used(bsize) &&
2660 cm->seq_params->enable_masked_compound;
2661 int mode_search_mask = (1 << COMPOUND_AVERAGE) | (1 << COMPOUND_DISTWTD) |
2662 (1 << COMPOUND_WEDGE) | (1 << COMPOUND_DIFFWTD);
2663
2664 const int num_planes = av1_num_planes(cm);
2665 const int mi_row = xd->mi_row;
2666 const int mi_col = xd->mi_col;
2667 int is_luma_interp_done = 0;
2668 set_default_interp_filters(mbmi, cm->features.interp_filter);
2669
2670 int64_t best_rd_compound;
2671 int64_t rd_thresh;
2672 const int comp_type_rd_shift = COMP_TYPE_RD_THRESH_SHIFT4;
2673 const int comp_type_rd_scale = COMP_TYPE_RD_THRESH_SCALE11;
2674 rd_thresh = get_rd_thresh_from_best_rd(ref_best_rd, (1 << comp_type_rd_shift),
2675 comp_type_rd_scale);
2676 // Select compound type and any parameters related to that type
2677 // (for example, the mask parameters if it is a masked mode) and compute
2678 // the RD
2679 *compmode_interinter_cost = av1_compound_type_rd(
2680 cpi, x, args, bsize, cur_mv, mode_search_mask, masked_compound_used,
2681 orig_dst, tmp_dst, rd_buffers, rate_mv, &best_rd_compound, rd_stats,
2682 ref_best_rd, skip_rd[1], &is_luma_interp_done, rd_thresh);
2683 if (ref_best_rd < INT64_MAX(9223372036854775807L) &&
2684 (best_rd_compound >> comp_type_rd_shift) * comp_type_rd_scale >
2685 ref_best_rd) {
2686 restore_dst_buf(xd, *orig_dst, num_planes);
2687 return 1;
2688 }
2689
2690 // Build only uv predictor for COMPOUND_AVERAGE.
2691 // Note there is no need to call av1_enc_build_inter_predictor
2692 // for luma if COMPOUND_AVERAGE is selected because it is the first
2693 // candidate in av1_compound_type_rd, which means it used the dst_buf
2694 // rather than the tmp_buf.
2695 if (mbmi->interinter_comp.type == COMPOUND_AVERAGE && is_luma_interp_done) {
2696 if (num_planes > 1) {
2697 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize,
2698 AOM_PLANE_U1, num_planes - 1);
2699 }
2700 *skip_build_pred = 1;
2701 }
2702 return 0;
2703}
2704
2705// Speed feature to prune out MVs that are similar to previous MVs if they
2706// don't achieve the best RD advantage.
2707static int prune_ref_mv_idx_search(int ref_mv_idx, int best_ref_mv_idx,
2708 int_mv save_mv[MAX_REF_MV_SEARCH3 - 1][2],
2709 MB_MODE_INFO *mbmi, int pruning_factor) {
2710 int i;
2711 const int is_comp_pred = has_second_ref(mbmi);
2712 const int thr = (1 + is_comp_pred) << (pruning_factor + 1);
2713
2714 // Skip the evaluation if an MV match is found.
2715 if (ref_mv_idx > 0) {
2716 for (int idx = 0; idx < ref_mv_idx; ++idx) {
2717 if (save_mv[idx][0].as_int == INVALID_MV0x80008000) continue;
2718
2719 int mv_diff = 0;
2720 for (i = 0; i < 1 + is_comp_pred; ++i) {
2721 mv_diff += abs(save_mv[idx][i].as_mv.row - mbmi->mv[i].as_mv.row) +
2722 abs(save_mv[idx][i].as_mv.col - mbmi->mv[i].as_mv.col);
2723 }
2724
2725 // If this mode is not the best one, and current MV is similar to
2726 // previous stored MV, terminate this ref_mv_idx evaluation.
2727 if (best_ref_mv_idx == -1 && mv_diff <= thr) return 1;
2728 }
2729 }
2730
2731 if (ref_mv_idx < MAX_REF_MV_SEARCH3 - 1) {
2732 for (i = 0; i < is_comp_pred + 1; ++i)
2733 save_mv[ref_mv_idx][i].as_int = mbmi->mv[i].as_int;
2734 }
2735
2736 return 0;
2737}
2738
2739/*!\brief Prunes ZeroMV Search Using Best NEWMV's SSE
2740 *
2741 * \ingroup inter_mode_search
2742 *
2743 * Compares the sse of zero mv and the best sse found in single new_mv. If the
2744 * sse of the zero_mv is higher, returns 1 to signal zero_mv can be skipped.
2745 * Else returns 0.
2746 *
2747 * Note that the sse of here comes from single_motion_search. So it is
2748 * interpolated with the filter in motion search, not the actual interpolation
2749 * filter used in encoding.
2750 *
2751 * \param[in] fn_ptr A table of function pointers to compute SSE.
2752 * \param[in] x Pointer to struct holding all the data for
2753 * the current macroblock.
2754 * \param[in] bsize The current block_size.
2755 * \param[in] args The args to handle_inter_mode, used to track
2756 * the best SSE.
2757 * \param[in] prune_zero_mv_with_sse The argument holds speed feature
2758 * prune_zero_mv_with_sse value
2759 * \return Returns 1 if zero_mv is pruned, 0 otherwise.
2760 */
2761static inline int prune_zero_mv_with_sse(const aom_variance_fn_ptr_t *fn_ptr,
2762 const MACROBLOCK *x, BLOCK_SIZE bsize,
2763 const HandleInterModeArgs *args,
2764 int prune_zero_mv_with_sse) {
2765 const MACROBLOCKD *xd = &x->e_mbd;
2766 const MB_MODE_INFO *mbmi = xd->mi[0];
2767
2768 const int is_comp_pred = has_second_ref(mbmi);
2769 const MV_REFERENCE_FRAME *refs = mbmi->ref_frame;
2770
2771 for (int idx = 0; idx < 1 + is_comp_pred; idx++) {
2772 if (xd->global_motion[refs[idx]].wmtype != IDENTITY) {
2773 // Pruning logic only works for IDENTITY type models
2774 // Note: In theory we could apply similar logic for TRANSLATION
2775 // type models, but we do not code these due to a spec bug
2776 // (see comments in gm_get_motion_vector() in av1/common/mv.h)
2777 assert(xd->global_motion[refs[idx]].wmtype != TRANSLATION)((void) sizeof ((xd->global_motion[refs[idx]].wmtype != TRANSLATION
) ? 1 : 0), __extension__ ({ if (xd->global_motion[refs[idx
]].wmtype != TRANSLATION) ; else __assert_fail ("xd->global_motion[refs[idx]].wmtype != TRANSLATION"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2777
, __extension__ __PRETTY_FUNCTION__); }))
;
2778 return 0;
2779 }
2780
2781 // Don't prune if we have invalid data
2782 assert(mbmi->mv[idx].as_int == 0)((void) sizeof ((mbmi->mv[idx].as_int == 0) ? 1 : 0), __extension__
({ if (mbmi->mv[idx].as_int == 0) ; else __assert_fail ("mbmi->mv[idx].as_int == 0"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2782
, __extension__ __PRETTY_FUNCTION__); }))
;
2783 if (args->best_single_sse_in_refs[refs[idx]] == INT32_MAX(2147483647)) {
2784 return 0;
2785 }
2786 }
2787
2788 // Sum up the sse of ZEROMV and best NEWMV
2789 unsigned int this_sse_sum = 0;
2790 unsigned int best_sse_sum = 0;
2791 for (int idx = 0; idx < 1 + is_comp_pred; idx++) {
2792 const struct macroblock_plane *const p = &x->plane[AOM_PLANE_Y0];
2793 const struct macroblockd_plane *pd = xd->plane;
2794 const struct buf_2d *src_buf = &p->src;
2795 const struct buf_2d *ref_buf = &pd->pre[idx];
2796 const uint8_t *src = src_buf->buf;
2797 const uint8_t *ref = ref_buf->buf;
2798 const int src_stride = src_buf->stride;
2799 const int ref_stride = ref_buf->stride;
2800
2801 unsigned int this_sse;
2802 fn_ptr[bsize].vf(ref, ref_stride, src, src_stride, &this_sse);
2803 this_sse_sum += this_sse;
2804
2805 const unsigned int best_sse = args->best_single_sse_in_refs[refs[idx]];
2806 best_sse_sum += best_sse;
2807 }
2808
2809 const double mul = prune_zero_mv_with_sse > 1 ? 1.00 : 1.25;
2810 if ((double)this_sse_sum > (mul * (double)best_sse_sum)) {
2811 return 1;
2812 }
2813
2814 return 0;
2815}
2816
2817/*!\brief Searches for interpolation filter in realtime mode during winner eval
2818 *
2819 * \ingroup inter_mode_search
2820 *
2821 * Does a simple interpolation filter search during winner mode evaluation. This
2822 * is currently only used by realtime mode as \ref
2823 * av1_interpolation_filter_search is not called during realtime encoding.
2824 *
2825 * This function only searches over two possible filters. EIGHTTAP_REGULAR is
2826 * always search. For lowres clips (<= 240p), MULTITAP_SHARP is also search. For
2827 * higher res slips (>240p), EIGHTTAP_SMOOTH is also searched.
2828 * *
2829 * \param[in] cpi Pointer to the compressor. Used for feature
2830 * flags.
2831 * \param[in,out] x Pointer to macroblock. This is primarily
2832 * used to access the buffers.
2833 * \param[in] mi_row The current row in mi unit (4X4 pixels).
2834 * \param[in] mi_col The current col in mi unit (4X4 pixels).
2835 * \param[in] bsize The current block_size.
2836 * \return Returns true if a predictor is built in xd->dst, false otherwise.
2837 */
2838static inline bool_Bool fast_interp_search(const AV1_COMP *cpi, MACROBLOCK *x,
2839 int mi_row, int mi_col,
2840 BLOCK_SIZE bsize) {
2841 static const InterpFilters filters_ref_set[3] = {
2842 { EIGHTTAP_REGULAR, EIGHTTAP_REGULAR },
2843 { EIGHTTAP_SMOOTH, EIGHTTAP_SMOOTH },
2844 { MULTITAP_SHARP, MULTITAP_SHARP }
2845 };
2846
2847 const AV1_COMMON *const cm = &cpi->common;
2848 MACROBLOCKD *const xd = &x->e_mbd;
2849 MB_MODE_INFO *const mi = xd->mi[0];
2850 int64_t best_cost = INT64_MAX(9223372036854775807L);
2851 int best_filter_index = -1;
2852 // dst_bufs[0] sores the new predictor, and dist_bifs[1] stores the best
2853 const int num_planes = av1_num_planes(cm);
2854 const int is_240p_or_lesser = AOMMIN(cm->width, cm->height)(((cm->width) < (cm->height)) ? (cm->width) : (cm
->height))
<= 240;
2855 assert(is_inter_mode(mi->mode))((void) sizeof ((is_inter_mode(mi->mode)) ? 1 : 0), __extension__
({ if (is_inter_mode(mi->mode)) ; else __assert_fail ("is_inter_mode(mi->mode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2855
, __extension__ __PRETTY_FUNCTION__); }))
;
2856 assert(mi->motion_mode == SIMPLE_TRANSLATION)((void) sizeof ((mi->motion_mode == SIMPLE_TRANSLATION) ? 1
: 0), __extension__ ({ if (mi->motion_mode == SIMPLE_TRANSLATION
) ; else __assert_fail ("mi->motion_mode == SIMPLE_TRANSLATION"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2856
, __extension__ __PRETTY_FUNCTION__); }))
;
2857 assert(!is_inter_compound_mode(mi->mode))((void) sizeof ((!is_inter_compound_mode(mi->mode)) ? 1 : 0
), __extension__ ({ if (!is_inter_compound_mode(mi->mode))
; else __assert_fail ("!is_inter_compound_mode(mi->mode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2857
, __extension__ __PRETTY_FUNCTION__); }))
;
2858
2859 if (!av1_is_interp_needed(xd)) {
2860 return false0;
2861 }
2862
2863 struct macroblockd_plane *pd = xd->plane;
2864 const BUFFER_SET orig_dst = {
2865 { pd[0].dst.buf, pd[1].dst.buf, pd[2].dst.buf },
2866 { pd[0].dst.stride, pd[1].dst.stride, pd[2].dst.stride },
2867 };
2868 uint8_t *const tmp_buf = get_buf_by_bd(xd, x->tmp_pred_bufs[0]);
2869 const BUFFER_SET tmp_dst = { { tmp_buf, tmp_buf + 1 * MAX_SB_SQUARE((1 << 7) * (1 << 7)),
2870 tmp_buf + 2 * MAX_SB_SQUARE((1 << 7) * (1 << 7)) },
2871 { MAX_SB_SIZE(1 << 7), MAX_SB_SIZE(1 << 7), MAX_SB_SIZE(1 << 7) } };
2872 const BUFFER_SET *dst_bufs[2] = { &orig_dst, &tmp_dst };
2873
2874 for (int i = 0; i < 3; ++i) {
2875 if (is_240p_or_lesser) {
2876 if (filters_ref_set[i].x_filter == EIGHTTAP_SMOOTH) {
2877 continue;
2878 }
2879 } else {
2880 if (filters_ref_set[i].x_filter == MULTITAP_SHARP) {
2881 continue;
2882 }
2883 }
2884 int64_t cost;
2885 RD_STATS tmp_rd = { 0 };
2886
2887 mi->interp_filters.as_filters = filters_ref_set[i];
2888 av1_enc_build_inter_predictor_y(xd, mi_row, mi_col);
2889
2890 model_rd_sb_fn[cpi->sf.rt_sf.use_simple_rd_model
2891 ? MODELRD_LEGACY
2892 : MODELRD_TYPE_INTERP_FILTER1](
2893 cpi, bsize, x, xd, AOM_PLANE_Y0, AOM_PLANE_Y0, &tmp_rd.rate, &tmp_rd.dist,
2894 &tmp_rd.skip_txfm, &tmp_rd.sse, NULL((void*)0), NULL((void*)0), NULL((void*)0));
2895
2896 tmp_rd.rate += av1_get_switchable_rate(x, xd, cm->features.interp_filter,
2897 cm->seq_params->enable_dual_filter);
2898 cost = RDCOST(x->rdmult, tmp_rd.rate, tmp_rd.dist)((((((int64_t)(tmp_rd.rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((tmp_rd.dist) * (1 <<
7)))
;
2899 if (cost < best_cost) {
2900 best_filter_index = i;
2901 best_cost = cost;
2902 swap_dst_buf(xd, dst_bufs, num_planes);
2903 }
2904 }
2905 assert(best_filter_index >= 0)((void) sizeof ((best_filter_index >= 0) ? 1 : 0), __extension__
({ if (best_filter_index >= 0) ; else __assert_fail ("best_filter_index >= 0"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2905
, __extension__ __PRETTY_FUNCTION__); }))
;
2906
2907 mi->interp_filters.as_filters = filters_ref_set[best_filter_index];
2908
2909 const bool_Bool is_best_pred_in_orig = &orig_dst == dst_bufs[1];
2910
2911 if (is_best_pred_in_orig) {
2912 swap_dst_buf(xd, dst_bufs, num_planes);
2913 } else {
2914 // Note that xd->pd's bufers are kept in sync with dst_bufs[0]. So if
2915 // is_best_pred_in_orig is false, that means the current buffer is the
2916 // original one.
2917 assert(&orig_dst == dst_bufs[0])((void) sizeof ((&orig_dst == dst_bufs[0]) ? 1 : 0), __extension__
({ if (&orig_dst == dst_bufs[0]) ; else __assert_fail ("&orig_dst == dst_bufs[0]"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2917
, __extension__ __PRETTY_FUNCTION__); }))
;
2918 assert(xd->plane[AOM_PLANE_Y].dst.buf == orig_dst.plane[AOM_PLANE_Y])((void) sizeof ((xd->plane[0].dst.buf == orig_dst.plane[0]
) ? 1 : 0), __extension__ ({ if (xd->plane[0].dst.buf == orig_dst
.plane[0]) ; else __assert_fail ("xd->plane[AOM_PLANE_Y].dst.buf == orig_dst.plane[AOM_PLANE_Y]"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 2918
, __extension__ __PRETTY_FUNCTION__); }))
;
2919 const int width = block_size_wide[bsize];
2920 const int height = block_size_high[bsize];
2921#if CONFIG_AV1_HIGHBITDEPTH1
2922 const bool_Bool is_hbd = is_cur_buf_hbd(xd);
2923 if (is_hbd) {
2924 aom_highbd_convolve_copy(CONVERT_TO_SHORTPTR(tmp_dst.plane[AOM_PLANE_Y])((uint16_t *)(((uintptr_t)(tmp_dst.plane[0])) << 1)),
2925 tmp_dst.stride[AOM_PLANE_Y0],
2926 CONVERT_TO_SHORTPTR(orig_dst.plane[AOM_PLANE_Y])((uint16_t *)(((uintptr_t)(orig_dst.plane[0])) << 1)),
2927 orig_dst.stride[AOM_PLANE_Y0], width, height);
2928 } else {
2929 aom_convolve_copy(tmp_dst.plane[AOM_PLANE_Y0], tmp_dst.stride[AOM_PLANE_Y0],
2930 orig_dst.plane[AOM_PLANE_Y0],
2931 orig_dst.stride[AOM_PLANE_Y0], width, height);
2932 }
2933#else
2934 aom_convolve_copy(tmp_dst.plane[AOM_PLANE_Y0], tmp_dst.stride[AOM_PLANE_Y0],
2935 orig_dst.plane[AOM_PLANE_Y0], orig_dst.stride[AOM_PLANE_Y0],
2936 width, height);
2937#endif
2938 }
2939
2940 // Build the YUV predictor.
2941 if (num_planes > 1) {
2942 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL((void*)0), bsize,
2943 AOM_PLANE_U1, AOM_PLANE_V2);
2944 }
2945
2946 return true1;
2947}
2948
2949/*!\brief AV1 inter mode RD computation
2950 *
2951 * \ingroup inter_mode_search
2952 * Do the RD search for a given inter mode and compute all information relevant
2953 * to the input mode. It will compute the best MV,
2954 * compound parameters (if the mode is a compound mode) and interpolation filter
2955 * parameters.
2956 *
2957 * \param[in] cpi Top-level encoder structure.
2958 * \param[in] tile_data Pointer to struct holding adaptive
2959 * data/contexts/models for the tile during
2960 * encoding.
2961 * \param[in] x Pointer to structure holding all the data
2962 * for the current macroblock.
2963 * \param[in] bsize Current block size.
2964 * \param[in,out] rd_stats Struct to keep track of the overall RD
2965 * information.
2966 * \param[in,out] rd_stats_y Struct to keep track of the RD information
2967 * for only the Y plane.
2968 * \param[in,out] rd_stats_uv Struct to keep track of the RD information
2969 * for only the UV planes.
2970 * \param[in] args HandleInterModeArgs struct holding
2971 * miscellaneous arguments for inter mode
2972 * search. See the documentation for this
2973 * struct for a description of each member.
2974 * \param[in] ref_best_rd Best RD found so far for this block.
2975 * It is used for early termination of this
2976 * search if the RD exceeds this value.
2977 * \param[in] tmp_buf Temporary buffer used to hold predictors
2978 * built in this search.
2979 * \param[in,out] rd_buffers CompoundTypeRdBuffers struct to hold all
2980 * allocated buffers for the compound
2981 * predictors and masks in the compound type
2982 * search.
2983 * \param[in,out] best_est_rd Estimated RD for motion mode search if
2984 * do_tx_search (see below) is 0.
2985 * \param[in] do_tx_search Parameter to indicate whether or not to do
2986 * a full transform search. This will compute
2987 * an estimated RD for the modes without the
2988 * transform search and later perform the full
2989 * transform search on the best candidates.
2990 * \param[in,out] inter_modes_info InterModesInfo struct to hold inter mode
2991 * information to perform a full transform
2992 * search only on winning candidates searched
2993 * with an estimate for transform coding RD.
2994 * \param[in,out] motion_mode_cand A motion_mode_candidate struct to store
2995 * motion mode information used in a speed
2996 * feature to search motion modes other than
2997 * SIMPLE_TRANSLATION only on winning
2998 * candidates.
2999 * \param[in,out] skip_rd A length 2 array, where skip_rd[0] is the
3000 * best total RD for a skip mode so far, and
3001 * skip_rd[1] is the best RD for a skip mode so
3002 * far in luma. This is used as a speed feature
3003 * to skip the transform search if the computed
3004 * skip RD for the current mode is not better
3005 * than the best skip_rd so far.
3006 * \param[in] inter_cost_info_from_tpl A PruneInfoFromTpl struct used to
3007 * narrow down the search based on data
3008 * collected in the TPL model.
3009 * \param[out] yrd Stores the rdcost corresponding to encoding
3010 * the luma plane.
3011 *
3012 * \return The RD cost for the mode being searched.
3013 */
3014static int64_t handle_inter_mode(
3015 AV1_COMP *const cpi, TileDataEnc *tile_data, MACROBLOCK *x,
3016 BLOCK_SIZE bsize, RD_STATS *rd_stats, RD_STATS *rd_stats_y,
3017 RD_STATS *rd_stats_uv, HandleInterModeArgs *args, int64_t ref_best_rd,
3018 uint8_t *const tmp_buf, const CompoundTypeRdBuffers *rd_buffers,
3019 int64_t *best_est_rd, const int do_tx_search,
3020 InterModesInfo *inter_modes_info, motion_mode_candidate *motion_mode_cand,
3021 int64_t *skip_rd, PruneInfoFromTpl *inter_cost_info_from_tpl,
3022 int64_t *yrd) {
3023 const AV1_COMMON *cm = &cpi->common;
3024 const int num_planes = av1_num_planes(cm);
3025 MACROBLOCKD *xd = &x->e_mbd;
3026 MB_MODE_INFO *mbmi = xd->mi[0];
3027 MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
3028 TxfmSearchInfo *txfm_info = &x->txfm_search_info;
3029 const int is_comp_pred = has_second_ref(mbmi);
3030 const PREDICTION_MODE this_mode = mbmi->mode;
3031
3032#if CONFIG_REALTIME_ONLY0
3033 const int prune_modes_based_on_tpl = 0;
3034#else // CONFIG_REALTIME_ONLY
3035 const TplParams *const tpl_data = &cpi->ppi->tpl_data;
3036 const int prune_modes_based_on_tpl =
3037 cpi->sf.inter_sf.prune_inter_modes_based_on_tpl &&
3038 av1_tpl_stats_ready(tpl_data, cpi->gf_frame_index);
3039#endif // CONFIG_REALTIME_ONLY
3040 int i;
3041 // Reference frames for this mode
3042 const int refs[2] = { mbmi->ref_frame[0],
3043 (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
3044 int rate_mv = 0;
3045 int64_t rd = INT64_MAX(9223372036854775807L);
3046 // Do first prediction into the destination buffer. Do the next
3047 // prediction into a temporary buffer. Then keep track of which one
3048 // of these currently holds the best predictor, and use the other
3049 // one for future predictions. In the end, copy from tmp_buf to
3050 // dst if necessary.
3051 struct macroblockd_plane *pd = xd->plane;
3052 const BUFFER_SET orig_dst = {
3053 { pd[0].dst.buf, pd[1].dst.buf, pd[2].dst.buf },
3054 { pd[0].dst.stride, pd[1].dst.stride, pd[2].dst.stride },
3055 };
3056 const BUFFER_SET tmp_dst = { { tmp_buf, tmp_buf + 1 * MAX_SB_SQUARE((1 << 7) * (1 << 7)),
3057 tmp_buf + 2 * MAX_SB_SQUARE((1 << 7) * (1 << 7)) },
3058 { MAX_SB_SIZE(1 << 7), MAX_SB_SIZE(1 << 7), MAX_SB_SIZE(1 << 7) } };
3059
3060 int64_t ret_val = INT64_MAX(9223372036854775807L);
3061 const int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
3062 RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
3063 int64_t best_rd = INT64_MAX(9223372036854775807L);
3064 uint8_t best_blk_skip[MAX_MIB_SIZE(1 << (7 - 2)) * MAX_MIB_SIZE(1 << (7 - 2))];
3065 uint8_t best_tx_type_map[MAX_MIB_SIZE(1 << (7 - 2)) * MAX_MIB_SIZE(1 << (7 - 2))];
3066 int64_t best_yrd = INT64_MAX(9223372036854775807L);
3067 MB_MODE_INFO best_mbmi = *mbmi;
3068 int best_xskip_txfm = 0;
3069 int64_t newmv_ret_val = INT64_MAX(9223372036854775807L);
3070 inter_mode_info mode_info[MAX_REF_MV_SEARCH3];
3071
3072 // Do not prune the mode based on inter cost from tpl if the current ref frame
3073 // is the winner ref in neighbouring blocks.
3074 int ref_match_found_in_above_nb = 0;
3075 int ref_match_found_in_left_nb = 0;
3076 if (prune_modes_based_on_tpl) {
3077 ref_match_found_in_above_nb =
3078 find_ref_match_in_above_nbs(cm->mi_params.mi_cols, xd);
3079 ref_match_found_in_left_nb =
3080 find_ref_match_in_left_nbs(cm->mi_params.mi_rows, xd);
3081 }
3082
3083 // First, perform a simple translation search for each of the indices. If
3084 // an index performs well, it will be fully searched in the main loop
3085 // of this function.
3086 const int ref_set = get_drl_refmv_count(x, mbmi->ref_frame, this_mode);
3087 // Save MV results from first 2 ref_mv_idx.
3088 int_mv save_mv[MAX_REF_MV_SEARCH3 - 1][2];
3089 int best_ref_mv_idx = -1;
3090 const int idx_mask =
3091 ref_mv_idx_to_search(cpi, x, rd_stats, args, ref_best_rd, bsize, ref_set);
3092 const int16_t mode_ctx =
3093 av1_mode_context_analyzer(mbmi_ext->mode_context, mbmi->ref_frame);
3094 const ModeCosts *mode_costs = &x->mode_costs;
3095 const int ref_mv_cost = cost_mv_ref(mode_costs, this_mode, mode_ctx);
3096 const int base_rate =
3097 args->ref_frame_cost + args->single_comp_cost + ref_mv_cost;
3098
3099 for (i = 0; i < MAX_REF_MV_SEARCH3 - 1; ++i) {
3100 save_mv[i][0].as_int = INVALID_MV0x80008000;
3101 save_mv[i][1].as_int = INVALID_MV0x80008000;
3102 }
3103 args->start_mv_cnt = 0;
3104
3105 // Main loop of this function. This will iterate over all of the ref mvs
3106 // in the dynamic reference list and do the following:
3107 // 1.) Get the current MV. Create newmv MV if necessary
3108 // 2.) Search compound type and parameters if applicable
3109 // 3.) Do interpolation filter search
3110 // 4.) Build the inter predictor
3111 // 5.) Pick the motion mode (SIMPLE_TRANSLATION, OBMC_CAUSAL,
3112 // WARPED_CAUSAL)
3113 // 6.) Update stats if best so far
3114 for (int ref_mv_idx = 0; ref_mv_idx < ref_set; ++ref_mv_idx) {
3115 mbmi->ref_mv_idx = ref_mv_idx;
3116
3117 mode_info[ref_mv_idx].full_search_mv.as_int = INVALID_MV0x80008000;
3118 mode_info[ref_mv_idx].full_mv_bestsme = INT_MAX2147483647;
3119 const int drl_cost = get_drl_cost(
3120 mbmi, mbmi_ext, mode_costs->drl_mode_cost0, ref_frame_type);
3121 mode_info[ref_mv_idx].drl_cost = drl_cost;
3122 mode_info[ref_mv_idx].skip = 0;
3123
3124 if (!mask_check_bit(idx_mask, ref_mv_idx)) {
3125 // MV did not perform well in simple translation search. Skip it.
3126 continue;
3127 }
3128 if (prune_modes_based_on_tpl && !ref_match_found_in_above_nb &&
3129 !ref_match_found_in_left_nb && (ref_best_rd != INT64_MAX(9223372036854775807L))) {
3130 // Skip mode if TPL model indicates it will not be beneficial.
3131 if (prune_modes_based_on_tpl_stats(
3132 inter_cost_info_from_tpl, refs, ref_mv_idx, this_mode,
3133 cpi->sf.inter_sf.prune_inter_modes_based_on_tpl))
3134 continue;
3135 }
3136 av1_init_rd_stats(rd_stats);
3137
3138 // Initialize compound mode data
3139 mbmi->interinter_comp.type = COMPOUND_AVERAGE;
3140 mbmi->comp_group_idx = 0;
3141 mbmi->compound_idx = 1;
3142 if (mbmi->ref_frame[1] == INTRA_FRAME) mbmi->ref_frame[1] = NONE_FRAME;
3143
3144 mbmi->num_proj_ref = 0;
3145 mbmi->motion_mode = SIMPLE_TRANSLATION;
3146
3147 // Compute cost for signalling this DRL index
3148 rd_stats->rate = base_rate;
3149 rd_stats->rate += drl_cost;
3150
3151 int rs = 0;
3152 int compmode_interinter_cost = 0;
3153
3154 int_mv cur_mv[2];
3155
3156 // TODO(Cherma): Extend this speed feature to support compound mode
3157 int skip_repeated_ref_mv =
3158 is_comp_pred ? 0 : cpi->sf.inter_sf.skip_repeated_ref_mv;
3159 // Generate the current mv according to the prediction mode
3160 if (!build_cur_mv(cur_mv, this_mode, cm, x, skip_repeated_ref_mv)) {
3161 continue;
3162 }
3163
3164 // The above call to build_cur_mv does not handle NEWMV modes. Build
3165 // the mv here if we have NEWMV for any predictors.
3166 if (have_newmv_in_inter_mode(this_mode)) {
3167#if CONFIG_COLLECT_COMPONENT_TIMING0
3168 start_timing(cpi, handle_newmv_time);
3169#endif
3170 newmv_ret_val =
3171 handle_newmv(cpi, x, bsize, cur_mv, &rate_mv, args, mode_info);
3172#if CONFIG_COLLECT_COMPONENT_TIMING0
3173 end_timing(cpi, handle_newmv_time);
3174#endif
3175
3176 if (newmv_ret_val != 0) continue;
3177
3178 if (is_inter_singleref_mode(this_mode) &&
3179 cur_mv[0].as_int != INVALID_MV0x80008000) {
3180 const MV_REFERENCE_FRAME ref = refs[0];
3181 const unsigned int this_sse = x->pred_sse[ref];
3182 if (this_sse < args->best_single_sse_in_refs[ref]) {
3183 args->best_single_sse_in_refs[ref] = this_sse;
3184 }
3185
3186 if (cpi->sf.rt_sf.skip_newmv_mode_based_on_sse) {
3187 const int th_idx = cpi->sf.rt_sf.skip_newmv_mode_based_on_sse - 1;
3188 const int pix_idx = num_pels_log2_lookup[bsize] - 4;
3189 const double scale_factor[3][11] = {
3190 { 0.7, 0.7, 0.7, 0.7, 0.7, 0.8, 0.8, 0.9, 0.9, 0.9, 0.9 },
3191 { 0.7, 0.7, 0.7, 0.7, 0.8, 0.8, 1, 1, 1, 1, 1 },
3192 { 0.7, 0.7, 0.7, 0.7, 1, 1, 1, 1, 1, 1, 1 }
3193 };
3194 assert(pix_idx >= 0)((void) sizeof ((pix_idx >= 0) ? 1 : 0), __extension__ ({ if
(pix_idx >= 0) ; else __assert_fail ("pix_idx >= 0", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 3194, __extension__ __PRETTY_FUNCTION__); }))
;
3195 assert(th_idx <= 2)((void) sizeof ((th_idx <= 2) ? 1 : 0), __extension__ ({ if
(th_idx <= 2) ; else __assert_fail ("th_idx <= 2", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 3195, __extension__ __PRETTY_FUNCTION__); }))
;
3196 if (args->best_pred_sse < scale_factor[th_idx][pix_idx] * this_sse)
3197 continue;
3198 }
3199 }
3200
3201 rd_stats->rate += rate_mv;
3202 }
3203 // Copy the motion vector for this mode into mbmi struct
3204 for (i = 0; i < is_comp_pred + 1; ++i) {
3205 mbmi->mv[i].as_int = cur_mv[i].as_int;
3206 }
3207
3208 if (RDCOST(x->rdmult, rd_stats->rate, 0)((((((int64_t)(rd_stats->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((0) * (1 << 7)))
> ref_best_rd &&
3209 mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV) {
3210 continue;
3211 }
3212
3213 // Skip the rest of the search if prune_ref_mv_idx_search speed feature
3214 // is enabled, and the current MV is similar to a previous one.
3215 if (cpi->sf.inter_sf.prune_ref_mv_idx_search && is_comp_pred &&
3216 prune_ref_mv_idx_search(ref_mv_idx, best_ref_mv_idx, save_mv, mbmi,
3217 cpi->sf.inter_sf.prune_ref_mv_idx_search))
3218 continue;
3219
3220 if (cpi->sf.gm_sf.prune_zero_mv_with_sse &&
3221 (this_mode == GLOBALMV || this_mode == GLOBAL_GLOBALMV)) {
3222 if (prune_zero_mv_with_sse(cpi->ppi->fn_ptr, x, bsize, args,
3223 cpi->sf.gm_sf.prune_zero_mv_with_sse)) {
3224 continue;
3225 }
3226 }
3227
3228 int skip_build_pred = 0;
3229 const int mi_row = xd->mi_row;
3230 const int mi_col = xd->mi_col;
3231
3232 // Handle a compound predictor, continue if it is determined this
3233 // cannot be the best compound mode
3234 if (is_comp_pred) {
3235#if CONFIG_COLLECT_COMPONENT_TIMING0
3236 start_timing(cpi, compound_type_rd_time);
3237#endif
3238 const int not_best_mode = process_compound_inter_mode(
3239 cpi, x, args, ref_best_rd, cur_mv, bsize, &compmode_interinter_cost,
3240 rd_buffers, &orig_dst, &tmp_dst, &rate_mv, rd_stats, skip_rd,
3241 &skip_build_pred);
3242#if CONFIG_COLLECT_COMPONENT_TIMING0
3243 end_timing(cpi, compound_type_rd_time);
3244#endif
3245 if (not_best_mode) continue;
3246 }
3247
3248 if (!args->skip_ifs) {
3249#if CONFIG_COLLECT_COMPONENT_TIMING0
3250 start_timing(cpi, interpolation_filter_search_time);
3251#endif
3252 // Determine the interpolation filter for this mode
3253 ret_val = av1_interpolation_filter_search(
3254 x, cpi, tile_data, bsize, &tmp_dst, &orig_dst, &rd, &rs,
3255 &skip_build_pred, args, ref_best_rd);
3256#if CONFIG_COLLECT_COMPONENT_TIMING0
3257 end_timing(cpi, interpolation_filter_search_time);
3258#endif
3259 if (args->modelled_rd != NULL((void*)0) && !is_comp_pred) {
3260 args->modelled_rd[this_mode][ref_mv_idx][refs[0]] = rd;
3261 }
3262 if (ret_val != 0) {
3263 restore_dst_buf(xd, orig_dst, num_planes);
3264 continue;
3265 } else if (cpi->sf.inter_sf.model_based_post_interp_filter_breakout &&
3266 ref_best_rd != INT64_MAX(9223372036854775807L) && (rd >> 3) * 3 > ref_best_rd) {
3267 restore_dst_buf(xd, orig_dst, num_planes);
3268 continue;
3269 }
3270
3271 // Compute modelled RD if enabled
3272 if (args->modelled_rd != NULL((void*)0)) {
3273 if (is_comp_pred) {
3274 const int mode0 = compound_ref0_mode(this_mode);
3275 const int mode1 = compound_ref1_mode(this_mode);
3276 const int64_t mrd =
3277 AOMMIN(args->modelled_rd[mode0][ref_mv_idx][refs[0]],(((args->modelled_rd[mode0][ref_mv_idx][refs[0]]) < (args
->modelled_rd[mode1][ref_mv_idx][refs[1]])) ? (args->modelled_rd
[mode0][ref_mv_idx][refs[0]]) : (args->modelled_rd[mode1][
ref_mv_idx][refs[1]]))
3278 args->modelled_rd[mode1][ref_mv_idx][refs[1]])(((args->modelled_rd[mode0][ref_mv_idx][refs[0]]) < (args
->modelled_rd[mode1][ref_mv_idx][refs[1]])) ? (args->modelled_rd
[mode0][ref_mv_idx][refs[0]]) : (args->modelled_rd[mode1][
ref_mv_idx][refs[1]]))
;
3279 if ((rd >> 3) * 6 > mrd && ref_best_rd < INT64_MAX(9223372036854775807L)) {
3280 restore_dst_buf(xd, orig_dst, num_planes);
3281 continue;
3282 }
3283 }
3284 }
3285 }
3286
3287 rd_stats->rate += compmode_interinter_cost;
3288 if (skip_build_pred != 1) {
3289 // Build this inter predictor if it has not been previously built
3290 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, &orig_dst, bsize, 0,
3291 av1_num_planes(cm) - 1);
3292 }
3293
3294#if CONFIG_COLLECT_COMPONENT_TIMING0
3295 start_timing(cpi, motion_mode_rd_time);
3296#endif
3297 int rate2_nocoeff = rd_stats->rate;
3298 // Determine the motion mode. This will be one of SIMPLE_TRANSLATION,
3299 // OBMC_CAUSAL or WARPED_CAUSAL
3300 int64_t this_yrd;
3301 ret_val = motion_mode_rd(cpi, tile_data, x, bsize, rd_stats, rd_stats_y,
3302 rd_stats_uv, args, ref_best_rd, skip_rd, &rate_mv,
3303 &orig_dst, best_est_rd, do_tx_search,
3304 inter_modes_info, 0, &this_yrd);
3305#if CONFIG_COLLECT_COMPONENT_TIMING0
3306 end_timing(cpi, motion_mode_rd_time);
3307#endif
3308 assert(((void) sizeof (((!(!av1_check_newmv_joint_nonzero(cm, x)) ||
(ret_val == (9223372036854775807L)))) ? 1 : 0), __extension__
({ if ((!(!av1_check_newmv_joint_nonzero(cm, x)) || (ret_val
== (9223372036854775807L)))) ; else __assert_fail ("IMPLIES(!av1_check_newmv_joint_nonzero(cm, x), ret_val == INT64_MAX)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3309
, __extension__ __PRETTY_FUNCTION__); }))
3309 IMPLIES(!av1_check_newmv_joint_nonzero(cm, x), ret_val == INT64_MAX))((void) sizeof (((!(!av1_check_newmv_joint_nonzero(cm, x)) ||
(ret_val == (9223372036854775807L)))) ? 1 : 0), __extension__
({ if ((!(!av1_check_newmv_joint_nonzero(cm, x)) || (ret_val
== (9223372036854775807L)))) ; else __assert_fail ("IMPLIES(!av1_check_newmv_joint_nonzero(cm, x), ret_val == INT64_MAX)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3309
, __extension__ __PRETTY_FUNCTION__); }))
;
3310
3311 if (ret_val != INT64_MAX(9223372036854775807L)) {
3312 int64_t tmp_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist)((((((int64_t)(rd_stats->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_stats->dist) * (1
<< 7)))
;
3313 const THR_MODES mode_enum = get_prediction_mode_idx(
3314 mbmi->mode, mbmi->ref_frame[0], mbmi->ref_frame[1]);
3315 // Collect mode stats for multiwinner mode processing
3316 store_winner_mode_stats(&cpi->common, x, mbmi, rd_stats, rd_stats_y,
3317 rd_stats_uv, mode_enum, NULL((void*)0), bsize, tmp_rd,
3318 cpi->sf.winner_mode_sf.multi_winner_mode_type,
3319 do_tx_search);
3320 if (tmp_rd < best_rd) {
3321 best_yrd = this_yrd;
3322 // Update the best rd stats if we found the best mode so far
3323 best_rd_stats = *rd_stats;
3324 best_rd_stats_y = *rd_stats_y;
3325 best_rd_stats_uv = *rd_stats_uv;
3326 best_rd = tmp_rd;
3327 best_mbmi = *mbmi;
3328 best_xskip_txfm = txfm_info->skip_txfm;
3329 memcpy(best_blk_skip, txfm_info->blk_skip,
3330 sizeof(best_blk_skip[0]) * xd->height * xd->width);
3331 av1_copy_array(best_tx_type_map, xd->tx_type_map,do { ((void) sizeof ((sizeof(*(best_tx_type_map)) == sizeof(*
(xd->tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof(
*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))) ; else
__assert_fail ("sizeof(*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3332
, __extension__ __PRETTY_FUNCTION__); })); memcpy(best_tx_type_map
, xd->tx_type_map, xd->height * xd->width * sizeof(*
(xd->tx_type_map))); } while (0)
3332 xd->height * xd->width)do { ((void) sizeof ((sizeof(*(best_tx_type_map)) == sizeof(*
(xd->tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof(
*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))) ; else
__assert_fail ("sizeof(*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3332
, __extension__ __PRETTY_FUNCTION__); })); memcpy(best_tx_type_map
, xd->tx_type_map, xd->height * xd->width * sizeof(*
(xd->tx_type_map))); } while (0)
;
3333 motion_mode_cand->rate_mv = rate_mv;
3334 motion_mode_cand->rate2_nocoeff = rate2_nocoeff;
3335 }
3336
3337 if (tmp_rd < ref_best_rd) {
3338 ref_best_rd = tmp_rd;
3339 best_ref_mv_idx = ref_mv_idx;
3340 }
3341 }
3342 restore_dst_buf(xd, orig_dst, num_planes);
3343 }
3344
3345 if (best_rd == INT64_MAX(9223372036854775807L)) return INT64_MAX(9223372036854775807L);
3346
3347 // re-instate status of the best choice
3348 *rd_stats = best_rd_stats;
3349 *rd_stats_y = best_rd_stats_y;
3350 *rd_stats_uv = best_rd_stats_uv;
3351 *yrd = best_yrd;
3352 *mbmi = best_mbmi;
3353 txfm_info->skip_txfm = best_xskip_txfm;
3354 assert(IMPLIES(mbmi->comp_group_idx == 1,((void) sizeof (((!(mbmi->comp_group_idx == 1) || (mbmi->
interinter_comp.type != COMPOUND_AVERAGE))) ? 1 : 0), __extension__
({ if ((!(mbmi->comp_group_idx == 1) || (mbmi->interinter_comp
.type != COMPOUND_AVERAGE))) ; else __assert_fail ("IMPLIES(mbmi->comp_group_idx == 1, mbmi->interinter_comp.type != COMPOUND_AVERAGE)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3355
, __extension__ __PRETTY_FUNCTION__); }))
3355 mbmi->interinter_comp.type != COMPOUND_AVERAGE))((void) sizeof (((!(mbmi->comp_group_idx == 1) || (mbmi->
interinter_comp.type != COMPOUND_AVERAGE))) ? 1 : 0), __extension__
({ if ((!(mbmi->comp_group_idx == 1) || (mbmi->interinter_comp
.type != COMPOUND_AVERAGE))) ; else __assert_fail ("IMPLIES(mbmi->comp_group_idx == 1, mbmi->interinter_comp.type != COMPOUND_AVERAGE)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3355
, __extension__ __PRETTY_FUNCTION__); }))
;
3356 memcpy(txfm_info->blk_skip, best_blk_skip,
3357 sizeof(best_blk_skip[0]) * xd->height * xd->width);
3358 av1_copy_array(xd->tx_type_map, best_tx_type_map, xd->height * xd->width)do { ((void) sizeof ((sizeof(*(xd->tx_type_map)) == sizeof
(*(best_tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof(
*(xd->tx_type_map)) == sizeof(*(best_tx_type_map))) ; else
__assert_fail ("sizeof(*(xd->tx_type_map)) == sizeof(*(best_tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3358
, __extension__ __PRETTY_FUNCTION__); })); memcpy(xd->tx_type_map
, best_tx_type_map, xd->height * xd->width * sizeof(*(best_tx_type_map
))); } while (0)
;
3359
3360 rd_stats->rdcost = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist)((((((int64_t)(rd_stats->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_stats->dist) * (1
<< 7)))
;
3361
3362 return rd_stats->rdcost;
3363}
3364
3365/*!\brief Search for the best intrabc predictor
3366 *
3367 * \ingroup intra_mode_search
3368 * \callergraph
3369 * This function performs a motion search to find the best intrabc predictor.
3370 *
3371 * \returns Returns the best overall rdcost (including the non-intrabc modes
3372 * search before this function).
3373 */
3374static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
3375 PICK_MODE_CONTEXT *ctx,
3376 RD_STATS *rd_stats, BLOCK_SIZE bsize,
3377 int64_t best_rd) {
3378 const AV1_COMMON *const cm = &cpi->common;
3379 if (!av1_allow_intrabc(cm) || !cpi->oxcf.kf_cfg.enable_intrabc ||
3380 !cpi->sf.mv_sf.use_intrabc || cpi->sf.rt_sf.use_nonrd_pick_mode)
3381 return INT64_MAX(9223372036854775807L);
3382 const int num_planes = av1_num_planes(cm);
3383
3384 MACROBLOCKD *const xd = &x->e_mbd;
3385 const TileInfo *tile = &xd->tile;
3386 MB_MODE_INFO *mbmi = xd->mi[0];
3387 TxfmSearchInfo *txfm_info = &x->txfm_search_info;
3388
3389 const int mi_row = xd->mi_row;
3390 const int mi_col = xd->mi_col;
3391 const int w = block_size_wide[bsize];
3392 const int h = block_size_high[bsize];
3393 const int sb_row = mi_row >> cm->seq_params->mib_size_log2;
3394 const int sb_col = mi_col >> cm->seq_params->mib_size_log2;
3395
3396 MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
3397 const MV_REFERENCE_FRAME ref_frame = INTRA_FRAME;
3398 av1_find_mv_refs(cm, xd, mbmi, ref_frame, mbmi_ext->ref_mv_count,
3399 xd->ref_mv_stack, xd->weight, NULL((void*)0), mbmi_ext->global_mvs,
3400 mbmi_ext->mode_context);
3401 // TODO(Ravi): Populate mbmi_ext->ref_mv_stack[ref_frame][4] and
3402 // mbmi_ext->weight[ref_frame][4] inside av1_find_mv_refs.
3403 av1_copy_usable_ref_mv_stack_and_weight(xd, mbmi_ext, ref_frame);
3404 int_mv nearestmv, nearmv;
3405 av1_find_best_ref_mvs_from_stack(0, mbmi_ext, ref_frame, &nearestmv, &nearmv,
3406 0);
3407
3408 if (nearestmv.as_int == INVALID_MV0x80008000) {
3409 nearestmv.as_int = 0;
3410 }
3411 if (nearmv.as_int == INVALID_MV0x80008000) {
3412 nearmv.as_int = 0;
3413 }
3414
3415 int_mv dv_ref = nearestmv.as_int == 0 ? nearmv : nearestmv;
3416 if (dv_ref.as_int == 0) {
3417 av1_find_ref_dv(&dv_ref, tile, cm->seq_params->mib_size, mi_row);
3418 }
3419 // Ref DV should not have sub-pel.
3420 assert((dv_ref.as_mv.col & 7) == 0)((void) sizeof (((dv_ref.as_mv.col & 7) == 0) ? 1 : 0), __extension__
({ if ((dv_ref.as_mv.col & 7) == 0) ; else __assert_fail
("(dv_ref.as_mv.col & 7) == 0", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 3420, __extension__ __PRETTY_FUNCTION__); }))
;
3421 assert((dv_ref.as_mv.row & 7) == 0)((void) sizeof (((dv_ref.as_mv.row & 7) == 0) ? 1 : 0), __extension__
({ if ((dv_ref.as_mv.row & 7) == 0) ; else __assert_fail
("(dv_ref.as_mv.row & 7) == 0", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 3421, __extension__ __PRETTY_FUNCTION__); }))
;
3422 mbmi_ext->ref_mv_stack[INTRA_FRAME][0].this_mv = dv_ref;
3423
3424 struct buf_2d yv12_mb[MAX_MB_PLANE3];
3425 av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, NULL((void*)0), NULL((void*)0), num_planes);
3426 for (int i = 0; i < num_planes; ++i) {
3427 xd->plane[i].pre[0] = yv12_mb[i];
3428 }
3429
3430 enum IntrabcMotionDirection {
3431 IBC_MOTION_ABOVE,
3432 IBC_MOTION_LEFT,
3433 IBC_MOTION_DIRECTIONS
3434 };
3435
3436 MB_MODE_INFO best_mbmi = *mbmi;
3437 RD_STATS best_rdstats = *rd_stats;
3438 uint8_t best_blk_skip[MAX_MIB_SIZE(1 << (7 - 2)) * MAX_MIB_SIZE(1 << (7 - 2))] = { 0 };
3439 uint8_t best_tx_type_map[MAX_MIB_SIZE(1 << (7 - 2)) * MAX_MIB_SIZE(1 << (7 - 2))];
3440 av1_copy_array(best_tx_type_map, xd->tx_type_map, ctx->num_4x4_blk)do { ((void) sizeof ((sizeof(*(best_tx_type_map)) == sizeof(*
(xd->tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof(
*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))) ; else
__assert_fail ("sizeof(*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3440
, __extension__ __PRETTY_FUNCTION__); })); memcpy(best_tx_type_map
, xd->tx_type_map, ctx->num_4x4_blk * sizeof(*(xd->tx_type_map
))); } while (0)
;
3441
3442 FULLPEL_MOTION_SEARCH_PARAMS fullms_params;
3443 const SEARCH_METHODS search_method =
3444 av1_get_default_mv_search_method(x, &cpi->sf.mv_sf, bsize);
3445 const search_site_config *lookahead_search_sites =
3446 cpi->mv_search_params.search_site_cfg[SS_CFG_LOOKAHEAD];
3447 const FULLPEL_MV start_mv = get_fullmv_from_mv(&dv_ref.as_mv);
3448 av1_make_default_fullpel_ms_params(&fullms_params, cpi, x, bsize,
3449 &dv_ref.as_mv, start_mv,
3450 lookahead_search_sites, search_method,
3451 /*fine_search_interval=*/0);
3452 const IntraBCMVCosts *const dv_costs = x->dv_costs;
3453 av1_set_ms_to_intra_mode(&fullms_params, dv_costs);
3454
3455 for (enum IntrabcMotionDirection dir = IBC_MOTION_ABOVE;
3456 dir < IBC_MOTION_DIRECTIONS; ++dir) {
3457 switch (dir) {
3458 case IBC_MOTION_ABOVE:
3459 fullms_params.mv_limits.col_min =
3460 (tile->mi_col_start - mi_col) * MI_SIZE(1 << 2);
3461 fullms_params.mv_limits.col_max =
3462 (tile->mi_col_end - mi_col) * MI_SIZE(1 << 2) - w;
3463 fullms_params.mv_limits.row_min =
3464 (tile->mi_row_start - mi_row) * MI_SIZE(1 << 2);
3465 fullms_params.mv_limits.row_max =
3466 (sb_row * cm->seq_params->mib_size - mi_row) * MI_SIZE(1 << 2) - h;
3467 break;
3468 case IBC_MOTION_LEFT:
3469 fullms_params.mv_limits.col_min =
3470 (tile->mi_col_start - mi_col) * MI_SIZE(1 << 2);
3471 fullms_params.mv_limits.col_max =
3472 (sb_col * cm->seq_params->mib_size - mi_col) * MI_SIZE(1 << 2) - w;
3473 // TODO(aconverse@google.com): Minimize the overlap between above and
3474 // left areas.
3475 fullms_params.mv_limits.row_min =
3476 (tile->mi_row_start - mi_row) * MI_SIZE(1 << 2);
3477 int bottom_coded_mi_edge =
3478 AOMMIN((sb_row + 1) * cm->seq_params->mib_size, tile->mi_row_end)((((sb_row + 1) * cm->seq_params->mib_size) < (tile->
mi_row_end)) ? ((sb_row + 1) * cm->seq_params->mib_size
) : (tile->mi_row_end))
;
3479 fullms_params.mv_limits.row_max =
3480 (bottom_coded_mi_edge - mi_row) * MI_SIZE(1 << 2) - h;
3481 break;
3482 default: assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 3482, __extension__ __PRETTY_FUNCTION__); }))
;
3483 }
3484 assert(fullms_params.mv_limits.col_min >= fullms_params.mv_limits.col_min)((void) sizeof ((fullms_params.mv_limits.col_min >= fullms_params
.mv_limits.col_min) ? 1 : 0), __extension__ ({ if (fullms_params
.mv_limits.col_min >= fullms_params.mv_limits.col_min) ; else
__assert_fail ("fullms_params.mv_limits.col_min >= fullms_params.mv_limits.col_min"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3484
, __extension__ __PRETTY_FUNCTION__); }))
;
3485 assert(fullms_params.mv_limits.col_max <= fullms_params.mv_limits.col_max)((void) sizeof ((fullms_params.mv_limits.col_max <= fullms_params
.mv_limits.col_max) ? 1 : 0), __extension__ ({ if (fullms_params
.mv_limits.col_max <= fullms_params.mv_limits.col_max) ; else
__assert_fail ("fullms_params.mv_limits.col_max <= fullms_params.mv_limits.col_max"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3485
, __extension__ __PRETTY_FUNCTION__); }))
;
3486 assert(fullms_params.mv_limits.row_min >= fullms_params.mv_limits.row_min)((void) sizeof ((fullms_params.mv_limits.row_min >= fullms_params
.mv_limits.row_min) ? 1 : 0), __extension__ ({ if (fullms_params
.mv_limits.row_min >= fullms_params.mv_limits.row_min) ; else
__assert_fail ("fullms_params.mv_limits.row_min >= fullms_params.mv_limits.row_min"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3486
, __extension__ __PRETTY_FUNCTION__); }))
;
3487 assert(fullms_params.mv_limits.row_max <= fullms_params.mv_limits.row_max)((void) sizeof ((fullms_params.mv_limits.row_max <= fullms_params
.mv_limits.row_max) ? 1 : 0), __extension__ ({ if (fullms_params
.mv_limits.row_max <= fullms_params.mv_limits.row_max) ; else
__assert_fail ("fullms_params.mv_limits.row_max <= fullms_params.mv_limits.row_max"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3487
, __extension__ __PRETTY_FUNCTION__); }))
;
3488
3489 av1_set_mv_search_range(&fullms_params.mv_limits, &dv_ref.as_mv);
3490
3491 if (fullms_params.mv_limits.col_max < fullms_params.mv_limits.col_min ||
3492 fullms_params.mv_limits.row_max < fullms_params.mv_limits.row_min) {
3493 continue;
3494 }
3495
3496 const int step_param = cpi->mv_search_params.mv_step_param;
3497 IntraBCHashInfo *intrabc_hash_info = &x->intrabc_hash_info;
3498 int_mv best_mv, best_hash_mv;
3499 FULLPEL_MV_STATS best_mv_stats;
3500
3501 int bestsme =
3502 av1_full_pixel_search(start_mv, &fullms_params, step_param, NULL((void*)0),
3503 &best_mv.as_fullmv, &best_mv_stats, NULL((void*)0));
3504 const int hashsme = av1_intrabc_hash_search(
3505 cpi, xd, &fullms_params, intrabc_hash_info, &best_hash_mv.as_fullmv);
3506 if (hashsme < bestsme) {
3507 best_mv = best_hash_mv;
3508 bestsme = hashsme;
3509 }
3510
3511 if (bestsme == INT_MAX2147483647) continue;
3512 const MV dv = get_mv_from_fullmv(&best_mv.as_fullmv);
3513 if (!av1_is_fullmv_in_range(&fullms_params.mv_limits,
3514 get_fullmv_from_mv(&dv)))
3515 continue;
3516 if (!av1_is_dv_valid(dv, cm, xd, mi_row, mi_col, bsize,
3517 cm->seq_params->mib_size_log2))
3518 continue;
3519
3520 // DV should not have sub-pel.
3521 assert((dv.col & 7) == 0)((void) sizeof (((dv.col & 7) == 0) ? 1 : 0), __extension__
({ if ((dv.col & 7) == 0) ; else __assert_fail ("(dv.col & 7) == 0"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3521
, __extension__ __PRETTY_FUNCTION__); }))
;
3522 assert((dv.row & 7) == 0)((void) sizeof (((dv.row & 7) == 0) ? 1 : 0), __extension__
({ if ((dv.row & 7) == 0) ; else __assert_fail ("(dv.row & 7) == 0"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3522
, __extension__ __PRETTY_FUNCTION__); }))
;
3523 memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
3524 mbmi->filter_intra_mode_info.use_filter_intra = 0;
3525 mbmi->use_intrabc = 1;
3526 mbmi->mode = DC_PRED;
3527 mbmi->uv_mode = UV_DC_PRED;
3528 mbmi->motion_mode = SIMPLE_TRANSLATION;
3529 mbmi->mv[0].as_mv = dv;
3530 mbmi->interp_filters = av1_broadcast_interp_filter(BILINEAR);
3531 mbmi->skip_txfm = 0;
3532 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL((void*)0), bsize, 0,
3533 av1_num_planes(cm) - 1);
3534
3535 // TODO(aconverse@google.com): The full motion field defining discount
3536 // in MV_COST_WEIGHT is too large. Explore other values.
3537 const int rate_mv = av1_mv_bit_cost(&dv, &dv_ref.as_mv, dv_costs->joint_mv,
3538 dv_costs->dv_costs, MV_COST_WEIGHT_SUB120);
3539 const int rate_mode = x->mode_costs.intrabc_cost[1];
3540 RD_STATS rd_stats_yuv, rd_stats_y, rd_stats_uv;
3541 if (!av1_txfm_search(cpi, x, bsize, &rd_stats_yuv, &rd_stats_y,
3542 &rd_stats_uv, rate_mode + rate_mv, INT64_MAX(9223372036854775807L)))
3543 continue;
3544 rd_stats_yuv.rdcost =
3545 RDCOST(x->rdmult, rd_stats_yuv.rate, rd_stats_yuv.dist)((((((int64_t)(rd_stats_yuv.rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_stats_yuv.dist) * (1
<< 7)))
;
3546 if (rd_stats_yuv.rdcost < best_rd) {
3547 best_rd = rd_stats_yuv.rdcost;
3548 best_mbmi = *mbmi;
3549 best_rdstats = rd_stats_yuv;
3550 memcpy(best_blk_skip, txfm_info->blk_skip,
3551 sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
3552 av1_copy_array(best_tx_type_map, xd->tx_type_map, xd->height * xd->width)do { ((void) sizeof ((sizeof(*(best_tx_type_map)) == sizeof(*
(xd->tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof(
*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))) ; else
__assert_fail ("sizeof(*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3552
, __extension__ __PRETTY_FUNCTION__); })); memcpy(best_tx_type_map
, xd->tx_type_map, xd->height * xd->width * sizeof(*
(xd->tx_type_map))); } while (0)
;
3553 }
3554 }
3555 *mbmi = best_mbmi;
3556 *rd_stats = best_rdstats;
3557 memcpy(txfm_info->blk_skip, best_blk_skip,
3558 sizeof(txfm_info->blk_skip[0]) * xd->height * xd->width);
3559 av1_copy_array(xd->tx_type_map, best_tx_type_map, ctx->num_4x4_blk)do { ((void) sizeof ((sizeof(*(xd->tx_type_map)) == sizeof
(*(best_tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof(
*(xd->tx_type_map)) == sizeof(*(best_tx_type_map))) ; else
__assert_fail ("sizeof(*(xd->tx_type_map)) == sizeof(*(best_tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3559
, __extension__ __PRETTY_FUNCTION__); })); memcpy(xd->tx_type_map
, best_tx_type_map, ctx->num_4x4_blk * sizeof(*(best_tx_type_map
))); } while (0)
;
3560#if CONFIG_RD_DEBUG0
3561 mbmi->rd_stats = *rd_stats;
3562#endif
3563 return best_rd;
3564}
3565
3566// TODO(chiyotsai@google.com): We are using struct $struct_name instead of their
3567// typedef here because Doxygen doesn't know about the typedefs yet. So using
3568// the typedef will prevent doxygen from finding this function and generating
3569// the callgraph. Once documents for AV1_COMP and MACROBLOCK are added to
3570// doxygen, we can revert back to using the typedefs.
3571void av1_rd_pick_intra_mode_sb(const struct AV1_COMP *cpi, struct macroblock *x,
3572 struct RD_STATS *rd_cost, BLOCK_SIZE bsize,
3573 PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
3574 const AV1_COMMON *const cm = &cpi->common;
3575 MACROBLOCKD *const xd = &x->e_mbd;
3576 MB_MODE_INFO *const mbmi = xd->mi[0];
3577 const int num_planes = av1_num_planes(cm);
3578 TxfmSearchInfo *txfm_info = &x->txfm_search_info;
3579 int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
3580 uint8_t y_skip_txfm = 0, uv_skip_txfm = 0;
3581 int64_t dist_y = 0, dist_uv = 0;
3582
3583 ctx->rd_stats.skip_txfm = 0;
3584 mbmi->ref_frame[0] = INTRA_FRAME;
3585 mbmi->ref_frame[1] = NONE_FRAME;
3586 mbmi->use_intrabc = 0;
3587 mbmi->mv[0].as_int = 0;
3588 mbmi->skip_mode = 0;
3589
3590 const int64_t intra_yrd =
3591 av1_rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
3592 &y_skip_txfm, bsize, best_rd, ctx);
3593
3594 // Initialize default mode evaluation params
3595 set_mode_eval_params(cpi, x, DEFAULT_EVAL);
3596
3597 if (intra_yrd < best_rd) {
3598 // Search intra modes for uv planes if needed
3599 if (num_planes > 1) {
3600 // Set up the tx variables for reproducing the y predictions in case we
3601 // need it for chroma-from-luma.
3602 if (xd->is_chroma_ref && store_cfl_required_rdo(cm, x)) {
3603 memcpy(txfm_info->blk_skip, ctx->blk_skip,
3604 sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
3605 av1_copy_array(xd->tx_type_map, ctx->tx_type_map, ctx->num_4x4_blk)do { ((void) sizeof ((sizeof(*(xd->tx_type_map)) == sizeof
(*(ctx->tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof
(*(xd->tx_type_map)) == sizeof(*(ctx->tx_type_map))) ; else
__assert_fail ("sizeof(*(xd->tx_type_map)) == sizeof(*(ctx->tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3605
, __extension__ __PRETTY_FUNCTION__); })); memcpy(xd->tx_type_map
, ctx->tx_type_map, ctx->num_4x4_blk * sizeof(*(ctx->
tx_type_map))); } while (0)
;
3606 }
3607 const TX_SIZE max_uv_tx_size = av1_get_tx_size(AOM_PLANE_U1, xd);
3608 av1_rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly,
3609 &dist_uv, &uv_skip_txfm, bsize,
3610 max_uv_tx_size);
3611 }
3612
3613 // Intra block is always coded as non-skip
3614 rd_cost->rate =
3615 rate_y + rate_uv +
3616 x->mode_costs.skip_txfm_cost[av1_get_skip_txfm_context(xd)][0];
3617 rd_cost->dist = dist_y + dist_uv;
3618 rd_cost->rdcost = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist)((((((int64_t)(rd_cost->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_cost->dist) * (1 <<
7)))
;
3619 rd_cost->skip_txfm = 0;
3620 } else {
3621 rd_cost->rate = INT_MAX2147483647;
3622 }
3623
3624 if (rd_cost->rate != INT_MAX2147483647 && rd_cost->rdcost < best_rd)
3625 best_rd = rd_cost->rdcost;
3626 if (rd_pick_intrabc_mode_sb(cpi, x, ctx, rd_cost, bsize, best_rd) < best_rd) {
3627 ctx->rd_stats.skip_txfm = mbmi->skip_txfm;
3628 memcpy(ctx->blk_skip, txfm_info->blk_skip,
3629 sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
3630 assert(rd_cost->rate != INT_MAX)((void) sizeof ((rd_cost->rate != 2147483647) ? 1 : 0), __extension__
({ if (rd_cost->rate != 2147483647) ; else __assert_fail (
"rd_cost->rate != INT_MAX", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 3630, __extension__ __PRETTY_FUNCTION__); }))
;
3631 }
3632 if (rd_cost->rate == INT_MAX2147483647) return;
3633
3634 ctx->mic = *xd->mi[0];
3635 av1_copy_mbmi_ext_to_mbmi_ext_frame(&ctx->mbmi_ext_best, &x->mbmi_ext,
3636 av1_ref_frame_type(xd->mi[0]->ref_frame));
3637 av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk)do { ((void) sizeof ((sizeof(*(ctx->tx_type_map)) == sizeof
(*(xd->tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof
(*(ctx->tx_type_map)) == sizeof(*(xd->tx_type_map))) ; else
__assert_fail ("sizeof(*(ctx->tx_type_map)) == sizeof(*(xd->tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3637
, __extension__ __PRETTY_FUNCTION__); })); memcpy(ctx->tx_type_map
, xd->tx_type_map, ctx->num_4x4_blk * sizeof(*(xd->tx_type_map
))); } while (0)
;
3638}
3639
3640static inline void calc_target_weighted_pred(
3641 const AV1_COMMON *cm, const MACROBLOCK *x, const MACROBLOCKD *xd,
3642 const uint8_t *above, int above_stride, const uint8_t *left,
3643 int left_stride);
3644
3645static inline void rd_pick_skip_mode(
3646 RD_STATS *rd_cost, InterModeSearchState *search_state,
3647 const AV1_COMP *const cpi, MACROBLOCK *const x, BLOCK_SIZE bsize,
3648 struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE3]) {
3649 const AV1_COMMON *const cm = &cpi->common;
3650 const SkipModeInfo *const skip_mode_info = &cm->current_frame.skip_mode_info;
3651 const int num_planes = av1_num_planes(cm);
3652 MACROBLOCKD *const xd = &x->e_mbd;
3653 MB_MODE_INFO *const mbmi = xd->mi[0];
3654
3655 x->compound_idx = 1; // COMPOUND_AVERAGE
3656 RD_STATS skip_mode_rd_stats;
3657 av1_invalid_rd_stats(&skip_mode_rd_stats);
3658
3659 if (skip_mode_info->ref_frame_idx_0 == INVALID_IDX-1 ||
3660 skip_mode_info->ref_frame_idx_1 == INVALID_IDX-1) {
3661 return;
3662 }
3663
3664 const MV_REFERENCE_FRAME ref_frame =
3665 LAST_FRAME + skip_mode_info->ref_frame_idx_0;
3666 const MV_REFERENCE_FRAME second_ref_frame =
3667 LAST_FRAME + skip_mode_info->ref_frame_idx_1;
3668 const PREDICTION_MODE this_mode = NEAREST_NEARESTMV;
3669 const THR_MODES mode_index =
3670 get_prediction_mode_idx(this_mode, ref_frame, second_ref_frame);
3671
3672 if (mode_index == THR_INVALID) {
3673 return;
3674 }
3675
3676 if ((!cpi->oxcf.ref_frm_cfg.enable_onesided_comp ||
3677 cpi->sf.inter_sf.disable_onesided_comp) &&
3678 cpi->all_one_sided_refs) {
3679 return;
3680 }
3681
3682 mbmi->mode = this_mode;
3683 mbmi->uv_mode = UV_DC_PRED;
3684 mbmi->ref_frame[0] = ref_frame;
3685 mbmi->ref_frame[1] = second_ref_frame;
3686 const uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
3687 if (x->mbmi_ext.ref_mv_count[ref_frame_type] == UINT8_MAX(255)) {
3688 MB_MODE_INFO_EXT *mbmi_ext = &x->mbmi_ext;
3689 if (mbmi_ext->ref_mv_count[ref_frame] == UINT8_MAX(255) ||
3690 mbmi_ext->ref_mv_count[second_ref_frame] == UINT8_MAX(255)) {
3691 return;
3692 }
3693 av1_find_mv_refs(cm, xd, mbmi, ref_frame_type, mbmi_ext->ref_mv_count,
3694 xd->ref_mv_stack, xd->weight, NULL((void*)0), mbmi_ext->global_mvs,
3695 mbmi_ext->mode_context);
3696 // TODO(Ravi): Populate mbmi_ext->ref_mv_stack[ref_frame][4] and
3697 // mbmi_ext->weight[ref_frame][4] inside av1_find_mv_refs.
3698 av1_copy_usable_ref_mv_stack_and_weight(xd, mbmi_ext, ref_frame_type);
3699 }
3700
3701 assert(this_mode == NEAREST_NEARESTMV)((void) sizeof ((this_mode == NEAREST_NEARESTMV) ? 1 : 0), __extension__
({ if (this_mode == NEAREST_NEARESTMV) ; else __assert_fail (
"this_mode == NEAREST_NEARESTMV", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 3701, __extension__ __PRETTY_FUNCTION__); }))
;
3702 if (!build_cur_mv(mbmi->mv, this_mode, cm, x, 0)) {
3703 return;
3704 }
3705
3706 mbmi->filter_intra_mode_info.use_filter_intra = 0;
3707 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
3708 mbmi->comp_group_idx = 0;
3709 mbmi->compound_idx = x->compound_idx;
3710 mbmi->interinter_comp.type = COMPOUND_AVERAGE;
3711 mbmi->motion_mode = SIMPLE_TRANSLATION;
3712 mbmi->ref_mv_idx = 0;
3713 mbmi->skip_mode = mbmi->skip_txfm = 1;
3714 mbmi->palette_mode_info.palette_size[0] = 0;
3715 mbmi->palette_mode_info.palette_size[1] = 0;
3716
3717 set_default_interp_filters(mbmi, cm->features.interp_filter);
3718
3719 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
3720 for (int i = 0; i < num_planes; i++) {
3721 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
3722 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
3723 }
3724
3725 BUFFER_SET orig_dst;
3726 for (int i = 0; i < num_planes; i++) {
3727 orig_dst.plane[i] = xd->plane[i].dst.buf;
3728 orig_dst.stride[i] = xd->plane[i].dst.stride;
3729 }
3730
3731 // Compare the use of skip_mode with the best intra/inter mode obtained.
3732 const int skip_mode_ctx = av1_get_skip_mode_context(xd);
3733 int64_t best_intra_inter_mode_cost = INT64_MAX(9223372036854775807L);
3734 if (rd_cost->dist < INT64_MAX(9223372036854775807L) && rd_cost->rate < INT32_MAX(2147483647)) {
3735 const ModeCosts *mode_costs = &x->mode_costs;
3736 best_intra_inter_mode_cost = RDCOST(((((((int64_t)(rd_cost->rate + mode_costs->skip_mode_cost
[skip_mode_ctx][0])) * (x->rdmult)) + (((1 << (9)) >>
1))) >> (9)) + ((rd_cost->dist) * (1 << 7)))
3737 x->rdmult, rd_cost->rate + mode_costs->skip_mode_cost[skip_mode_ctx][0],((((((int64_t)(rd_cost->rate + mode_costs->skip_mode_cost
[skip_mode_ctx][0])) * (x->rdmult)) + (((1 << (9)) >>
1))) >> (9)) + ((rd_cost->dist) * (1 << 7)))
3738 rd_cost->dist)((((((int64_t)(rd_cost->rate + mode_costs->skip_mode_cost
[skip_mode_ctx][0])) * (x->rdmult)) + (((1 << (9)) >>
1))) >> (9)) + ((rd_cost->dist) * (1 << 7)))
;
3739 // Account for non-skip mode rate in total rd stats
3740 rd_cost->rate += mode_costs->skip_mode_cost[skip_mode_ctx][0];
3741 av1_rd_cost_update(x->rdmult, rd_cost);
3742 }
3743
3744 // Obtain the rdcost for skip_mode.
3745 skip_mode_rd(&skip_mode_rd_stats, cpi, x, bsize, &orig_dst,
3746 best_intra_inter_mode_cost);
3747
3748 if (skip_mode_rd_stats.rdcost <= best_intra_inter_mode_cost &&
3749 (!xd->lossless[mbmi->segment_id] || skip_mode_rd_stats.dist == 0)) {
3750 assert(mode_index != THR_INVALID)((void) sizeof ((mode_index != THR_INVALID) ? 1 : 0), __extension__
({ if (mode_index != THR_INVALID) ; else __assert_fail ("mode_index != THR_INVALID"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3750
, __extension__ __PRETTY_FUNCTION__); }))
;
3751 search_state->best_mbmode.skip_mode = 1;
3752 search_state->best_mbmode = *mbmi;
3753 memset(search_state->best_mbmode.inter_tx_size,
3754 search_state->best_mbmode.tx_size,
3755 sizeof(search_state->best_mbmode.inter_tx_size));
3756 set_txfm_ctxs(search_state->best_mbmode.tx_size, xd->width, xd->height,
3757 search_state->best_mbmode.skip_txfm && is_inter_block(mbmi),
3758 xd);
3759 search_state->best_mode_index = mode_index;
3760
3761 // Update rd_cost
3762 rd_cost->rate = skip_mode_rd_stats.rate;
3763 rd_cost->dist = rd_cost->sse = skip_mode_rd_stats.dist;
3764 rd_cost->rdcost = skip_mode_rd_stats.rdcost;
3765
3766 search_state->best_rd = rd_cost->rdcost;
3767 search_state->best_skip2 = 1;
3768 search_state->best_mode_skippable = 1;
3769
3770 x->txfm_search_info.skip_txfm = 1;
3771 }
3772}
3773
3774// Get winner mode stats of given mode index
3775static inline MB_MODE_INFO *get_winner_mode_stats(
3776 MACROBLOCK *x, MB_MODE_INFO *best_mbmode, RD_STATS *best_rd_cost,
3777 int best_rate_y, int best_rate_uv, THR_MODES *best_mode_index,
3778 RD_STATS **winner_rd_cost, int *winner_rate_y, int *winner_rate_uv,
3779 THR_MODES *winner_mode_index, MULTI_WINNER_MODE_TYPE multi_winner_mode_type,
3780 int mode_idx) {
3781 MB_MODE_INFO *winner_mbmi;
3782 if (multi_winner_mode_type) {
3783 assert(mode_idx >= 0 && mode_idx < x->winner_mode_count)((void) sizeof ((mode_idx >= 0 && mode_idx < x->
winner_mode_count) ? 1 : 0), __extension__ ({ if (mode_idx >=
0 && mode_idx < x->winner_mode_count) ; else __assert_fail
("mode_idx >= 0 && mode_idx < x->winner_mode_count"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3783
, __extension__ __PRETTY_FUNCTION__); }))
;
3784 WinnerModeStats *winner_mode_stat = &x->winner_mode_stats[mode_idx];
3785 winner_mbmi = &winner_mode_stat->mbmi;
3786
3787 *winner_rd_cost = &winner_mode_stat->rd_cost;
3788 *winner_rate_y = winner_mode_stat->rate_y;
3789 *winner_rate_uv = winner_mode_stat->rate_uv;
3790 *winner_mode_index = winner_mode_stat->mode_index;
3791 } else {
3792 winner_mbmi = best_mbmode;
3793 *winner_rd_cost = best_rd_cost;
3794 *winner_rate_y = best_rate_y;
3795 *winner_rate_uv = best_rate_uv;
3796 *winner_mode_index = *best_mode_index;
3797 }
3798 return winner_mbmi;
3799}
3800
3801// speed feature: fast intra/inter transform type search
3802// Used for speed >= 2
3803// When this speed feature is on, in rd mode search, only DCT is used.
3804// After the mode is determined, this function is called, to select
3805// transform types and get accurate rdcost.
3806static inline void refine_winner_mode_tx(
3807 const AV1_COMP *cpi, MACROBLOCK *x, RD_STATS *rd_cost, BLOCK_SIZE bsize,
3808 PICK_MODE_CONTEXT *ctx, THR_MODES *best_mode_index,
3809 MB_MODE_INFO *best_mbmode, struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE3],
3810 int best_rate_y, int best_rate_uv, int *best_skip2, int winner_mode_count) {
3811 const AV1_COMMON *const cm = &cpi->common;
3812 MACROBLOCKD *const xd = &x->e_mbd;
3813 MB_MODE_INFO *const mbmi = xd->mi[0];
3814 TxfmSearchParams *txfm_params = &x->txfm_search_params;
3815 TxfmSearchInfo *txfm_info = &x->txfm_search_info;
3816 int64_t best_rd;
3817 const int num_planes = av1_num_planes(cm);
3818
3819 if (!is_winner_mode_processing_enabled(cpi, x, best_mbmode,
3820 rd_cost->skip_txfm))
3821 return;
3822
3823 // Set params for winner mode evaluation
3824 set_mode_eval_params(cpi, x, WINNER_MODE_EVAL);
3825
3826 // No best mode identified so far
3827 if (*best_mode_index == THR_INVALID) return;
3828
3829 best_rd = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist)((((((int64_t)(rd_cost->rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_cost->dist) * (1 <<
7)))
;
3830 for (int mode_idx = 0; mode_idx < winner_mode_count; mode_idx++) {
3831 RD_STATS *winner_rd_stats = NULL((void*)0);
3832 int winner_rate_y = 0, winner_rate_uv = 0;
3833 THR_MODES winner_mode_index = 0;
3834
3835 // TODO(any): Combine best mode and multi-winner mode processing paths
3836 // Get winner mode stats for current mode index
3837 MB_MODE_INFO *winner_mbmi = get_winner_mode_stats(
3838 x, best_mbmode, rd_cost, best_rate_y, best_rate_uv, best_mode_index,
3839 &winner_rd_stats, &winner_rate_y, &winner_rate_uv, &winner_mode_index,
3840 cpi->sf.winner_mode_sf.multi_winner_mode_type, mode_idx);
3841
3842 if (xd->lossless[winner_mbmi->segment_id] == 0 &&
3843 winner_mode_index != THR_INVALID &&
3844 is_winner_mode_processing_enabled(cpi, x, winner_mbmi,
3845 rd_cost->skip_txfm)) {
3846 RD_STATS rd_stats = *winner_rd_stats;
3847 int skip_blk = 0;
3848 RD_STATS rd_stats_y, rd_stats_uv;
3849 const int skip_ctx = av1_get_skip_txfm_context(xd);
3850
3851 *mbmi = *winner_mbmi;
3852
3853 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
3854
3855 // Select prediction reference frames.
3856 for (int i = 0; i < num_planes; i++) {
3857 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
3858 if (has_second_ref(mbmi))
3859 xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
3860 }
3861
3862 if (is_inter_mode(mbmi->mode)) {
3863 const int mi_row = xd->mi_row;
3864 const int mi_col = xd->mi_col;
3865 bool_Bool is_predictor_built = false0;
3866 const PREDICTION_MODE prediction_mode = mbmi->mode;
3867 // Do interpolation filter search for realtime mode if applicable.
3868 if (cpi->sf.winner_mode_sf.winner_mode_ifs &&
3869 cpi->oxcf.mode == REALTIME &&
3870 cm->current_frame.reference_mode == SINGLE_REFERENCE &&
3871 is_inter_mode(prediction_mode) &&
3872 mbmi->motion_mode == SIMPLE_TRANSLATION &&
3873 !is_inter_compound_mode(prediction_mode)) {
3874 is_predictor_built =
3875 fast_interp_search(cpi, x, mi_row, mi_col, bsize);
3876 }
3877 if (!is_predictor_built) {
3878 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL((void*)0), bsize, 0,
3879 av1_num_planes(cm) - 1);
3880 }
3881 if (mbmi->motion_mode == OBMC_CAUSAL)
3882 av1_build_obmc_inter_predictors_sb(cm, xd);
3883
3884 av1_subtract_plane(x, bsize, 0);
3885 if (txfm_params->tx_mode_search_type == TX_MODE_SELECT &&
3886 !xd->lossless[mbmi->segment_id]) {
3887 av1_pick_recursive_tx_size_type_yrd(cpi, x, &rd_stats_y, bsize,
3888 INT64_MAX(9223372036854775807L));
3889 assert(rd_stats_y.rate != INT_MAX)((void) sizeof ((rd_stats_y.rate != 2147483647) ? 1 : 0), __extension__
({ if (rd_stats_y.rate != 2147483647) ; else __assert_fail (
"rd_stats_y.rate != INT_MAX", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 3889, __extension__ __PRETTY_FUNCTION__); }))
;
3890 } else {
3891 av1_pick_uniform_tx_size_type_yrd(cpi, x, &rd_stats_y, bsize,
3892 INT64_MAX(9223372036854775807L));
3893 memset(mbmi->inter_tx_size, mbmi->tx_size,
3894 sizeof(mbmi->inter_tx_size));
3895 for (int i = 0; i < xd->height * xd->width; ++i)
3896 set_blk_skip(txfm_info->blk_skip, 0, i, rd_stats_y.skip_txfm);
3897 }
3898 } else {
3899 av1_pick_uniform_tx_size_type_yrd(cpi, x, &rd_stats_y, bsize,
3900 INT64_MAX(9223372036854775807L));
3901 }
3902
3903 if (num_planes > 1) {
3904 av1_txfm_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX(9223372036854775807L));
3905 } else {
3906 av1_init_rd_stats(&rd_stats_uv);
3907 }
3908
3909 const int comp_pred = mbmi->ref_frame[1] > INTRA_FRAME;
3910
3911 const ModeCosts *mode_costs = &x->mode_costs;
3912 if (is_inter_mode(mbmi->mode) &&
3913 (!cpi->oxcf.algo_cfg.sharpness || !comp_pred) &&
3914 RDCOST(x->rdmult,((((((int64_t)(mode_costs->skip_txfm_cost[skip_ctx][0] + rd_stats_y
.rate + rd_stats_uv.rate)) * (x->rdmult)) + (((1 << (
9)) >> 1))) >> (9)) + (((rd_stats_y.dist + rd_stats_uv
.dist)) * (1 << 7)))
3915 mode_costs->skip_txfm_cost[skip_ctx][0] + rd_stats_y.rate +((((((int64_t)(mode_costs->skip_txfm_cost[skip_ctx][0] + rd_stats_y
.rate + rd_stats_uv.rate)) * (x->rdmult)) + (((1 << (
9)) >> 1))) >> (9)) + (((rd_stats_y.dist + rd_stats_uv
.dist)) * (1 << 7)))
3916 rd_stats_uv.rate,((((((int64_t)(mode_costs->skip_txfm_cost[skip_ctx][0] + rd_stats_y
.rate + rd_stats_uv.rate)) * (x->rdmult)) + (((1 << (
9)) >> 1))) >> (9)) + (((rd_stats_y.dist + rd_stats_uv
.dist)) * (1 << 7)))
3917 (rd_stats_y.dist + rd_stats_uv.dist))((((((int64_t)(mode_costs->skip_txfm_cost[skip_ctx][0] + rd_stats_y
.rate + rd_stats_uv.rate)) * (x->rdmult)) + (((1 << (
9)) >> 1))) >> (9)) + (((rd_stats_y.dist + rd_stats_uv
.dist)) * (1 << 7)))
>
3918 RDCOST(x->rdmult, mode_costs->skip_txfm_cost[skip_ctx][1],((((((int64_t)(mode_costs->skip_txfm_cost[skip_ctx][1])) *
(x->rdmult)) + (((1 << (9)) >> 1))) >> (
9)) + (((rd_stats_y.sse + rd_stats_uv.sse)) * (1 << 7))
)
3919 (rd_stats_y.sse + rd_stats_uv.sse))((((((int64_t)(mode_costs->skip_txfm_cost[skip_ctx][1])) *
(x->rdmult)) + (((1 << (9)) >> 1))) >> (
9)) + (((rd_stats_y.sse + rd_stats_uv.sse)) * (1 << 7))
)
) {
3920 skip_blk = 1;
3921 rd_stats_y.rate = mode_costs->skip_txfm_cost[skip_ctx][1];
3922 rd_stats_uv.rate = 0;
3923 rd_stats_y.dist = rd_stats_y.sse;
3924 rd_stats_uv.dist = rd_stats_uv.sse;
3925 } else {
3926 skip_blk = 0;
3927 rd_stats_y.rate += mode_costs->skip_txfm_cost[skip_ctx][0];
3928 }
3929 int this_rate = rd_stats.rate + rd_stats_y.rate + rd_stats_uv.rate -
3930 winner_rate_y - winner_rate_uv;
3931 int64_t this_rd =
3932 RDCOST(x->rdmult, this_rate, (rd_stats_y.dist + rd_stats_uv.dist))((((((int64_t)(this_rate)) * (x->rdmult)) + (((1 << (
9)) >> 1))) >> (9)) + (((rd_stats_y.dist + rd_stats_uv
.dist)) * (1 << 7)))
;
3933 if (best_rd > this_rd) {
3934 *best_mbmode = *mbmi;
3935 *best_mode_index = winner_mode_index;
3936 av1_copy_array(ctx->blk_skip, txfm_info->blk_skip, ctx->num_4x4_blk)do { ((void) sizeof ((sizeof(*(ctx->blk_skip)) == sizeof(*
(txfm_info->blk_skip))) ? 1 : 0), __extension__ ({ if (sizeof
(*(ctx->blk_skip)) == sizeof(*(txfm_info->blk_skip))) ;
else __assert_fail ("sizeof(*(ctx->blk_skip)) == sizeof(*(txfm_info->blk_skip))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3936
, __extension__ __PRETTY_FUNCTION__); })); memcpy(ctx->blk_skip
, txfm_info->blk_skip, ctx->num_4x4_blk * sizeof(*(txfm_info
->blk_skip))); } while (0)
;
3937 av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk)do { ((void) sizeof ((sizeof(*(ctx->tx_type_map)) == sizeof
(*(xd->tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof
(*(ctx->tx_type_map)) == sizeof(*(xd->tx_type_map))) ; else
__assert_fail ("sizeof(*(ctx->tx_type_map)) == sizeof(*(xd->tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 3937
, __extension__ __PRETTY_FUNCTION__); })); memcpy(ctx->tx_type_map
, xd->tx_type_map, ctx->num_4x4_blk * sizeof(*(xd->tx_type_map
))); } while (0)
;
3938 rd_cost->rate = this_rate;
3939 rd_cost->dist = rd_stats_y.dist + rd_stats_uv.dist;
3940 rd_cost->sse = rd_stats_y.sse + rd_stats_uv.sse;
3941 rd_cost->rdcost = this_rd;
3942 best_rd = this_rd;
3943 *best_skip2 = skip_blk;
3944 }
3945 }
3946 }
3947}
3948
3949/*!\cond */
3950typedef struct {
3951 // Mask for each reference frame, specifying which prediction modes to NOT try
3952 // during search.
3953 uint32_t pred_modes[REF_FRAMES];
3954 // If ref_combo[i][j + 1] is true, do NOT try prediction using combination of
3955 // reference frames (i, j).
3956 // Note: indexing with 'j + 1' is due to the fact that 2nd reference can be -1
3957 // (NONE_FRAME).
3958 bool_Bool ref_combo[REF_FRAMES][REF_FRAMES + 1];
3959} mode_skip_mask_t;
3960/*!\endcond */
3961
3962// Update 'ref_combo' mask to disable given 'ref' in single and compound modes.
3963static inline void disable_reference(
3964 MV_REFERENCE_FRAME ref, bool_Bool ref_combo[REF_FRAMES][REF_FRAMES + 1]) {
3965 for (MV_REFERENCE_FRAME ref2 = NONE_FRAME; ref2 < REF_FRAMES; ++ref2) {
3966 ref_combo[ref][ref2 + 1] = true1;
3967 }
3968}
3969
3970// Update 'ref_combo' mask to disable all inter references except ALTREF.
3971static inline void disable_inter_references_except_altref(
3972 bool_Bool ref_combo[REF_FRAMES][REF_FRAMES + 1]) {
3973 disable_reference(LAST_FRAME, ref_combo);
3974 disable_reference(LAST2_FRAME, ref_combo);
3975 disable_reference(LAST3_FRAME, ref_combo);
3976 disable_reference(GOLDEN_FRAME, ref_combo);
3977 disable_reference(BWDREF_FRAME, ref_combo);
3978 disable_reference(ALTREF2_FRAME, ref_combo);
3979}
3980
3981static const MV_REFERENCE_FRAME reduced_ref_combos[][2] = {
3982 { LAST_FRAME, NONE_FRAME }, { ALTREF_FRAME, NONE_FRAME },
3983 { LAST_FRAME, ALTREF_FRAME }, { GOLDEN_FRAME, NONE_FRAME },
3984 { INTRA_FRAME, NONE_FRAME }, { GOLDEN_FRAME, ALTREF_FRAME },
3985 { LAST_FRAME, GOLDEN_FRAME }, { LAST_FRAME, INTRA_FRAME },
3986 { LAST_FRAME, BWDREF_FRAME }, { LAST_FRAME, LAST3_FRAME },
3987 { GOLDEN_FRAME, BWDREF_FRAME }, { GOLDEN_FRAME, INTRA_FRAME },
3988 { BWDREF_FRAME, NONE_FRAME }, { BWDREF_FRAME, ALTREF_FRAME },
3989 { ALTREF_FRAME, INTRA_FRAME }, { BWDREF_FRAME, INTRA_FRAME },
3990};
3991
3992typedef enum { REF_SET_FULL, REF_SET_REDUCED, REF_SET_REALTIME } REF_SET;
3993
3994static inline void default_skip_mask(mode_skip_mask_t *mask, REF_SET ref_set) {
3995 if (ref_set == REF_SET_FULL) {
3996 // Everything available by default.
3997 memset(mask, 0, sizeof(*mask));
3998 } else {
3999 // All modes available by default.
4000 memset(mask->pred_modes, 0, sizeof(mask->pred_modes));
4001 // All references disabled first.
4002 for (MV_REFERENCE_FRAME ref1 = INTRA_FRAME; ref1 < REF_FRAMES; ++ref1) {
4003 for (MV_REFERENCE_FRAME ref2 = NONE_FRAME; ref2 < REF_FRAMES; ++ref2) {
4004 mask->ref_combo[ref1][ref2 + 1] = true1;
4005 }
4006 }
4007 const MV_REFERENCE_FRAME(*ref_set_combos)[2];
4008 int num_ref_combos;
4009
4010 // Then enable reduced set of references explicitly.
4011 switch (ref_set) {
4012 case REF_SET_REDUCED:
4013 ref_set_combos = reduced_ref_combos;
4014 num_ref_combos =
4015 (int)sizeof(reduced_ref_combos) / sizeof(reduced_ref_combos[0]);
4016 break;
4017 case REF_SET_REALTIME:
4018 ref_set_combos = real_time_ref_combos;
4019 num_ref_combos =
4020 (int)sizeof(real_time_ref_combos) / sizeof(real_time_ref_combos[0]);
4021 break;
4022 default: assert(0)((void) sizeof ((0) ? 1 : 0), __extension__ ({ if (0) ; else __assert_fail
("0", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 4022, __extension__ __PRETTY_FUNCTION__); }))
; num_ref_combos = 0;
4023 }
4024
4025 for (int i = 0; i < num_ref_combos; ++i) {
4026 const MV_REFERENCE_FRAME *const this_combo = ref_set_combos[i];
4027 mask->ref_combo[this_combo[0]][this_combo[1] + 1] = false0;
4028 }
4029 }
4030}
4031
4032static inline void init_mode_skip_mask(mode_skip_mask_t *mask,
4033 const AV1_COMP *cpi, MACROBLOCK *x,
4034 BLOCK_SIZE bsize) {
4035 const AV1_COMMON *const cm = &cpi->common;
4036 const struct segmentation *const seg = &cm->seg;
4037 MACROBLOCKD *const xd = &x->e_mbd;
4038 MB_MODE_INFO *const mbmi = xd->mi[0];
4039 unsigned char segment_id = mbmi->segment_id;
4040 const SPEED_FEATURES *const sf = &cpi->sf;
4041 const INTER_MODE_SPEED_FEATURES *const inter_sf = &sf->inter_sf;
4042 REF_SET ref_set = REF_SET_FULL;
4043
4044 if (sf->rt_sf.use_real_time_ref_set)
4045 ref_set = REF_SET_REALTIME;
4046 else if (cpi->oxcf.ref_frm_cfg.enable_reduced_reference_set)
4047 ref_set = REF_SET_REDUCED;
4048
4049 default_skip_mask(mask, ref_set);
4050
4051 int min_pred_mv_sad = INT_MAX2147483647;
4052 MV_REFERENCE_FRAME ref_frame;
4053 if (ref_set == REF_SET_REALTIME) {
4054 // For real-time encoding, we only look at a subset of ref frames. So the
4055 // threshold for pruning should be computed from this subset as well.
4056 const int num_rt_refs =
4057 sizeof(real_time_ref_combos) / sizeof(*real_time_ref_combos);
4058 for (int r_idx = 0; r_idx < num_rt_refs; r_idx++) {
4059 const MV_REFERENCE_FRAME ref = real_time_ref_combos[r_idx][0];
4060 if (ref != INTRA_FRAME) {
4061 min_pred_mv_sad = AOMMIN(min_pred_mv_sad, x->pred_mv_sad[ref])(((min_pred_mv_sad) < (x->pred_mv_sad[ref])) ? (min_pred_mv_sad
) : (x->pred_mv_sad[ref]))
;
4062 }
4063 }
4064 } else {
4065 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame)
4066 min_pred_mv_sad = AOMMIN(min_pred_mv_sad, x->pred_mv_sad[ref_frame])(((min_pred_mv_sad) < (x->pred_mv_sad[ref_frame])) ? (min_pred_mv_sad
) : (x->pred_mv_sad[ref_frame]))
;
4067 }
4068
4069 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
4070 if (!(cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame])) {
4071 // Skip checking missing reference in both single and compound reference
4072 // modes.
4073 disable_reference(ref_frame, mask->ref_combo);
4074 } else {
4075 // Skip fixed mv modes for poor references
4076 if ((x->pred_mv_sad[ref_frame] >> 2) > min_pred_mv_sad) {
4077 mask->pred_modes[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
4078 }
4079 }
4080 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
4081 get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
4082 // Reference not used for the segment.
4083 disable_reference(ref_frame, mask->ref_combo);
4084 }
4085 }
4086 // Note: We use the following drop-out only if the SEG_LVL_REF_FRAME feature
4087 // is disabled for this segment. This is to prevent the possibility that we
4088 // end up unable to pick any mode.
4089 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
4090 // Only consider GLOBALMV/ALTREF_FRAME for alt ref frame,
4091 // unless ARNR filtering is enabled in which case we want
4092 // an unfiltered alternative. We allow near/nearest as well
4093 // because they may result in zero-zero MVs but be cheaper.
4094 if (cpi->rc.is_src_frame_alt_ref &&
4095 (cpi->oxcf.algo_cfg.arnr_max_frames == 0)) {
4096 disable_inter_references_except_altref(mask->ref_combo);
4097
4098 mask->pred_modes[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
4099 const MV_REFERENCE_FRAME tmp_ref_frames[2] = { ALTREF_FRAME, NONE_FRAME };
4100 int_mv near_mv, nearest_mv, global_mv;
4101 get_this_mv(&nearest_mv, NEARESTMV, 0, 0, 0, tmp_ref_frames,
4102 &x->mbmi_ext);
4103 get_this_mv(&near_mv, NEARMV, 0, 0, 0, tmp_ref_frames, &x->mbmi_ext);
4104 get_this_mv(&global_mv, GLOBALMV, 0, 0, 0, tmp_ref_frames, &x->mbmi_ext);
4105
4106 if (near_mv.as_int != global_mv.as_int)
4107 mask->pred_modes[ALTREF_FRAME] |= (1 << NEARMV);
4108 if (nearest_mv.as_int != global_mv.as_int)
4109 mask->pred_modes[ALTREF_FRAME] |= (1 << NEARESTMV);
4110 }
4111 }
4112
4113 if (cpi->rc.is_src_frame_alt_ref) {
4114 if (inter_sf->alt_ref_search_fp &&
4115 (cpi->ref_frame_flags & av1_ref_frame_flag_list[ALTREF_FRAME])) {
4116 mask->pred_modes[ALTREF_FRAME] = 0;
4117 disable_inter_references_except_altref(mask->ref_combo);
4118 disable_reference(INTRA_FRAME, mask->ref_combo);
4119 }
4120 }
4121
4122 if (inter_sf->alt_ref_search_fp) {
4123 if (!cm->show_frame && x->best_pred_mv_sad[0] < INT_MAX2147483647) {
4124 int sad_thresh = x->best_pred_mv_sad[0] + (x->best_pred_mv_sad[0] >> 3);
4125 // Conservatively skip the modes w.r.t. BWDREF, ALTREF2 and ALTREF, if
4126 // those are past frames
4127 MV_REFERENCE_FRAME start_frame =
4128 inter_sf->alt_ref_search_fp == 1 ? ALTREF2_FRAME : BWDREF_FRAME;
4129 for (ref_frame = start_frame; ref_frame <= ALTREF_FRAME; ref_frame++) {
4130 if (cpi->ref_frame_dist_info.ref_relative_dist[ref_frame - LAST_FRAME] <
4131 0) {
4132 // Prune inter modes when relative dist of ALTREF2 and ALTREF is close
4133 // to the relative dist of LAST_FRAME.
4134 if (inter_sf->alt_ref_search_fp == 1 &&
4135 (abs(cpi->ref_frame_dist_info
4136 .ref_relative_dist[ref_frame - LAST_FRAME]) >
4137 1.5 * abs(cpi->ref_frame_dist_info
4138 .ref_relative_dist[LAST_FRAME - LAST_FRAME]))) {
4139 continue;
4140 }
4141 if (x->pred_mv_sad[ref_frame] > sad_thresh)
4142 mask->pred_modes[ref_frame] |= INTER_ALL;
4143 }
4144 }
4145 }
4146 }
4147
4148 if (sf->rt_sf.prune_inter_modes_wrt_gf_arf_based_on_sad) {
4149 if (x->best_pred_mv_sad[0] < INT_MAX2147483647) {
4150 int sad_thresh = x->best_pred_mv_sad[0] + (x->best_pred_mv_sad[0] >> 1);
4151 const int prune_ref_list[2] = { GOLDEN_FRAME, ALTREF_FRAME };
4152
4153 // Conservatively skip the modes w.r.t. GOLDEN and ALTREF references
4154 for (int ref_idx = 0; ref_idx < 2; ref_idx++) {
4155 ref_frame = prune_ref_list[ref_idx];
4156 if (x->pred_mv_sad[ref_frame] > sad_thresh)
4157 mask->pred_modes[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
4158 }
4159 }
4160 }
4161
4162 if (bsize > sf->part_sf.max_intra_bsize) {
4163 disable_reference(INTRA_FRAME, mask->ref_combo);
4164 }
4165
4166 if (!cpi->oxcf.tool_cfg.enable_global_motion) {
4167 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
4168 mask->pred_modes[ref_frame] |= (1 << GLOBALMV);
4169 mask->pred_modes[ref_frame] |= (1 << GLOBAL_GLOBALMV);
4170 }
4171 }
4172
4173 mask->pred_modes[INTRA_FRAME] |=
4174 ~(uint32_t)sf->intra_sf.intra_y_mode_mask[max_txsize_lookup[bsize]];
4175
4176 // Prune reference frames which are not the closest to the current
4177 // frame and with large pred_mv_sad.
4178 if (inter_sf->prune_single_ref) {
4179 assert(inter_sf->prune_single_ref > 0 && inter_sf->prune_single_ref < 3)((void) sizeof ((inter_sf->prune_single_ref > 0 &&
inter_sf->prune_single_ref < 3) ? 1 : 0), __extension__
({ if (inter_sf->prune_single_ref > 0 && inter_sf
->prune_single_ref < 3) ; else __assert_fail ("inter_sf->prune_single_ref > 0 && inter_sf->prune_single_ref < 3"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 4179
, __extension__ __PRETTY_FUNCTION__); }))
;
4180 const double prune_threshes[2] = { 1.20, 1.05 };
4181
4182 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
4183 const RefFrameDistanceInfo *const ref_frame_dist_info =
4184 &cpi->ref_frame_dist_info;
4185 const int is_closest_ref =
4186 (ref_frame == ref_frame_dist_info->nearest_past_ref) ||
4187 (ref_frame == ref_frame_dist_info->nearest_future_ref);
4188
4189 if (!is_closest_ref) {
4190 const int dir =
4191 (ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME] < 0)
4192 ? 0
4193 : 1;
4194 if (x->best_pred_mv_sad[dir] < INT_MAX2147483647 &&
4195 x->pred_mv_sad[ref_frame] >
4196 prune_threshes[inter_sf->prune_single_ref - 1] *
4197 x->best_pred_mv_sad[dir])
4198 mask->pred_modes[ref_frame] |= INTER_SINGLE_ALL;
4199 }
4200 }
4201 }
4202}
4203
4204static inline void init_neighbor_pred_buf(const OBMCBuffer *const obmc_buffer,
4205 HandleInterModeArgs *const args,
4206 int is_hbd) {
4207 if (is_hbd) {
4208 const int len = sizeof(uint16_t);
4209 args->above_pred_buf[0] = CONVERT_TO_BYTEPTR(obmc_buffer->above_pred)((uint8_t *)(((uintptr_t)(obmc_buffer->above_pred)) >>
1))
;
4210 args->above_pred_buf[1] = CONVERT_TO_BYTEPTR(obmc_buffer->above_pred +((uint8_t *)(((uintptr_t)(obmc_buffer->above_pred + (((1 <<
7) * (1 << 7)) >> 1) * len)) >> 1))
4211 (MAX_SB_SQUARE >> 1) * len)((uint8_t *)(((uintptr_t)(obmc_buffer->above_pred + (((1 <<
7) * (1 << 7)) >> 1) * len)) >> 1))
;
4212 args->above_pred_buf[2] =
4213 CONVERT_TO_BYTEPTR(obmc_buffer->above_pred + MAX_SB_SQUARE * len)((uint8_t *)(((uintptr_t)(obmc_buffer->above_pred + ((1 <<
7) * (1 << 7)) * len)) >> 1))
;
4214 args->left_pred_buf[0] = CONVERT_TO_BYTEPTR(obmc_buffer->left_pred)((uint8_t *)(((uintptr_t)(obmc_buffer->left_pred)) >>
1))
;
4215 args->left_pred_buf[1] =
4216 CONVERT_TO_BYTEPTR(obmc_buffer->left_pred + (MAX_SB_SQUARE >> 1) * len)((uint8_t *)(((uintptr_t)(obmc_buffer->left_pred + (((1 <<
7) * (1 << 7)) >> 1) * len)) >> 1))
;
4217 args->left_pred_buf[2] =
4218 CONVERT_TO_BYTEPTR(obmc_buffer->left_pred + MAX_SB_SQUARE * len)((uint8_t *)(((uintptr_t)(obmc_buffer->left_pred + ((1 <<
7) * (1 << 7)) * len)) >> 1))
;
4219 } else {
4220 args->above_pred_buf[0] = obmc_buffer->above_pred;
4221 args->above_pred_buf[1] = obmc_buffer->above_pred + (MAX_SB_SQUARE((1 << 7) * (1 << 7)) >> 1);
4222 args->above_pred_buf[2] = obmc_buffer->above_pred + MAX_SB_SQUARE((1 << 7) * (1 << 7));
4223 args->left_pred_buf[0] = obmc_buffer->left_pred;
4224 args->left_pred_buf[1] = obmc_buffer->left_pred + (MAX_SB_SQUARE((1 << 7) * (1 << 7)) >> 1);
4225 args->left_pred_buf[2] = obmc_buffer->left_pred + MAX_SB_SQUARE((1 << 7) * (1 << 7));
4226 }
4227}
4228
4229static inline int prune_ref_frame(const AV1_COMP *cpi, const MACROBLOCK *x,
4230 MV_REFERENCE_FRAME ref_frame) {
4231 const AV1_COMMON *const cm = &cpi->common;
4232 MV_REFERENCE_FRAME rf[2];
4233 av1_set_ref_frame(rf, ref_frame);
4234
4235 if ((cpi->prune_ref_frame_mask >> ref_frame) & 1) return 1;
4236
4237 if (prune_ref_by_selective_ref_frame(cpi, x, rf,
4238 cm->cur_frame->ref_display_order_hint)) {
4239 return 1;
4240 }
4241
4242 return 0;
4243}
4244
4245static inline int is_ref_frame_used_by_compound_ref(int ref_frame,
4246 int skip_ref_frame_mask) {
4247 for (int r = ALTREF_FRAME + 1; r < MODE_CTX_REF_FRAMES(REF_FRAMES + (FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS)); ++r) {
4248 if (!(skip_ref_frame_mask & (1 << r))) {
4249 const MV_REFERENCE_FRAME *rf = ref_frame_map[r - REF_FRAMES];
4250 if (rf[0] == ref_frame || rf[1] == ref_frame) {
4251 return 1;
4252 }
4253 }
4254 }
4255 return 0;
4256}
4257
4258static inline int is_ref_frame_used_in_cache(MV_REFERENCE_FRAME ref_frame,
4259 const MB_MODE_INFO *mi_cache) {
4260 if (!mi_cache) {
4261 return 0;
4262 }
4263
4264 if (ref_frame < REF_FRAMES) {
4265 return (ref_frame == mi_cache->ref_frame[0] ||
4266 ref_frame == mi_cache->ref_frame[1]);
4267 }
4268
4269 // if we are here, then the current mode is compound.
4270 MV_REFERENCE_FRAME cached_ref_type = av1_ref_frame_type(mi_cache->ref_frame);
4271 return ref_frame == cached_ref_type;
4272}
4273
4274// Please add/modify parameter setting in this function, making it consistent
4275// and easy to read and maintain.
4276static inline void set_params_rd_pick_inter_mode(
4277 const AV1_COMP *cpi, MACROBLOCK *x, HandleInterModeArgs *args,
4278 BLOCK_SIZE bsize, mode_skip_mask_t *mode_skip_mask, int skip_ref_frame_mask,
4279 unsigned int *ref_costs_single, unsigned int (*ref_costs_comp)[REF_FRAMES],
4280 struct buf_2d (*yv12_mb)[MAX_MB_PLANE3]) {
4281 const AV1_COMMON *const cm = &cpi->common;
4282 MACROBLOCKD *const xd = &x->e_mbd;
4283 MB_MODE_INFO *const mbmi = xd->mi[0];
4284 MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
4285 unsigned char segment_id = mbmi->segment_id;
4286
4287 init_neighbor_pred_buf(&x->obmc_buffer, args, is_cur_buf_hbd(&x->e_mbd));
4288 av1_collect_neighbors_ref_counts(xd);
4289 estimate_ref_frame_costs(cm, xd, &x->mode_costs, segment_id, ref_costs_single,
4290 ref_costs_comp);
4291
4292 const int mi_row = xd->mi_row;
4293 const int mi_col = xd->mi_col;
4294 x->best_pred_mv_sad[0] = INT_MAX2147483647;
4295 x->best_pred_mv_sad[1] = INT_MAX2147483647;
4296
4297 for (MV_REFERENCE_FRAME ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME;
4298 ++ref_frame) {
4299 x->pred_mv_sad[ref_frame] = INT_MAX2147483647;
4300 mbmi_ext->mode_context[ref_frame] = 0;
4301 mbmi_ext->ref_mv_count[ref_frame] = UINT8_MAX(255);
4302 if (cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
4303 // Skip the ref frame if the mask says skip and the ref is not used by
4304 // compound ref.
4305 if (skip_ref_frame_mask & (1 << ref_frame) &&
4306 !is_ref_frame_used_by_compound_ref(ref_frame, skip_ref_frame_mask) &&
4307 !is_ref_frame_used_in_cache(ref_frame, x->mb_mode_cache)) {
4308 continue;
4309 }
4310 assert(get_ref_frame_yv12_buf(cm, ref_frame) != NULL)((void) sizeof ((get_ref_frame_yv12_buf(cm, ref_frame) != ((void
*)0)) ? 1 : 0), __extension__ ({ if (get_ref_frame_yv12_buf(cm
, ref_frame) != ((void*)0)) ; else __assert_fail ("get_ref_frame_yv12_buf(cm, ref_frame) != NULL"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 4310
, __extension__ __PRETTY_FUNCTION__); }))
;
4311 setup_buffer_ref_mvs_inter(cpi, x, ref_frame, bsize, yv12_mb);
4312 }
4313 if (cpi->sf.inter_sf.alt_ref_search_fp ||
4314 cpi->sf.inter_sf.prune_single_ref ||
4315 cpi->sf.rt_sf.prune_inter_modes_wrt_gf_arf_based_on_sad) {
4316 // Store the best pred_mv_sad across all past frames
4317 if (cpi->ref_frame_dist_info.ref_relative_dist[ref_frame - LAST_FRAME] <
4318 0)
4319 x->best_pred_mv_sad[0] =
4320 AOMMIN(x->best_pred_mv_sad[0], x->pred_mv_sad[ref_frame])(((x->best_pred_mv_sad[0]) < (x->pred_mv_sad[ref_frame
])) ? (x->best_pred_mv_sad[0]) : (x->pred_mv_sad[ref_frame
]))
;
4321 else
4322 // Store the best pred_mv_sad across all future frames
4323 x->best_pred_mv_sad[1] =
4324 AOMMIN(x->best_pred_mv_sad[1], x->pred_mv_sad[ref_frame])(((x->best_pred_mv_sad[1]) < (x->pred_mv_sad[ref_frame
])) ? (x->best_pred_mv_sad[1]) : (x->pred_mv_sad[ref_frame
]))
;
4325 }
4326 }
4327
4328 if (!cpi->sf.rt_sf.use_real_time_ref_set && is_comp_ref_allowed(bsize)) {
4329 // No second reference on RT ref set, so no need to initialize
4330 for (MV_REFERENCE_FRAME ref_frame = EXTREF_FRAME;
4331 ref_frame < MODE_CTX_REF_FRAMES(REF_FRAMES + (FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS)); ++ref_frame) {
4332 mbmi_ext->mode_context[ref_frame] = 0;
4333 mbmi_ext->ref_mv_count[ref_frame] = UINT8_MAX(255);
4334 const MV_REFERENCE_FRAME *rf = ref_frame_map[ref_frame - REF_FRAMES];
4335 if (!((cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[0]]) &&
4336 (cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[1]]))) {
4337 continue;
4338 }
4339
4340 if (skip_ref_frame_mask & (1 << ref_frame) &&
4341 !is_ref_frame_used_in_cache(ref_frame, x->mb_mode_cache)) {
4342 continue;
4343 }
4344 // Ref mv list population is not required, when compound references are
4345 // pruned.
4346 if (prune_ref_frame(cpi, x, ref_frame)) continue;
4347
4348 av1_find_mv_refs(cm, xd, mbmi, ref_frame, mbmi_ext->ref_mv_count,
4349 xd->ref_mv_stack, xd->weight, NULL((void*)0), mbmi_ext->global_mvs,
4350 mbmi_ext->mode_context);
4351 // TODO(Ravi): Populate mbmi_ext->ref_mv_stack[ref_frame][4] and
4352 // mbmi_ext->weight[ref_frame][4] inside av1_find_mv_refs.
4353 av1_copy_usable_ref_mv_stack_and_weight(xd, mbmi_ext, ref_frame);
4354 }
4355 }
4356
4357 av1_count_overlappable_neighbors(cm, xd);
4358 const FRAME_UPDATE_TYPE update_type =
4359 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
4360 int use_actual_frame_probs = 1;
4361 int prune_obmc;
4362#if CONFIG_FPMT_TEST0
4363 use_actual_frame_probs =
4364 (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) ? 0 : 1;
4365 if (!use_actual_frame_probs) {
4366 prune_obmc = cpi->ppi->temp_frame_probs.obmc_probs[update_type][bsize] <
4367 cpi->sf.inter_sf.prune_obmc_prob_thresh;
4368 }
4369#endif
4370 if (use_actual_frame_probs) {
4371 prune_obmc = cpi->ppi->frame_probs.obmc_probs[update_type][bsize] <
4372 cpi->sf.inter_sf.prune_obmc_prob_thresh;
4373 }
4374 if (cpi->oxcf.motion_mode_cfg.enable_obmc && !prune_obmc) {
4375 if (check_num_overlappable_neighbors(mbmi) &&
4376 is_motion_variation_allowed_bsize(bsize)) {
4377 int dst_width1[MAX_MB_PLANE3] = { MAX_SB_SIZE(1 << 7), MAX_SB_SIZE(1 << 7), MAX_SB_SIZE(1 << 7) };
4378 int dst_width2[MAX_MB_PLANE3] = { MAX_SB_SIZE(1 << 7) >> 1, MAX_SB_SIZE(1 << 7) >> 1,
4379 MAX_SB_SIZE(1 << 7) >> 1 };
4380 int dst_height1[MAX_MB_PLANE3] = { MAX_SB_SIZE(1 << 7) >> 1, MAX_SB_SIZE(1 << 7) >> 1,
4381 MAX_SB_SIZE(1 << 7) >> 1 };
4382 int dst_height2[MAX_MB_PLANE3] = { MAX_SB_SIZE(1 << 7), MAX_SB_SIZE(1 << 7), MAX_SB_SIZE(1 << 7) };
4383 av1_build_prediction_by_above_preds(cm, xd, args->above_pred_buf,
4384 dst_width1, dst_height1,
4385 args->above_pred_stride);
4386 av1_build_prediction_by_left_preds(cm, xd, args->left_pred_buf,
4387 dst_width2, dst_height2,
4388 args->left_pred_stride);
4389 const int num_planes = av1_num_planes(cm);
4390 av1_setup_dst_planes(xd->plane, bsize, &cm->cur_frame->buf, mi_row,
4391 mi_col, 0, num_planes);
4392 calc_target_weighted_pred(
4393 cm, x, xd, args->above_pred_buf[0], args->above_pred_stride[0],
4394 args->left_pred_buf[0], args->left_pred_stride[0]);
4395 }
4396 }
4397
4398 init_mode_skip_mask(mode_skip_mask, cpi, x, bsize);
4399
4400 // Set params for mode evaluation
4401 set_mode_eval_params(cpi, x, MODE_EVAL);
4402
4403 x->comp_rd_stats_idx = 0;
4404
4405 for (int idx = 0; idx < REF_FRAMES; idx++) {
4406 args->best_single_sse_in_refs[idx] = INT32_MAX(2147483647);
4407 }
4408}
4409
4410static inline void init_single_inter_mode_search_state(
4411 InterModeSearchState *search_state) {
4412 for (int dir = 0; dir < 2; ++dir) {
4413 for (int mode = 0; mode < SINGLE_INTER_MODE_NUM; ++mode) {
4414 for (int ref_frame = 0; ref_frame < FWD_REFS; ++ref_frame) {
4415 SingleInterModeState *state;
4416
4417 state = &search_state->single_state[dir][mode][ref_frame];
4418 state->ref_frame = NONE_FRAME;
4419 state->rd = INT64_MAX(9223372036854775807L);
4420
4421 state = &search_state->single_state_modelled[dir][mode][ref_frame];
4422 state->ref_frame = NONE_FRAME;
4423 state->rd = INT64_MAX(9223372036854775807L);
4424
4425 search_state->single_rd_order[dir][mode][ref_frame] = NONE_FRAME;
4426 }
4427 }
4428 }
4429
4430 for (int ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame) {
4431 search_state->best_single_rd[ref_frame] = INT64_MAX(9223372036854775807L);
4432 search_state->best_single_mode[ref_frame] = PRED_MODE_INVALID;
4433 }
4434 av1_zero(search_state->single_state_cnt)memset(&(search_state->single_state_cnt), 0, sizeof(search_state
->single_state_cnt))
;
4435 av1_zero(search_state->single_state_modelled_cnt)memset(&(search_state->single_state_modelled_cnt), 0, sizeof
(search_state->single_state_modelled_cnt))
;
4436}
4437
4438static inline void init_inter_mode_search_state(
4439 InterModeSearchState *search_state, const AV1_COMP *cpi,
4440 const MACROBLOCK *x, BLOCK_SIZE bsize, int64_t best_rd_so_far) {
4441 init_intra_mode_search_state(&search_state->intra_search_state);
4442 av1_invalid_rd_stats(&search_state->best_y_rdcost);
4443
4444 search_state->best_rd = best_rd_so_far;
4445 search_state->best_skip_rd[0] = INT64_MAX(9223372036854775807L);
4446 search_state->best_skip_rd[1] = INT64_MAX(9223372036854775807L);
4447
4448 av1_zero(search_state->best_mbmode)memset(&(search_state->best_mbmode), 0, sizeof(search_state
->best_mbmode))
;
4449
4450 search_state->best_rate_y = INT_MAX2147483647;
4451
4452 search_state->best_rate_uv = INT_MAX2147483647;
4453
4454 search_state->best_mode_skippable = 0;
4455
4456 search_state->best_skip2 = 0;
4457
4458 search_state->best_mode_index = THR_INVALID;
4459
4460 const MACROBLOCKD *const xd = &x->e_mbd;
4461 const MB_MODE_INFO *const mbmi = xd->mi[0];
4462 const unsigned char segment_id = mbmi->segment_id;
4463
4464 search_state->num_available_refs = 0;
4465 memset(search_state->dist_refs, -1, sizeof(search_state->dist_refs));
4466 memset(search_state->dist_order_refs, -1,
4467 sizeof(search_state->dist_order_refs));
4468
4469 for (int i = 0; i <= LAST_NEW_MV_INDEX6; ++i)
4470 search_state->mode_threshold[i] = 0;
4471 const int *const rd_threshes = cpi->rd.threshes[segment_id][bsize];
4472 for (int i = LAST_NEW_MV_INDEX6 + 1; i < SINGLE_REF_MODE_END; ++i)
4473 search_state->mode_threshold[i] =
4474 ((int64_t)rd_threshes[i] * x->thresh_freq_fact[bsize][i]) >>
4475 RD_THRESH_FAC_FRAC_BITS(5);
4476
4477 search_state->best_intra_rd = INT64_MAX(9223372036854775807L);
4478
4479 search_state->best_pred_sse = UINT_MAX(2147483647 *2U +1U);
4480
4481 av1_zero(search_state->single_newmv)memset(&(search_state->single_newmv), 0, sizeof(search_state
->single_newmv))
;
4482 av1_zero(search_state->single_newmv_rate)memset(&(search_state->single_newmv_rate), 0, sizeof(search_state
->single_newmv_rate))
;
4483 av1_zero(search_state->single_newmv_valid)memset(&(search_state->single_newmv_valid), 0, sizeof(
search_state->single_newmv_valid))
;
4484 for (int i = SINGLE_INTER_MODE_START; i < SINGLE_INTER_MODE_END; ++i) {
4485 for (int j = 0; j < MAX_REF_MV_SEARCH3; ++j) {
4486 for (int ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame) {
4487 search_state->modelled_rd[i][j][ref_frame] = INT64_MAX(9223372036854775807L);
4488 search_state->simple_rd[i][j][ref_frame] = INT64_MAX(9223372036854775807L);
4489 }
4490 }
4491 }
4492
4493 for (int i = 0; i < REFERENCE_MODES; ++i) {
4494 search_state->best_pred_rd[i] = INT64_MAX(9223372036854775807L);
4495 }
4496
4497 if (cpi->common.current_frame.reference_mode != SINGLE_REFERENCE) {
4498 for (int i = SINGLE_REF_MODE_END; i < THR_INTER_MODE_END; ++i)
4499 search_state->mode_threshold[i] =
4500 ((int64_t)rd_threshes[i] * x->thresh_freq_fact[bsize][i]) >>
4501 RD_THRESH_FAC_FRAC_BITS(5);
4502
4503 for (int i = COMP_INTER_MODE_START; i < COMP_INTER_MODE_END; ++i) {
4504 for (int j = 0; j < MAX_REF_MV_SEARCH3; ++j) {
4505 for (int ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame) {
4506 search_state->modelled_rd[i][j][ref_frame] = INT64_MAX(9223372036854775807L);
4507 search_state->simple_rd[i][j][ref_frame] = INT64_MAX(9223372036854775807L);
4508 }
4509 }
4510 }
4511
4512 init_single_inter_mode_search_state(search_state);
4513 }
4514}
4515
4516static bool_Bool mask_says_skip(const mode_skip_mask_t *mode_skip_mask,
4517 const MV_REFERENCE_FRAME *ref_frame,
4518 const PREDICTION_MODE this_mode) {
4519 if (mode_skip_mask->pred_modes[ref_frame[0]] & (1 << this_mode)) {
4520 return true1;
4521 }
4522
4523 return mode_skip_mask->ref_combo[ref_frame[0]][ref_frame[1] + 1];
4524}
4525
4526static int inter_mode_compatible_skip(const AV1_COMP *cpi, const MACROBLOCK *x,
4527 BLOCK_SIZE bsize,
4528 PREDICTION_MODE curr_mode,
4529 const MV_REFERENCE_FRAME *ref_frames) {
4530 const int comp_pred = ref_frames[1] > INTRA_FRAME;
4531 if (comp_pred) {
4532 if (!is_comp_ref_allowed(bsize)) return 1;
4533 if (!(cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frames[1]])) {
4534 return 1;
4535 }
4536
4537 const AV1_COMMON *const cm = &cpi->common;
4538 if (frame_is_intra_only(cm)) return 1;
4539
4540 const CurrentFrame *const current_frame = &cm->current_frame;
4541 if (current_frame->reference_mode == SINGLE_REFERENCE) return 1;
4542
4543 const struct segmentation *const seg = &cm->seg;
4544 const unsigned char segment_id = x->e_mbd.mi[0]->segment_id;
4545 // Do not allow compound prediction if the segment level reference frame
4546 // feature is in use as in this case there can only be one reference.
4547 if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) return 1;
4548 }
4549
4550 if (ref_frames[0] > INTRA_FRAME && ref_frames[1] == INTRA_FRAME) {
4551 // Mode must be compatible
4552 if (!is_interintra_allowed_bsize(bsize)) return 1;
4553 if (!is_interintra_allowed_mode(curr_mode)) return 1;
4554 }
4555
4556 return 0;
4557}
4558
4559static int fetch_picked_ref_frames_mask(const MACROBLOCK *const x,
4560 BLOCK_SIZE bsize, int mib_size) {
4561 const int sb_size_mask = mib_size - 1;
4562 const MACROBLOCKD *const xd = &x->e_mbd;
4563 const int mi_row = xd->mi_row;
4564 const int mi_col = xd->mi_col;
4565 const int mi_row_in_sb = mi_row & sb_size_mask;
4566 const int mi_col_in_sb = mi_col & sb_size_mask;
4567 const int mi_w = mi_size_wide[bsize];
4568 const int mi_h = mi_size_high[bsize];
4569 int picked_ref_frames_mask = 0;
4570 for (int i = mi_row_in_sb; i < mi_row_in_sb + mi_h; ++i) {
4571 for (int j = mi_col_in_sb; j < mi_col_in_sb + mi_w; ++j) {
4572 picked_ref_frames_mask |= x->picked_ref_frames_mask[i * 32 + j];
4573 }
4574 }
4575 return picked_ref_frames_mask;
4576}
4577
4578// Check if reference frame pair of the current block matches with the given
4579// block.
4580static inline int match_ref_frame_pair(const MB_MODE_INFO *mbmi,
4581 const MV_REFERENCE_FRAME *ref_frames) {
4582 return ((ref_frames[0] == mbmi->ref_frame[0]) &&
4583 (ref_frames[1] == mbmi->ref_frame[1]));
4584}
4585
4586// Case 1: return 0, means don't skip this mode
4587// Case 2: return 1, means skip this mode completely
4588// Case 3: return 2, means skip compound only, but still try single motion modes
4589static int inter_mode_search_order_independent_skip(
4590 const AV1_COMP *cpi, const MACROBLOCK *x, mode_skip_mask_t *mode_skip_mask,
4591 InterModeSearchState *search_state, int skip_ref_frame_mask,
4592 PREDICTION_MODE mode, const MV_REFERENCE_FRAME *ref_frame) {
4593 if (mask_says_skip(mode_skip_mask, ref_frame, mode)) {
8
Assuming the condition is false
9
Taking false branch
4594 return 1;
4595 }
4596
4597 const int ref_type = av1_ref_frame_type(ref_frame);
10
Calling 'av1_ref_frame_type'
13
Returning from 'av1_ref_frame_type'
14
'ref_type' initialized here
4598 if (!cpi->sf.rt_sf.use_real_time_ref_set)
15
Assuming field 'use_real_time_ref_set' is not equal to 0
4599 if (prune_ref_frame(cpi, x, ref_type)) return 1;
4600
4601 // This is only used in motion vector unit test.
4602 if (cpi->oxcf.unit_test_cfg.motion_vector_unit_test &&
16
Assuming field 'motion_vector_unit_test' is 0
4603 ref_frame[0] == INTRA_FRAME)
4604 return 1;
4605
4606 const AV1_COMMON *const cm = &cpi->common;
4607 if (skip_repeated_mv(cm, x, mode, ref_frame, search_state)) {
17
Taking false branch
4608 return 1;
4609 }
4610
4611 // Reuse the prediction mode in cache
4612 if (x->use_mb_mode_cache) {
18
Assuming field 'use_mb_mode_cache' is 0
19
Taking false branch
4613 const MB_MODE_INFO *cached_mi = x->mb_mode_cache;
4614 const PREDICTION_MODE cached_mode = cached_mi->mode;
4615 const MV_REFERENCE_FRAME *cached_frame = cached_mi->ref_frame;
4616 const int cached_mode_is_single = cached_frame[1] <= INTRA_FRAME;
4617
4618 // If the cached mode is intra, then we just need to match the mode.
4619 if (is_mode_intra(cached_mode) && mode != cached_mode) {
4620 return 1;
4621 }
4622
4623 // If the cached mode is single inter mode, then we match the mode and
4624 // reference frame.
4625 if (cached_mode_is_single) {
4626 if (mode != cached_mode || ref_frame[0] != cached_frame[0]) {
4627 return 1;
4628 }
4629 } else {
4630 // If the cached mode is compound, then we need to consider several cases.
4631 const int mode_is_single = ref_frame[1] <= INTRA_FRAME;
4632 if (mode_is_single) {
4633 // If the mode is single, we know the modes can't match. But we might
4634 // still want to search it if compound mode depends on the current mode.
4635 int skip_motion_mode_only = 0;
4636 if (cached_mode == NEW_NEARMV || cached_mode == NEW_NEARESTMV) {
4637 skip_motion_mode_only = (ref_frame[0] == cached_frame[0]);
4638 } else if (cached_mode == NEAR_NEWMV || cached_mode == NEAREST_NEWMV) {
4639 skip_motion_mode_only = (ref_frame[0] == cached_frame[1]);
4640 } else if (cached_mode == NEW_NEWMV) {
4641 skip_motion_mode_only = (ref_frame[0] == cached_frame[0] ||
4642 ref_frame[0] == cached_frame[1]);
4643 }
4644
4645 return 1 + skip_motion_mode_only;
4646 } else {
4647 // If both modes are compound, then everything must match.
4648 if (mode != cached_mode || ref_frame[0] != cached_frame[0] ||
4649 ref_frame[1] != cached_frame[1]) {
4650 return 1;
4651 }
4652 }
4653 }
4654 }
4655
4656 const MB_MODE_INFO *const mbmi = x->e_mbd.mi[0];
4657 // If no valid mode has been found so far in PARTITION_NONE when finding a
4658 // valid partition is required, do not skip mode.
4659 if (search_state->best_rd == INT64_MAX(9223372036854775807L) && mbmi->partition == PARTITION_NONE &&
20
Assuming field 'best_rd' is not equal to INT64_MAX
4660 x->must_find_valid_partition)
4661 return 0;
4662
4663 const SPEED_FEATURES *const sf = &cpi->sf;
4664 // Prune NEARMV and NEAR_NEARMV based on q index and neighbor's reference
4665 // frames
4666 if (sf->inter_sf.prune_nearmv_using_neighbors &&
21
Assuming field 'prune_nearmv_using_neighbors' is 0
4667 (mode == NEAR_NEARMV || mode == NEARMV)) {
4668 const MACROBLOCKD *const xd = &x->e_mbd;
4669 if (search_state->best_rd != INT64_MAX(9223372036854775807L) && xd->left_available &&
4670 xd->up_available) {
4671 const int thresholds[PRUNE_NEARMV_MAX][3] = { { 1, 0, 0 },
4672 { 1, 1, 0 },
4673 { 2, 1, 0 } };
4674 const int qindex_sub_range = x->qindex * 3 / QINDEX_RANGE(255 - 0 + 1);
4675
4676 assert(sf->inter_sf.prune_nearmv_using_neighbors <= PRUNE_NEARMV_MAX &&((void) sizeof ((sf->inter_sf.prune_nearmv_using_neighbors
<= PRUNE_NEARMV_MAX && qindex_sub_range < 3) ?
1 : 0), __extension__ ({ if (sf->inter_sf.prune_nearmv_using_neighbors
<= PRUNE_NEARMV_MAX && qindex_sub_range < 3) ;
else __assert_fail ("sf->inter_sf.prune_nearmv_using_neighbors <= PRUNE_NEARMV_MAX && qindex_sub_range < 3"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 4677
, __extension__ __PRETTY_FUNCTION__); }))
4677 qindex_sub_range < 3)((void) sizeof ((sf->inter_sf.prune_nearmv_using_neighbors
<= PRUNE_NEARMV_MAX && qindex_sub_range < 3) ?
1 : 0), __extension__ ({ if (sf->inter_sf.prune_nearmv_using_neighbors
<= PRUNE_NEARMV_MAX && qindex_sub_range < 3) ;
else __assert_fail ("sf->inter_sf.prune_nearmv_using_neighbors <= PRUNE_NEARMV_MAX && qindex_sub_range < 3"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 4677
, __extension__ __PRETTY_FUNCTION__); }))
;
4678 const int num_ref_frame_pair_match_thresh =
4679 thresholds[sf->inter_sf.prune_nearmv_using_neighbors - 1]
4680 [qindex_sub_range];
4681
4682 assert(num_ref_frame_pair_match_thresh <= 2 &&((void) sizeof ((num_ref_frame_pair_match_thresh <= 2 &&
num_ref_frame_pair_match_thresh >= 0) ? 1 : 0), __extension__
({ if (num_ref_frame_pair_match_thresh <= 2 && num_ref_frame_pair_match_thresh
>= 0) ; else __assert_fail ("num_ref_frame_pair_match_thresh <= 2 && num_ref_frame_pair_match_thresh >= 0"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 4683
, __extension__ __PRETTY_FUNCTION__); }))
4683 num_ref_frame_pair_match_thresh >= 0)((void) sizeof ((num_ref_frame_pair_match_thresh <= 2 &&
num_ref_frame_pair_match_thresh >= 0) ? 1 : 0), __extension__
({ if (num_ref_frame_pair_match_thresh <= 2 && num_ref_frame_pair_match_thresh
>= 0) ; else __assert_fail ("num_ref_frame_pair_match_thresh <= 2 && num_ref_frame_pair_match_thresh >= 0"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 4683
, __extension__ __PRETTY_FUNCTION__); }))
;
4684 int num_ref_frame_pair_match = 0;
4685
4686 num_ref_frame_pair_match = match_ref_frame_pair(xd->left_mbmi, ref_frame);
4687 num_ref_frame_pair_match +=
4688 match_ref_frame_pair(xd->above_mbmi, ref_frame);
4689
4690 // Pruning based on ref frame pair match with neighbors.
4691 if (num_ref_frame_pair_match < num_ref_frame_pair_match_thresh) return 1;
4692 }
4693 }
4694
4695 int skip_motion_mode = 0;
4696 if (mbmi->partition != PARTITION_NONE) {
22
Assuming field 'partition' is not equal to PARTITION_NONE
23
Taking true branch
4697 int skip_ref = skip_ref_frame_mask & (1 << ref_type);
24
The result of left shift is undefined because the right operand is negative
4698 if (ref_type <= ALTREF_FRAME && skip_ref) {
4699 // Since the compound ref modes depends on the motion estimation result of
4700 // two single ref modes (best mv of single ref modes as the start point),
4701 // if current single ref mode is marked skip, we need to check if it will
4702 // be used in compound ref modes.
4703 if (is_ref_frame_used_by_compound_ref(ref_type, skip_ref_frame_mask)) {
4704 // Found a not skipped compound ref mode which contains current
4705 // single ref. So this single ref can't be skipped completely
4706 // Just skip its motion mode search, still try its simple
4707 // transition mode.
4708 skip_motion_mode = 1;
4709 skip_ref = 0;
4710 }
4711 }
4712 // If we are reusing the prediction from cache, and the current frame is
4713 // required by the cache, then we cannot prune it.
4714 if (is_ref_frame_used_in_cache(ref_type, x->mb_mode_cache)) {
4715 skip_ref = 0;
4716 // If the cache only needs the current reference type for compound
4717 // prediction, then we can skip motion mode search.
4718 skip_motion_mode = (ref_type <= ALTREF_FRAME &&
4719 x->mb_mode_cache->ref_frame[1] > INTRA_FRAME);
4720 }
4721 if (skip_ref) return 1;
4722 }
4723
4724 if (ref_frame[0] == INTRA_FRAME) {
4725 if (mode != DC_PRED) {
4726 // Disable intra modes other than DC_PRED for blocks with low variance
4727 // Threshold for intra skipping based on source variance
4728 // TODO(debargha): Specialize the threshold for super block sizes
4729 const unsigned int skip_intra_var_thresh = 64;
4730 if ((sf->rt_sf.mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
4731 x->source_variance < skip_intra_var_thresh)
4732 return 1;
4733 }
4734 }
4735
4736 if (skip_motion_mode) return 2;
4737
4738 return 0;
4739}
4740
4741static inline void init_mbmi(MB_MODE_INFO *mbmi, PREDICTION_MODE curr_mode,
4742 const MV_REFERENCE_FRAME *ref_frames,
4743 const AV1_COMMON *cm) {
4744 PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
4745 mbmi->ref_mv_idx = 0;
4746 mbmi->mode = curr_mode;
4747 mbmi->uv_mode = UV_DC_PRED;
4748 mbmi->ref_frame[0] = ref_frames[0];
4749 mbmi->ref_frame[1] = ref_frames[1];
4750 pmi->palette_size[0] = 0;
4751 pmi->palette_size[1] = 0;
4752 mbmi->filter_intra_mode_info.use_filter_intra = 0;
4753 mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
4754 mbmi->motion_mode = SIMPLE_TRANSLATION;
4755 mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
4756 set_default_interp_filters(mbmi, cm->features.interp_filter);
4757}
4758
4759static inline void collect_single_states(MACROBLOCK *x,
4760 InterModeSearchState *search_state,
4761 const MB_MODE_INFO *const mbmi) {
4762 int i, j;
4763 const MV_REFERENCE_FRAME ref_frame = mbmi->ref_frame[0];
4764 const PREDICTION_MODE this_mode = mbmi->mode;
4765 const int dir = ref_frame <= GOLDEN_FRAME ? 0 : 1;
4766 const int mode_offset = INTER_OFFSET(this_mode)((this_mode)-NEARESTMV);
4767 const int ref_set = get_drl_refmv_count(x, mbmi->ref_frame, this_mode);
4768
4769 // Simple rd
4770 int64_t simple_rd = search_state->simple_rd[this_mode][0][ref_frame];
4771 for (int ref_mv_idx = 1; ref_mv_idx < ref_set; ++ref_mv_idx) {
4772 const int64_t rd =
4773 search_state->simple_rd[this_mode][ref_mv_idx][ref_frame];
4774 if (rd < simple_rd) simple_rd = rd;
4775 }
4776
4777 // Insertion sort of single_state
4778 const SingleInterModeState this_state_s = { simple_rd, ref_frame, 1 };
4779 SingleInterModeState *state_s = search_state->single_state[dir][mode_offset];
4780 i = search_state->single_state_cnt[dir][mode_offset];
4781 for (j = i; j > 0 && state_s[j - 1].rd > this_state_s.rd; --j)
4782 state_s[j] = state_s[j - 1];
4783 state_s[j] = this_state_s;
4784 search_state->single_state_cnt[dir][mode_offset]++;
4785
4786 // Modelled rd
4787 int64_t modelled_rd = search_state->modelled_rd[this_mode][0][ref_frame];
4788 for (int ref_mv_idx = 1; ref_mv_idx < ref_set; ++ref_mv_idx) {
4789 const int64_t rd =
4790 search_state->modelled_rd[this_mode][ref_mv_idx][ref_frame];
4791 if (rd < modelled_rd) modelled_rd = rd;
4792 }
4793
4794 // Insertion sort of single_state_modelled
4795 const SingleInterModeState this_state_m = { modelled_rd, ref_frame, 1 };
4796 SingleInterModeState *state_m =
4797 search_state->single_state_modelled[dir][mode_offset];
4798 i = search_state->single_state_modelled_cnt[dir][mode_offset];
4799 for (j = i; j > 0 && state_m[j - 1].rd > this_state_m.rd; --j)
4800 state_m[j] = state_m[j - 1];
4801 state_m[j] = this_state_m;
4802 search_state->single_state_modelled_cnt[dir][mode_offset]++;
4803}
4804
4805static inline void analyze_single_states(const AV1_COMP *cpi,
4806 InterModeSearchState *search_state) {
4807 const int prune_level = cpi->sf.inter_sf.prune_comp_search_by_single_result;
4808 assert(prune_level >= 1)((void) sizeof ((prune_level >= 1) ? 1 : 0), __extension__
({ if (prune_level >= 1) ; else __assert_fail ("prune_level >= 1"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 4808
, __extension__ __PRETTY_FUNCTION__); }))
;
4809 int i, j, dir, mode;
4810
4811 for (dir = 0; dir < 2; ++dir) {
4812 int64_t best_rd;
4813 SingleInterModeState(*state)[FWD_REFS];
4814 const int prune_factor = prune_level >= 2 ? 6 : 5;
4815
4816 // Use the best rd of GLOBALMV or NEWMV to prune the unlikely
4817 // reference frames for all the modes (NEARESTMV and NEARMV may not
4818 // have same motion vectors). Always keep the best of each mode
4819 // because it might form the best possible combination with other mode.
4820 state = search_state->single_state[dir];
4821 best_rd = AOMMIN(state[INTER_OFFSET(NEWMV)][0].rd,(((state[((NEWMV)-NEARESTMV)][0].rd) < (state[((GLOBALMV)-
NEARESTMV)][0].rd)) ? (state[((NEWMV)-NEARESTMV)][0].rd) : (state
[((GLOBALMV)-NEARESTMV)][0].rd))
4822 state[INTER_OFFSET(GLOBALMV)][0].rd)(((state[((NEWMV)-NEARESTMV)][0].rd) < (state[((GLOBALMV)-
NEARESTMV)][0].rd)) ? (state[((NEWMV)-NEARESTMV)][0].rd) : (state
[((GLOBALMV)-NEARESTMV)][0].rd))
;
4823 for (mode = 0; mode < SINGLE_INTER_MODE_NUM; ++mode) {
4824 for (i = 1; i < search_state->single_state_cnt[dir][mode]; ++i) {
4825 if (state[mode][i].rd != INT64_MAX(9223372036854775807L) &&
4826 (state[mode][i].rd >> 3) * prune_factor > best_rd) {
4827 state[mode][i].valid = 0;
4828 }
4829 }
4830 }
4831
4832 state = search_state->single_state_modelled[dir];
4833 best_rd = AOMMIN(state[INTER_OFFSET(NEWMV)][0].rd,(((state[((NEWMV)-NEARESTMV)][0].rd) < (state[((GLOBALMV)-
NEARESTMV)][0].rd)) ? (state[((NEWMV)-NEARESTMV)][0].rd) : (state
[((GLOBALMV)-NEARESTMV)][0].rd))
4834 state[INTER_OFFSET(GLOBALMV)][0].rd)(((state[((NEWMV)-NEARESTMV)][0].rd) < (state[((GLOBALMV)-
NEARESTMV)][0].rd)) ? (state[((NEWMV)-NEARESTMV)][0].rd) : (state
[((GLOBALMV)-NEARESTMV)][0].rd))
;
4835 for (mode = 0; mode < SINGLE_INTER_MODE_NUM; ++mode) {
4836 for (i = 1; i < search_state->single_state_modelled_cnt[dir][mode]; ++i) {
4837 if (state[mode][i].rd != INT64_MAX(9223372036854775807L) &&
4838 (state[mode][i].rd >> 3) * prune_factor > best_rd) {
4839 state[mode][i].valid = 0;
4840 }
4841 }
4842 }
4843 }
4844
4845 // Ordering by simple rd first, then by modelled rd
4846 for (dir = 0; dir < 2; ++dir) {
4847 for (mode = 0; mode < SINGLE_INTER_MODE_NUM; ++mode) {
4848 const int state_cnt_s = search_state->single_state_cnt[dir][mode];
4849 const int state_cnt_m =
4850 search_state->single_state_modelled_cnt[dir][mode];
4851 SingleInterModeState *state_s = search_state->single_state[dir][mode];
4852 SingleInterModeState *state_m =
4853 search_state->single_state_modelled[dir][mode];
4854 int count = 0;
4855 const int max_candidates = AOMMAX(state_cnt_s, state_cnt_m)(((state_cnt_s) > (state_cnt_m)) ? (state_cnt_s) : (state_cnt_m
))
;
4856 for (i = 0; i < state_cnt_s; ++i) {
4857 if (state_s[i].rd == INT64_MAX(9223372036854775807L)) break;
4858 if (state_s[i].valid) {
4859 search_state->single_rd_order[dir][mode][count++] =
4860 state_s[i].ref_frame;
4861 }
4862 }
4863 if (count >= max_candidates) continue;
4864
4865 for (i = 0; i < state_cnt_m && count < max_candidates; ++i) {
4866 if (state_m[i].rd == INT64_MAX(9223372036854775807L)) break;
4867 if (!state_m[i].valid) continue;
4868 const int ref_frame = state_m[i].ref_frame;
4869 int match = 0;
4870 // Check if existing already
4871 for (j = 0; j < count; ++j) {
4872 if (search_state->single_rd_order[dir][mode][j] == ref_frame) {
4873 match = 1;
4874 break;
4875 }
4876 }
4877 if (match) continue;
4878 // Check if this ref_frame is removed in simple rd
4879 int valid = 1;
4880 for (j = 0; j < state_cnt_s; ++j) {
4881 if (ref_frame == state_s[j].ref_frame) {
4882 valid = state_s[j].valid;
4883 break;
4884 }
4885 }
4886 if (valid) {
4887 search_state->single_rd_order[dir][mode][count++] = ref_frame;
4888 }
4889 }
4890 }
4891 }
4892}
4893
4894static int compound_skip_get_candidates(
4895 const AV1_COMP *cpi, const InterModeSearchState *search_state,
4896 const int dir, const PREDICTION_MODE mode) {
4897 const int mode_offset = INTER_OFFSET(mode)((mode)-NEARESTMV);
4898 const SingleInterModeState *state =
4899 search_state->single_state[dir][mode_offset];
4900 const SingleInterModeState *state_modelled =
4901 search_state->single_state_modelled[dir][mode_offset];
4902
4903 int max_candidates = 0;
4904 for (int i = 0; i < FWD_REFS; ++i) {
4905 if (search_state->single_rd_order[dir][mode_offset][i] == NONE_FRAME) break;
4906 max_candidates++;
4907 }
4908
4909 int candidates = max_candidates;
4910 if (cpi->sf.inter_sf.prune_comp_search_by_single_result >= 2) {
4911 candidates = AOMMIN(2, max_candidates)(((2) < (max_candidates)) ? (2) : (max_candidates));
4912 }
4913 if (cpi->sf.inter_sf.prune_comp_search_by_single_result >= 3) {
4914 if (state[0].rd != INT64_MAX(9223372036854775807L) && state_modelled[0].rd != INT64_MAX(9223372036854775807L) &&
4915 state[0].ref_frame == state_modelled[0].ref_frame)
4916 candidates = 1;
4917 if (mode == NEARMV || mode == GLOBALMV) candidates = 1;
4918 }
4919
4920 if (cpi->sf.inter_sf.prune_comp_search_by_single_result >= 4) {
4921 // Limit the number of candidates to 1 in each direction for compound
4922 // prediction
4923 candidates = AOMMIN(1, candidates)(((1) < (candidates)) ? (1) : (candidates));
4924 }
4925 return candidates;
4926}
4927
4928static int compound_skip_by_single_states(
4929 const AV1_COMP *cpi, const InterModeSearchState *search_state,
4930 const PREDICTION_MODE this_mode, const MV_REFERENCE_FRAME ref_frame,
4931 const MV_REFERENCE_FRAME second_ref_frame, const MACROBLOCK *x) {
4932 const MV_REFERENCE_FRAME refs[2] = { ref_frame, second_ref_frame };
4933 const int mode[2] = { compound_ref0_mode(this_mode),
4934 compound_ref1_mode(this_mode) };
4935 const int mode_offset[2] = { INTER_OFFSET(mode[0])((mode[0])-NEARESTMV), INTER_OFFSET(mode[1])((mode[1])-NEARESTMV) };
4936 const int mode_dir[2] = { refs[0] <= GOLDEN_FRAME ? 0 : 1,
4937 refs[1] <= GOLDEN_FRAME ? 0 : 1 };
4938 int ref_searched[2] = { 0, 0 };
4939 int ref_mv_match[2] = { 1, 1 };
4940 int i, j;
4941
4942 for (i = 0; i < 2; ++i) {
4943 const SingleInterModeState *state =
4944 search_state->single_state[mode_dir[i]][mode_offset[i]];
4945 const int state_cnt =
4946 search_state->single_state_cnt[mode_dir[i]][mode_offset[i]];
4947 for (j = 0; j < state_cnt; ++j) {
4948 if (state[j].ref_frame == refs[i]) {
4949 ref_searched[i] = 1;
4950 break;
4951 }
4952 }
4953 }
4954
4955 const int ref_set = get_drl_refmv_count(x, refs, this_mode);
4956 for (i = 0; i < 2; ++i) {
4957 if (!ref_searched[i] || (mode[i] != NEARESTMV && mode[i] != NEARMV)) {
4958 continue;
4959 }
4960 const MV_REFERENCE_FRAME single_refs[2] = { refs[i], NONE_FRAME };
4961 for (int ref_mv_idx = 0; ref_mv_idx < ref_set; ref_mv_idx++) {
4962 int_mv single_mv;
4963 int_mv comp_mv;
4964 get_this_mv(&single_mv, mode[i], 0, ref_mv_idx, 0, single_refs,
4965 &x->mbmi_ext);
4966 get_this_mv(&comp_mv, this_mode, i, ref_mv_idx, 0, refs, &x->mbmi_ext);
4967 if (single_mv.as_int != comp_mv.as_int) {
4968 ref_mv_match[i] = 0;
4969 break;
4970 }
4971 }
4972 }
4973
4974 for (i = 0; i < 2; ++i) {
4975 if (!ref_searched[i] || !ref_mv_match[i]) continue;
4976 const int candidates =
4977 compound_skip_get_candidates(cpi, search_state, mode_dir[i], mode[i]);
4978 const MV_REFERENCE_FRAME *ref_order =
4979 search_state->single_rd_order[mode_dir[i]][mode_offset[i]];
4980 int match = 0;
4981 for (j = 0; j < candidates; ++j) {
4982 if (refs[i] == ref_order[j]) {
4983 match = 1;
4984 break;
4985 }
4986 }
4987 if (!match) return 1;
4988 }
4989
4990 return 0;
4991}
4992
4993// Check if ref frames of current block matches with given block.
4994static inline void match_ref_frame(const MB_MODE_INFO *const mbmi,
4995 const MV_REFERENCE_FRAME *ref_frames,
4996 int *const is_ref_match) {
4997 if (is_inter_block(mbmi)) {
4998 is_ref_match[0] |= ref_frames[0] == mbmi->ref_frame[0];
4999 is_ref_match[1] |= ref_frames[1] == mbmi->ref_frame[0];
5000 if (has_second_ref(mbmi)) {
5001 is_ref_match[0] |= ref_frames[0] == mbmi->ref_frame[1];
5002 is_ref_match[1] |= ref_frames[1] == mbmi->ref_frame[1];
5003 }
5004 }
5005}
5006
5007// Prune compound mode using ref frames of neighbor blocks.
5008static inline int compound_skip_using_neighbor_refs(
5009 MACROBLOCKD *const xd, const PREDICTION_MODE this_mode,
5010 const MV_REFERENCE_FRAME *ref_frames, int prune_ext_comp_using_neighbors) {
5011 // Exclude non-extended compound modes from pruning
5012 if (this_mode == NEAREST_NEARESTMV || this_mode == NEAR_NEARMV ||
5013 this_mode == NEW_NEWMV || this_mode == GLOBAL_GLOBALMV)
5014 return 0;
5015
5016 if (prune_ext_comp_using_neighbors >= 3) return 1;
5017
5018 int is_ref_match[2] = { 0 }; // 0 - match for forward refs
5019 // 1 - match for backward refs
5020 // Check if ref frames of this block matches with left neighbor.
5021 if (xd->left_available)
5022 match_ref_frame(xd->left_mbmi, ref_frames, is_ref_match);
5023
5024 // Check if ref frames of this block matches with above neighbor.
5025 if (xd->up_available)
5026 match_ref_frame(xd->above_mbmi, ref_frames, is_ref_match);
5027
5028 // Combine ref frame match with neighbors in forward and backward refs.
5029 const int track_ref_match = is_ref_match[0] + is_ref_match[1];
5030
5031 // Pruning based on ref frame match with neighbors.
5032 if (track_ref_match >= prune_ext_comp_using_neighbors) return 0;
5033 return 1;
5034}
5035
5036// Update best single mode for the given reference frame based on simple rd.
5037static inline void update_best_single_mode(InterModeSearchState *search_state,
5038 const PREDICTION_MODE this_mode,
5039 const MV_REFERENCE_FRAME ref_frame,
5040 int64_t this_rd) {
5041 if (this_rd < search_state->best_single_rd[ref_frame]) {
5042 search_state->best_single_rd[ref_frame] = this_rd;
5043 search_state->best_single_mode[ref_frame] = this_mode;
5044 }
5045}
5046
5047// Prune compound mode using best single mode for the same reference.
5048static inline int skip_compound_using_best_single_mode_ref(
5049 const PREDICTION_MODE this_mode, const MV_REFERENCE_FRAME *ref_frames,
5050 const PREDICTION_MODE *best_single_mode,
5051 int prune_comp_using_best_single_mode_ref) {
5052 // Exclude non-extended compound modes from pruning
5053 if (this_mode == NEAREST_NEARESTMV || this_mode == NEAR_NEARMV ||
5054 this_mode == NEW_NEWMV || this_mode == GLOBAL_GLOBALMV)
5055 return 0;
5056
5057 assert(this_mode >= NEAREST_NEWMV && this_mode <= NEW_NEARMV)((void) sizeof ((this_mode >= NEAREST_NEWMV && this_mode
<= NEW_NEARMV) ? 1 : 0), __extension__ ({ if (this_mode >=
NEAREST_NEWMV && this_mode <= NEW_NEARMV) ; else __assert_fail
("this_mode >= NEAREST_NEWMV && this_mode <= NEW_NEARMV"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 5057
, __extension__ __PRETTY_FUNCTION__); }))
;
5058 const PREDICTION_MODE comp_mode_ref0 = compound_ref0_mode(this_mode);
5059 // Get ref frame direction corresponding to NEWMV
5060 // 0 - NEWMV corresponding to forward direction
5061 // 1 - NEWMV corresponding to backward direction
5062 const int newmv_dir = comp_mode_ref0 != NEWMV;
5063
5064 // Avoid pruning the compound mode when ref frame corresponding to NEWMV
5065 // have NEWMV as single mode winner.
5066 // Example: For an extended-compound mode,
5067 // {mode, {fwd_frame, bwd_frame}} = {NEAR_NEWMV, {LAST_FRAME, ALTREF_FRAME}}
5068 // - Ref frame corresponding to NEWMV is ALTREF_FRAME
5069 // - Avoid pruning this mode, if best single mode corresponding to ref frame
5070 // ALTREF_FRAME is NEWMV
5071 const PREDICTION_MODE single_mode = best_single_mode[ref_frames[newmv_dir]];
5072 if (single_mode == NEWMV) return 0;
5073
5074 // Avoid pruning the compound mode when best single mode is not available
5075 if (prune_comp_using_best_single_mode_ref == 1)
5076 if (single_mode == MB_MODE_COUNT) return 0;
5077 return 1;
5078}
5079
5080static int compare_int64(const void *a, const void *b) {
5081 int64_t a64 = *((int64_t *)a);
5082 int64_t b64 = *((int64_t *)b);
5083 if (a64 < b64) {
5084 return -1;
5085 } else if (a64 == b64) {
5086 return 0;
5087 } else {
5088 return 1;
5089 }
5090}
5091
5092static inline void update_search_state(
5093 InterModeSearchState *search_state, RD_STATS *best_rd_stats_dst,
5094 PICK_MODE_CONTEXT *ctx, const RD_STATS *new_best_rd_stats,
5095 const RD_STATS *new_best_rd_stats_y, const RD_STATS *new_best_rd_stats_uv,
5096 THR_MODES new_best_mode, const MACROBLOCK *x, int txfm_search_done) {
5097 const MACROBLOCKD *xd = &x->e_mbd;
5098 const MB_MODE_INFO *mbmi = xd->mi[0];
5099 const int skip_ctx = av1_get_skip_txfm_context(xd);
5100 const int skip_txfm =
5101 mbmi->skip_txfm && !is_mode_intra(av1_mode_defs[new_best_mode].mode);
5102 const TxfmSearchInfo *txfm_info = &x->txfm_search_info;
5103
5104 search_state->best_rd = new_best_rd_stats->rdcost;
5105 search_state->best_mode_index = new_best_mode;
5106 *best_rd_stats_dst = *new_best_rd_stats;
5107 search_state->best_mbmode = *mbmi;
5108 search_state->best_skip2 = skip_txfm;
5109 search_state->best_mode_skippable = new_best_rd_stats->skip_txfm;
5110 // When !txfm_search_done, new_best_rd_stats won't provide correct rate_y and
5111 // rate_uv because av1_txfm_search process is replaced by rd estimation.
5112 // Therefore, we should avoid updating best_rate_y and best_rate_uv here.
5113 // These two values will be updated when av1_txfm_search is called.
5114 if (txfm_search_done) {
5115 search_state->best_rate_y =
5116 new_best_rd_stats_y->rate +
5117 x->mode_costs.skip_txfm_cost[skip_ctx]
5118 [new_best_rd_stats->skip_txfm || skip_txfm];
5119 search_state->best_rate_uv = new_best_rd_stats_uv->rate;
5120 }
5121 search_state->best_y_rdcost = *new_best_rd_stats_y;
5122 memcpy(ctx->blk_skip, txfm_info->blk_skip,
5123 sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
5124 av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk)do { ((void) sizeof ((sizeof(*(ctx->tx_type_map)) == sizeof
(*(xd->tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof
(*(ctx->tx_type_map)) == sizeof(*(xd->tx_type_map))) ; else
__assert_fail ("sizeof(*(ctx->tx_type_map)) == sizeof(*(xd->tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 5124
, __extension__ __PRETTY_FUNCTION__); })); memcpy(ctx->tx_type_map
, xd->tx_type_map, ctx->num_4x4_blk * sizeof(*(xd->tx_type_map
))); } while (0)
;
5125}
5126
5127// Find the best RD for a reference frame (among single reference modes)
5128// and store +10% of it in the 0-th element in ref_frame_rd.
5129static inline void find_top_ref(int64_t ref_frame_rd[REF_FRAMES]) {
5130 assert(ref_frame_rd[0] == INT64_MAX)((void) sizeof ((ref_frame_rd[0] == (9223372036854775807L)) ?
1 : 0), __extension__ ({ if (ref_frame_rd[0] == (9223372036854775807L
)) ; else __assert_fail ("ref_frame_rd[0] == INT64_MAX", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 5130, __extension__ __PRETTY_FUNCTION__); }))
;
5131 int64_t ref_copy[REF_FRAMES - 1];
5132 memcpy(ref_copy, ref_frame_rd + 1,
5133 sizeof(ref_frame_rd[0]) * (REF_FRAMES - 1));
5134 qsort(ref_copy, REF_FRAMES - 1, sizeof(int64_t), compare_int64);
5135
5136 int64_t cutoff = ref_copy[0];
5137 // The cut-off is within 10% of the best.
5138 if (cutoff != INT64_MAX(9223372036854775807L)) {
5139 assert(cutoff < INT64_MAX / 200)((void) sizeof ((cutoff < (9223372036854775807L) / 200) ? 1
: 0), __extension__ ({ if (cutoff < (9223372036854775807L
) / 200) ; else __assert_fail ("cutoff < INT64_MAX / 200",
"/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 5139
, __extension__ __PRETTY_FUNCTION__); }))
;
5140 cutoff = (110 * cutoff) / 100;
5141 }
5142 ref_frame_rd[0] = cutoff;
5143}
5144
5145// Check if either frame is within the cutoff.
5146static inline bool_Bool in_single_ref_cutoff(int64_t ref_frame_rd[REF_FRAMES],
5147 MV_REFERENCE_FRAME frame1,
5148 MV_REFERENCE_FRAME frame2) {
5149 assert(frame2 > 0)((void) sizeof ((frame2 > 0) ? 1 : 0), __extension__ ({ if
(frame2 > 0) ; else __assert_fail ("frame2 > 0", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 5149, __extension__ __PRETTY_FUNCTION__); }))
;
5150 return ref_frame_rd[frame1] <= ref_frame_rd[0] ||
5151 ref_frame_rd[frame2] <= ref_frame_rd[0];
5152}
5153
5154static inline void evaluate_motion_mode_for_winner_candidates(
5155 const AV1_COMP *const cpi, MACROBLOCK *const x, RD_STATS *const rd_cost,
5156 HandleInterModeArgs *const args, TileDataEnc *const tile_data,
5157 PICK_MODE_CONTEXT *const ctx,
5158 struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE3],
5159 const motion_mode_best_st_candidate *const best_motion_mode_cands,
5160 int do_tx_search, const BLOCK_SIZE bsize, int64_t *const best_est_rd,
5161 InterModeSearchState *const search_state, int64_t *yrd) {
5162 const AV1_COMMON *const cm = &cpi->common;
5163 const int num_planes = av1_num_planes(cm);
5164 MACROBLOCKD *const xd = &x->e_mbd;
5165 MB_MODE_INFO *const mbmi = xd->mi[0];
5166 InterModesInfo *const inter_modes_info = x->inter_modes_info;
5167 const int num_best_cand = best_motion_mode_cands->num_motion_mode_cand;
5168
5169 for (int cand = 0; cand < num_best_cand; cand++) {
5170 RD_STATS rd_stats;
5171 RD_STATS rd_stats_y;
5172 RD_STATS rd_stats_uv;
5173 av1_init_rd_stats(&rd_stats);
5174 av1_init_rd_stats(&rd_stats_y);
5175 av1_init_rd_stats(&rd_stats_uv);
5176 int rate_mv;
5177
5178 rate_mv = best_motion_mode_cands->motion_mode_cand[cand].rate_mv;
5179 args->skip_motion_mode =
5180 best_motion_mode_cands->motion_mode_cand[cand].skip_motion_mode;
5181 *mbmi = best_motion_mode_cands->motion_mode_cand[cand].mbmi;
5182 rd_stats.rate =
5183 best_motion_mode_cands->motion_mode_cand[cand].rate2_nocoeff;
5184
5185 // Continue if the best candidate is compound.
5186 if (!is_inter_singleref_mode(mbmi->mode)) continue;
5187
5188 x->txfm_search_info.skip_txfm = 0;
5189 struct macroblockd_plane *pd = xd->plane;
5190 const BUFFER_SET orig_dst = {
5191 { pd[0].dst.buf, pd[1].dst.buf, pd[2].dst.buf },
5192 { pd[0].dst.stride, pd[1].dst.stride, pd[2].dst.stride },
5193 };
5194
5195 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5196 // Initialize motion mode to simple translation
5197 // Calculation of switchable rate depends on it.
5198 mbmi->motion_mode = 0;
5199 const int is_comp_pred = mbmi->ref_frame[1] > INTRA_FRAME;
5200 for (int i = 0; i < num_planes; i++) {
5201 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
5202 if (is_comp_pred) xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
5203 }
5204
5205 int64_t skip_rd[2] = { search_state->best_skip_rd[0],
5206 search_state->best_skip_rd[1] };
5207 int64_t this_yrd = INT64_MAX(9223372036854775807L);
5208 int64_t ret_value = motion_mode_rd(
5209 cpi, tile_data, x, bsize, &rd_stats, &rd_stats_y, &rd_stats_uv, args,
5210 search_state->best_rd, skip_rd, &rate_mv, &orig_dst, best_est_rd,
5211 do_tx_search, inter_modes_info, 1, &this_yrd);
5212
5213 if (ret_value != INT64_MAX(9223372036854775807L)) {
5214 rd_stats.rdcost = RDCOST(x->rdmult, rd_stats.rate, rd_stats.dist)((((((int64_t)(rd_stats.rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_stats.dist) * (1 <<
7)))
;
5215 const THR_MODES mode_enum = get_prediction_mode_idx(
5216 mbmi->mode, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5217 // Collect mode stats for multiwinner mode processing
5218 store_winner_mode_stats(
5219 &cpi->common, x, mbmi, &rd_stats, &rd_stats_y, &rd_stats_uv,
5220 mode_enum, NULL((void*)0), bsize, rd_stats.rdcost,
5221 cpi->sf.winner_mode_sf.multi_winner_mode_type, do_tx_search);
5222
5223 int64_t best_scaled_rd = search_state->best_rd;
5224 int64_t this_scaled_rd = rd_stats.rdcost;
5225 if (search_state->best_mode_index != THR_INVALID)
5226 increase_warp_mode_rd(&search_state->best_mbmode, mbmi, &best_scaled_rd,
5227 &this_scaled_rd,
5228 cpi->sf.inter_sf.bias_warp_mode_rd_scale_pct);
5229
5230 if (this_scaled_rd < best_scaled_rd) {
5231 *yrd = this_yrd;
5232 update_search_state(search_state, rd_cost, ctx, &rd_stats, &rd_stats_y,
5233 &rd_stats_uv, mode_enum, x, do_tx_search);
5234 if (do_tx_search) search_state->best_skip_rd[0] = skip_rd[0];
5235 }
5236 }
5237 }
5238}
5239
5240/*!\cond */
5241// Arguments for speed feature pruning of inter mode search
5242typedef struct {
5243 int *skip_motion_mode;
5244 mode_skip_mask_t *mode_skip_mask;
5245 InterModeSearchState *search_state;
5246 int skip_ref_frame_mask;
5247 int reach_first_comp_mode;
5248 int mode_thresh_mul_fact;
5249 int num_single_modes_processed;
5250 int prune_cpd_using_sr_stats_ready;
5251} InterModeSFArgs;
5252/*!\endcond */
5253
5254static int skip_inter_mode(AV1_COMP *cpi, MACROBLOCK *x, const BLOCK_SIZE bsize,
5255 int64_t *ref_frame_rd, int midx,
5256 InterModeSFArgs *args, int is_low_temp_var) {
5257 const SPEED_FEATURES *const sf = &cpi->sf;
5258 MACROBLOCKD *const xd = &x->e_mbd;
5259 // Get the actual prediction mode we are trying in this iteration
5260 const THR_MODES mode_enum = av1_default_mode_order[midx];
5261 const MODE_DEFINITION *mode_def = &av1_mode_defs[mode_enum];
5262 const PREDICTION_MODE this_mode = mode_def->mode;
5263 const MV_REFERENCE_FRAME *ref_frames = mode_def->ref_frame;
5264 const MV_REFERENCE_FRAME ref_frame = ref_frames[0];
5265 const MV_REFERENCE_FRAME second_ref_frame = ref_frames[1];
5266 const int comp_pred = second_ref_frame > INTRA_FRAME;
1
Assuming 'second_ref_frame' is <= INTRA_FRAME
5267
5268 if (ref_frame == INTRA_FRAME) return 1;
2
Assuming 'ref_frame' is not equal to INTRA_FRAME
3
Taking false branch
5269
5270 const FRAME_UPDATE_TYPE update_type =
5271 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
5272 if (sf->inter_sf.skip_arf_compound && update_type == ARF_UPDATE &&
4
Assuming field 'skip_arf_compound' is 0
5273 comp_pred) {
5274 return 1;
5275 }
5276
5277 // This is for real time encoding.
5278 if (is_low_temp_var && !comp_pred && ref_frame != LAST_FRAME &&
5
Assuming 'is_low_temp_var' is 0
5279 this_mode != NEARESTMV)
5280 return 1;
5281
5282 // Check if this mode should be skipped because it is incompatible with the
5283 // current frame
5284 if (inter_mode_compatible_skip(cpi, x, bsize, this_mode, ref_frames))
6
Taking false branch
5285 return 1;
5286 const int ret = inter_mode_search_order_independent_skip(
7
Calling 'inter_mode_search_order_independent_skip'
5287 cpi, x, args->mode_skip_mask, args->search_state,
5288 args->skip_ref_frame_mask, this_mode, mode_def->ref_frame);
5289 if (ret == 1) return 1;
5290 *(args->skip_motion_mode) = (ret == 2);
5291
5292 // We've reached the first compound prediction mode, get stats from the
5293 // single reference predictors to help with pruning.
5294 // Disable this pruning logic if interpolation filter search was skipped for
5295 // single prediction modes as it can result in aggressive pruning of compound
5296 // prediction modes due to the absence of modelled_rd populated by
5297 // av1_interpolation_filter_search().
5298 // TODO(Remya): Check the impact of the sf
5299 // 'prune_comp_search_by_single_result' if compound prediction modes are
5300 // enabled in future for REALTIME encode.
5301 if (!sf->interp_sf.skip_interp_filter_search &&
5302 sf->inter_sf.prune_comp_search_by_single_result > 0 && comp_pred &&
5303 args->reach_first_comp_mode == 0) {
5304 analyze_single_states(cpi, args->search_state);
5305 args->reach_first_comp_mode = 1;
5306 }
5307
5308 // Prune aggressively when best mode is skippable.
5309 int mul_fact = args->search_state->best_mode_skippable
5310 ? args->mode_thresh_mul_fact
5311 : (1 << MODE_THRESH_QBITS12);
5312 int64_t mode_threshold =
5313 (args->search_state->mode_threshold[mode_enum] * mul_fact) >>
5314 MODE_THRESH_QBITS12;
5315
5316 if (args->search_state->best_rd < mode_threshold) return 1;
5317
5318 // Skip this compound mode based on the RD results from the single prediction
5319 // modes
5320 if (!sf->interp_sf.skip_interp_filter_search &&
5321 sf->inter_sf.prune_comp_search_by_single_result > 0 && comp_pred) {
5322 if (compound_skip_by_single_states(cpi, args->search_state, this_mode,
5323 ref_frame, second_ref_frame, x))
5324 return 1;
5325 }
5326
5327 if (sf->inter_sf.prune_compound_using_single_ref && comp_pred) {
5328 // After we done with single reference modes, find the 2nd best RD
5329 // for a reference frame. Only search compound modes that have a reference
5330 // frame at least as good as the 2nd best.
5331 if (!args->prune_cpd_using_sr_stats_ready &&
5332 args->num_single_modes_processed == NUM_SINGLE_REF_MODES) {
5333 find_top_ref(ref_frame_rd);
5334 args->prune_cpd_using_sr_stats_ready = 1;
5335 }
5336 if (args->prune_cpd_using_sr_stats_ready &&
5337 !in_single_ref_cutoff(ref_frame_rd, ref_frame, second_ref_frame))
5338 return 1;
5339 }
5340
5341 // Skip NEW_NEARMV and NEAR_NEWMV extended compound modes
5342 if (sf->inter_sf.skip_ext_comp_nearmv_mode &&
5343 (this_mode == NEW_NEARMV || this_mode == NEAR_NEWMV)) {
5344 return 1;
5345 }
5346
5347 if (sf->inter_sf.prune_ext_comp_using_neighbors && comp_pred) {
5348 if (compound_skip_using_neighbor_refs(
5349 xd, this_mode, ref_frames,
5350 sf->inter_sf.prune_ext_comp_using_neighbors))
5351 return 1;
5352 }
5353
5354 if (sf->inter_sf.prune_comp_using_best_single_mode_ref && comp_pred) {
5355 if (skip_compound_using_best_single_mode_ref(
5356 this_mode, ref_frames, args->search_state->best_single_mode,
5357 sf->inter_sf.prune_comp_using_best_single_mode_ref))
5358 return 1;
5359 }
5360
5361 if (sf->inter_sf.prune_nearest_near_mv_using_refmv_weight && !comp_pred) {
5362 const int8_t ref_frame_type = av1_ref_frame_type(ref_frames);
5363 if (skip_nearest_near_mv_using_refmv_weight(
5364 x, this_mode, ref_frame_type,
5365 args->search_state->best_mbmode.mode)) {
5366 // Ensure the mode is pruned only when the current block has obtained a
5367 // valid inter mode.
5368 assert(is_inter_mode(args->search_state->best_mbmode.mode))((void) sizeof ((is_inter_mode(args->search_state->best_mbmode
.mode)) ? 1 : 0), __extension__ ({ if (is_inter_mode(args->
search_state->best_mbmode.mode)) ; else __assert_fail ("is_inter_mode(args->search_state->best_mbmode.mode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 5368
, __extension__ __PRETTY_FUNCTION__); }))
;
5369 return 1;
5370 }
5371 }
5372
5373 if (sf->rt_sf.prune_inter_modes_with_golden_ref &&
5374 ref_frame == GOLDEN_FRAME && !comp_pred) {
5375 const int subgop_size = AOMMIN(cpi->ppi->gf_group.size, FIXED_GF_INTERVAL)(((cpi->ppi->gf_group.size) < (16)) ? (cpi->ppi->
gf_group.size) : (16))
;
5376 if (cpi->rc.frames_since_golden > (subgop_size >> 2) &&
5377 args->search_state->best_mbmode.ref_frame[0] != GOLDEN_FRAME) {
5378 if ((bsize > BLOCK_16X16 && this_mode == NEWMV) || this_mode == NEARMV)
5379 return 1;
5380 }
5381 }
5382
5383 return 0;
5384}
5385
5386static void record_best_compound(REFERENCE_MODE reference_mode,
5387 RD_STATS *rd_stats, int comp_pred, int rdmult,
5388 InterModeSearchState *search_state,
5389 int compmode_cost) {
5390 int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
5391
5392 if (reference_mode == REFERENCE_MODE_SELECT) {
5393 single_rate = rd_stats->rate - compmode_cost;
5394 hybrid_rate = rd_stats->rate;
5395 } else {
5396 single_rate = rd_stats->rate;
5397 hybrid_rate = rd_stats->rate + compmode_cost;
5398 }
5399
5400 single_rd = RDCOST(rdmult, single_rate, rd_stats->dist)((((((int64_t)(single_rate)) * (rdmult)) + (((1 << (9))
>> 1))) >> (9)) + ((rd_stats->dist) * (1 <<
7)))
;
5401 hybrid_rd = RDCOST(rdmult, hybrid_rate, rd_stats->dist)((((((int64_t)(hybrid_rate)) * (rdmult)) + (((1 << (9))
>> 1))) >> (9)) + ((rd_stats->dist) * (1 <<
7)))
;
5402
5403 if (!comp_pred) {
5404 if (single_rd < search_state->best_pred_rd[SINGLE_REFERENCE])
5405 search_state->best_pred_rd[SINGLE_REFERENCE] = single_rd;
5406 } else {
5407 if (single_rd < search_state->best_pred_rd[COMPOUND_REFERENCE])
5408 search_state->best_pred_rd[COMPOUND_REFERENCE] = single_rd;
5409 }
5410 if (hybrid_rd < search_state->best_pred_rd[REFERENCE_MODE_SELECT])
5411 search_state->best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
5412}
5413
5414// Does a transform search over a list of the best inter mode candidates.
5415// This is called if the original mode search computed an RD estimate
5416// for the transform search rather than doing a full search.
5417static void tx_search_best_inter_candidates(
5418 AV1_COMP *cpi, TileDataEnc *tile_data, MACROBLOCK *x,
5419 int64_t best_rd_so_far, BLOCK_SIZE bsize,
5420 struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE3], int mi_row, int mi_col,
5421 InterModeSearchState *search_state, RD_STATS *rd_cost,
5422 PICK_MODE_CONTEXT *ctx, int64_t *yrd) {
5423 AV1_COMMON *const cm = &cpi->common;
5424 MACROBLOCKD *const xd = &x->e_mbd;
5425 TxfmSearchInfo *txfm_info = &x->txfm_search_info;
5426 const ModeCosts *mode_costs = &x->mode_costs;
5427 const int num_planes = av1_num_planes(cm);
5428 const int skip_ctx = av1_get_skip_txfm_context(xd);
5429 MB_MODE_INFO *const mbmi = xd->mi[0];
5430 InterModesInfo *inter_modes_info = x->inter_modes_info;
5431 inter_modes_info_sort(inter_modes_info, inter_modes_info->rd_idx_pair_arr);
5432 search_state->best_rd = best_rd_so_far;
5433 search_state->best_mode_index = THR_INVALID;
5434 // Initialize best mode stats for winner mode processing
5435 x->winner_mode_count = 0;
5436 store_winner_mode_stats(&cpi->common, x, mbmi, NULL((void*)0), NULL((void*)0), NULL((void*)0), THR_INVALID,
5437 NULL((void*)0), bsize, best_rd_so_far,
5438 cpi->sf.winner_mode_sf.multi_winner_mode_type, 0);
5439 inter_modes_info->num =
5440 inter_modes_info->num < cpi->sf.rt_sf.num_inter_modes_for_tx_search
5441 ? inter_modes_info->num
5442 : cpi->sf.rt_sf.num_inter_modes_for_tx_search;
5443 const int64_t top_est_rd =
5444 inter_modes_info->num > 0
5445 ? inter_modes_info
5446 ->est_rd_arr[inter_modes_info->rd_idx_pair_arr[0].idx]
5447 : INT64_MAX(9223372036854775807L);
5448 *yrd = INT64_MAX(9223372036854775807L);
5449 int64_t best_rd_in_this_partition = INT64_MAX(9223372036854775807L);
5450 int num_inter_mode_cands = inter_modes_info->num;
5451 int newmv_mode_evaled = 0;
5452 int max_allowed_cands = INT_MAX2147483647;
5453 if (cpi->sf.inter_sf.limit_inter_mode_cands) {
5454 // The bound on the no. of inter mode candidates, beyond which the
5455 // candidates are limited if a newmv mode got evaluated, is set as
5456 // max_allowed_cands + 1.
5457 const int num_allowed_cands[5] = { INT_MAX2147483647, 10, 9, 6, 2 };
5458 assert(cpi->sf.inter_sf.limit_inter_mode_cands <= 4)((void) sizeof ((cpi->sf.inter_sf.limit_inter_mode_cands <=
4) ? 1 : 0), __extension__ ({ if (cpi->sf.inter_sf.limit_inter_mode_cands
<= 4) ; else __assert_fail ("cpi->sf.inter_sf.limit_inter_mode_cands <= 4"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 5458
, __extension__ __PRETTY_FUNCTION__); }))
;
5459 max_allowed_cands =
5460 num_allowed_cands[cpi->sf.inter_sf.limit_inter_mode_cands];
5461 }
5462
5463 int num_mode_thresh = INT_MAX2147483647;
5464 if (cpi->sf.inter_sf.limit_txfm_eval_per_mode) {
5465 // Bound the no. of transform searches per prediction mode beyond a
5466 // threshold.
5467 const int num_mode_thresh_ary[4] = { INT_MAX2147483647, 4, 3, 0 };
5468 assert(cpi->sf.inter_sf.limit_txfm_eval_per_mode <= 3)((void) sizeof ((cpi->sf.inter_sf.limit_txfm_eval_per_mode
<= 3) ? 1 : 0), __extension__ ({ if (cpi->sf.inter_sf.
limit_txfm_eval_per_mode <= 3) ; else __assert_fail ("cpi->sf.inter_sf.limit_txfm_eval_per_mode <= 3"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 5468
, __extension__ __PRETTY_FUNCTION__); }))
;
5469 num_mode_thresh =
5470 num_mode_thresh_ary[cpi->sf.inter_sf.limit_txfm_eval_per_mode];
5471 }
5472
5473 int num_tx_cands = 0;
5474 int num_tx_search_modes[INTER_MODE_END - INTER_MODE_START] = { 0 };
5475 // Iterate over best inter mode candidates and perform tx search
5476 for (int j = 0; j < num_inter_mode_cands; ++j) {
5477 const int data_idx = inter_modes_info->rd_idx_pair_arr[j].idx;
5478 *mbmi = inter_modes_info->mbmi_arr[data_idx];
5479 const PREDICTION_MODE prediction_mode = mbmi->mode;
5480 int64_t curr_est_rd = inter_modes_info->est_rd_arr[data_idx];
5481 if (curr_est_rd * 0.80 > top_est_rd) break;
5482
5483 if (num_tx_cands > num_mode_thresh) {
5484 if ((prediction_mode != NEARESTMV &&
5485 num_tx_search_modes[prediction_mode - INTER_MODE_START] >= 1) ||
5486 (prediction_mode == NEARESTMV &&
5487 num_tx_search_modes[prediction_mode - INTER_MODE_START] >= 2))
5488 continue;
5489 }
5490
5491 txfm_info->skip_txfm = 0;
5492 set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5493
5494 // Select prediction reference frames.
5495 const int is_comp_pred = mbmi->ref_frame[1] > INTRA_FRAME;
5496 for (int i = 0; i < num_planes; i++) {
5497 xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
5498 if (is_comp_pred) xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
5499 }
5500
5501 bool_Bool is_predictor_built = false0;
5502
5503 // Initialize RD stats
5504 RD_STATS rd_stats;
5505 RD_STATS rd_stats_y;
5506 RD_STATS rd_stats_uv;
5507 const int mode_rate = inter_modes_info->mode_rate_arr[data_idx];
5508 int64_t skip_rd = INT64_MAX(9223372036854775807L);
5509 const int txfm_rd_gate_level = get_txfm_rd_gate_level(
5510 cm->seq_params->enable_masked_compound,
5511 cpi->sf.inter_sf.txfm_rd_gate_level, bsize, TX_SEARCH_DEFAULT,
5512 /*eval_motion_mode=*/0);
5513 if (txfm_rd_gate_level) {
5514 // Check if the mode is good enough based on skip RD
5515 int64_t curr_sse = inter_modes_info->sse_arr[data_idx];
5516 skip_rd = RDCOST(x->rdmult, mode_rate, curr_sse)((((((int64_t)(mode_rate)) * (x->rdmult)) + (((1 << (
9)) >> 1))) >> (9)) + ((curr_sse) * (1 << 7
)))
;
5517 int eval_txfm = check_txfm_eval(x, bsize, search_state->best_skip_rd[0],
5518 skip_rd, txfm_rd_gate_level, 0);
5519 if (!eval_txfm) continue;
5520 }
5521
5522 // Build the prediction for this mode
5523 if (!is_predictor_built) {
5524 av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL((void*)0), bsize, 0,
5525 av1_num_planes(cm) - 1);
5526 }
5527 if (mbmi->motion_mode == OBMC_CAUSAL) {
5528 av1_build_obmc_inter_predictors_sb(cm, xd);
5529 }
5530
5531 num_tx_cands++;
5532 if (have_newmv_in_inter_mode(prediction_mode)) newmv_mode_evaled = 1;
5533 num_tx_search_modes[prediction_mode - INTER_MODE_START]++;
5534 int64_t this_yrd = INT64_MAX(9223372036854775807L);
5535 // Do the transform search
5536 if (!av1_txfm_search(cpi, x, bsize, &rd_stats, &rd_stats_y, &rd_stats_uv,
5537 mode_rate, search_state->best_rd)) {
5538 continue;
5539 } else {
5540 const int y_rate =
5541 rd_stats.skip_txfm
5542 ? mode_costs->skip_txfm_cost[skip_ctx][1]
5543 : (rd_stats_y.rate + mode_costs->skip_txfm_cost[skip_ctx][0]);
5544 this_yrd = RDCOST(x->rdmult, y_rate + mode_rate, rd_stats_y.dist)((((((int64_t)(y_rate + mode_rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_stats_y.dist) * (1 <<
7)))
;
5545
5546 if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 1) {
5547 inter_mode_data_push(
5548 tile_data, mbmi->bsize, rd_stats.sse, rd_stats.dist,
5549 rd_stats_y.rate + rd_stats_uv.rate +
5550 mode_costs->skip_txfm_cost[skip_ctx][mbmi->skip_txfm]);
5551 }
5552 }
5553
5554 rd_stats.rdcost = RDCOST(x->rdmult, rd_stats.rate, rd_stats.dist)((((((int64_t)(rd_stats.rate)) * (x->rdmult)) + (((1 <<
(9)) >> 1))) >> (9)) + ((rd_stats.dist) * (1 <<
7)))
;
5555
5556 const THR_MODES mode_enum = get_prediction_mode_idx(
5557 prediction_mode, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5558
5559 // Collect mode stats for multiwinner mode processing
5560 const int txfm_search_done = 1;
5561 store_winner_mode_stats(
5562 &cpi->common, x, mbmi, &rd_stats, &rd_stats_y, &rd_stats_uv, mode_enum,
5563 NULL((void*)0), bsize, rd_stats.rdcost,
5564 cpi->sf.winner_mode_sf.multi_winner_mode_type, txfm_search_done);
5565
5566 int64_t best_scaled_rd = search_state->best_rd;
5567 int64_t this_scaled_rd = rd_stats.rdcost;
5568 increase_warp_mode_rd(&search_state->best_mbmode, mbmi, &best_scaled_rd,
5569 &this_scaled_rd,
5570 cpi->sf.inter_sf.bias_warp_mode_rd_scale_pct);
5571 if (this_scaled_rd < best_rd_in_this_partition) {
5572 best_rd_in_this_partition = rd_stats.rdcost;
5573 *yrd = this_yrd;
5574 }
5575
5576 if (this_scaled_rd < best_scaled_rd) {
5577 update_search_state(search_state, rd_cost, ctx, &rd_stats, &rd_stats_y,
5578 &rd_stats_uv, mode_enum, x, txfm_search_done);
5579 search_state->best_skip_rd[0] = skip_rd;
5580 // Limit the total number of modes to be evaluated if the first is valid
5581 // and transform skip or compound
5582 if (cpi->sf.inter_sf.inter_mode_txfm_breakout) {
5583 if (!j && (search_state->best_mbmode.skip_txfm || rd_stats.skip_txfm)) {
5584 // Evaluate more candidates at high quantizers where occurrence of
5585 // transform skip is high.
5586 const int max_cands_cap[5] = { 2, 3, 5, 7, 9 };
5587 const int qindex_band = (5 * x->qindex) >> QINDEX_BITS8;
5588 num_inter_mode_cands =
5589 AOMMIN(max_cands_cap[qindex_band], inter_modes_info->num)(((max_cands_cap[qindex_band]) < (inter_modes_info->num
)) ? (max_cands_cap[qindex_band]) : (inter_modes_info->num
))
;
5590 } else if (!j && has_second_ref(&search_state->best_mbmode)) {
5591 const int aggr = cpi->sf.inter_sf.inter_mode_txfm_breakout - 1;
5592 // Evaluate more candidates at low quantizers where occurrence of
5593 // single reference mode is high.
5594 const int max_cands_cap_cmp[2][4] = { { 10, 7, 5, 4 },
5595 { 10, 7, 5, 3 } };
5596 const int qindex_band_cmp = (4 * x->qindex) >> QINDEX_BITS8;
5597 num_inter_mode_cands = AOMMIN((((max_cands_cap_cmp[aggr][qindex_band_cmp]) < (inter_modes_info
->num)) ? (max_cands_cap_cmp[aggr][qindex_band_cmp]) : (inter_modes_info
->num))
5598 max_cands_cap_cmp[aggr][qindex_band_cmp], inter_modes_info->num)(((max_cands_cap_cmp[aggr][qindex_band_cmp]) < (inter_modes_info
->num)) ? (max_cands_cap_cmp[aggr][qindex_band_cmp]) : (inter_modes_info
->num))
;
5599 }
5600 }
5601 }
5602 // If the number of candidates evaluated exceeds max_allowed_cands, break if
5603 // a newmv mode was evaluated already.
5604 if ((num_tx_cands > max_allowed_cands) && newmv_mode_evaled) break;
5605 }
5606}
5607
5608// Indicates number of winner simple translation modes to be used
5609static const unsigned int num_winner_motion_modes[3] = { 0, 10, 3 };
5610
5611// Adds a motion mode to the candidate list for motion_mode_for_winner_cand
5612// speed feature. This list consists of modes that have only searched
5613// SIMPLE_TRANSLATION. The final list will be used to search other motion
5614// modes after the initial RD search.
5615static void handle_winner_cand(
5616 MB_MODE_INFO *const mbmi,
5617 motion_mode_best_st_candidate *best_motion_mode_cands,
5618 int max_winner_motion_mode_cand, int64_t this_rd,
5619 motion_mode_candidate *motion_mode_cand, int skip_motion_mode) {
5620 // Number of current motion mode candidates in list
5621 const int num_motion_mode_cand = best_motion_mode_cands->num_motion_mode_cand;
5622 int valid_motion_mode_cand_loc = num_motion_mode_cand;
5623
5624 // find the best location to insert new motion mode candidate
5625 for (int j = 0; j < num_motion_mode_cand; j++) {
5626 if (this_rd < best_motion_mode_cands->motion_mode_cand[j].rd_cost) {
5627 valid_motion_mode_cand_loc = j;
5628 break;
5629 }
5630 }
5631
5632 // Insert motion mode if location is found
5633 if (valid_motion_mode_cand_loc < max_winner_motion_mode_cand) {
5634 if (num_motion_mode_cand > 0 &&
5635 valid_motion_mode_cand_loc < max_winner_motion_mode_cand - 1)
5636 memmove(
5637 &best_motion_mode_cands
5638 ->motion_mode_cand[valid_motion_mode_cand_loc + 1],
5639 &best_motion_mode_cands->motion_mode_cand[valid_motion_mode_cand_loc],
5640 (AOMMIN(num_motion_mode_cand, max_winner_motion_mode_cand - 1)(((num_motion_mode_cand) < (max_winner_motion_mode_cand - 1
)) ? (num_motion_mode_cand) : (max_winner_motion_mode_cand - 1
))
-
5641 valid_motion_mode_cand_loc) *
5642 sizeof(best_motion_mode_cands->motion_mode_cand[0]));
5643 motion_mode_cand->mbmi = *mbmi;
5644 motion_mode_cand->rd_cost = this_rd;
5645 motion_mode_cand->skip_motion_mode = skip_motion_mode;
5646 best_motion_mode_cands->motion_mode_cand[valid_motion_mode_cand_loc] =
5647 *motion_mode_cand;
5648 best_motion_mode_cands->num_motion_mode_cand =
5649 AOMMIN(max_winner_motion_mode_cand,(((max_winner_motion_mode_cand) < (best_motion_mode_cands->
num_motion_mode_cand + 1)) ? (max_winner_motion_mode_cand) : (
best_motion_mode_cands->num_motion_mode_cand + 1))
5650 best_motion_mode_cands->num_motion_mode_cand + 1)(((max_winner_motion_mode_cand) < (best_motion_mode_cands->
num_motion_mode_cand + 1)) ? (max_winner_motion_mode_cand) : (
best_motion_mode_cands->num_motion_mode_cand + 1))
;
5651 }
5652}
5653
5654/*!\brief Search intra modes in interframes
5655 *
5656 * \ingroup intra_mode_search
5657 *
5658 * This function searches for the best intra mode when the current frame is an
5659 * interframe. This function however does *not* handle luma palette mode.
5660 * Palette mode is currently handled by \ref av1_search_palette_mode.
5661 *
5662 * This function will first iterate through the luma mode candidates to find the
5663 * best luma intra mode. Once the best luma mode it's found, it will then search
5664 * for the best chroma mode. Because palette mode is currently not handled by
5665 * here, a cache of uv mode is stored in
5666 * InterModeSearchState::intra_search_state so it can be reused later by \ref
5667 * av1_search_palette_mode.
5668 *
5669 * \param[in,out] search_state Struct keep track of the prediction mode
5670 * search state in interframe.
5671 *
5672 * \param[in] cpi Top-level encoder structure.
5673 * \param[in,out] x Pointer to struct holding all the data for
5674 * the current prediction block.
5675 * \param[out] rd_cost Stores the best rd_cost among all the
5676 * prediction modes searched.
5677 * \param[in] bsize Current block size.
5678 * \param[in,out] ctx Structure to hold the number of 4x4 blks to
5679 * copy the tx_type and txfm_skip arrays.
5680 * for only the Y plane.
5681 * \param[in] sf_args Stores the list of intra mode candidates
5682 * to be searched.
5683 * \param[in] intra_ref_frame_cost The entropy cost for signaling that the
5684 * current ref frame is an intra frame.
5685 * \param[in] yrd_threshold The rdcost threshold for luma intra mode to
5686 * terminate chroma intra mode search.
5687 *
5688 * \remark If a new best mode is found, search_state and rd_costs are updated
5689 * correspondingly. While x is also modified, it is only used as a temporary
5690 * buffer, and the final decisions are stored in search_state.
5691 */
5692static inline void search_intra_modes_in_interframe(
5693 InterModeSearchState *search_state, const AV1_COMP *cpi, MACROBLOCK *x,
5694 RD_STATS *rd_cost, BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
5695 const InterModeSFArgs *sf_args, unsigned int intra_ref_frame_cost,
5696 int64_t yrd_threshold) {
5697 const AV1_COMMON *const cm = &cpi->common;
5698 const SPEED_FEATURES *const sf = &cpi->sf;
5699 const IntraModeCfg *const intra_mode_cfg = &cpi->oxcf.intra_mode_cfg;
5700 MACROBLOCKD *const xd = &x->e_mbd;
5701 MB_MODE_INFO *const mbmi = xd->mi[0];
5702 IntraModeSearchState *intra_search_state = &search_state->intra_search_state;
5703
5704 int is_best_y_mode_intra = 0;
5705 RD_STATS best_intra_rd_stats_y;
5706 int64_t best_rd_y = INT64_MAX(9223372036854775807L);
5707 int best_mode_cost_y = -1;
5708 MB_MODE_INFO best_mbmi = *xd->mi[0];
5709 THR_MODES best_mode_enum = THR_INVALID;
5710 uint8_t best_blk_skip[MAX_MIB_SIZE(1 << (7 - 2)) * MAX_MIB_SIZE(1 << (7 - 2))];
5711 uint8_t best_tx_type_map[MAX_MIB_SIZE(1 << (7 - 2)) * MAX_MIB_SIZE(1 << (7 - 2))];
5712 const int num_4x4 = bsize_to_num_blk(bsize);
5713
5714 // Performs luma search
5715 int64_t best_model_rd = INT64_MAX(9223372036854775807L);
5716 int64_t top_intra_model_rd[TOP_INTRA_MODEL_COUNT4];
5717 for (int i = 0; i < TOP_INTRA_MODEL_COUNT4; i++) {
5718 top_intra_model_rd[i] = INT64_MAX(9223372036854775807L);
5719 }
5720
5721 if (cpi->oxcf.algo_cfg.sharpness) {
5722 int bh = mi_size_high[bsize];
5723 int bw = mi_size_wide[bsize];
5724 if (bh > 4 || bw > 4) return;
5725 }
5726
5727 for (int mode_idx = 0; mode_idx < LUMA_MODE_COUNT(PAETH_PRED - DC_PRED + 1 + 6 * 8); ++mode_idx) {
5728 if (sf->intra_sf.skip_intra_in_interframe &&
5729 search_state->intra_search_state.skip_intra_modes)
5730 break;
5731 set_y_mode_and_delta_angle(
5732 mode_idx, mbmi, sf->intra_sf.prune_luma_odd_delta_angles_in_intra);
5733 assert(mbmi->mode < INTRA_MODE_END)((void) sizeof ((mbmi->mode < INTRA_MODE_END) ? 1 : 0),
__extension__ ({ if (mbmi->mode < INTRA_MODE_END) ; else
__assert_fail ("mbmi->mode < INTRA_MODE_END", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 5733, __extension__ __PRETTY_FUNCTION__); }))
;
5734
5735 // Use intra_y_mode_mask speed feature to skip intra mode evaluation.
5736 if (sf_args->mode_skip_mask->pred_modes[INTRA_FRAME] & (1 << mbmi->mode))
5737 continue;
5738
5739 const THR_MODES mode_enum =
5740 get_prediction_mode_idx(mbmi->mode, INTRA_FRAME, NONE_FRAME);
5741 if ((!intra_mode_cfg->enable_smooth_intra ||
5742 cpi->sf.intra_sf.disable_smooth_intra) &&
5743 (mbmi->mode == SMOOTH_PRED || mbmi->mode == SMOOTH_H_PRED ||
5744 mbmi->mode == SMOOTH_V_PRED))
5745 continue;
5746 if (!intra_mode_cfg->enable_paeth_intra && mbmi->mode == PAETH_PRED)
5747 continue;
5748 if (av1_is_directional_mode(mbmi->mode) &&
5749 !(av1_use_angle_delta(bsize) && intra_mode_cfg->enable_angle_delta) &&
5750 mbmi->angle_delta[PLANE_TYPE_Y] != 0)
5751 continue;
5752 const PREDICTION_MODE this_mode = mbmi->mode;
5753
5754 assert(av1_mode_defs[mode_enum].ref_frame[0] == INTRA_FRAME)((void) sizeof ((av1_mode_defs[mode_enum].ref_frame[0] == INTRA_FRAME
) ? 1 : 0), __extension__ ({ if (av1_mode_defs[mode_enum].ref_frame
[0] == INTRA_FRAME) ; else __assert_fail ("av1_mode_defs[mode_enum].ref_frame[0] == INTRA_FRAME"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 5754
, __extension__ __PRETTY_FUNCTION__); }))
;
5755 assert(av1_mode_defs[mode_enum].ref_frame[1] == NONE_FRAME)((void) sizeof ((av1_mode_defs[mode_enum].ref_frame[1] == NONE_FRAME
) ? 1 : 0), __extension__ ({ if (av1_mode_defs[mode_enum].ref_frame
[1] == NONE_FRAME) ; else __assert_fail ("av1_mode_defs[mode_enum].ref_frame[1] == NONE_FRAME"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 5755
, __extension__ __PRETTY_FUNCTION__); }))
;
5756 init_mbmi(mbmi, this_mode, av1_mode_defs[mode_enum].ref_frame, cm);
5757 x->txfm_search_info.skip_txfm = 0;
5758
5759 if (this_mode != DC_PRED) {
5760 // Only search the oblique modes if the best so far is
5761 // one of the neighboring directional modes
5762 if ((sf->rt_sf.mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
5763 (this_mode >= D45_PRED && this_mode <= PAETH_PRED)) {
5764 if (search_state->best_mode_index != THR_INVALID &&
5765 search_state->best_mbmode.ref_frame[0] > INTRA_FRAME)
5766 continue;
5767 }
5768 if (sf->rt_sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
5769 if (conditional_skipintra(
5770 this_mode, search_state->intra_search_state.best_intra_mode))
5771 continue;
5772 }
5773 }
5774
5775 RD_STATS intra_rd_stats_y;
5776 int mode_cost_y;
5777 int64_t intra_rd_y = INT64_MAX(9223372036854775807L);
5778 const int is_luma_result_valid = av1_handle_intra_y_mode(
5779 intra_search_state, cpi, x, bsize, intra_ref_frame_cost, ctx,
5780 &intra_rd_stats_y, search_state->best_rd, &mode_cost_y, &intra_rd_y,
5781 &best_model_rd, top_intra_model_rd);
5782
5783 if (intra_rd_y < INT64_MAX(9223372036854775807L)) {
5784 adjust_cost(cpi, x, &intra_rd_y);
5785 }
5786
5787 if (is_luma_result_valid && intra_rd_y < yrd_threshold) {
5788 is_best_y_mode_intra = 1;
5789 if (intra_rd_y < best_rd_y) {
5790 best_intra_rd_stats_y = intra_rd_stats_y;
5791 best_mode_cost_y = mode_cost_y;
5792 best_rd_y = intra_rd_y;
5793 best_mbmi = *mbmi;
5794 best_mode_enum = mode_enum;
5795 memcpy(best_blk_skip, x->txfm_search_info.blk_skip,
5796 sizeof(best_blk_skip[0]) * num_4x4);
5797 av1_copy_array(best_tx_type_map, xd->tx_type_map, num_4x4)do { ((void) sizeof ((sizeof(*(best_tx_type_map)) == sizeof(*
(xd->tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof(
*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))) ; else
__assert_fail ("sizeof(*(best_tx_type_map)) == sizeof(*(xd->tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 5797
, __extension__ __PRETTY_FUNCTION__); })); memcpy(best_tx_type_map
, xd->tx_type_map, num_4x4 * sizeof(*(xd->tx_type_map))
); } while (0)
;
5798 }
5799 }
5800 }
5801
5802 if (!is_best_y_mode_intra) {
5803 return;
5804 }
5805
5806 assert(best_rd_y < INT64_MAX)((void) sizeof ((best_rd_y < (9223372036854775807L)) ? 1 :
0), __extension__ ({ if (best_rd_y < (9223372036854775807L
)) ; else __assert_fail ("best_rd_y < INT64_MAX", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 5806, __extension__ __PRETTY_FUNCTION__); }))
;
5807
5808 // Restores the best luma mode
5809 *mbmi = best_mbmi;
5810 memcpy(x->txfm_search_info.blk_skip, best_blk_skip,
5811 sizeof(best_blk_skip[0]) * num_4x4);
5812 av1_copy_array(xd->tx_type_map, best_tx_type_map, num_4x4)do { ((void) sizeof ((sizeof(*(xd->tx_type_map)) == sizeof
(*(best_tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof(
*(xd->tx_type_map)) == sizeof(*(best_tx_type_map))) ; else
__assert_fail ("sizeof(*(xd->tx_type_map)) == sizeof(*(best_tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 5812
, __extension__ __PRETTY_FUNCTION__); })); memcpy(xd->tx_type_map
, best_tx_type_map, num_4x4 * sizeof(*(best_tx_type_map))); }
while (0)
;
5813
5814 // Performs chroma search
5815 RD_STATS intra_rd_stats, intra_rd_stats_uv;
5816 av1_init_rd_stats(&intra_rd_stats);
5817 av1_init_rd_stats(&intra_rd_stats_uv);
5818 const int num_planes = av1_num_planes(cm);
5819 if (num_planes > 1) {
5820 const int intra_uv_mode_valid = av1_search_intra_uv_modes_in_interframe(
5821 intra_search_state, cpi, x, bsize, &intra_rd_stats,
5822 &best_intra_rd_stats_y, &intra_rd_stats_uv, search_state->best_rd);
5823
5824 if (!intra_uv_mode_valid) {
5825 return;
5826 }
5827 }
5828
5829 // Merge the luma and chroma rd stats
5830 assert(best_mode_cost_y >= 0)((void) sizeof ((best_mode_cost_y >= 0) ? 1 : 0), __extension__
({ if (best_mode_cost_y >= 0) ; else __assert_fail ("best_mode_cost_y >= 0"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 5830
, __extension__ __PRETTY_FUNCTION__); }))
;
5831 intra_rd_stats.rate = best_intra_rd_stats_y.rate + best_mode_cost_y;
5832 if (!xd->lossless[mbmi->segment_id] && block_signals_txsize(bsize)) {
5833 // av1_pick_uniform_tx_size_type_yrd above includes the cost of the tx_size
5834 // in the tokenonly rate, but for intra blocks, tx_size is always coded
5835 // (prediction granularity), so we account for it in the full rate,
5836 // not the tokenonly rate.
5837 best_intra_rd_stats_y.rate -= tx_size_cost(x, bsize, mbmi->tx_size);
5838 }
5839
5840 const ModeCosts *mode_costs = &x->mode_costs;
5841 const PREDICTION_MODE mode = mbmi->mode;
5842 if (num_planes > 1 && xd->is_chroma_ref) {
5843 const int uv_mode_cost =
5844 mode_costs->intra_uv_mode_cost[is_cfl_allowed(xd)][mode][mbmi->uv_mode];
5845 intra_rd_stats.rate +=
5846 intra_rd_stats_uv.rate +
5847 intra_mode_info_cost_uv(cpi, x, mbmi, bsize, uv_mode_cost);
5848 }
5849
5850 // Intra block is always coded as non-skip
5851 intra_rd_stats.skip_txfm = 0;
5852 intra_rd_stats.dist = best_intra_rd_stats_y.dist + intra_rd_stats_uv.dist;
5853 // Add in the cost of the no skip flag.
5854 const int skip_ctx = av1_get_skip_txfm_context(xd);
5855 intra_rd_stats.rate += mode_costs->skip_txfm_cost[skip_ctx][0];
5856 // Calculate the final RD estimate for this mode.
5857 const int64_t this_rd =
5858 RDCOST(x->rdmult, intra_rd_stats.rate, intra_rd_stats.dist)((((((int64_t)(intra_rd_stats.rate)) * (x->rdmult)) + (((1
<< (9)) >> 1))) >> (9)) + ((intra_rd_stats
.dist) * (1 << 7)))
;
5859 // Keep record of best intra rd
5860 if (this_rd < search_state->best_intra_rd) {
5861 search_state->best_intra_rd = this_rd;
5862 intra_search_state->best_intra_mode = mode;
5863 }
5864
5865 for (int i = 0; i < REFERENCE_MODES; ++i) {
5866 search_state->best_pred_rd[i] =
5867 AOMMIN(search_state->best_pred_rd[i], this_rd)(((search_state->best_pred_rd[i]) < (this_rd)) ? (search_state
->best_pred_rd[i]) : (this_rd))
;
5868 }
5869
5870 intra_rd_stats.rdcost = this_rd;
5871
5872 adjust_rdcost(cpi, x, &intra_rd_stats);
5873
5874 // Collect mode stats for multiwinner mode processing
5875 const int txfm_search_done = 1;
5876 store_winner_mode_stats(
5877 &cpi->common, x, mbmi, &intra_rd_stats, &best_intra_rd_stats_y,
5878 &intra_rd_stats_uv, best_mode_enum, NULL((void*)0), bsize, intra_rd_stats.rdcost,
5879 cpi->sf.winner_mode_sf.multi_winner_mode_type, txfm_search_done);
5880 if (intra_rd_stats.rdcost < search_state->best_rd) {
5881 update_search_state(search_state, rd_cost, ctx, &intra_rd_stats,
5882 &best_intra_rd_stats_y, &intra_rd_stats_uv,
5883 best_mode_enum, x, txfm_search_done);
5884 }
5885}
5886
5887#if !CONFIG_REALTIME_ONLY0
5888// Prepare inter_cost and intra_cost from TPL stats, which are used as ML
5889// features in intra mode pruning.
5890static inline void calculate_cost_from_tpl_data(const AV1_COMP *cpi,
5891 MACROBLOCK *x, BLOCK_SIZE bsize,
5892 int mi_row, int mi_col,
5893 int64_t *inter_cost,
5894 int64_t *intra_cost) {
5895 const AV1_COMMON *const cm = &cpi->common;
5896 // Only consider full SB.
5897 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
5898 const int tpl_bsize_1d = cpi->ppi->tpl_data.tpl_bsize_1d;
5899 const int len = (block_size_wide[sb_size] / tpl_bsize_1d) *
5900 (block_size_high[sb_size] / tpl_bsize_1d);
5901 SuperBlockEnc *sb_enc = &x->sb_enc;
5902 if (sb_enc->tpl_data_count == len) {
5903 const BLOCK_SIZE tpl_bsize = convert_length_to_bsize(tpl_bsize_1d);
5904 const int tpl_stride = sb_enc->tpl_stride;
5905 const int tplw = mi_size_wide[tpl_bsize];
5906 const int tplh = mi_size_high[tpl_bsize];
5907 const int nw = mi_size_wide[bsize] / tplw;
5908 const int nh = mi_size_high[bsize] / tplh;
5909 if (nw >= 1 && nh >= 1) {
5910 const int of_h = mi_row % mi_size_high[sb_size];
5911 const int of_w = mi_col % mi_size_wide[sb_size];
5912 const int start = of_h / tplh * tpl_stride + of_w / tplw;
5913
5914 for (int k = 0; k < nh; k++) {
5915 for (int l = 0; l < nw; l++) {
5916 *inter_cost += sb_enc->tpl_inter_cost[start + k * tpl_stride + l];
5917 *intra_cost += sb_enc->tpl_intra_cost[start + k * tpl_stride + l];
5918 }
5919 }
5920 *inter_cost /= nw * nh;
5921 *intra_cost /= nw * nh;
5922 }
5923 }
5924}
5925#endif // !CONFIG_REALTIME_ONLY
5926
5927// When the speed feature skip_intra_in_interframe > 0, enable ML model to prune
5928// intra mode search.
5929static inline void skip_intra_modes_in_interframe(
5930 AV1_COMMON *const cm, struct macroblock *x, BLOCK_SIZE bsize,
5931 InterModeSearchState *search_state, const SPEED_FEATURES *const sf,
5932 int64_t inter_cost, int64_t intra_cost) {
5933 MACROBLOCKD *const xd = &x->e_mbd;
5934 const int comp_pred = search_state->best_mbmode.ref_frame[1] > INTRA_FRAME;
5935 if (sf->rt_sf.prune_intra_mode_based_on_mv_range &&
5936 bsize > sf->part_sf.max_intra_bsize && !comp_pred) {
5937 const MV best_mv = search_state->best_mbmode.mv[0].as_mv;
5938 const int mv_thresh = 16 << sf->rt_sf.prune_intra_mode_based_on_mv_range;
5939 if (abs(best_mv.row) < mv_thresh && abs(best_mv.col) < mv_thresh &&
5940 x->source_variance > 128) {
5941 search_state->intra_search_state.skip_intra_modes = 1;
5942 return;
5943 }
5944 }
5945
5946 const unsigned int src_var_thresh_intra_skip = 1;
5947 const int skip_intra_in_interframe = sf->intra_sf.skip_intra_in_interframe;
5948 if (!(skip_intra_in_interframe &&
5949 (x->source_variance > src_var_thresh_intra_skip)))
5950 return;
5951
5952 // Prune intra search based on best inter mode being transfrom skip.
5953 if ((skip_intra_in_interframe >= 2) && search_state->best_mbmode.skip_txfm) {
5954 const int qindex_thresh[2] = { 200, MAXQ255 };
5955 const int ind = (skip_intra_in_interframe >= 3) ? 1 : 0;
5956 if (!have_newmv_in_inter_mode(search_state->best_mbmode.mode) &&
5957 (x->qindex <= qindex_thresh[ind])) {
5958 search_state->intra_search_state.skip_intra_modes = 1;
5959 return;
5960 } else if ((skip_intra_in_interframe >= 4) &&
5961 (inter_cost < 0 || intra_cost < 0)) {
5962 search_state->intra_search_state.skip_intra_modes = 1;
5963 return;
5964 }
5965 }
5966 // Use ML model to prune intra search.
5967 if (inter_cost >= 0 && intra_cost >= 0) {
5968 const NN_CONFIG *nn_config = (AOMMIN(cm->width, cm->height)(((cm->width) < (cm->height)) ? (cm->width) : (cm
->height))
<= 480)
5969 ? &av1_intrap_nn_config
5970 : &av1_intrap_hd_nn_config;
5971 float nn_features[6];
5972 float scores[2] = { 0.0f };
5973
5974 nn_features[0] = (float)search_state->best_mbmode.skip_txfm;
5975 nn_features[1] = (float)mi_size_wide_log2[bsize];
5976 nn_features[2] = (float)mi_size_high_log2[bsize];
5977 nn_features[3] = (float)intra_cost;
5978 nn_features[4] = (float)inter_cost;
5979 const int ac_q = av1_ac_quant_QTX(x->qindex, 0, xd->bd);
5980 const int ac_q_max = av1_ac_quant_QTX(255, 0, xd->bd);
5981 nn_features[5] = (float)(ac_q_max / ac_q);
5982
5983 av1_nn_predict(nn_features, nn_config, 1, scores);
5984
5985 // For two parameters, the max prob returned from av1_nn_softmax equals
5986 // 1.0 / (1.0 + e^(-|diff_score|)). Here use scores directly to avoid the
5987 // calling of av1_nn_softmax.
5988 const float thresh[5] = { 1.4f, 1.4f, 1.4f, 1.4f, 1.4f };
5989 assert(skip_intra_in_interframe <= 5)((void) sizeof ((skip_intra_in_interframe <= 5) ? 1 : 0), __extension__
({ if (skip_intra_in_interframe <= 5) ; else __assert_fail
("skip_intra_in_interframe <= 5", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 5989, __extension__ __PRETTY_FUNCTION__); }))
;
5990 if (scores[1] > scores[0] + thresh[skip_intra_in_interframe - 1]) {
5991 search_state->intra_search_state.skip_intra_modes = 1;
5992 }
5993 }
5994}
5995
5996static inline bool_Bool skip_interp_filter_search(const AV1_COMP *cpi,
5997 int is_single_pred) {
5998 const MODE encoding_mode = cpi->oxcf.mode;
5999 if (encoding_mode == REALTIME) {
6000 return (cpi->common.current_frame.reference_mode == SINGLE_REFERENCE &&
6001 (cpi->sf.interp_sf.skip_interp_filter_search ||
6002 cpi->sf.winner_mode_sf.winner_mode_ifs));
6003 } else if (encoding_mode == GOOD) {
6004 // Skip interpolation filter search for single prediction modes.
6005 return (cpi->sf.interp_sf.skip_interp_filter_search && is_single_pred);
6006 }
6007 return false0;
6008}
6009
6010static inline int get_block_temp_var(const AV1_COMP *cpi, const MACROBLOCK *x,
6011 BLOCK_SIZE bsize) {
6012 const AV1_COMMON *const cm = &cpi->common;
6013 const SPEED_FEATURES *const sf = &cpi->sf;
6014
6015 if (sf->part_sf.partition_search_type != VAR_BASED_PARTITION ||
6016 !sf->rt_sf.short_circuit_low_temp_var ||
6017 !sf->rt_sf.prune_inter_modes_using_temp_var) {
6018 return 0;
6019 }
6020
6021 const int mi_row = x->e_mbd.mi_row;
6022 const int mi_col = x->e_mbd.mi_col;
6023 int is_low_temp_var = 0;
6024
6025 if (cm->seq_params->sb_size == BLOCK_64X64)
6026 is_low_temp_var = av1_get_force_skip_low_temp_var_small_sb(
6027 &x->part_search_info.variance_low[0], mi_row, mi_col, bsize);
6028 else
6029 is_low_temp_var = av1_get_force_skip_low_temp_var(
6030 &x->part_search_info.variance_low[0], mi_row, mi_col, bsize);
6031
6032 return is_low_temp_var;
6033}
6034
6035// TODO(chiyotsai@google.com): See the todo for av1_rd_pick_intra_mode_sb.
6036void av1_rd_pick_inter_mode(struct AV1_COMP *cpi, struct TileDataEnc *tile_data,
6037 struct macroblock *x, struct RD_STATS *rd_cost,
6038 BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
6039 int64_t best_rd_so_far) {
6040 AV1_COMMON *const cm = &cpi->common;
6041 const FeatureFlags *const features = &cm->features;
6042 const int num_planes = av1_num_planes(cm);
6043 const SPEED_FEATURES *const sf = &cpi->sf;
6044 MACROBLOCKD *const xd = &x->e_mbd;
6045 MB_MODE_INFO *const mbmi = xd->mi[0];
6046 TxfmSearchInfo *txfm_info = &x->txfm_search_info;
6047 int i;
6048 const ModeCosts *mode_costs = &x->mode_costs;
6049 const int *comp_inter_cost =
6050 mode_costs->comp_inter_cost[av1_get_reference_mode_context(xd)];
6051
6052 InterModeSearchState search_state;
6053 init_inter_mode_search_state(&search_state, cpi, x, bsize, best_rd_so_far);
6054 INTERINTRA_MODE interintra_modes[REF_FRAMES] = {
6055 INTERINTRA_MODES, INTERINTRA_MODES, INTERINTRA_MODES, INTERINTRA_MODES,
6056 INTERINTRA_MODES, INTERINTRA_MODES, INTERINTRA_MODES, INTERINTRA_MODES
6057 };
6058 HandleInterModeArgs args = { { NULL((void*)0) },
6059 { MAX_SB_SIZE(1 << 7), MAX_SB_SIZE(1 << 7), MAX_SB_SIZE(1 << 7) },
6060 { NULL((void*)0) },
6061 { MAX_SB_SIZE(1 << 7) >> 1, MAX_SB_SIZE(1 << 7) >> 1,
6062 MAX_SB_SIZE(1 << 7) >> 1 },
6063 NULL((void*)0),
6064 NULL((void*)0),
6065 NULL((void*)0),
6066 search_state.modelled_rd,
6067 INT_MAX2147483647,
6068 INT_MAX2147483647,
6069 search_state.simple_rd,
6070 0,
6071 false0,
6072 interintra_modes,
6073 { { { 0 }, { { 0 } }, { 0 }, 0, 0, 0, 0 } },
6074 { { 0, 0 } },
6075 { 0 },
6076 0,
6077 0,
6078 -1,
6079 -1,
6080 -1,
6081 { 0 },
6082 { 0 },
6083 UINT_MAX(2147483647 *2U +1U) };
6084 // Currently, is_low_temp_var is used in real time encoding.
6085 const int is_low_temp_var = get_block_temp_var(cpi, x, bsize);
6086
6087 for (i = 0; i < MODE_CTX_REF_FRAMES(REF_FRAMES + (FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS)); ++i) args.cmp_mode[i] = -1;
6088 // Indicates the appropriate number of simple translation winner modes for
6089 // exhaustive motion mode evaluation
6090 const int max_winner_motion_mode_cand =
6091 num_winner_motion_modes[sf->winner_mode_sf.motion_mode_for_winner_cand];
6092 assert(max_winner_motion_mode_cand <= MAX_WINNER_MOTION_MODES)((void) sizeof ((max_winner_motion_mode_cand <= 10) ? 1 : 0
), __extension__ ({ if (max_winner_motion_mode_cand <= 10)
; else __assert_fail ("max_winner_motion_mode_cand <= MAX_WINNER_MOTION_MODES"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6092
, __extension__ __PRETTY_FUNCTION__); }))
;
6093 motion_mode_candidate motion_mode_cand;
6094 motion_mode_best_st_candidate best_motion_mode_cands;
6095 // Initializing the number of motion mode candidates to zero.
6096 best_motion_mode_cands.num_motion_mode_cand = 0;
6097 for (i = 0; i < MAX_WINNER_MOTION_MODES10; ++i)
6098 best_motion_mode_cands.motion_mode_cand[i].rd_cost = INT64_MAX(9223372036854775807L);
6099
6100 for (i = 0; i < REF_FRAMES; ++i) x->pred_sse[i] = INT_MAX2147483647;
6101
6102 av1_invalid_rd_stats(rd_cost);
6103
6104 for (i = 0; i < REF_FRAMES; ++i) {
6105 x->warp_sample_info[i].num = -1;
6106 }
6107
6108 // Ref frames that are selected by square partition blocks.
6109 int picked_ref_frames_mask = 0;
6110 if (sf->inter_sf.prune_ref_frame_for_rect_partitions &&
6111 mbmi->partition != PARTITION_NONE) {
6112 // prune_ref_frame_for_rect_partitions = 1 implies prune only extended
6113 // partition blocks. prune_ref_frame_for_rect_partitions >=2
6114 // implies prune for vert, horiz and extended partition blocks.
6115 if ((mbmi->partition != PARTITION_VERT &&
6116 mbmi->partition != PARTITION_HORZ) ||
6117 sf->inter_sf.prune_ref_frame_for_rect_partitions >= 2) {
6118 picked_ref_frames_mask =
6119 fetch_picked_ref_frames_mask(x, bsize, cm->seq_params->mib_size);
6120 }
6121 }
6122
6123#if CONFIG_COLLECT_COMPONENT_TIMING0
6124 start_timing(cpi, set_params_rd_pick_inter_mode_time);
6125#endif
6126 // Skip ref frames that never selected by square blocks.
6127 const int skip_ref_frame_mask =
6128 picked_ref_frames_mask ? ~picked_ref_frames_mask : 0;
6129 mode_skip_mask_t mode_skip_mask;
6130 unsigned int ref_costs_single[REF_FRAMES];
6131 unsigned int ref_costs_comp[REF_FRAMES][REF_FRAMES];
6132 struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE3];
6133 // init params, set frame modes, speed features
6134 set_params_rd_pick_inter_mode(cpi, x, &args, bsize, &mode_skip_mask,
6135 skip_ref_frame_mask, ref_costs_single,
6136 ref_costs_comp, yv12_mb);
6137#if CONFIG_COLLECT_COMPONENT_TIMING0
6138 end_timing(cpi, set_params_rd_pick_inter_mode_time);
6139#endif
6140
6141 int64_t best_est_rd = INT64_MAX(9223372036854775807L);
6142 const InterModeRdModel *md = &tile_data->inter_mode_rd_models[bsize];
6143 // If do_tx_search is 0, only estimated RD should be computed.
6144 // If do_tx_search is 1, all modes have TX search performed.
6145 const int do_tx_search =
6146 !((sf->inter_sf.inter_mode_rd_model_estimation == 1 && md->ready) ||
6147 (sf->inter_sf.inter_mode_rd_model_estimation == 2 &&
6148 num_pels_log2_lookup[bsize] > 8));
6149 InterModesInfo *inter_modes_info = x->inter_modes_info;
6150 inter_modes_info->num = 0;
6151
6152 // Temporary buffers used by handle_inter_mode().
6153 uint8_t *const tmp_buf = get_buf_by_bd(xd, x->tmp_pred_bufs[0]);
6154
6155 // The best RD found for the reference frame, among single reference modes.
6156 // Note that the 0-th element will contain a cut-off that is later used
6157 // to determine if we should skip a compound mode.
6158 int64_t ref_frame_rd[REF_FRAMES] = { INT64_MAX(9223372036854775807L), INT64_MAX(9223372036854775807L), INT64_MAX(9223372036854775807L),
6159 INT64_MAX(9223372036854775807L), INT64_MAX(9223372036854775807L), INT64_MAX(9223372036854775807L),
6160 INT64_MAX(9223372036854775807L), INT64_MAX(9223372036854775807L) };
6161
6162 // Prepared stats used later to check if we could skip intra mode eval.
6163 int64_t inter_cost = -1;
6164 int64_t intra_cost = -1;
6165 // Need to tweak the threshold for hdres speed 0 & 1.
6166 const int mi_row = xd->mi_row;
6167 const int mi_col = xd->mi_col;
6168
6169 // Obtain the relevant tpl stats for pruning inter modes
6170 PruneInfoFromTpl inter_cost_info_from_tpl;
6171#if !CONFIG_REALTIME_ONLY0
6172 if (sf->inter_sf.prune_inter_modes_based_on_tpl) {
6173 // x->tpl_keep_ref_frame[id] = 1 => no pruning in
6174 // prune_ref_by_selective_ref_frame()
6175 // x->tpl_keep_ref_frame[id] = 0 => ref frame can be pruned in
6176 // prune_ref_by_selective_ref_frame()
6177 // Populating valid_refs[idx] = 1 ensures that
6178 // 'inter_cost_info_from_tpl.best_inter_cost' does not correspond to a
6179 // pruned ref frame.
6180 int valid_refs[INTER_REFS_PER_FRAME];
6181 for (MV_REFERENCE_FRAME frame = LAST_FRAME; frame < REF_FRAMES; frame++) {
6182 const MV_REFERENCE_FRAME refs[2] = { frame, NONE_FRAME };
6183 valid_refs[frame - 1] =
6184 x->tpl_keep_ref_frame[frame] ||
6185 !prune_ref_by_selective_ref_frame(
6186 cpi, x, refs, cm->cur_frame->ref_display_order_hint);
6187 }
6188 av1_zero(inter_cost_info_from_tpl)memset(&(inter_cost_info_from_tpl), 0, sizeof(inter_cost_info_from_tpl
))
;
6189 get_block_level_tpl_stats(cpi, bsize, mi_row, mi_col, valid_refs,
6190 &inter_cost_info_from_tpl);
6191 }
6192
6193 const int do_pruning =
6194 (AOMMIN(cm->width, cm->height)(((cm->width) < (cm->height)) ? (cm->width) : (cm
->height))
> 480 && cpi->speed <= 1) ? 0 : 1;
6195 if (do_pruning && sf->intra_sf.skip_intra_in_interframe &&
6196 cpi->oxcf.algo_cfg.enable_tpl_model)
6197 calculate_cost_from_tpl_data(cpi, x, bsize, mi_row, mi_col, &inter_cost,
6198 &intra_cost);
6199#endif // !CONFIG_REALTIME_ONLY
6200
6201 // Initialize best mode stats for winner mode processing.
6202 const int max_winner_mode_count =
6203 winner_mode_count_allowed[sf->winner_mode_sf.multi_winner_mode_type];
6204 zero_winner_mode_stats(bsize, max_winner_mode_count, x->winner_mode_stats);
6205 x->winner_mode_count = 0;
6206 store_winner_mode_stats(&cpi->common, x, mbmi, NULL((void*)0), NULL((void*)0), NULL((void*)0), THR_INVALID,
6207 NULL((void*)0), bsize, best_rd_so_far,
6208 sf->winner_mode_sf.multi_winner_mode_type, 0);
6209
6210 int mode_thresh_mul_fact = (1 << MODE_THRESH_QBITS12);
6211 if (sf->inter_sf.prune_inter_modes_if_skippable) {
6212 // Higher multiplication factor values for lower quantizers.
6213 mode_thresh_mul_fact = mode_threshold_mul_factor[x->qindex];
6214 }
6215
6216 // Initialize arguments for mode loop speed features
6217 InterModeSFArgs sf_args = { &args.skip_motion_mode,
6218 &mode_skip_mask,
6219 &search_state,
6220 skip_ref_frame_mask,
6221 0,
6222 mode_thresh_mul_fact,
6223 0,
6224 0 };
6225 int64_t best_inter_yrd = INT64_MAX(9223372036854775807L);
6226
6227 // This is the main loop of this function. It loops over all possible inter
6228 // modes and calls handle_inter_mode() to compute the RD for each.
6229 // Here midx is just an iterator index that should not be used by itself
6230 // except to keep track of the number of modes searched. It should be used
6231 // with av1_default_mode_order to get the enum that defines the mode, which
6232 // can be used with av1_mode_defs to get the prediction mode and the ref
6233 // frames.
6234 // TODO(yunqing, any): Setting mode_start and mode_end outside for-loop brings
6235 // good speedup for real time case. If we decide to use compound mode in real
6236 // time, maybe we can modify av1_default_mode_order table.
6237 THR_MODES mode_start = THR_INTER_MODE_START;
6238 THR_MODES mode_end = THR_INTER_MODE_END;
6239 const CurrentFrame *const current_frame = &cm->current_frame;
6240 if (current_frame->reference_mode == SINGLE_REFERENCE) {
6241 mode_start = SINGLE_REF_MODE_START;
6242 mode_end = SINGLE_REF_MODE_END;
6243 }
6244
6245 for (THR_MODES midx = mode_start; midx < mode_end; ++midx) {
6246 // Get the actual prediction mode we are trying in this iteration
6247 const THR_MODES mode_enum = av1_default_mode_order[midx];
6248 const MODE_DEFINITION *mode_def = &av1_mode_defs[mode_enum];
6249 const PREDICTION_MODE this_mode = mode_def->mode;
6250 const MV_REFERENCE_FRAME *ref_frames = mode_def->ref_frame;
6251
6252 const MV_REFERENCE_FRAME ref_frame = ref_frames[0];
6253 const MV_REFERENCE_FRAME second_ref_frame = ref_frames[1];
6254 const int is_single_pred =
6255 ref_frame > INTRA_FRAME && second_ref_frame == NONE_FRAME;
6256 const int comp_pred = second_ref_frame > INTRA_FRAME;
6257
6258 init_mbmi(mbmi, this_mode, ref_frames, cm);
6259
6260 txfm_info->skip_txfm = 0;
6261 sf_args.num_single_modes_processed += is_single_pred;
6262 set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
6263#if CONFIG_COLLECT_COMPONENT_TIMING0
6264 start_timing(cpi, skip_inter_mode_time);
6265#endif
6266 // Apply speed features to decide if this inter mode can be skipped
6267 const int is_skip_inter_mode = skip_inter_mode(
6268 cpi, x, bsize, ref_frame_rd, midx, &sf_args, is_low_temp_var);
6269#if CONFIG_COLLECT_COMPONENT_TIMING0
6270 end_timing(cpi, skip_inter_mode_time);
6271#endif
6272 if (is_skip_inter_mode) continue;
6273
6274 // Select prediction reference frames.
6275 for (i = 0; i < num_planes; i++) {
6276 xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
6277 if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
6278 }
6279
6280 mbmi->angle_delta[PLANE_TYPE_Y] = 0;
6281 mbmi->angle_delta[PLANE_TYPE_UV] = 0;
6282 mbmi->filter_intra_mode_info.use_filter_intra = 0;
6283 mbmi->ref_mv_idx = 0;
6284
6285 const int64_t ref_best_rd = search_state.best_rd;
6286 RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
6287 av1_init_rd_stats(&rd_stats);
6288
6289 const int ref_frame_cost = comp_pred
6290 ? ref_costs_comp[ref_frame][second_ref_frame]
6291 : ref_costs_single[ref_frame];
6292 const int compmode_cost =
6293 is_comp_ref_allowed(mbmi->bsize) ? comp_inter_cost[comp_pred] : 0;
6294 const int real_compmode_cost =
6295 cm->current_frame.reference_mode == REFERENCE_MODE_SELECT
6296 ? compmode_cost
6297 : 0;
6298 // Point to variables that are maintained between loop iterations
6299 args.single_newmv = search_state.single_newmv;
6300 args.single_newmv_rate = search_state.single_newmv_rate;
6301 args.single_newmv_valid = search_state.single_newmv_valid;
6302 args.single_comp_cost = real_compmode_cost;
6303 args.ref_frame_cost = ref_frame_cost;
6304 args.best_pred_sse = search_state.best_pred_sse;
6305 args.skip_ifs = skip_interp_filter_search(cpi, is_single_pred);
6306 int64_t skip_rd[2] = { search_state.best_skip_rd[0],
6307 search_state.best_skip_rd[1] };
6308 int64_t this_yrd = INT64_MAX(9223372036854775807L);
6309#if CONFIG_COLLECT_COMPONENT_TIMING0
6310 start_timing(cpi, handle_inter_mode_time);
6311#endif
6312 int64_t this_rd = handle_inter_mode(
6313 cpi, tile_data, x, bsize, &rd_stats, &rd_stats_y, &rd_stats_uv, &args,
6314 ref_best_rd, tmp_buf, &x->comp_rd_buffer, &best_est_rd, do_tx_search,
6315 inter_modes_info, &motion_mode_cand, skip_rd, &inter_cost_info_from_tpl,
6316 &this_yrd);
6317#if CONFIG_COLLECT_COMPONENT_TIMING0
6318 end_timing(cpi, handle_inter_mode_time);
6319#endif
6320 if (current_frame->reference_mode != SINGLE_REFERENCE) {
6321 if (!args.skip_ifs &&
6322 sf->inter_sf.prune_comp_search_by_single_result > 0 &&
6323 is_inter_singleref_mode(this_mode)) {
6324 collect_single_states(x, &search_state, mbmi);
6325 }
6326
6327 if (sf->inter_sf.prune_comp_using_best_single_mode_ref > 0 &&
6328 is_inter_singleref_mode(this_mode))
6329 update_best_single_mode(&search_state, this_mode, ref_frame, this_rd);
6330 }
6331
6332 if (this_rd == INT64_MAX(9223372036854775807L)) continue;
6333
6334 if (mbmi->skip_txfm) {
6335 rd_stats_y.rate = 0;
6336 rd_stats_uv.rate = 0;
6337 }
6338
6339 if (sf->inter_sf.prune_compound_using_single_ref && is_single_pred &&
6340 this_rd < ref_frame_rd[ref_frame]) {
6341 ref_frame_rd[ref_frame] = this_rd;
6342 }
6343
6344 adjust_cost(cpi, x, &this_rd);
6345 adjust_rdcost(cpi, x, &rd_stats);
6346
6347 // Did this mode help, i.e., is it the new best mode
6348 if (this_rd < search_state.best_rd) {
6349 assert(IMPLIES(comp_pred,((void) sizeof (((!(comp_pred) || (cm->current_frame.reference_mode
!= SINGLE_REFERENCE))) ? 1 : 0), __extension__ ({ if ((!(comp_pred
) || (cm->current_frame.reference_mode != SINGLE_REFERENCE
))) ; else __assert_fail ("IMPLIES(comp_pred, cm->current_frame.reference_mode != SINGLE_REFERENCE)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6350
, __extension__ __PRETTY_FUNCTION__); }))
6350 cm->current_frame.reference_mode != SINGLE_REFERENCE))((void) sizeof (((!(comp_pred) || (cm->current_frame.reference_mode
!= SINGLE_REFERENCE))) ? 1 : 0), __extension__ ({ if ((!(comp_pred
) || (cm->current_frame.reference_mode != SINGLE_REFERENCE
))) ; else __assert_fail ("IMPLIES(comp_pred, cm->current_frame.reference_mode != SINGLE_REFERENCE)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6350
, __extension__ __PRETTY_FUNCTION__); }))
;
6351 search_state.best_pred_sse = x->pred_sse[ref_frame];
6352 best_inter_yrd = this_yrd;
6353 update_search_state(&search_state, rd_cost, ctx, &rd_stats, &rd_stats_y,
6354 &rd_stats_uv, mode_enum, x, do_tx_search);
6355 if (do_tx_search) search_state.best_skip_rd[0] = skip_rd[0];
6356 // skip_rd[0] is the best total rd for a skip mode so far.
6357 // skip_rd[1] is the best total rd for a skip mode so far in luma.
6358 // When do_tx_search = 1, both skip_rd[0] and skip_rd[1] are updated.
6359 // When do_tx_search = 0, skip_rd[1] is updated.
6360 search_state.best_skip_rd[1] = skip_rd[1];
6361 }
6362 if (sf->winner_mode_sf.motion_mode_for_winner_cand) {
6363 // Add this mode to motion mode candidate list for motion mode search
6364 // if using motion_mode_for_winner_cand speed feature
6365 handle_winner_cand(mbmi, &best_motion_mode_cands,
6366 max_winner_motion_mode_cand, this_rd,
6367 &motion_mode_cand, args.skip_motion_mode);
6368 }
6369
6370 /* keep record of best compound/single-only prediction */
6371 record_best_compound(cm->current_frame.reference_mode, &rd_stats, comp_pred,
6372 x->rdmult, &search_state, compmode_cost);
6373 }
6374
6375#if CONFIG_COLLECT_COMPONENT_TIMING0
6376 start_timing(cpi, evaluate_motion_mode_for_winner_candidates_time);
6377#endif
6378 if (sf->winner_mode_sf.motion_mode_for_winner_cand) {
6379 // For the single ref winner candidates, evaluate other motion modes (non
6380 // simple translation).
6381 evaluate_motion_mode_for_winner_candidates(
6382 cpi, x, rd_cost, &args, tile_data, ctx, yv12_mb,
6383 &best_motion_mode_cands, do_tx_search, bsize, &best_est_rd,
6384 &search_state, &best_inter_yrd);
6385 }
6386#if CONFIG_COLLECT_COMPONENT_TIMING0
6387 end_timing(cpi, evaluate_motion_mode_for_winner_candidates_time);
6388#endif
6389
6390#if CONFIG_COLLECT_COMPONENT_TIMING0
6391 start_timing(cpi, do_tx_search_time);
6392#endif
6393 if (do_tx_search != 1) {
6394 // A full tx search has not yet been done, do tx search for
6395 // top mode candidates
6396 tx_search_best_inter_candidates(cpi, tile_data, x, best_rd_so_far, bsize,
6397 yv12_mb, mi_row, mi_col, &search_state,
6398 rd_cost, ctx, &best_inter_yrd);
6399 }
6400#if CONFIG_COLLECT_COMPONENT_TIMING0
6401 end_timing(cpi, do_tx_search_time);
6402#endif
6403
6404#if CONFIG_COLLECT_COMPONENT_TIMING0
6405 start_timing(cpi, handle_intra_mode_time);
6406#endif
6407 // Gate intra mode evaluation if best of inter is skip except when source
6408 // variance is extremely low and also based on max intra bsize.
6409 skip_intra_modes_in_interframe(cm, x, bsize, &search_state, sf, inter_cost,
6410 intra_cost);
6411
6412 const unsigned int intra_ref_frame_cost = ref_costs_single[INTRA_FRAME];
6413 search_intra_modes_in_interframe(&search_state, cpi, x, rd_cost, bsize, ctx,
6414 &sf_args, intra_ref_frame_cost,
6415 best_inter_yrd);
6416#if CONFIG_COLLECT_COMPONENT_TIMING0
6417 end_timing(cpi, handle_intra_mode_time);
6418#endif
6419
6420#if CONFIG_COLLECT_COMPONENT_TIMING0
6421 start_timing(cpi, refine_winner_mode_tx_time);
6422#endif
6423 int winner_mode_count =
6424 sf->winner_mode_sf.multi_winner_mode_type ? x->winner_mode_count : 1;
6425 // In effect only when fast tx search speed features are enabled.
6426 refine_winner_mode_tx(
6427 cpi, x, rd_cost, bsize, ctx, &search_state.best_mode_index,
6428 &search_state.best_mbmode, yv12_mb, search_state.best_rate_y,
6429 search_state.best_rate_uv, &search_state.best_skip2, winner_mode_count);
6430#if CONFIG_COLLECT_COMPONENT_TIMING0
6431 end_timing(cpi, refine_winner_mode_tx_time);
6432#endif
6433
6434 // Initialize default mode evaluation params
6435 set_mode_eval_params(cpi, x, DEFAULT_EVAL);
6436
6437 // Only try palette mode when the best mode so far is an intra mode.
6438 const int try_palette =
6439 cpi->oxcf.tool_cfg.enable_palette &&
6440 av1_allow_palette(features->allow_screen_content_tools, mbmi->bsize) &&
6441 !is_inter_mode(search_state.best_mbmode.mode) && rd_cost->rate != INT_MAX2147483647;
6442 RD_STATS this_rd_cost;
6443 int this_skippable = 0;
6444 if (try_palette) {
6445#if CONFIG_COLLECT_COMPONENT_TIMING0
6446 start_timing(cpi, av1_search_palette_mode_time);
6447#endif
6448 this_skippable = av1_search_palette_mode(
6449 &search_state.intra_search_state, cpi, x, bsize, intra_ref_frame_cost,
6450 ctx, &this_rd_cost, search_state.best_rd);
6451#if CONFIG_COLLECT_COMPONENT_TIMING0
6452 end_timing(cpi, av1_search_palette_mode_time);
6453#endif
6454 if (this_rd_cost.rdcost < search_state.best_rd) {
6455 search_state.best_mode_index = THR_DC;
6456 mbmi->mv[0].as_int = 0;
6457 rd_cost->rate = this_rd_cost.rate;
6458 rd_cost->dist = this_rd_cost.dist;
6459 rd_cost->rdcost = this_rd_cost.rdcost;
6460 search_state.best_rd = rd_cost->rdcost;
6461 search_state.best_mbmode = *mbmi;
6462 search_state.best_skip2 = 0;
6463 search_state.best_mode_skippable = this_skippable;
6464 memcpy(ctx->blk_skip, txfm_info->blk_skip,
6465 sizeof(txfm_info->blk_skip[0]) * ctx->num_4x4_blk);
6466 av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk)do { ((void) sizeof ((sizeof(*(ctx->tx_type_map)) == sizeof
(*(xd->tx_type_map))) ? 1 : 0), __extension__ ({ if (sizeof
(*(ctx->tx_type_map)) == sizeof(*(xd->tx_type_map))) ; else
__assert_fail ("sizeof(*(ctx->tx_type_map)) == sizeof(*(xd->tx_type_map))"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6466
, __extension__ __PRETTY_FUNCTION__); })); memcpy(ctx->tx_type_map
, xd->tx_type_map, ctx->num_4x4_blk * sizeof(*(xd->tx_type_map
))); } while (0)
;
6467 }
6468 }
6469
6470 search_state.best_mbmode.skip_mode = 0;
6471 if (cm->current_frame.skip_mode_info.skip_mode_flag &&
6472 cpi->oxcf.algo_cfg.sharpness != 3 && is_comp_ref_allowed(bsize)) {
6473 const struct segmentation *const seg = &cm->seg;
6474 unsigned char segment_id = mbmi->segment_id;
6475 if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
6476 rd_pick_skip_mode(rd_cost, &search_state, cpi, x, bsize, yv12_mb);
6477 }
6478 }
6479
6480 // Make sure that the ref_mv_idx is only nonzero when we're
6481 // using a mode which can support ref_mv_idx
6482 if (search_state.best_mbmode.ref_mv_idx != 0 &&
6483 !(search_state.best_mbmode.mode == NEWMV ||
6484 search_state.best_mbmode.mode == NEW_NEWMV ||
6485 have_nearmv_in_inter_mode(search_state.best_mbmode.mode))) {
6486 search_state.best_mbmode.ref_mv_idx = 0;
6487 }
6488
6489 if (search_state.best_mode_index == THR_INVALID ||
6490 search_state.best_rd >= best_rd_so_far) {
6491 rd_cost->rate = INT_MAX2147483647;
6492 rd_cost->rdcost = INT64_MAX(9223372036854775807L);
6493 return;
6494 }
6495
6496 const InterpFilter interp_filter = features->interp_filter;
6497 assert((interp_filter == SWITCHABLE) ||((void) sizeof (((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.y_filter
) || !is_inter_block(&search_state.best_mbmode)) ? 1 : 0)
, __extension__ ({ if ((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.y_filter
) || !is_inter_block(&search_state.best_mbmode)) ; else __assert_fail
("(interp_filter == SWITCHABLE) || (interp_filter == search_state.best_mbmode.interp_filters.as_filters.y_filter) || !is_inter_block(&search_state.best_mbmode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6500
, __extension__ __PRETTY_FUNCTION__); }))
6498 (interp_filter ==((void) sizeof (((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.y_filter
) || !is_inter_block(&search_state.best_mbmode)) ? 1 : 0)
, __extension__ ({ if ((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.y_filter
) || !is_inter_block(&search_state.best_mbmode)) ; else __assert_fail
("(interp_filter == SWITCHABLE) || (interp_filter == search_state.best_mbmode.interp_filters.as_filters.y_filter) || !is_inter_block(&search_state.best_mbmode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6500
, __extension__ __PRETTY_FUNCTION__); }))
6499 search_state.best_mbmode.interp_filters.as_filters.y_filter) ||((void) sizeof (((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.y_filter
) || !is_inter_block(&search_state.best_mbmode)) ? 1 : 0)
, __extension__ ({ if ((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.y_filter
) || !is_inter_block(&search_state.best_mbmode)) ; else __assert_fail
("(interp_filter == SWITCHABLE) || (interp_filter == search_state.best_mbmode.interp_filters.as_filters.y_filter) || !is_inter_block(&search_state.best_mbmode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6500
, __extension__ __PRETTY_FUNCTION__); }))
6500 !is_inter_block(&search_state.best_mbmode))((void) sizeof (((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.y_filter
) || !is_inter_block(&search_state.best_mbmode)) ? 1 : 0)
, __extension__ ({ if ((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.y_filter
) || !is_inter_block(&search_state.best_mbmode)) ; else __assert_fail
("(interp_filter == SWITCHABLE) || (interp_filter == search_state.best_mbmode.interp_filters.as_filters.y_filter) || !is_inter_block(&search_state.best_mbmode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6500
, __extension__ __PRETTY_FUNCTION__); }))
;
6501 assert((interp_filter == SWITCHABLE) ||((void) sizeof (((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.x_filter
) || !is_inter_block(&search_state.best_mbmode)) ? 1 : 0)
, __extension__ ({ if ((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.x_filter
) || !is_inter_block(&search_state.best_mbmode)) ; else __assert_fail
("(interp_filter == SWITCHABLE) || (interp_filter == search_state.best_mbmode.interp_filters.as_filters.x_filter) || !is_inter_block(&search_state.best_mbmode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6504
, __extension__ __PRETTY_FUNCTION__); }))
6502 (interp_filter ==((void) sizeof (((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.x_filter
) || !is_inter_block(&search_state.best_mbmode)) ? 1 : 0)
, __extension__ ({ if ((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.x_filter
) || !is_inter_block(&search_state.best_mbmode)) ; else __assert_fail
("(interp_filter == SWITCHABLE) || (interp_filter == search_state.best_mbmode.interp_filters.as_filters.x_filter) || !is_inter_block(&search_state.best_mbmode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6504
, __extension__ __PRETTY_FUNCTION__); }))
6503 search_state.best_mbmode.interp_filters.as_filters.x_filter) ||((void) sizeof (((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.x_filter
) || !is_inter_block(&search_state.best_mbmode)) ? 1 : 0)
, __extension__ ({ if ((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.x_filter
) || !is_inter_block(&search_state.best_mbmode)) ; else __assert_fail
("(interp_filter == SWITCHABLE) || (interp_filter == search_state.best_mbmode.interp_filters.as_filters.x_filter) || !is_inter_block(&search_state.best_mbmode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6504
, __extension__ __PRETTY_FUNCTION__); }))
6504 !is_inter_block(&search_state.best_mbmode))((void) sizeof (((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.x_filter
) || !is_inter_block(&search_state.best_mbmode)) ? 1 : 0)
, __extension__ ({ if ((interp_filter == SWITCHABLE) || (interp_filter
== search_state.best_mbmode.interp_filters.as_filters.x_filter
) || !is_inter_block(&search_state.best_mbmode)) ; else __assert_fail
("(interp_filter == SWITCHABLE) || (interp_filter == search_state.best_mbmode.interp_filters.as_filters.x_filter) || !is_inter_block(&search_state.best_mbmode)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6504
, __extension__ __PRETTY_FUNCTION__); }))
;
6505
6506 if (!cpi->rc.is_src_frame_alt_ref && sf->inter_sf.adaptive_rd_thresh) {
6507 av1_update_rd_thresh_fact(
6508 cm, x->thresh_freq_fact, sf->inter_sf.adaptive_rd_thresh, bsize,
6509 search_state.best_mode_index, mode_start, mode_end, THR_DC, MAX_MODES);
6510 }
6511
6512 // macroblock modes
6513 *mbmi = search_state.best_mbmode;
6514 txfm_info->skip_txfm |= search_state.best_skip2;
6515
6516 // Note: this section is needed since the mode may have been forced to
6517 // GLOBALMV by the all-zero mode handling of ref-mv.
6518 if (mbmi->mode == GLOBALMV || mbmi->mode == GLOBAL_GLOBALMV) {
6519 // Correct the interp filters for GLOBALMV
6520 if (is_nontrans_global_motion(xd, xd->mi[0])) {
6521 int_interpfilters filters =
6522 av1_broadcast_interp_filter(av1_unswitchable_filter(interp_filter));
6523 assert(mbmi->interp_filters.as_int == filters.as_int)((void) sizeof ((mbmi->interp_filters.as_int == filters.as_int
) ? 1 : 0), __extension__ ({ if (mbmi->interp_filters.as_int
== filters.as_int) ; else __assert_fail ("mbmi->interp_filters.as_int == filters.as_int"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6523
, __extension__ __PRETTY_FUNCTION__); }))
;
6524 (void)filters;
6525 }
6526 }
6527
6528 txfm_info->skip_txfm |= search_state.best_mode_skippable;
6529
6530 assert(search_state.best_mode_index != THR_INVALID)((void) sizeof ((search_state.best_mode_index != THR_INVALID)
? 1 : 0), __extension__ ({ if (search_state.best_mode_index !=
THR_INVALID) ; else __assert_fail ("search_state.best_mode_index != THR_INVALID"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6530
, __extension__ __PRETTY_FUNCTION__); }))
;
6531
6532#if CONFIG_INTERNAL_STATS0
6533 store_coding_context(x, ctx, search_state.best_mode_index,
6534 search_state.best_mode_skippable);
6535#else
6536 store_coding_context(x, ctx, search_state.best_mode_skippable);
6537#endif // CONFIG_INTERNAL_STATS
6538
6539 if (mbmi->palette_mode_info.palette_size[1] > 0) {
6540 assert(try_palette)((void) sizeof ((try_palette) ? 1 : 0), __extension__ ({ if (
try_palette) ; else __assert_fail ("try_palette", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 6540, __extension__ __PRETTY_FUNCTION__); }))
;
6541 av1_restore_uv_color_map(cpi, x);
6542 }
6543}
6544
6545void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
6546 TileDataEnc *tile_data, MACROBLOCK *x,
6547 int mi_row, int mi_col,
6548 RD_STATS *rd_cost, BLOCK_SIZE bsize,
6549 PICK_MODE_CONTEXT *ctx,
6550 int64_t best_rd_so_far) {
6551 const AV1_COMMON *const cm = &cpi->common;
6552 const FeatureFlags *const features = &cm->features;
6553 MACROBLOCKD *const xd = &x->e_mbd;
6554 MB_MODE_INFO *const mbmi = xd->mi[0];
6555 unsigned char segment_id = mbmi->segment_id;
6556 const int comp_pred = 0;
6557 int i;
6558 unsigned int ref_costs_single[REF_FRAMES];
6559 unsigned int ref_costs_comp[REF_FRAMES][REF_FRAMES];
6560 const ModeCosts *mode_costs = &x->mode_costs;
6561 const int *comp_inter_cost =
6562 mode_costs->comp_inter_cost[av1_get_reference_mode_context(xd)];
6563 InterpFilter best_filter = SWITCHABLE;
6564 int64_t this_rd = INT64_MAX(9223372036854775807L);
6565 int rate2 = 0;
6566 const int64_t distortion2 = 0;
6567 (void)mi_row;
6568 (void)mi_col;
6569 (void)tile_data;
6570
6571 av1_collect_neighbors_ref_counts(xd);
6572
6573 estimate_ref_frame_costs(cm, xd, mode_costs, segment_id, ref_costs_single,
6574 ref_costs_comp);
6575
6576 for (i = 0; i < REF_FRAMES; ++i) x->pred_sse[i] = INT_MAX2147483647;
6577 for (i = LAST_FRAME; i < REF_FRAMES; ++i) x->pred_mv_sad[i] = INT_MAX2147483647;
6578
6579 rd_cost->rate = INT_MAX2147483647;
6580
6581 assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP))((void) sizeof ((segfeature_active(&cm->seg, segment_id
, SEG_LVL_SKIP)) ? 1 : 0), __extension__ ({ if (segfeature_active
(&cm->seg, segment_id, SEG_LVL_SKIP)) ; else __assert_fail
("segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6581
, __extension__ __PRETTY_FUNCTION__); }))
;
6582
6583 mbmi->palette_mode_info.palette_size[0] = 0;
6584 mbmi->palette_mode_info.palette_size[1] = 0;
6585 mbmi->filter_intra_mode_info.use_filter_intra = 0;
6586 mbmi->mode = GLOBALMV;
6587 mbmi->motion_mode = SIMPLE_TRANSLATION;
6588 mbmi->uv_mode = UV_DC_PRED;
6589 if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME))
6590 mbmi->ref_frame[0] = get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
6591 else
6592 mbmi->ref_frame[0] = LAST_FRAME;
6593 mbmi->ref_frame[1] = NONE_FRAME;
6594 mbmi->mv[0].as_int =
6595 gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
6596 features->allow_high_precision_mv, bsize, mi_col,
6597 mi_row, features->cur_frame_force_integer_mv)
6598 .as_int;
6599 mbmi->tx_size = max_txsize_lookup[bsize];
6600 x->txfm_search_info.skip_txfm = 1;
6601
6602 mbmi->ref_mv_idx = 0;
6603
6604 mbmi->motion_mode = SIMPLE_TRANSLATION;
6605 av1_count_overlappable_neighbors(cm, xd);
6606 if (is_motion_variation_allowed_bsize(bsize) && !has_second_ref(mbmi)) {
6607 int pts[SAMPLES_ARRAY_SIZE((1 << 3) * 2)], pts_inref[SAMPLES_ARRAY_SIZE((1 << 3) * 2)];
6608 mbmi->num_proj_ref = av1_findSamples(cm, xd, pts, pts_inref);
6609 // Select the samples according to motion vector difference
6610 if (mbmi->num_proj_ref > 1) {
6611 mbmi->num_proj_ref = av1_selectSamples(&mbmi->mv[0].as_mv, pts, pts_inref,
6612 mbmi->num_proj_ref, bsize);
6613 }
6614 }
6615
6616 const InterpFilter interp_filter = features->interp_filter;
6617 set_default_interp_filters(mbmi, interp_filter);
6618
6619 if (interp_filter != SWITCHABLE) {
6620 best_filter = interp_filter;
6621 } else {
6622 best_filter = EIGHTTAP_REGULAR;
6623 if (av1_is_interp_needed(xd)) {
6624 int rs;
6625 int best_rs = INT_MAX2147483647;
6626 for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
6627 mbmi->interp_filters = av1_broadcast_interp_filter(i);
6628 rs = av1_get_switchable_rate(x, xd, interp_filter,
6629 cm->seq_params->enable_dual_filter);
6630 if (rs < best_rs) {
6631 best_rs = rs;
6632 best_filter = mbmi->interp_filters.as_filters.y_filter;
6633 }
6634 }
6635 }
6636 }
6637 // Set the appropriate filter
6638 mbmi->interp_filters = av1_broadcast_interp_filter(best_filter);
6639 rate2 += av1_get_switchable_rate(x, xd, interp_filter,
6640 cm->seq_params->enable_dual_filter);
6641
6642 if (cm->current_frame.reference_mode == REFERENCE_MODE_SELECT)
6643 rate2 += comp_inter_cost[comp_pred];
6644
6645 // Estimate the reference frame signaling cost and add it
6646 // to the rolling cost variable.
6647 rate2 += ref_costs_single[LAST_FRAME];
6648 this_rd = RDCOST(x->rdmult, rate2, distortion2)((((((int64_t)(rate2)) * (x->rdmult)) + (((1 << (9))
>> 1))) >> (9)) + ((distortion2) * (1 << 7
)))
;
6649
6650 rd_cost->rate = rate2;
6651 rd_cost->dist = distortion2;
6652 rd_cost->rdcost = this_rd;
6653
6654 if (this_rd >= best_rd_so_far) {
6655 rd_cost->rate = INT_MAX2147483647;
6656 rd_cost->rdcost = INT64_MAX(9223372036854775807L);
6657 return;
6658 }
6659
6660 assert((interp_filter == SWITCHABLE) ||((void) sizeof (((interp_filter == SWITCHABLE) || (interp_filter
== mbmi->interp_filters.as_filters.y_filter)) ? 1 : 0), __extension__
({ if ((interp_filter == SWITCHABLE) || (interp_filter == mbmi
->interp_filters.as_filters.y_filter)) ; else __assert_fail
("(interp_filter == SWITCHABLE) || (interp_filter == mbmi->interp_filters.as_filters.y_filter)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6661
, __extension__ __PRETTY_FUNCTION__); }))
6661 (interp_filter == mbmi->interp_filters.as_filters.y_filter))((void) sizeof (((interp_filter == SWITCHABLE) || (interp_filter
== mbmi->interp_filters.as_filters.y_filter)) ? 1 : 0), __extension__
({ if ((interp_filter == SWITCHABLE) || (interp_filter == mbmi
->interp_filters.as_filters.y_filter)) ; else __assert_fail
("(interp_filter == SWITCHABLE) || (interp_filter == mbmi->interp_filters.as_filters.y_filter)"
, "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c", 6661
, __extension__ __PRETTY_FUNCTION__); }))
;
6662
6663 if (cpi->sf.inter_sf.adaptive_rd_thresh) {
6664 av1_update_rd_thresh_fact(cm, x->thresh_freq_fact,
6665 cpi->sf.inter_sf.adaptive_rd_thresh, bsize,
6666 THR_GLOBALMV, THR_INTER_MODE_START,
6667 THR_INTER_MODE_END, THR_DC, MAX_MODES);
6668 }
6669
6670#if CONFIG_INTERNAL_STATS0
6671 store_coding_context(x, ctx, THR_GLOBALMV, 0);
6672#else
6673 store_coding_context(x, ctx, 0);
6674#endif // CONFIG_INTERNAL_STATS
6675}
6676
6677/*!\cond */
6678struct calc_target_weighted_pred_ctxt {
6679 const OBMCBuffer *obmc_buffer;
6680 const uint8_t *tmp;
6681 int tmp_stride;
6682 int overlap;
6683};
6684/*!\endcond */
6685
6686static inline void calc_target_weighted_pred_above(
6687 MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size,
6688 int dir, MB_MODE_INFO *nb_mi, void *fun_ctxt, const int num_planes) {
6689 (void)nb_mi;
6690 (void)num_planes;
6691 (void)rel_mi_row;
6692 (void)dir;
6693
6694 struct calc_target_weighted_pred_ctxt *ctxt =
6695 (struct calc_target_weighted_pred_ctxt *)fun_ctxt;
6696
6697 const int bw = xd->width << MI_SIZE_LOG22;
6698 const uint8_t *const mask1d = av1_get_obmc_mask(ctxt->overlap);
6699
6700 int32_t *wsrc = ctxt->obmc_buffer->wsrc + (rel_mi_col * MI_SIZE(1 << 2));
6701 int32_t *mask = ctxt->obmc_buffer->mask + (rel_mi_col * MI_SIZE(1 << 2));
6702 const uint8_t *tmp = ctxt->tmp + rel_mi_col * MI_SIZE(1 << 2);
6703 const int is_hbd = is_cur_buf_hbd(xd);
6704
6705 if (!is_hbd) {
6706 for (int row = 0; row < ctxt->overlap; ++row) {
6707 const uint8_t m0 = mask1d[row];
6708 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA(1 << 6) - m0;
6709 for (int col = 0; col < op_mi_size * MI_SIZE(1 << 2); ++col) {
6710 wsrc[col] = m1 * tmp[col];
6711 mask[col] = m0;
6712 }
6713 wsrc += bw;
6714 mask += bw;
6715 tmp += ctxt->tmp_stride;
6716 }
6717 } else {
6718 const uint16_t *tmp16 = CONVERT_TO_SHORTPTR(tmp)((uint16_t *)(((uintptr_t)(tmp)) << 1));
6719
6720 for (int row = 0; row < ctxt->overlap; ++row) {
6721 const uint8_t m0 = mask1d[row];
6722 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA(1 << 6) - m0;
6723 for (int col = 0; col < op_mi_size * MI_SIZE(1 << 2); ++col) {
6724 wsrc[col] = m1 * tmp16[col];
6725 mask[col] = m0;
6726 }
6727 wsrc += bw;
6728 mask += bw;
6729 tmp16 += ctxt->tmp_stride;
6730 }
6731 }
6732}
6733
6734static inline void calc_target_weighted_pred_left(
6735 MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size,
6736 int dir, MB_MODE_INFO *nb_mi, void *fun_ctxt, const int num_planes) {
6737 (void)nb_mi;
6738 (void)num_planes;
6739 (void)rel_mi_col;
6740 (void)dir;
6741
6742 struct calc_target_weighted_pred_ctxt *ctxt =
6743 (struct calc_target_weighted_pred_ctxt *)fun_ctxt;
6744
6745 const int bw = xd->width << MI_SIZE_LOG22;
6746 const uint8_t *const mask1d = av1_get_obmc_mask(ctxt->overlap);
6747
6748 int32_t *wsrc = ctxt->obmc_buffer->wsrc + (rel_mi_row * MI_SIZE(1 << 2) * bw);
6749 int32_t *mask = ctxt->obmc_buffer->mask + (rel_mi_row * MI_SIZE(1 << 2) * bw);
6750 const uint8_t *tmp = ctxt->tmp + (rel_mi_row * MI_SIZE(1 << 2) * ctxt->tmp_stride);
6751 const int is_hbd = is_cur_buf_hbd(xd);
6752
6753 if (!is_hbd) {
6754 for (int row = 0; row < op_mi_size * MI_SIZE(1 << 2); ++row) {
6755 for (int col = 0; col < ctxt->overlap; ++col) {
6756 const uint8_t m0 = mask1d[col];
6757 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA(1 << 6) - m0;
6758 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS6) * m0 +
6759 (tmp[col] << AOM_BLEND_A64_ROUND_BITS6) * m1;
6760 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS6) * m0;
6761 }
6762 wsrc += bw;
6763 mask += bw;
6764 tmp += ctxt->tmp_stride;
6765 }
6766 } else {
6767 const uint16_t *tmp16 = CONVERT_TO_SHORTPTR(tmp)((uint16_t *)(((uintptr_t)(tmp)) << 1));
6768
6769 for (int row = 0; row < op_mi_size * MI_SIZE(1 << 2); ++row) {
6770 for (int col = 0; col < ctxt->overlap; ++col) {
6771 const uint8_t m0 = mask1d[col];
6772 const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA(1 << 6) - m0;
6773 wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS6) * m0 +
6774 (tmp16[col] << AOM_BLEND_A64_ROUND_BITS6) * m1;
6775 mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS6) * m0;
6776 }
6777 wsrc += bw;
6778 mask += bw;
6779 tmp16 += ctxt->tmp_stride;
6780 }
6781 }
6782}
6783
6784// This function has a structure similar to av1_build_obmc_inter_prediction
6785//
6786// The OBMC predictor is computed as:
6787//
6788// PObmc(x,y) =
6789// AOM_BLEND_A64(Mh(x),
6790// AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
6791// PLeft(x, y))
6792//
6793// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
6794// rounding, this can be written as:
6795//
6796// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
6797// Mh(x) * Mv(y) * P(x,y) +
6798// Mh(x) * Cv(y) * Pabove(x,y) +
6799// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
6800//
6801// Where :
6802//
6803// Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
6804// Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
6805//
6806// This function computes 'wsrc' and 'mask' as:
6807//
6808// wsrc(x, y) =
6809// AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
6810// Mh(x) * Cv(y) * Pabove(x,y) +
6811// AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
6812//
6813// mask(x, y) = Mh(x) * Mv(y)
6814//
6815// These can then be used to efficiently approximate the error for any
6816// predictor P in the context of the provided neighbouring predictors by
6817// computing:
6818//
6819// error(x, y) =
6820// wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
6821//
6822static inline void calc_target_weighted_pred(
6823 const AV1_COMMON *cm, const MACROBLOCK *x, const MACROBLOCKD *xd,
6824 const uint8_t *above, int above_stride, const uint8_t *left,
6825 int left_stride) {
6826 const BLOCK_SIZE bsize = xd->mi[0]->bsize;
6827 const int bw = xd->width << MI_SIZE_LOG22;
6828 const int bh = xd->height << MI_SIZE_LOG22;
6829 const OBMCBuffer *obmc_buffer = &x->obmc_buffer;
6830 int32_t *mask_buf = obmc_buffer->mask;
6831 int32_t *wsrc_buf = obmc_buffer->wsrc;
6832
6833 const int is_hbd = is_cur_buf_hbd(xd);
6834 const int src_scale = AOM_BLEND_A64_MAX_ALPHA(1 << 6) * AOM_BLEND_A64_MAX_ALPHA(1 << 6);
6835
6836 // plane 0 should not be sub-sampled
6837 assert(xd->plane[0].subsampling_x == 0)((void) sizeof ((xd->plane[0].subsampling_x == 0) ? 1 : 0)
, __extension__ ({ if (xd->plane[0].subsampling_x == 0) ; else
__assert_fail ("xd->plane[0].subsampling_x == 0", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 6837, __extension__ __PRETTY_FUNCTION__); }))
;
6838 assert(xd->plane[0].subsampling_y == 0)((void) sizeof ((xd->plane[0].subsampling_y == 0) ? 1 : 0)
, __extension__ ({ if (xd->plane[0].subsampling_y == 0) ; else
__assert_fail ("xd->plane[0].subsampling_y == 0", "/root/firefox-clang/third_party/aom/av1/encoder/rdopt.c"
, 6838, __extension__ __PRETTY_FUNCTION__); }))
;
6839
6840 av1_zero_array(wsrc_buf, bw * bh)memset(wsrc_buf, 0, bw * bh * sizeof(*(wsrc_buf)));
6841 for (int i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA(1 << 6);
6842
6843 // handle above row
6844 if (xd->up_available) {
6845 const int overlap =
6846 AOMMIN(block_size_high[bsize], block_size_high[BLOCK_64X64])(((block_size_high[bsize]) < (block_size_high[BLOCK_64X64]
)) ? (block_size_high[bsize]) : (block_size_high[BLOCK_64X64]
))
>> 1;
6847 struct calc_target_weighted_pred_ctxt ctxt = { obmc_buffer, above,
6848 above_stride, overlap };
6849 foreach_overlappable_nb_above(cm, (MACROBLOCKD *)xd,
6850 max_neighbor_obmc[mi_size_wide_log2[bsize]],
6851 calc_target_weighted_pred_above, &ctxt);
6852 }
6853
6854 for (int i = 0; i < bw * bh; ++i) {
6855 wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA(1 << 6);
6856 mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA(1 << 6);
6857 }
6858
6859 // handle left column
6860 if (xd->left_available) {
6861 const int overlap =
6862 AOMMIN(block_size_wide[bsize], block_size_wide[BLOCK_64X64])(((block_size_wide[bsize]) < (block_size_wide[BLOCK_64X64]
)) ? (block_size_wide[bsize]) : (block_size_wide[BLOCK_64X64]
))
>> 1;
6863 struct calc_target_weighted_pred_ctxt ctxt = { obmc_buffer, left,
6864 left_stride, overlap };
6865 foreach_overlappable_nb_left(cm, (MACROBLOCKD *)xd,
6866 max_neighbor_obmc[mi_size_high_log2[bsize]],
6867 calc_target_weighted_pred_left, &ctxt);
6868 }
6869
6870 if (!is_hbd) {
6871 const uint8_t *src = x->plane[0].src.buf;
6872
6873 for (int row = 0; row < bh; ++row) {
6874 for (int col = 0; col < bw; ++col) {
6875 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
6876 }
6877 wsrc_buf += bw;
6878 src += x->plane[0].src.stride;
6879 }
6880 } else {
6881 const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf)((uint16_t *)(((uintptr_t)(x->plane[0].src.buf)) << 1
))
;
6882
6883 for (int row = 0; row < bh; ++row) {
6884 for (int col = 0; col < bw; ++col) {
6885 wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
6886 }
6887 wsrc_buf += bw;
6888 src += x->plane[0].src.stride;
6889 }
6890 }
6891}

/root/firefox-clang/third_party/aom/av1/common/mvref_common.h

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#ifndef AOM_AV1_COMMON_MVREF_COMMON_H_
12#define AOM_AV1_COMMON_MVREF_COMMON_H_
13
14#include "av1/common/av1_common_int.h"
15#include "av1/common/blockd.h"
16
17#ifdef __cplusplus
18extern "C" {
19#endif
20
21#define MVREF_ROW_COLS3 3
22
23// Set the upper limit of the motion vector component magnitude.
24// This would make a motion vector fit in 26 bits. Plus 3 bits for the
25// reference frame index. A tuple of motion vector can hence be stored within
26// 32 bit range for efficient load/store operations.
27#define REFMVS_LIMIT((1 << 12) - 1) ((1 << 12) - 1)
28
29typedef struct position {
30 int row;
31 int col;
32} POSITION;
33
34// clamp_mv_ref
35#define MV_BORDER(16 << 3) (16 << 3) // Allow 16 pels in 1/8th pel units
36
37static inline int get_relative_dist(const OrderHintInfo *oh, int a, int b) {
38 if (!oh->enable_order_hint) return 0;
39
40 const int bits = oh->order_hint_bits_minus_1 + 1;
41
42 assert(bits >= 1)((void) sizeof ((bits >= 1) ? 1 : 0), __extension__ ({ if (
bits >= 1) ; else __assert_fail ("bits >= 1", "/root/firefox-clang/third_party/aom/av1/common/mvref_common.h"
, 42, __extension__ __PRETTY_FUNCTION__); }))
;
43 assert(a >= 0 && a < (1 << bits))((void) sizeof ((a >= 0 && a < (1 << bits
)) ? 1 : 0), __extension__ ({ if (a >= 0 && a <
(1 << bits)) ; else __assert_fail ("a >= 0 && a < (1 << bits)"
, "/root/firefox-clang/third_party/aom/av1/common/mvref_common.h"
, 43, __extension__ __PRETTY_FUNCTION__); }))
;
44 assert(b >= 0 && b < (1 << bits))((void) sizeof ((b >= 0 && b < (1 << bits
)) ? 1 : 0), __extension__ ({ if (b >= 0 && b <
(1 << bits)) ; else __assert_fail ("b >= 0 && b < (1 << bits)"
, "/root/firefox-clang/third_party/aom/av1/common/mvref_common.h"
, 44, __extension__ __PRETTY_FUNCTION__); }))
;
45
46 int diff = a - b;
47 const int m = 1 << (bits - 1);
48 diff = (diff & (m - 1)) - (diff & m);
49 return diff;
50}
51
52static inline void clamp_mv_ref(MV *mv, int bw, int bh, const MACROBLOCKD *xd) {
53 const SubpelMvLimits mv_limits = {
54 xd->mb_to_left_edge - GET_MV_SUBPEL(bw)((bw)*8) - MV_BORDER(16 << 3),
55 xd->mb_to_right_edge + GET_MV_SUBPEL(bw)((bw)*8) + MV_BORDER(16 << 3),
56 xd->mb_to_top_edge - GET_MV_SUBPEL(bh)((bh)*8) - MV_BORDER(16 << 3),
57 xd->mb_to_bottom_edge + GET_MV_SUBPEL(bh)((bh)*8) + MV_BORDER(16 << 3)
58 };
59 clamp_mv(mv, &mv_limits);
60}
61
62static inline int_mv get_block_mv(const MB_MODE_INFO *candidate, int which_mv) {
63 return candidate->mv[which_mv];
64}
65
66// Checks that the given mi_row, mi_col and search point
67// are inside the borders of the tile.
68static inline int is_inside(const TileInfo *const tile, int mi_col, int mi_row,
69 const POSITION *mi_pos) {
70 return !(mi_row + mi_pos->row < tile->mi_row_start ||
71 mi_col + mi_pos->col < tile->mi_col_start ||
72 mi_row + mi_pos->row >= tile->mi_row_end ||
73 mi_col + mi_pos->col >= tile->mi_col_end);
74}
75
76static inline int find_valid_row_offset(const TileInfo *const tile, int mi_row,
77 int row_offset) {
78 return clamp(row_offset, tile->mi_row_start - mi_row,
79 tile->mi_row_end - mi_row - 1);
80}
81
82static inline int find_valid_col_offset(const TileInfo *const tile, int mi_col,
83 int col_offset) {
84 return clamp(col_offset, tile->mi_col_start - mi_col,
85 tile->mi_col_end - mi_col - 1);
86}
87
88static inline void lower_mv_precision(MV *mv, int allow_hp, int is_integer) {
89 if (is_integer) {
90 integer_mv_precision(mv);
91 } else {
92 if (!allow_hp) {
93 if (mv->row & 1) mv->row += (mv->row > 0 ? -1 : 1);
94 if (mv->col & 1) mv->col += (mv->col > 0 ? -1 : 1);
95 }
96 }
97}
98
99static inline int8_t get_uni_comp_ref_idx(const MV_REFERENCE_FRAME *const rf) {
100 // Single ref pred
101 if (rf[1] <= INTRA_FRAME) return -1;
102
103 // Bi-directional comp ref pred
104 if ((rf[0] < BWDREF_FRAME) && (rf[1] >= BWDREF_FRAME)) return -1;
105
106 for (int8_t ref_idx = 0; ref_idx < TOTAL_UNIDIR_COMP_REFS; ++ref_idx) {
107 if (rf[0] == comp_ref0(ref_idx) && rf[1] == comp_ref1(ref_idx))
108 return ref_idx;
109 }
110 return -1;
111}
112
113static inline int8_t av1_ref_frame_type(const MV_REFERENCE_FRAME *const rf) {
114 if (rf[1] > INTRA_FRAME) {
11
Taking false branch
115 const int8_t uni_comp_ref_idx = get_uni_comp_ref_idx(rf);
116 if (uni_comp_ref_idx >= 0) {
117 assert((REF_FRAMES + FWD_REFS * BWD_REFS + uni_comp_ref_idx) <((void) sizeof (((REF_FRAMES + FWD_REFS * BWD_REFS + uni_comp_ref_idx
) < (REF_FRAMES + (FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS
))) ? 1 : 0), __extension__ ({ if ((REF_FRAMES + FWD_REFS * BWD_REFS
+ uni_comp_ref_idx) < (REF_FRAMES + (FWD_REFS * BWD_REFS +
TOTAL_UNIDIR_COMP_REFS))) ; else __assert_fail ("(REF_FRAMES + FWD_REFS * BWD_REFS + uni_comp_ref_idx) < MODE_CTX_REF_FRAMES"
, "/root/firefox-clang/third_party/aom/av1/common/mvref_common.h"
, 118, __extension__ __PRETTY_FUNCTION__); }))
118 MODE_CTX_REF_FRAMES)((void) sizeof (((REF_FRAMES + FWD_REFS * BWD_REFS + uni_comp_ref_idx
) < (REF_FRAMES + (FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS
))) ? 1 : 0), __extension__ ({ if ((REF_FRAMES + FWD_REFS * BWD_REFS
+ uni_comp_ref_idx) < (REF_FRAMES + (FWD_REFS * BWD_REFS +
TOTAL_UNIDIR_COMP_REFS))) ; else __assert_fail ("(REF_FRAMES + FWD_REFS * BWD_REFS + uni_comp_ref_idx) < MODE_CTX_REF_FRAMES"
, "/root/firefox-clang/third_party/aom/av1/common/mvref_common.h"
, 118, __extension__ __PRETTY_FUNCTION__); }))
;
119 return REF_FRAMES + FWD_REFS * BWD_REFS + uni_comp_ref_idx;
120 } else {
121 return REF_FRAMES + FWD_RF_OFFSET(rf[0])(rf[0] - LAST_FRAME) +
122 BWD_RF_OFFSET(rf[1])(rf[1] - BWDREF_FRAME) * FWD_REFS;
123 }
124 }
125
126 return rf[0];
12
Returning value
127}
128
129// clang-format off
130static MV_REFERENCE_FRAME ref_frame_map[TOTAL_COMP_REFS(FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS)][2] = {
131 { LAST_FRAME, BWDREF_FRAME }, { LAST2_FRAME, BWDREF_FRAME },
132 { LAST3_FRAME, BWDREF_FRAME }, { GOLDEN_FRAME, BWDREF_FRAME },
133
134 { LAST_FRAME, ALTREF2_FRAME }, { LAST2_FRAME, ALTREF2_FRAME },
135 { LAST3_FRAME, ALTREF2_FRAME }, { GOLDEN_FRAME, ALTREF2_FRAME },
136
137 { LAST_FRAME, ALTREF_FRAME }, { LAST2_FRAME, ALTREF_FRAME },
138 { LAST3_FRAME, ALTREF_FRAME }, { GOLDEN_FRAME, ALTREF_FRAME },
139
140 { LAST_FRAME, LAST2_FRAME }, { LAST_FRAME, LAST3_FRAME },
141 { LAST_FRAME, GOLDEN_FRAME }, { BWDREF_FRAME, ALTREF_FRAME },
142
143 // NOTE: Following reference frame pairs are not supported to be explicitly
144 // signalled, but they are possibly chosen by the use of skip_mode,
145 // which may use the most recent one-sided reference frame pair.
146 { LAST2_FRAME, LAST3_FRAME }, { LAST2_FRAME, GOLDEN_FRAME },
147 { LAST3_FRAME, GOLDEN_FRAME }, {BWDREF_FRAME, ALTREF2_FRAME},
148 { ALTREF2_FRAME, ALTREF_FRAME }
149};
150// clang-format on
151
152static inline void av1_set_ref_frame(MV_REFERENCE_FRAME *rf,
153 MV_REFERENCE_FRAME ref_frame_type) {
154 if (ref_frame_type >= REF_FRAMES) {
155 rf[0] = ref_frame_map[ref_frame_type - REF_FRAMES][0];
156 rf[1] = ref_frame_map[ref_frame_type - REF_FRAMES][1];
157 } else {
158 assert(ref_frame_type > NONE_FRAME)((void) sizeof ((ref_frame_type > NONE_FRAME) ? 1 : 0), __extension__
({ if (ref_frame_type > NONE_FRAME) ; else __assert_fail (
"ref_frame_type > NONE_FRAME", "/root/firefox-clang/third_party/aom/av1/common/mvref_common.h"
, 158, __extension__ __PRETTY_FUNCTION__); }))
;
159 rf[0] = ref_frame_type;
160 rf[1] = NONE_FRAME;
161 }
162}
163
164static uint16_t compound_mode_ctx_map[3][COMP_NEWMV_CTXS5] = {
165 { 0, 1, 1, 1, 1 },
166 { 1, 2, 3, 4, 4 },
167 { 4, 4, 5, 6, 7 },
168};
169
170static inline int16_t av1_mode_context_analyzer(
171 const int16_t *const mode_context, const MV_REFERENCE_FRAME *const rf) {
172 const int8_t ref_frame = av1_ref_frame_type(rf);
173
174 if (rf[1] <= INTRA_FRAME) return mode_context[ref_frame];
175
176 const int16_t newmv_ctx = mode_context[ref_frame] & NEWMV_CTX_MASK((1 << 3) - 1);
177 const int16_t refmv_ctx =
178 (mode_context[ref_frame] >> REFMV_OFFSET4) & REFMV_CTX_MASK((1 << (8 - 4)) - 1);
179
180 const int16_t comp_ctx = compound_mode_ctx_map[refmv_ctx >> 1][AOMMIN((((newmv_ctx) < (5 - 1)) ? (newmv_ctx) : (5 - 1))
181 newmv_ctx, COMP_NEWMV_CTXS - 1)(((newmv_ctx) < (5 - 1)) ? (newmv_ctx) : (5 - 1))];
182 return comp_ctx;
183}
184
185static inline uint8_t av1_drl_ctx(const uint16_t *ref_mv_weight, int ref_idx) {
186 if (ref_mv_weight[ref_idx] >= REF_CAT_LEVEL640 &&
187 ref_mv_weight[ref_idx + 1] >= REF_CAT_LEVEL640)
188 return 0;
189
190 if (ref_mv_weight[ref_idx] >= REF_CAT_LEVEL640 &&
191 ref_mv_weight[ref_idx + 1] < REF_CAT_LEVEL640)
192 return 1;
193
194 if (ref_mv_weight[ref_idx] < REF_CAT_LEVEL640 &&
195 ref_mv_weight[ref_idx + 1] < REF_CAT_LEVEL640)
196 return 2;
197
198 return 0;
199}
200
201void av1_setup_frame_buf_refs(AV1_COMMON *cm);
202void av1_setup_frame_sign_bias(AV1_COMMON *cm);
203void av1_setup_skip_mode_allowed(AV1_COMMON *cm);
204void av1_calculate_ref_frame_side(AV1_COMMON *cm);
205void av1_setup_motion_field(AV1_COMMON *cm);
206void av1_set_frame_refs(AV1_COMMON *const cm, int *remapped_ref_idx,
207 int lst_map_idx, int gld_map_idx);
208
209static inline void av1_collect_neighbors_ref_counts(MACROBLOCKD *const xd) {
210 av1_zero(xd->neighbors_ref_counts)memset(&(xd->neighbors_ref_counts), 0, sizeof(xd->neighbors_ref_counts
))
;
211
212 uint8_t *const ref_counts = xd->neighbors_ref_counts;
213
214 const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
215 const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
216 const int above_in_image = xd->up_available;
217 const int left_in_image = xd->left_available;
218
219 // Above neighbor
220 if (above_in_image && is_inter_block(above_mbmi)) {
221 ref_counts[above_mbmi->ref_frame[0]]++;
222 if (has_second_ref(above_mbmi)) {
223 ref_counts[above_mbmi->ref_frame[1]]++;
224 }
225 }
226
227 // Left neighbor
228 if (left_in_image && is_inter_block(left_mbmi)) {
229 ref_counts[left_mbmi->ref_frame[0]]++;
230 if (has_second_ref(left_mbmi)) {
231 ref_counts[left_mbmi->ref_frame[1]]++;
232 }
233 }
234}
235
236void av1_get_mv_projection(MV *output, MV ref, int num, int den);
237
238void av1_copy_frame_mvs(const AV1_COMMON *const cm,
239 const MB_MODE_INFO *const mi, int mi_row, int mi_col,
240 int x_mis, int y_mis);
241
242// The global_mvs output parameter points to an array of REF_FRAMES elements.
243// The caller may pass a null global_mvs if it does not need the global_mvs
244// output.
245void av1_find_mv_refs(const AV1_COMMON *cm, const MACROBLOCKD *xd,
246 MB_MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
247 uint8_t ref_mv_count[MODE_CTX_REF_FRAMES(REF_FRAMES + (FWD_REFS * BWD_REFS + TOTAL_UNIDIR_COMP_REFS))],
248 CANDIDATE_MV ref_mv_stack[][MAX_REF_MV_STACK_SIZE8],
249 uint16_t ref_mv_weight[][MAX_REF_MV_STACK_SIZE8],
250 int_mv mv_ref_list[][MAX_MV_REF_CANDIDATES2],
251 int_mv *global_mvs, int16_t *mode_context);
252
253// check a list of motion vectors by sad score using a number rows of pixels
254// above and a number cols of pixels in the left to select the one with best
255// score to use as ref motion vector
256void av1_find_best_ref_mvs(int allow_hp, int_mv *mvlist, int_mv *nearest_mv,
257 int_mv *near_mv, int is_integer);
258
259uint8_t av1_selectSamples(MV *mv, int *pts, int *pts_inref, int len,
260 BLOCK_SIZE bsize);
261uint8_t av1_findSamples(const AV1_COMMON *cm, MACROBLOCKD *xd, int *pts,
262 int *pts_inref);
263
264#define INTRABC_DELAY_PIXELS256 256 // Delay of 256 pixels
265#define INTRABC_DELAY_SB64(256 / 64) (INTRABC_DELAY_PIXELS256 / 64)
266
267static inline void av1_find_ref_dv(int_mv *ref_dv, const TileInfo *const tile,
268 int mib_size, int mi_row) {
269 if (mi_row - mib_size < tile->mi_row_start) {
270 ref_dv->as_fullmv.row = 0;
271 ref_dv->as_fullmv.col = -MI_SIZE(1 << 2) * mib_size - INTRABC_DELAY_PIXELS256;
272 } else {
273 ref_dv->as_fullmv.row = -MI_SIZE(1 << 2) * mib_size;
274 ref_dv->as_fullmv.col = 0;
275 }
276 convert_fullmv_to_mv(ref_dv);
277}
278
279static inline int av1_is_dv_valid(const MV dv, const AV1_COMMON *cm,
280 const MACROBLOCKD *xd, int mi_row, int mi_col,
281 BLOCK_SIZE bsize, int mib_size_log2) {
282 const int bw = block_size_wide[bsize];
283 const int bh = block_size_high[bsize];
284 const int SCALE_PX_TO_MV = 8;
285 // Disallow subpixel for now
286 // SUBPEL_MASK is not the correct scale
287 if (((dv.row & (SCALE_PX_TO_MV - 1)) || (dv.col & (SCALE_PX_TO_MV - 1))))
288 return 0;
289
290 const TileInfo *const tile = &xd->tile;
291 // Is the source top-left inside the current tile?
292 const int src_top_edge = mi_row * MI_SIZE(1 << 2) * SCALE_PX_TO_MV + dv.row;
293 const int tile_top_edge = tile->mi_row_start * MI_SIZE(1 << 2) * SCALE_PX_TO_MV;
294 if (src_top_edge < tile_top_edge) return 0;
295 const int src_left_edge = mi_col * MI_SIZE(1 << 2) * SCALE_PX_TO_MV + dv.col;
296 const int tile_left_edge = tile->mi_col_start * MI_SIZE(1 << 2) * SCALE_PX_TO_MV;
297 if (src_left_edge < tile_left_edge) return 0;
298 // Is the bottom right inside the current tile?
299 const int src_bottom_edge = (mi_row * MI_SIZE(1 << 2) + bh) * SCALE_PX_TO_MV + dv.row;
300 const int tile_bottom_edge = tile->mi_row_end * MI_SIZE(1 << 2) * SCALE_PX_TO_MV;
301 if (src_bottom_edge > tile_bottom_edge) return 0;
302 const int src_right_edge = (mi_col * MI_SIZE(1 << 2) + bw) * SCALE_PX_TO_MV + dv.col;
303 const int tile_right_edge = tile->mi_col_end * MI_SIZE(1 << 2) * SCALE_PX_TO_MV;
304 if (src_right_edge > tile_right_edge) return 0;
305
306 // Special case for sub 8x8 chroma cases, to prevent referring to chroma
307 // pixels outside current tile.
308 if (xd->is_chroma_ref && av1_num_planes(cm) > 1) {
309 const struct macroblockd_plane *const pd = &xd->plane[1];
310 if (bw < 8 && pd->subsampling_x)
311 if (src_left_edge < tile_left_edge + 4 * SCALE_PX_TO_MV) return 0;
312 if (bh < 8 && pd->subsampling_y)
313 if (src_top_edge < tile_top_edge + 4 * SCALE_PX_TO_MV) return 0;
314 }
315
316 // Is the bottom right within an already coded SB? Also consider additional
317 // constraints to facilitate HW decoder.
318 const int max_mib_size = 1 << mib_size_log2;
319 const int active_sb_row = mi_row >> mib_size_log2;
320 const int active_sb64_col = (mi_col * MI_SIZE(1 << 2)) >> 6;
321 const int sb_size = max_mib_size * MI_SIZE(1 << 2);
322 const int src_sb_row = ((src_bottom_edge >> 3) - 1) / sb_size;
323 const int src_sb64_col = ((src_right_edge >> 3) - 1) >> 6;
324 const int total_sb64_per_row =
325 ((tile->mi_col_end - tile->mi_col_start - 1) >> 4) + 1;
326 const int active_sb64 = active_sb_row * total_sb64_per_row + active_sb64_col;
327 const int src_sb64 = src_sb_row * total_sb64_per_row + src_sb64_col;
328 if (src_sb64 >= active_sb64 - INTRABC_DELAY_SB64(256 / 64)) return 0;
329
330 // Wavefront constraint: use only top left area of frame for reference.
331 const int gradient = 1 + INTRABC_DELAY_SB64(256 / 64) + (sb_size > 64);
332 const int wf_offset = gradient * (active_sb_row - src_sb_row);
333 if (src_sb_row > active_sb_row ||
334 src_sb64_col >= active_sb64_col - INTRABC_DELAY_SB64(256 / 64) + wf_offset)
335 return 0;
336
337 return 1;
338}
339
340#ifdef __cplusplus
341} // extern "C"
342#endif
343
344#endif // AOM_AV1_COMMON_MVREF_COMMON_H_