1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker * Copyright (c) 2016, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker *
4*77c1e3ccSAndroid Build Coastguard Worker * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker */
11*77c1e3ccSAndroid Build Coastguard Worker
12*77c1e3ccSAndroid Build Coastguard Worker #ifndef AOM_AV1_COMMON_CFL_H_
13*77c1e3ccSAndroid Build Coastguard Worker #define AOM_AV1_COMMON_CFL_H_
14*77c1e3ccSAndroid Build Coastguard Worker
15*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/av1_common_int.h"
16*77c1e3ccSAndroid Build Coastguard Worker #include "av1/common/blockd.h"
17*77c1e3ccSAndroid Build Coastguard Worker
18*77c1e3ccSAndroid Build Coastguard Worker // Can we use CfL for the current block?
is_cfl_allowed(const MACROBLOCKD * xd)19*77c1e3ccSAndroid Build Coastguard Worker static inline CFL_ALLOWED_TYPE is_cfl_allowed(const MACROBLOCKD *xd) {
20*77c1e3ccSAndroid Build Coastguard Worker const MB_MODE_INFO *mbmi = xd->mi[0];
21*77c1e3ccSAndroid Build Coastguard Worker const BLOCK_SIZE bsize = mbmi->bsize;
22*77c1e3ccSAndroid Build Coastguard Worker assert(bsize < BLOCK_SIZES_ALL);
23*77c1e3ccSAndroid Build Coastguard Worker if (xd->lossless[mbmi->segment_id]) {
24*77c1e3ccSAndroid Build Coastguard Worker // In lossless, CfL is available when the partition size is equal to the
25*77c1e3ccSAndroid Build Coastguard Worker // transform size.
26*77c1e3ccSAndroid Build Coastguard Worker const int ssx = xd->plane[AOM_PLANE_U].subsampling_x;
27*77c1e3ccSAndroid Build Coastguard Worker const int ssy = xd->plane[AOM_PLANE_U].subsampling_y;
28*77c1e3ccSAndroid Build Coastguard Worker const int plane_bsize = get_plane_block_size(bsize, ssx, ssy);
29*77c1e3ccSAndroid Build Coastguard Worker return (CFL_ALLOWED_TYPE)(plane_bsize == BLOCK_4X4);
30*77c1e3ccSAndroid Build Coastguard Worker }
31*77c1e3ccSAndroid Build Coastguard Worker // Spec: CfL is available to luma partitions lesser than or equal to 32x32
32*77c1e3ccSAndroid Build Coastguard Worker return (CFL_ALLOWED_TYPE)(block_size_wide[bsize] <= 32 &&
33*77c1e3ccSAndroid Build Coastguard Worker block_size_high[bsize] <= 32);
34*77c1e3ccSAndroid Build Coastguard Worker }
35*77c1e3ccSAndroid Build Coastguard Worker
36*77c1e3ccSAndroid Build Coastguard Worker // Do we need to save the luma pixels from the current block,
37*77c1e3ccSAndroid Build Coastguard Worker // for a possible future CfL prediction?
store_cfl_required(const AV1_COMMON * cm,const MACROBLOCKD * xd)38*77c1e3ccSAndroid Build Coastguard Worker static inline CFL_ALLOWED_TYPE store_cfl_required(const AV1_COMMON *cm,
39*77c1e3ccSAndroid Build Coastguard Worker const MACROBLOCKD *xd) {
40*77c1e3ccSAndroid Build Coastguard Worker const MB_MODE_INFO *mbmi = xd->mi[0];
41*77c1e3ccSAndroid Build Coastguard Worker
42*77c1e3ccSAndroid Build Coastguard Worker if (cm->seq_params->monochrome) return CFL_DISALLOWED;
43*77c1e3ccSAndroid Build Coastguard Worker
44*77c1e3ccSAndroid Build Coastguard Worker if (!xd->is_chroma_ref) {
45*77c1e3ccSAndroid Build Coastguard Worker // For non-chroma-reference blocks, we should always store the luma pixels,
46*77c1e3ccSAndroid Build Coastguard Worker // in case the corresponding chroma-reference block uses CfL.
47*77c1e3ccSAndroid Build Coastguard Worker // Note that this can only happen for block sizes which are <8 on
48*77c1e3ccSAndroid Build Coastguard Worker // their shortest side, as otherwise they would be chroma reference
49*77c1e3ccSAndroid Build Coastguard Worker // blocks.
50*77c1e3ccSAndroid Build Coastguard Worker return CFL_ALLOWED;
51*77c1e3ccSAndroid Build Coastguard Worker }
52*77c1e3ccSAndroid Build Coastguard Worker
53*77c1e3ccSAndroid Build Coastguard Worker // If this block has chroma information, we know whether we're
54*77c1e3ccSAndroid Build Coastguard Worker // actually going to perform a CfL prediction
55*77c1e3ccSAndroid Build Coastguard Worker return (CFL_ALLOWED_TYPE)(!is_inter_block(mbmi) &&
56*77c1e3ccSAndroid Build Coastguard Worker mbmi->uv_mode == UV_CFL_PRED);
57*77c1e3ccSAndroid Build Coastguard Worker }
58*77c1e3ccSAndroid Build Coastguard Worker
get_scaled_luma_q0(int alpha_q3,int16_t pred_buf_q3)59*77c1e3ccSAndroid Build Coastguard Worker static inline int get_scaled_luma_q0(int alpha_q3, int16_t pred_buf_q3) {
60*77c1e3ccSAndroid Build Coastguard Worker int scaled_luma_q6 = alpha_q3 * pred_buf_q3;
61*77c1e3ccSAndroid Build Coastguard Worker return ROUND_POWER_OF_TWO_SIGNED(scaled_luma_q6, 6);
62*77c1e3ccSAndroid Build Coastguard Worker }
63*77c1e3ccSAndroid Build Coastguard Worker
get_cfl_pred_type(int plane)64*77c1e3ccSAndroid Build Coastguard Worker static inline CFL_PRED_TYPE get_cfl_pred_type(int plane) {
65*77c1e3ccSAndroid Build Coastguard Worker assert(plane > 0);
66*77c1e3ccSAndroid Build Coastguard Worker return (CFL_PRED_TYPE)(plane - 1);
67*77c1e3ccSAndroid Build Coastguard Worker }
68*77c1e3ccSAndroid Build Coastguard Worker
clear_cfl_dc_pred_cache_flags(CFL_CTX * cfl)69*77c1e3ccSAndroid Build Coastguard Worker static inline void clear_cfl_dc_pred_cache_flags(CFL_CTX *cfl) {
70*77c1e3ccSAndroid Build Coastguard Worker cfl->use_dc_pred_cache = false;
71*77c1e3ccSAndroid Build Coastguard Worker cfl->dc_pred_is_cached[CFL_PRED_U] = false;
72*77c1e3ccSAndroid Build Coastguard Worker cfl->dc_pred_is_cached[CFL_PRED_V] = false;
73*77c1e3ccSAndroid Build Coastguard Worker }
74*77c1e3ccSAndroid Build Coastguard Worker
75*77c1e3ccSAndroid Build Coastguard Worker void av1_cfl_predict_block(MACROBLOCKD *const xd, uint8_t *dst, int dst_stride,
76*77c1e3ccSAndroid Build Coastguard Worker TX_SIZE tx_size, int plane);
77*77c1e3ccSAndroid Build Coastguard Worker
78*77c1e3ccSAndroid Build Coastguard Worker void cfl_store_block(MACROBLOCKD *const xd, BLOCK_SIZE bsize, TX_SIZE tx_size);
79*77c1e3ccSAndroid Build Coastguard Worker
80*77c1e3ccSAndroid Build Coastguard Worker void cfl_store_tx(MACROBLOCKD *const xd, int row, int col, TX_SIZE tx_size,
81*77c1e3ccSAndroid Build Coastguard Worker BLOCK_SIZE bsize);
82*77c1e3ccSAndroid Build Coastguard Worker
83*77c1e3ccSAndroid Build Coastguard Worker void cfl_store_dc_pred(MACROBLOCKD *const xd, const uint8_t *input,
84*77c1e3ccSAndroid Build Coastguard Worker CFL_PRED_TYPE pred_plane, int width);
85*77c1e3ccSAndroid Build Coastguard Worker
86*77c1e3ccSAndroid Build Coastguard Worker void cfl_load_dc_pred(MACROBLOCKD *const xd, uint8_t *dst, int dst_stride,
87*77c1e3ccSAndroid Build Coastguard Worker TX_SIZE tx_size, CFL_PRED_TYPE pred_plane);
88*77c1e3ccSAndroid Build Coastguard Worker
89*77c1e3ccSAndroid Build Coastguard Worker // Allows the CFL_SUBSAMPLE function to switch types depending on the bitdepth.
90*77c1e3ccSAndroid Build Coastguard Worker #define CFL_lbd_TYPE uint8_t *cfl_type
91*77c1e3ccSAndroid Build Coastguard Worker #define CFL_hbd_TYPE uint16_t *cfl_type
92*77c1e3ccSAndroid Build Coastguard Worker
93*77c1e3ccSAndroid Build Coastguard Worker // Declare a size-specific wrapper for the size-generic function. The compiler
94*77c1e3ccSAndroid Build Coastguard Worker // will inline the size generic function in here, the advantage is that the size
95*77c1e3ccSAndroid Build Coastguard Worker // will be constant allowing for loop unrolling and other constant propagated
96*77c1e3ccSAndroid Build Coastguard Worker // goodness.
97*77c1e3ccSAndroid Build Coastguard Worker #define CFL_SUBSAMPLE(arch, sub, bd, width, height) \
98*77c1e3ccSAndroid Build Coastguard Worker void cfl_subsample_##bd##_##sub##_##width##x##height##_##arch( \
99*77c1e3ccSAndroid Build Coastguard Worker const CFL_##bd##_TYPE, int input_stride, uint16_t *output_q3); \
100*77c1e3ccSAndroid Build Coastguard Worker void cfl_subsample_##bd##_##sub##_##width##x##height##_##arch( \
101*77c1e3ccSAndroid Build Coastguard Worker const CFL_##bd##_TYPE, int input_stride, uint16_t *output_q3) { \
102*77c1e3ccSAndroid Build Coastguard Worker cfl_luma_subsampling_##sub##_##bd##_##arch(cfl_type, input_stride, \
103*77c1e3ccSAndroid Build Coastguard Worker output_q3, width, height); \
104*77c1e3ccSAndroid Build Coastguard Worker }
105*77c1e3ccSAndroid Build Coastguard Worker
106*77c1e3ccSAndroid Build Coastguard Worker // Declare size-specific wrappers for all valid CfL sizes.
107*77c1e3ccSAndroid Build Coastguard Worker #define CFL_SUBSAMPLE_FUNCTIONS(arch, sub, bd) \
108*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 4, 4) \
109*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 8, 8) \
110*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 16, 16) \
111*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 32, 32) \
112*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 4, 8) \
113*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 8, 4) \
114*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 8, 16) \
115*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 16, 8) \
116*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 16, 32) \
117*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 32, 16) \
118*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 4, 16) \
119*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 16, 4) \
120*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 8, 32) \
121*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE(arch, sub, bd, 32, 8) \
122*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_fn cfl_get_luma_subsampling_##sub##_##bd##_##arch( \
123*77c1e3ccSAndroid Build Coastguard Worker TX_SIZE tx_size) { \
124*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE_FUNCTION_ARRAY(arch, sub, bd) \
125*77c1e3ccSAndroid Build Coastguard Worker return subfn_##sub[tx_size]; \
126*77c1e3ccSAndroid Build Coastguard Worker }
127*77c1e3ccSAndroid Build Coastguard Worker
128*77c1e3ccSAndroid Build Coastguard Worker // Declare an architecture-specific array of function pointers for size-specific
129*77c1e3ccSAndroid Build Coastguard Worker // wrappers.
130*77c1e3ccSAndroid Build Coastguard Worker #define CFL_SUBSAMPLE_FUNCTION_ARRAY(arch, sub, bd) \
131*77c1e3ccSAndroid Build Coastguard Worker static const cfl_subsample_##bd##_fn subfn_##sub[TX_SIZES_ALL] = { \
132*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_4x4_##arch, /* 4x4 */ \
133*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_8x8_##arch, /* 8x8 */ \
134*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_16x16_##arch, /* 16x16 */ \
135*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_32x32_##arch, /* 32x32 */ \
136*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 64x64 (invalid CFL size) */ \
137*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_4x8_##arch, /* 4x8 */ \
138*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_8x4_##arch, /* 8x4 */ \
139*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_8x16_##arch, /* 8x16 */ \
140*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_16x8_##arch, /* 16x8 */ \
141*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_16x32_##arch, /* 16x32 */ \
142*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_32x16_##arch, /* 32x16 */ \
143*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 32x64 (invalid CFL size) */ \
144*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 64x32 (invalid CFL size) */ \
145*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_4x16_##arch, /* 4x16 */ \
146*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_16x4_##arch, /* 16x4 */ \
147*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_8x32_##arch, /* 8x32 */ \
148*77c1e3ccSAndroid Build Coastguard Worker cfl_subsample_##bd##_##sub##_32x8_##arch, /* 32x8 */ \
149*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 16x64 (invalid CFL size) */ \
150*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 64x16 (invalid CFL size) */ \
151*77c1e3ccSAndroid Build Coastguard Worker };
152*77c1e3ccSAndroid Build Coastguard Worker
153*77c1e3ccSAndroid Build Coastguard Worker // The RTCD script does not support passing in an array, so we wrap it in this
154*77c1e3ccSAndroid Build Coastguard Worker // function.
155*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_AV1_HIGHBITDEPTH
156*77c1e3ccSAndroid Build Coastguard Worker #define CFL_GET_SUBSAMPLE_FUNCTION(arch) \
157*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE_FUNCTIONS(arch, 420, lbd) \
158*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE_FUNCTIONS(arch, 422, lbd) \
159*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE_FUNCTIONS(arch, 444, lbd) \
160*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE_FUNCTIONS(arch, 420, hbd) \
161*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE_FUNCTIONS(arch, 422, hbd) \
162*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE_FUNCTIONS(arch, 444, hbd)
163*77c1e3ccSAndroid Build Coastguard Worker #else
164*77c1e3ccSAndroid Build Coastguard Worker #define CFL_GET_SUBSAMPLE_FUNCTION(arch) \
165*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE_FUNCTIONS(arch, 420, lbd) \
166*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE_FUNCTIONS(arch, 422, lbd) \
167*77c1e3ccSAndroid Build Coastguard Worker CFL_SUBSAMPLE_FUNCTIONS(arch, 444, lbd)
168*77c1e3ccSAndroid Build Coastguard Worker #endif
169*77c1e3ccSAndroid Build Coastguard Worker
170*77c1e3ccSAndroid Build Coastguard Worker // Declare a size-specific wrapper for the size-generic function. The compiler
171*77c1e3ccSAndroid Build Coastguard Worker // will inline the size generic function in here, the advantage is that the size
172*77c1e3ccSAndroid Build Coastguard Worker // will be constant allowing for loop unrolling and other constant propagated
173*77c1e3ccSAndroid Build Coastguard Worker // goodness.
174*77c1e3ccSAndroid Build Coastguard Worker #define CFL_SUB_AVG_X(arch, width, height, round_offset, num_pel_log2) \
175*77c1e3ccSAndroid Build Coastguard Worker void cfl_subtract_average_##width##x##height##_##arch(const uint16_t *src, \
176*77c1e3ccSAndroid Build Coastguard Worker int16_t *dst); \
177*77c1e3ccSAndroid Build Coastguard Worker void cfl_subtract_average_##width##x##height##_##arch(const uint16_t *src, \
178*77c1e3ccSAndroid Build Coastguard Worker int16_t *dst) { \
179*77c1e3ccSAndroid Build Coastguard Worker subtract_average_##arch(src, dst, width, height, round_offset, \
180*77c1e3ccSAndroid Build Coastguard Worker num_pel_log2); \
181*77c1e3ccSAndroid Build Coastguard Worker }
182*77c1e3ccSAndroid Build Coastguard Worker
183*77c1e3ccSAndroid Build Coastguard Worker // Declare size-specific wrappers for all valid CfL sizes.
184*77c1e3ccSAndroid Build Coastguard Worker #define CFL_SUB_AVG_FN(arch) \
185*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 4, 4, 8, 4) \
186*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 4, 8, 16, 5) \
187*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 4, 16, 32, 6) \
188*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 8, 4, 16, 5) \
189*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 8, 8, 32, 6) \
190*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 8, 16, 64, 7) \
191*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 8, 32, 128, 8) \
192*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 16, 4, 32, 6) \
193*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 16, 8, 64, 7) \
194*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 16, 16, 128, 8) \
195*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 16, 32, 256, 9) \
196*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 32, 8, 128, 8) \
197*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 32, 16, 256, 9) \
198*77c1e3ccSAndroid Build Coastguard Worker CFL_SUB_AVG_X(arch, 32, 32, 512, 10) \
199*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_fn cfl_get_subtract_average_fn_##arch( \
200*77c1e3ccSAndroid Build Coastguard Worker TX_SIZE tx_size) { \
201*77c1e3ccSAndroid Build Coastguard Worker static const cfl_subtract_average_fn sub_avg[TX_SIZES_ALL] = { \
202*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_4x4_##arch, /* 4x4 */ \
203*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_8x8_##arch, /* 8x8 */ \
204*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_16x16_##arch, /* 16x16 */ \
205*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_32x32_##arch, /* 32x32 */ \
206*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 64x64 (invalid CFL size) */ \
207*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_4x8_##arch, /* 4x8 */ \
208*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_8x4_##arch, /* 8x4 */ \
209*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_8x16_##arch, /* 8x16 */ \
210*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_16x8_##arch, /* 16x8 */ \
211*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_16x32_##arch, /* 16x32 */ \
212*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_32x16_##arch, /* 32x16 */ \
213*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 32x64 (invalid CFL size) */ \
214*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 64x32 (invalid CFL size) */ \
215*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_4x16_##arch, /* 4x16 (invalid CFL size) */ \
216*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_16x4_##arch, /* 16x4 (invalid CFL size) */ \
217*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_8x32_##arch, /* 8x32 (invalid CFL size) */ \
218*77c1e3ccSAndroid Build Coastguard Worker cfl_subtract_average_32x8_##arch, /* 32x8 (invalid CFL size) */ \
219*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 16x64 (invalid CFL size) */ \
220*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 64x16 (invalid CFL size) */ \
221*77c1e3ccSAndroid Build Coastguard Worker }; \
222*77c1e3ccSAndroid Build Coastguard Worker /* Modulo TX_SIZES_ALL to ensure that an attacker won't be able to */ \
223*77c1e3ccSAndroid Build Coastguard Worker /* index the function pointer array out of bounds. */ \
224*77c1e3ccSAndroid Build Coastguard Worker return sub_avg[tx_size % TX_SIZES_ALL]; \
225*77c1e3ccSAndroid Build Coastguard Worker }
226*77c1e3ccSAndroid Build Coastguard Worker
227*77c1e3ccSAndroid Build Coastguard Worker #define CFL_PREDICT_lbd(arch, width, height) \
228*77c1e3ccSAndroid Build Coastguard Worker void cfl_predict_lbd_##width##x##height##_##arch( \
229*77c1e3ccSAndroid Build Coastguard Worker const int16_t *pred_buf_q3, uint8_t *dst, int dst_stride, int alpha_q3); \
230*77c1e3ccSAndroid Build Coastguard Worker void cfl_predict_lbd_##width##x##height##_##arch( \
231*77c1e3ccSAndroid Build Coastguard Worker const int16_t *pred_buf_q3, uint8_t *dst, int dst_stride, \
232*77c1e3ccSAndroid Build Coastguard Worker int alpha_q3) { \
233*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_lbd_##arch(pred_buf_q3, dst, dst_stride, alpha_q3, width, \
234*77c1e3ccSAndroid Build Coastguard Worker height); \
235*77c1e3ccSAndroid Build Coastguard Worker }
236*77c1e3ccSAndroid Build Coastguard Worker
237*77c1e3ccSAndroid Build Coastguard Worker #if CONFIG_AV1_HIGHBITDEPTH
238*77c1e3ccSAndroid Build Coastguard Worker #define CFL_PREDICT_hbd(arch, width, height) \
239*77c1e3ccSAndroid Build Coastguard Worker void cfl_predict_hbd_##width##x##height##_##arch( \
240*77c1e3ccSAndroid Build Coastguard Worker const int16_t *pred_buf_q3, uint16_t *dst, int dst_stride, int alpha_q3, \
241*77c1e3ccSAndroid Build Coastguard Worker int bd); \
242*77c1e3ccSAndroid Build Coastguard Worker void cfl_predict_hbd_##width##x##height##_##arch( \
243*77c1e3ccSAndroid Build Coastguard Worker const int16_t *pred_buf_q3, uint16_t *dst, int dst_stride, int alpha_q3, \
244*77c1e3ccSAndroid Build Coastguard Worker int bd) { \
245*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_hbd_##arch(pred_buf_q3, dst, dst_stride, alpha_q3, bd, width, \
246*77c1e3ccSAndroid Build Coastguard Worker height); \
247*77c1e3ccSAndroid Build Coastguard Worker }
248*77c1e3ccSAndroid Build Coastguard Worker #endif
249*77c1e3ccSAndroid Build Coastguard Worker
250*77c1e3ccSAndroid Build Coastguard Worker // This wrapper exists because clang format does not like calling macros with
251*77c1e3ccSAndroid Build Coastguard Worker // lowercase letters.
252*77c1e3ccSAndroid Build Coastguard Worker #define CFL_PREDICT_X(arch, width, height, bd) \
253*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_##bd(arch, width, height)
254*77c1e3ccSAndroid Build Coastguard Worker
255*77c1e3ccSAndroid Build Coastguard Worker #define CFL_PREDICT_FN(arch, bd) \
256*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 4, 4, bd) \
257*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 4, 8, bd) \
258*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 4, 16, bd) \
259*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 8, 4, bd) \
260*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 8, 8, bd) \
261*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 8, 16, bd) \
262*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 8, 32, bd) \
263*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 16, 4, bd) \
264*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 16, 8, bd) \
265*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 16, 16, bd) \
266*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 16, 32, bd) \
267*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 32, 8, bd) \
268*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 32, 16, bd) \
269*77c1e3ccSAndroid Build Coastguard Worker CFL_PREDICT_X(arch, 32, 32, bd) \
270*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_fn cfl_get_predict_##bd##_fn_##arch(TX_SIZE tx_size) { \
271*77c1e3ccSAndroid Build Coastguard Worker static const cfl_predict_##bd##_fn pred[TX_SIZES_ALL] = { \
272*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_4x4_##arch, /* 4x4 */ \
273*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_8x8_##arch, /* 8x8 */ \
274*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_16x16_##arch, /* 16x16 */ \
275*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_32x32_##arch, /* 32x32 */ \
276*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 64x64 (invalid CFL size) */ \
277*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_4x8_##arch, /* 4x8 */ \
278*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_8x4_##arch, /* 8x4 */ \
279*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_8x16_##arch, /* 8x16 */ \
280*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_16x8_##arch, /* 16x8 */ \
281*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_16x32_##arch, /* 16x32 */ \
282*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_32x16_##arch, /* 32x16 */ \
283*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 32x64 (invalid CFL size) */ \
284*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 64x32 (invalid CFL size) */ \
285*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_4x16_##arch, /* 4x16 */ \
286*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_16x4_##arch, /* 16x4 */ \
287*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_8x32_##arch, /* 8x32 */ \
288*77c1e3ccSAndroid Build Coastguard Worker cfl_predict_##bd##_32x8_##arch, /* 32x8 */ \
289*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 16x64 (invalid CFL size) */ \
290*77c1e3ccSAndroid Build Coastguard Worker NULL, /* 64x16 (invalid CFL size) */ \
291*77c1e3ccSAndroid Build Coastguard Worker }; \
292*77c1e3ccSAndroid Build Coastguard Worker /* Modulo TX_SIZES_ALL to ensure that an attacker won't be able to */ \
293*77c1e3ccSAndroid Build Coastguard Worker /* index the function pointer array out of bounds. */ \
294*77c1e3ccSAndroid Build Coastguard Worker return pred[tx_size % TX_SIZES_ALL]; \
295*77c1e3ccSAndroid Build Coastguard Worker }
296*77c1e3ccSAndroid Build Coastguard Worker
297*77c1e3ccSAndroid Build Coastguard Worker #endif // AOM_AV1_COMMON_CFL_H_
298