blob: 993e5ca3aaa2243e5e5ebeeabfdb0857daf94fdf [file] [log] [blame]
Angie Chiang80b82262017-02-24 11:39:47 -08001/*
2 * Copyright (c) 2017, 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
Angie Chiang41220ab2018-02-14 17:48:23 -080012#include "av1/encoder/encodetxb.h"
13
Linfeng Zhangae7b2f32017-11-08 15:46:57 -080014#include "aom_ports/mem.h"
Angie Chiang0397eda2017-03-15 16:57:14 -070015#include "av1/common/blockd.h"
Angie Chiange50f3ec2017-04-10 15:50:33 -070016#include "av1/common/idct.h"
Angie Chiang0397eda2017-03-15 16:57:14 -070017#include "av1/common/pred_common.h"
Angie Chiang41220ab2018-02-14 17:48:23 -080018#include "av1/common/scan.h"
Angie Chiang1628fcc2017-04-13 16:30:30 -070019#include "av1/encoder/bitstream.h"
Angie Chiang47c72182017-02-27 14:30:38 -080020#include "av1/encoder/cost.h"
Angie Chiang41220ab2018-02-14 17:48:23 -080021#include "av1/encoder/encodeframe.h"
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -080022#include "av1/encoder/hash.h"
Angie Chiang808d8592017-04-06 18:36:55 -070023#include "av1/encoder/rdopt.h"
Angie Chiang0397eda2017-03-15 16:57:14 -070024#include "av1/encoder/tokenize.h"
Angie Chiang80b82262017-02-24 11:39:47 -080025
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -080026static int hbt_needs_init = 1;
Peng Bin8a204cd2018-04-08 13:07:35 +080027static CRC32C crc_calculator;
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -080028static const int HBT_EOB = 16; // also the length in opt_qcoeff
29static const int HBT_TABLE_SIZE = 65536; // 16 bit: holds 65536 'arrays'
30static const int HBT_ARRAY_LENGTH = 256; // 8 bit: 256 entries
31// If removed in hbt_create_hashes or increased beyond int8_t, widen deltas type
32static const int HBT_KICKOUT = 3;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -080033
34typedef struct OptTxbQcoeff {
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -080035 // Use larger type if larger/no kickout value is used in hbt_create_hashes
36 int8_t deltas[16];
37 uint32_t hbt_qc_hash;
38 uint32_t hbt_ctx_hash;
39 int init;
40 int rate_cost;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -080041} OptTxbQcoeff;
42
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -080043OptTxbQcoeff *hbt_hash_table;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -080044
Dake Hea47cd6c2017-10-13 18:09:58 -070045typedef struct LevelDownStats {
46 int update;
47 tran_low_t low_qc;
48 tran_low_t low_dqc;
Dake Hea47cd6c2017-10-13 18:09:58 -070049 int64_t dist0;
50 int rate;
51 int rate_low;
52 int64_t dist;
53 int64_t dist_low;
54 int64_t rd;
55 int64_t rd_low;
Dake He4d447692017-12-15 09:10:06 -080056 int64_t nz_rd;
Dake Hea47cd6c2017-10-13 18:09:58 -070057 int64_t rd_diff;
58 int cost_diff;
59 int64_t dist_diff;
60 int new_eob;
61} LevelDownStats;
62
Angie Chiangf0fbf9d2017-03-15 15:01:22 -070063void av1_alloc_txb_buf(AV1_COMP *cpi) {
Jingning Hanf5a4d3b2017-08-27 23:01:19 -070064 AV1_COMMON *cm = &cpi->common;
Imdad Sardharwalla4ec84ab2018-02-06 12:20:18 +000065 int size = ((cm->mi_rows >> cm->seq_params.mib_size_log2) + 1) *
66 ((cm->mi_cols >> cm->seq_params.mib_size_log2) + 1);
Jingning Hanf5a4d3b2017-08-27 23:01:19 -070067
Angie Chiang9367e3e2017-10-02 16:28:11 -070068 av1_free_txb_buf(cpi);
Jingning Hanf5a4d3b2017-08-27 23:01:19 -070069 // TODO(jingning): This should be further reduced.
70 CHECK_MEM_ERROR(cm, cpi->coeff_buffer_base,
Peng Bin27d7ca92018-03-22 22:25:56 +080071 aom_memalign(32, sizeof(*cpi->coeff_buffer_base) * size));
Angie Chiangf0fbf9d2017-03-15 15:01:22 -070072}
73
Angie Chianged9667e2018-03-02 15:10:50 -080074void av1_free_txb_buf(AV1_COMP *cpi) { aom_free(cpi->coeff_buffer_base); }
Angie Chiangf0fbf9d2017-03-15 15:01:22 -070075
Jingning Hanf5a4d3b2017-08-27 23:01:19 -070076void av1_set_coeff_buffer(const AV1_COMP *const cpi, MACROBLOCK *const x,
77 int mi_row, int mi_col) {
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +000078 const AV1_COMMON *const cm = &cpi->common;
79 const int num_planes = av1_num_planes(cm);
Imdad Sardharwalla4ec84ab2018-02-06 12:20:18 +000080 int mib_size_log2 = cm->seq_params.mib_size_log2;
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +000081 int stride = (cm->mi_cols >> mib_size_log2) + 1;
Dominic Symes917d6c02017-10-11 18:00:52 +020082 int offset = (mi_row >> mib_size_log2) * stride + (mi_col >> mib_size_log2);
Jingning Hanf5a4d3b2017-08-27 23:01:19 -070083 CB_COEFF_BUFFER *coeff_buf = &cpi->coeff_buffer_base[offset];
84 const int txb_offset = x->cb_offset / (TX_SIZE_W_MIN * TX_SIZE_H_MIN);
Hui Suad01a472018-03-01 10:46:34 -080085 assert(x->cb_offset < (1 << num_pels_log2_lookup[cm->seq_params.sb_size]));
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +000086 for (int plane = 0; plane < num_planes; ++plane) {
Jingning Hanf5a4d3b2017-08-27 23:01:19 -070087 x->mbmi_ext->tcoeff[plane] = coeff_buf->tcoeff[plane] + x->cb_offset;
88 x->mbmi_ext->eobs[plane] = coeff_buf->eobs[plane] + txb_offset;
89 x->mbmi_ext->txb_skip_ctx[plane] =
90 coeff_buf->txb_skip_ctx[plane] + txb_offset;
91 x->mbmi_ext->dc_sign_ctx[plane] =
92 coeff_buf->dc_sign_ctx[plane] + txb_offset;
93 }
94}
95
Angie Chiang80b82262017-02-24 11:39:47 -080096static void write_golomb(aom_writer *w, int level) {
97 int x = level + 1;
98 int i = x;
99 int length = 0;
100
101 while (i) {
102 i >>= 1;
103 ++length;
104 }
105 assert(length > 0);
106
107 for (i = 0; i < length - 1; ++i) aom_write_bit(w, 0);
108
109 for (i = length - 1; i >= 0; --i) aom_write_bit(w, (x >> i) & 0x01);
110}
111
Dake Hea47cd6c2017-10-13 18:09:58 -0700112static INLINE tran_low_t get_lower_coeff(tran_low_t qc) {
113 if (qc == 0) {
114 return 0;
115 }
116 return qc > 0 ? qc - 1 : qc + 1;
117}
118
Angie Chiangb3167a62018-01-30 19:37:57 -0800119static INLINE tran_low_t qcoeff_to_dqcoeff(tran_low_t qc, int coeff_idx,
Angie Chiangb3167a62018-01-30 19:37:57 -0800120 int dqv, int shift,
121 const qm_val_t *iqmatrix) {
Angie Chiang40b07312018-03-30 10:42:55 -0700122 int sign = qc < 0 ? -1 : 1;
Angie Chiangb3167a62018-01-30 19:37:57 -0800123 if (iqmatrix != NULL)
124 dqv =
125 ((iqmatrix[coeff_idx] * dqv) + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
Angie Chiang40b07312018-03-30 10:42:55 -0700126 return sign * ((abs(qc) * dqv) >> shift);
Dake Hea47cd6c2017-10-13 18:09:58 -0700127}
128
129static INLINE int64_t get_coeff_dist(tran_low_t tcoeff, tran_low_t dqcoeff,
130 int shift) {
131 const int64_t diff = (tcoeff - dqcoeff) * (1 << shift);
132 const int64_t error = diff * diff;
133 return error;
134}
135
Urvang Joshiac97d272018-07-31 15:16:52 -0700136static const int8_t eob_to_pos_small[33] = {
137 0, 1, 2, // 0-2
138 3, 3, // 3-4
139 4, 4, 4, 4, // 5-8
140 5, 5, 5, 5, 5, 5, 5, 5, // 9-16
141 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 // 17-32
142};
143
144static const int8_t eob_to_pos_large[17] = {
145 6, // place holder
146 7, // 33-64
147 8, 8, // 65-128
148 9, 9, 9, 9, // 129-256
149 10, 10, 10, 10, 10, 10, 10, 10, // 257-512
150 11 // 513-
151};
152
153static INLINE int get_eob_pos_token(const int eob, int *const extra) {
154 int t;
155
156 if (eob < 33) {
157 t = eob_to_pos_small[eob];
158 } else {
159 const int e = AOMMIN((eob - 1) >> 5, 16);
160 t = eob_to_pos_large[e];
161 }
162
163 *extra = eob - k_eob_group_start[t];
164
165 return t;
166}
167
Yue Chen198738d2018-03-08 17:26:01 -0800168#if CONFIG_ENTROPY_STATS
Yaowu Xu49abec82018-03-13 16:09:01 -0700169void av1_update_eob_context(int cdf_idx, int eob, TX_SIZE tx_size,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900170 TX_CLASS tx_class, PLANE_TYPE plane,
Yunqing Wang0e141b52017-11-02 15:08:58 -0700171 FRAME_CONTEXT *ec_ctx, FRAME_COUNTS *counts,
172 uint8_t allow_update_cdf) {
Yue Chen198738d2018-03-08 17:26:01 -0800173#else
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900174void av1_update_eob_context(int eob, TX_SIZE tx_size, TX_CLASS tx_class,
Yaowu Xu49abec82018-03-13 16:09:01 -0700175 PLANE_TYPE plane, FRAME_CONTEXT *ec_ctx,
176 uint8_t allow_update_cdf) {
Yue Chen198738d2018-03-08 17:26:01 -0800177#endif
Yaowu Xu49abec82018-03-13 16:09:01 -0700178 int eob_extra;
Linfeng Zhang0c72b2f2017-12-04 10:59:28 -0800179 const int eob_pt = get_eob_pos_token(eob, &eob_extra);
Debargha Mukherjeeb3eda2f2017-11-28 16:00:20 -0800180 TX_SIZE txs_ctx = get_txsize_entropy_ctx(tx_size);
Dake Hea47cd6c2017-10-13 18:09:58 -0700181
Dake He0db7d0e2017-12-21 15:23:20 -0800182 const int eob_multi_size = txsize_log2_minus4[tx_size];
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900183 const int eob_multi_ctx = (tx_class == TX_CLASS_2D) ? 0 : 1;
Dake He0db7d0e2017-12-21 15:23:20 -0800184
185 switch (eob_multi_size) {
186 case 0:
Yue Chen198738d2018-03-08 17:26:01 -0800187#if CONFIG_ENTROPY_STATS
188 ++counts->eob_multi16[cdf_idx][plane][eob_multi_ctx][eob_pt - 1];
189#endif
Dake He0db7d0e2017-12-21 15:23:20 -0800190 if (allow_update_cdf)
191 update_cdf(ec_ctx->eob_flag_cdf16[plane][eob_multi_ctx], eob_pt - 1, 5);
192 break;
193 case 1:
Yue Chen198738d2018-03-08 17:26:01 -0800194#if CONFIG_ENTROPY_STATS
195 ++counts->eob_multi32[cdf_idx][plane][eob_multi_ctx][eob_pt - 1];
196#endif
Dake He0db7d0e2017-12-21 15:23:20 -0800197 if (allow_update_cdf)
198 update_cdf(ec_ctx->eob_flag_cdf32[plane][eob_multi_ctx], eob_pt - 1, 6);
199 break;
200 case 2:
Yue Chen198738d2018-03-08 17:26:01 -0800201#if CONFIG_ENTROPY_STATS
202 ++counts->eob_multi64[cdf_idx][plane][eob_multi_ctx][eob_pt - 1];
203#endif
Dake He0db7d0e2017-12-21 15:23:20 -0800204 if (allow_update_cdf)
205 update_cdf(ec_ctx->eob_flag_cdf64[plane][eob_multi_ctx], eob_pt - 1, 7);
206 break;
207 case 3:
Yue Chen198738d2018-03-08 17:26:01 -0800208#if CONFIG_ENTROPY_STATS
209 ++counts->eob_multi128[cdf_idx][plane][eob_multi_ctx][eob_pt - 1];
210#endif
Hui Su1cb1c002018-02-05 18:21:20 -0800211 if (allow_update_cdf) {
Dake He0db7d0e2017-12-21 15:23:20 -0800212 update_cdf(ec_ctx->eob_flag_cdf128[plane][eob_multi_ctx], eob_pt - 1,
213 8);
Hui Su1cb1c002018-02-05 18:21:20 -0800214 }
Dake He0db7d0e2017-12-21 15:23:20 -0800215 break;
216 case 4:
Yue Chen198738d2018-03-08 17:26:01 -0800217#if CONFIG_ENTROPY_STATS
218 ++counts->eob_multi256[cdf_idx][plane][eob_multi_ctx][eob_pt - 1];
219#endif
Hui Su1cb1c002018-02-05 18:21:20 -0800220 if (allow_update_cdf) {
Dake He0db7d0e2017-12-21 15:23:20 -0800221 update_cdf(ec_ctx->eob_flag_cdf256[plane][eob_multi_ctx], eob_pt - 1,
222 9);
Hui Su1cb1c002018-02-05 18:21:20 -0800223 }
Dake He0db7d0e2017-12-21 15:23:20 -0800224 break;
225 case 5:
Yue Chen198738d2018-03-08 17:26:01 -0800226#if CONFIG_ENTROPY_STATS
227 ++counts->eob_multi512[cdf_idx][plane][eob_multi_ctx][eob_pt - 1];
228#endif
Hui Su1cb1c002018-02-05 18:21:20 -0800229 if (allow_update_cdf) {
Dake He0db7d0e2017-12-21 15:23:20 -0800230 update_cdf(ec_ctx->eob_flag_cdf512[plane][eob_multi_ctx], eob_pt - 1,
231 10);
Hui Su1cb1c002018-02-05 18:21:20 -0800232 }
Dake He0db7d0e2017-12-21 15:23:20 -0800233 break;
234 case 6:
235 default:
Yue Chen198738d2018-03-08 17:26:01 -0800236#if CONFIG_ENTROPY_STATS
237 ++counts->eob_multi1024[cdf_idx][plane][eob_multi_ctx][eob_pt - 1];
238#endif
Hui Su1cb1c002018-02-05 18:21:20 -0800239 if (allow_update_cdf) {
Dake He0db7d0e2017-12-21 15:23:20 -0800240 update_cdf(ec_ctx->eob_flag_cdf1024[plane][eob_multi_ctx], eob_pt - 1,
241 11);
Hui Su1cb1c002018-02-05 18:21:20 -0800242 }
Dake He0db7d0e2017-12-21 15:23:20 -0800243 break;
244 }
Jingning Han00803a72017-10-25 16:04:34 -0700245
Angie Chiang7ab884e2017-10-18 15:57:12 -0700246 if (k_eob_offset_bits[eob_pt] > 0) {
Jingning Hanff4a9f82018-06-08 10:48:45 -0700247 int eob_ctx = eob_pt - 3;
Angie Chiang7ab884e2017-10-18 15:57:12 -0700248 int eob_shift = k_eob_offset_bits[eob_pt] - 1;
249 int bit = (eob_extra & (1 << eob_shift)) ? 1 : 0;
Hui Su1e959892018-01-22 12:14:43 -0800250#if CONFIG_ENTROPY_STATS
Yue Chen198738d2018-03-08 17:26:01 -0800251 counts->eob_extra[cdf_idx][txs_ctx][plane][eob_pt][bit]++;
Hui Su1e959892018-01-22 12:14:43 -0800252#endif // CONFIG_ENTROPY_STATS
Yunqing Wang0e141b52017-11-02 15:08:58 -0700253 if (allow_update_cdf)
Jingning Hanff4a9f82018-06-08 10:48:45 -0700254 update_cdf(ec_ctx->eob_extra_cdf[txs_ctx][plane][eob_ctx], bit, 2);
Angie Chiang7ab884e2017-10-18 15:57:12 -0700255 }
Dake Hea47cd6c2017-10-13 18:09:58 -0700256}
257
Yaowu Xu49abec82018-03-13 16:09:01 -0700258static int get_eob_cost(int eob, const LV_MAP_EOB_COST *txb_eob_costs,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900259 const LV_MAP_COEFF_COST *txb_costs, TX_CLASS tx_class) {
Yaowu Xu49abec82018-03-13 16:09:01 -0700260 int eob_extra;
Linfeng Zhang0c72b2f2017-12-04 10:59:28 -0800261 const int eob_pt = get_eob_pos_token(eob, &eob_extra);
Dake Hea47cd6c2017-10-13 18:09:58 -0700262 int eob_cost = 0;
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900263 const int eob_multi_ctx = (tx_class == TX_CLASS_2D) ? 0 : 1;
Dake He0db7d0e2017-12-21 15:23:20 -0800264 eob_cost = txb_eob_costs->eob_cost[eob_multi_ctx][eob_pt - 1];
Dake He0db7d0e2017-12-21 15:23:20 -0800265
Dake Hea47cd6c2017-10-13 18:09:58 -0700266 if (k_eob_offset_bits[eob_pt] > 0) {
Jingning Hanff4a9f82018-06-08 10:48:45 -0700267 const int eob_ctx = eob_pt - 3;
Hui Su751a2332018-01-23 11:35:03 -0800268 const int eob_shift = k_eob_offset_bits[eob_pt] - 1;
269 const int bit = (eob_extra & (1 << eob_shift)) ? 1 : 0;
Jingning Hanff4a9f82018-06-08 10:48:45 -0700270 eob_cost += txb_costs->eob_extra_cost[eob_ctx][bit];
Hui Su751a2332018-01-23 11:35:03 -0800271 const int offset_bits = k_eob_offset_bits[eob_pt];
272 if (offset_bits > 1) eob_cost += av1_cost_literal(offset_bits - 1);
Dake Hea47cd6c2017-10-13 18:09:58 -0700273 }
274 return eob_cost;
275}
276
Angie Chiange4ea7482018-03-15 11:36:41 -0700277static INLINE int get_sign_bit_cost(tran_low_t qc, int coeff_idx,
278 const int (*dc_sign_cost)[2],
279 int dc_sign_ctx) {
Angie Chiange4ea7482018-03-15 11:36:41 -0700280 if (coeff_idx == 0) {
Angie Chiang2f94a452018-04-03 20:21:06 -0700281 const int sign = (qc < 0) ? 1 : 0;
Angie Chiange4ea7482018-03-15 11:36:41 -0700282 return dc_sign_cost[dc_sign_ctx][sign];
Angie Chiange4ea7482018-03-15 11:36:41 -0700283 }
Angie Chiang40b07312018-03-30 10:42:55 -0700284 return av1_cost_literal(1);
Angie Chiange4ea7482018-03-15 11:36:41 -0700285}
286
Angie Chiange4ea7482018-03-15 11:36:41 -0700287static INLINE int get_golomb_cost(int abs_qc) {
288 if (abs_qc >= 1 + NUM_BASE_LEVELS + COEFF_BASE_RANGE) {
289 const int r = abs_qc - COEFF_BASE_RANGE - NUM_BASE_LEVELS;
290 const int length = get_msb(r) + 1;
291 return av1_cost_literal(2 * length - 1);
292 }
293 return 0;
294}
295
Jim Bankoski24b30d72019-01-14 09:07:43 -0800296static INLINE int get_br_cost(tran_low_t level, const int *coeff_lps) {
297 const int base_range = AOMMIN(level - 1 - NUM_BASE_LEVELS, COEFF_BASE_RANGE);
298 return coeff_lps[base_range] + get_golomb_cost(level);
299}
300
Linfeng Zhang1015a342017-10-24 16:20:41 -0700301static int get_coeff_cost(const tran_low_t qc, const int scan_idx,
Sebastien Alaiwan78f7bb92018-01-11 11:02:43 +0100302 const int is_eob, const TxbInfo *const txb_info,
Linfeng Zhang5f1b8ce2017-12-11 15:53:10 -0800303 const LV_MAP_COEFF_COST *const txb_costs,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900304 const int coeff_ctx, const TX_CLASS tx_class) {
Xing Jinbd91e942018-06-21 13:43:17 +0800305 const TXB_CTX *const txb_ctx = txb_info->txb_ctx;
Angie Chiange4ea7482018-03-15 11:36:41 -0700306 const int is_nz = (qc != 0);
307 const tran_low_t abs_qc = abs(qc);
308 int cost = 0;
309 const int16_t *const scan = txb_info->scan_order->scan;
310 const int pos = scan[scan_idx];
311
312 if (is_eob) {
313 cost += txb_costs->base_eob_cost[coeff_ctx][AOMMIN(abs_qc, 3) - 1];
314 } else {
315 cost += txb_costs->base_cost[coeff_ctx][AOMMIN(abs_qc, 3)];
316 }
317 if (is_nz) {
318 cost += get_sign_bit_cost(qc, scan_idx, txb_costs->dc_sign_cost,
319 txb_ctx->dc_sign_ctx);
320
321 if (abs_qc > NUM_BASE_LEVELS) {
322 const int ctx =
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900323 get_br_ctx(txb_info->levels, pos, txb_info->bwl, tx_class);
Jim Bankoskife171222019-01-14 08:41:57 -0800324 cost += get_br_cost(abs_qc, txb_costs->lps_cost[ctx]);
Angie Chiange4ea7482018-03-15 11:36:41 -0700325 }
326 }
327 return cost;
328}
Dake Hea47cd6c2017-10-13 18:09:58 -0700329
Frederic Barbiere8c67522018-03-27 15:09:57 +0200330static INLINE int get_nz_map_ctx(const uint8_t *const levels,
331 const int coeff_idx, const int bwl,
332 const int height, const int scan_idx,
333 const int is_eob, const TX_SIZE tx_size,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900334 const TX_CLASS tx_class) {
Frederic Barbiere8c67522018-03-27 15:09:57 +0200335 if (is_eob) {
336 if (scan_idx == 0) return 0;
337 if (scan_idx <= (height << bwl) / 8) return 1;
338 if (scan_idx <= (height << bwl) / 4) return 2;
339 return 3;
340 }
Frederic Barbiere8c67522018-03-27 15:09:57 +0200341 const int stats =
342 get_nz_mag(levels + get_padded_idx(coeff_idx, bwl), bwl, tx_class);
343 return get_nz_map_ctx_from_stats(stats, coeff_idx, bwl, tx_size, tx_class);
344}
345
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -0800346static void get_dist_cost_stats(LevelDownStats *const stats, const int scan_idx,
Ola Hugosson13892102017-11-06 08:01:44 +0100347 const int is_eob,
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -0800348 const LV_MAP_COEFF_COST *const txb_costs,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900349 const TxbInfo *const txb_info,
350 const TX_CLASS tx_class) {
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -0800351 const int16_t *const scan = txb_info->scan_order->scan;
Dake Hea47cd6c2017-10-13 18:09:58 -0700352 const int coeff_idx = scan[scan_idx];
353 const tran_low_t qc = txb_info->qcoeff[coeff_idx];
Linfeng Zhang1015a342017-10-24 16:20:41 -0700354 const uint8_t *const levels = txb_info->levels;
Dake Hea47cd6c2017-10-13 18:09:58 -0700355 stats->new_eob = -1;
356 stats->update = 0;
Debargha Mukherjeee2f6b162018-01-04 17:23:05 -0800357 stats->rd_low = 0;
358 stats->rd = 0;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -0800359 stats->nz_rd = 0;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -0800360 stats->dist_low = 0;
361 stats->rate_low = 0;
362 stats->low_qc = 0;
Dake Hea47cd6c2017-10-13 18:09:58 -0700363
364 const tran_low_t tqc = txb_info->tcoeff[coeff_idx];
365 const int dqv = txb_info->dequant[coeff_idx != 0];
Sebastien Alaiwan78f7bb92018-01-11 11:02:43 +0100366 const int coeff_ctx =
367 get_nz_map_ctx(levels, coeff_idx, txb_info->bwl, txb_info->height,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900368 scan_idx, is_eob, txb_info->tx_size, tx_class);
369 const int qc_cost = get_coeff_cost(qc, scan_idx, is_eob, txb_info, txb_costs,
370 coeff_ctx, tx_class);
Angie Chiang99b12422018-03-02 17:15:00 -0800371 assert(qc != 0);
372 const tran_low_t dqc = qcoeff_to_dqcoeff(qc, coeff_idx, dqv, txb_info->shift,
373 txb_info->iqmatrix);
374 const int64_t dqc_dist = get_coeff_dist(tqc, dqc, txb_info->shift);
Cheng Chen79641202018-01-04 18:52:52 -0800375
Angie Chiang99b12422018-03-02 17:15:00 -0800376 // distortion difference when coefficient is quantized to 0
377 const tran_low_t dqc0 =
378 qcoeff_to_dqcoeff(0, coeff_idx, dqv, txb_info->shift, txb_info->iqmatrix);
Cheng Chen79641202018-01-04 18:52:52 -0800379
Angie Chiang99b12422018-03-02 17:15:00 -0800380 stats->dist0 = get_coeff_dist(tqc, dqc0, txb_info->shift);
381 stats->dist = dqc_dist - stats->dist0;
382 stats->rate = qc_cost;
Cheng Chen79641202018-01-04 18:52:52 -0800383
Dake Hea47cd6c2017-10-13 18:09:58 -0700384 stats->rd = RDCOST(txb_info->rdmult, stats->rate, stats->dist);
385
386 stats->low_qc = get_lower_coeff(qc);
Dake Hea47cd6c2017-10-13 18:09:58 -0700387
Dake He4d447692017-12-15 09:10:06 -0800388 if (is_eob && stats->low_qc == 0) {
Dake He4d447692017-12-15 09:10:06 -0800389 stats->rd_low = stats->rd; // disable selection of low_qc in this case.
Ola Hugosson13892102017-11-06 08:01:44 +0100390 } else {
Cheng Chen37d88732018-01-09 14:02:41 -0800391 if (stats->low_qc == 0) {
392 stats->dist_low = 0;
393 } else {
Frederic Barbiere111cba2018-02-20 16:11:28 +0100394 stats->low_dqc = qcoeff_to_dqcoeff(stats->low_qc, coeff_idx, dqv,
395 txb_info->shift, txb_info->iqmatrix);
Cheng Chen37d88732018-01-09 14:02:41 -0800396 const int64_t low_dqc_dist =
397 get_coeff_dist(tqc, stats->low_dqc, txb_info->shift);
398 stats->dist_low = low_dqc_dist - stats->dist0;
399 }
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900400 const int low_qc_cost =
401 get_coeff_cost(stats->low_qc, scan_idx, is_eob, txb_info, txb_costs,
402 coeff_ctx, tx_class);
Dake He4d447692017-12-15 09:10:06 -0800403 stats->rate_low = low_qc_cost;
404 stats->rd_low = RDCOST(txb_info->rdmult, stats->rate_low, stats->dist_low);
Ola Hugosson13892102017-11-06 08:01:44 +0100405 }
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800406}
Cheng Chen37d88732018-01-09 14:02:41 -0800407
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800408static void get_dist_cost_stats_with_eob(
409 LevelDownStats *const stats, const int scan_idx,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900410 const LV_MAP_COEFF_COST *const txb_costs, const TxbInfo *const txb_info,
411 const TX_CLASS tx_class) {
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800412 const int is_eob = 0;
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900413 get_dist_cost_stats(stats, scan_idx, is_eob, txb_costs, txb_info, tx_class);
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800414
415 const int16_t *const scan = txb_info->scan_order->scan;
416 const int coeff_idx = scan[scan_idx];
417 const tran_low_t qc = txb_info->qcoeff[coeff_idx];
418 const int coeff_ctx_temp = get_nz_map_ctx(
419 txb_info->levels, coeff_idx, txb_info->bwl, txb_info->height, scan_idx, 1,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900420 txb_info->tx_size, tx_class);
421 const int qc_eob_cost = get_coeff_cost(qc, scan_idx, 1, txb_info, txb_costs,
422 coeff_ctx_temp, tx_class);
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800423 int64_t rd_eob = RDCOST(txb_info->rdmult, qc_eob_cost, stats->dist);
424 if (stats->low_qc != 0) {
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900425 const int low_qc_eob_cost =
426 get_coeff_cost(stats->low_qc, scan_idx, 1, txb_info, txb_costs,
427 coeff_ctx_temp, tx_class);
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800428 int64_t rd_eob_low =
429 RDCOST(txb_info->rdmult, low_qc_eob_cost, stats->dist_low);
430 rd_eob = (rd_eob > rd_eob_low) ? rd_eob_low : rd_eob;
Cheng Chen37d88732018-01-09 14:02:41 -0800431 }
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800432
433 stats->nz_rd = AOMMIN(stats->rd_low, stats->rd) - rd_eob;
Dake Hea47cd6c2017-10-13 18:09:58 -0700434}
435
Linfeng Zhang1015a342017-10-24 16:20:41 -0700436static INLINE void update_qcoeff(const int coeff_idx, const tran_low_t qc,
437 const TxbInfo *const txb_info) {
Dake Hea47cd6c2017-10-13 18:09:58 -0700438 txb_info->qcoeff[coeff_idx] = qc;
Linfeng Zhangd5647372017-12-05 17:06:07 -0800439 txb_info->levels[get_padded_idx(coeff_idx, txb_info->bwl)] =
Jingning Han5cb408e2017-11-17 14:43:39 -0800440 (uint8_t)clamp(abs(qc), 0, INT8_MAX);
Linfeng Zhang1015a342017-10-24 16:20:41 -0700441}
442
443static INLINE void update_coeff(const int coeff_idx, const tran_low_t qc,
444 const TxbInfo *const txb_info) {
445 update_qcoeff(coeff_idx, qc, txb_info);
Dake Hea47cd6c2017-10-13 18:09:58 -0700446 const int dqv = txb_info->dequant[coeff_idx != 0];
Frederic Barbiere111cba2018-02-20 16:11:28 +0100447 txb_info->dqcoeff[coeff_idx] = qcoeff_to_dqcoeff(
448 qc, coeff_idx, dqv, txb_info->shift, txb_info->iqmatrix);
Dake Hea47cd6c2017-10-13 18:09:58 -0700449}
450
Peng Bin27d7ca92018-03-22 22:25:56 +0800451void av1_txb_init_levels_c(const tran_low_t *const coeff, const int width,
452 const int height, uint8_t *const levels) {
Linfeng Zhang679d81e2017-10-31 15:27:42 -0700453 const int stride = width + TX_PAD_HOR;
Linfeng Zhang1122d7d2017-10-31 15:30:28 -0700454 uint8_t *ls = levels;
Linfeng Zhang679d81e2017-10-31 15:27:42 -0700455
Linfeng Zhang1122d7d2017-10-31 15:30:28 -0700456 memset(levels + stride * height, 0,
457 sizeof(*levels) * (TX_PAD_BOTTOM * stride + TX_PAD_END));
Linfeng Zhang679d81e2017-10-31 15:27:42 -0700458
Linfeng Zhang1122d7d2017-10-31 15:30:28 -0700459 for (int i = 0; i < height; i++) {
460 for (int j = 0; j < width; j++) {
Jingning Han5cb408e2017-11-17 14:43:39 -0800461 *ls++ = (uint8_t)clamp(abs(coeff[i * width + j]), 0, INT8_MAX);
Linfeng Zhang1122d7d2017-10-31 15:30:28 -0700462 }
463 for (int j = 0; j < TX_PAD_HOR; j++) {
464 *ls++ = 0;
465 }
Linfeng Zhang1015a342017-10-24 16:20:41 -0700466 }
467}
468
Linfeng Zhang0ba23e82017-12-20 16:27:28 -0800469void av1_get_nz_map_contexts_c(const uint8_t *const levels,
470 const int16_t *const scan, const uint16_t eob,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900471 const TX_SIZE tx_size, const TX_CLASS tx_class,
Linfeng Zhang0ba23e82017-12-20 16:27:28 -0800472 int8_t *const coeff_contexts) {
Linfeng Zhangd67c13f2017-12-11 11:49:12 -0800473 const int bwl = get_txb_bwl(tx_size);
Linfeng Zhangd67c13f2017-12-11 11:49:12 -0800474 const int height = get_txb_high(tx_size);
Linfeng Zhangd67c13f2017-12-11 11:49:12 -0800475 for (int i = 0; i < eob; ++i) {
476 const int pos = scan[i];
Sebastien Alaiwan78f7bb92018-01-11 11:02:43 +0100477 coeff_contexts[pos] = get_nz_map_ctx(levels, pos, bwl, height, i,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900478 i == eob - 1, tx_size, tx_class);
Linfeng Zhangd67c13f2017-12-11 11:49:12 -0800479 }
480}
481
Angie Chiang80b82262017-02-24 11:39:47 -0800482void av1_write_coeffs_txb(const AV1_COMMON *const cm, MACROBLOCKD *xd,
Luc Trudeau2eb9b842017-12-13 11:19:16 -0500483 aom_writer *w, int blk_row, int blk_col, int plane,
484 TX_SIZE tx_size, const tran_low_t *tcoeff,
Jingning Han7eab9ff2017-07-06 10:12:54 -0700485 uint16_t eob, TXB_CTX *txb_ctx) {
Debargha Mukherjeeb3eda2f2017-11-28 16:00:20 -0800486 const TX_SIZE txs_ctx = get_txsize_entropy_ctx(tx_size);
Peng Bin66205b72018-09-04 15:11:08 +0800487 FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
488 aom_write_symbol(w, eob == 0,
489 ec_ctx->txb_skip_cdf[txs_ctx][txb_ctx->txb_skip_ctx], 2);
490 if (eob == 0) return;
491 const PLANE_TYPE plane_type = get_plane_type(plane);
Sarah Parker7c71cc02018-01-29 12:27:58 -0800492 const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, blk_row, blk_col,
493 tx_size, cm->reduced_tx_set_used);
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900494 const TX_CLASS tx_class = tx_type_to_class[tx_type];
Yaowu Xuf1e12932018-02-26 15:50:09 -0800495 const SCAN_ORDER *const scan_order = get_scan(tx_size, tx_type);
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -0800496 const int16_t *const scan = scan_order->scan;
Angie Chiang80b82262017-02-24 11:39:47 -0800497 int c;
Angie Chianga9ba58e2017-12-01 19:22:43 -0800498 const int bwl = get_txb_bwl(tx_size);
499 const int width = get_txb_wide(tx_size);
500 const int height = get_txb_high(tx_size);
Peng Bin66205b72018-09-04 15:11:08 +0800501
Linfeng Zhang679d81e2017-10-31 15:27:42 -0700502 uint8_t levels_buf[TX_PAD_2D];
503 uint8_t *const levels = set_levels(levels_buf, width);
Linfeng Zhangd67c13f2017-12-11 11:49:12 -0800504 DECLARE_ALIGNED(16, int8_t, coeff_contexts[MAX_TX_SQUARE]);
Linfeng Zhang1122d7d2017-10-31 15:30:28 -0700505 av1_txb_init_levels(tcoeff, width, height, levels);
Linfeng Zhangce065ca2017-10-17 16:49:30 -0700506
Debargha Mukherjee3ebb0d02017-12-14 05:05:18 -0800507 av1_write_tx_type(cm, xd, blk_row, blk_col, plane, tx_size, w);
Angie Chiang80b82262017-02-24 11:39:47 -0800508
Yaowu Xu49abec82018-03-13 16:09:01 -0700509 int eob_extra;
Linfeng Zhang0c72b2f2017-12-04 10:59:28 -0800510 const int eob_pt = get_eob_pos_token(eob, &eob_extra);
Dake He0db7d0e2017-12-21 15:23:20 -0800511 const int eob_multi_size = txsize_log2_minus4[tx_size];
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900512 const int eob_multi_ctx = (tx_class == TX_CLASS_2D) ? 0 : 1;
Dake He0db7d0e2017-12-21 15:23:20 -0800513 switch (eob_multi_size) {
514 case 0:
515 aom_write_symbol(w, eob_pt - 1,
516 ec_ctx->eob_flag_cdf16[plane_type][eob_multi_ctx], 5);
517 break;
518 case 1:
519 aom_write_symbol(w, eob_pt - 1,
520 ec_ctx->eob_flag_cdf32[plane_type][eob_multi_ctx], 6);
521 break;
522 case 2:
523 aom_write_symbol(w, eob_pt - 1,
524 ec_ctx->eob_flag_cdf64[plane_type][eob_multi_ctx], 7);
525 break;
526 case 3:
527 aom_write_symbol(w, eob_pt - 1,
528 ec_ctx->eob_flag_cdf128[plane_type][eob_multi_ctx], 8);
529 break;
530 case 4:
531 aom_write_symbol(w, eob_pt - 1,
532 ec_ctx->eob_flag_cdf256[plane_type][eob_multi_ctx], 9);
533 break;
534 case 5:
535 aom_write_symbol(w, eob_pt - 1,
536 ec_ctx->eob_flag_cdf512[plane_type][eob_multi_ctx], 10);
537 break;
538 default:
539 aom_write_symbol(w, eob_pt - 1,
540 ec_ctx->eob_flag_cdf1024[plane_type][eob_multi_ctx], 11);
541 break;
542 }
543
wenyao.liu0be59012018-12-24 10:27:31 +0800544 const int eob_offset_bits = k_eob_offset_bits[eob_pt];
545 if (eob_offset_bits > 0) {
Jingning Hanff4a9f82018-06-08 10:48:45 -0700546 const int eob_ctx = eob_pt - 3;
wenyao.liu0be59012018-12-24 10:27:31 +0800547 int eob_shift = eob_offset_bits - 1;
Angie Chiang7ab884e2017-10-18 15:57:12 -0700548 int bit = (eob_extra & (1 << eob_shift)) ? 1 : 0;
Jingning Hanff4a9f82018-06-08 10:48:45 -0700549 aom_write_symbol(w, bit,
550 ec_ctx->eob_extra_cdf[txs_ctx][plane_type][eob_ctx], 2);
wenyao.liu0be59012018-12-24 10:27:31 +0800551 for (int i = 1; i < eob_offset_bits; i++) {
552 eob_shift = eob_offset_bits - 1 - i;
Angie Chiang7ab884e2017-10-18 15:57:12 -0700553 bit = (eob_extra & (1 << eob_shift)) ? 1 : 0;
Dake Hea47cd6c2017-10-13 18:09:58 -0700554 aom_write_bit(w, bit);
Dake Hea47cd6c2017-10-13 18:09:58 -0700555 }
556 }
Dake He03a32922017-10-31 08:06:45 -0700557
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900558 av1_get_nz_map_contexts(levels, scan, eob, tx_size, tx_class, coeff_contexts);
Linfeng Zhangd67c13f2017-12-11 11:49:12 -0800559
560 for (c = eob - 1; c >= 0; --c) {
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -0800561 const int pos = scan[c];
Linfeng Zhangd67c13f2017-12-11 11:49:12 -0800562 const int coeff_ctx = coeff_contexts[pos];
563 const tran_low_t v = tcoeff[pos];
Angie Chiang41220ab2018-02-14 17:48:23 -0800564 const tran_low_t level = abs(v);
Dake He03a32922017-10-31 08:06:45 -0700565
Dake He3fe369c2017-11-16 17:56:44 -0800566 if (c == eob - 1) {
567 aom_write_symbol(
Angie Chiang41220ab2018-02-14 17:48:23 -0800568 w, AOMMIN(level, 3) - 1,
Dake He4d447692017-12-15 09:10:06 -0800569 ec_ctx->coeff_base_eob_cdf[txs_ctx][plane_type][coeff_ctx], 3);
Dake He3fe369c2017-11-16 17:56:44 -0800570 } else {
Angie Chiang41220ab2018-02-14 17:48:23 -0800571 aom_write_symbol(w, AOMMIN(level, 3),
Dake He3fe369c2017-11-16 17:56:44 -0800572 ec_ctx->coeff_base_cdf[txs_ctx][plane_type][coeff_ctx],
573 4);
574 }
Angie Chiang41220ab2018-02-14 17:48:23 -0800575 if (level > NUM_BASE_LEVELS) {
Sebastien Alaiwan78f7bb92018-01-11 11:02:43 +0100576 // level is above 1.
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -0800577 const int base_range = level - 1 - NUM_BASE_LEVELS;
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900578 const int br_ctx = get_br_ctx(levels, pos, bwl, tx_class);
wenyao.liu0be59012018-12-24 10:27:31 +0800579 aom_cdf_prob *cdf =
580 ec_ctx->coeff_br_cdf[AOMMIN(txs_ctx, TX_32X32)][plane_type][br_ctx];
Angie Chiang41220ab2018-02-14 17:48:23 -0800581 for (int idx = 0; idx < COEFF_BASE_RANGE; idx += BR_CDF_SIZE - 1) {
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -0800582 const int k = AOMMIN(base_range - idx, BR_CDF_SIZE - 1);
wenyao.liu0be59012018-12-24 10:27:31 +0800583 aom_write_symbol(w, k, cdf, BR_CDF_SIZE);
Ola Hugossone72a2092017-11-12 09:11:53 +0100584 if (k < BR_CDF_SIZE - 1) break;
585 }
Angie Chiang6d5419c2018-02-20 15:12:15 -0800586 }
587 }
588
589 // Loop to code all signs in the transform block,
590 // starting with the sign of DC (if applicable)
591 for (c = 0; c < eob; ++c) {
592 const tran_low_t v = tcoeff[scan[c]];
593 const tran_low_t level = abs(v);
594 const int sign = (v < 0) ? 1 : 0;
595 if (level) {
596 if (c == 0) {
597 aom_write_symbol(
598 w, sign, ec_ctx->dc_sign_cdf[plane_type][txb_ctx->dc_sign_ctx], 2);
599 } else {
600 aom_write_bit(w, sign);
601 }
Yushin Cho73711d52018-05-04 13:59:46 -0700602 if (level > COEFF_BASE_RANGE + NUM_BASE_LEVELS)
603 write_golomb(w, level - COEFF_BASE_RANGE - 1 - NUM_BASE_LEVELS);
Angie Chiang41220ab2018-02-14 17:48:23 -0800604 }
605 }
Angie Chiang80b82262017-02-24 11:39:47 -0800606}
Angie Chiang47c72182017-02-27 14:30:38 -0800607
Angie Chiang140b3332017-12-12 17:29:25 -0800608typedef struct encode_txb_args {
609 const AV1_COMMON *cm;
610 MACROBLOCK *x;
611 aom_writer *w;
612} ENCODE_TXB_ARGS;
613
Jingning Han3a32e102018-01-11 16:00:35 -0800614static void write_coeffs_txb_wrap(const AV1_COMMON *cm, MACROBLOCK *x,
615 aom_writer *w, int plane, int block,
616 int blk_row, int blk_col, TX_SIZE tx_size) {
Angie Chiangc8af6112017-03-16 16:11:22 -0700617 MACROBLOCKD *xd = &x->e_mbd;
Angie Chiang140b3332017-12-12 17:29:25 -0800618 tran_low_t *tcoeff = BLOCK_OFFSET(x->mbmi_ext->tcoeff[plane], block);
619 uint16_t eob = x->mbmi_ext->eobs[plane][block];
620 TXB_CTX txb_ctx = { x->mbmi_ext->txb_skip_ctx[plane][block],
621 x->mbmi_ext->dc_sign_ctx[plane][block] };
Luc Trudeau2eb9b842017-12-13 11:19:16 -0500622 av1_write_coeffs_txb(cm, xd, w, blk_row, blk_col, plane, tx_size, tcoeff, eob,
623 &txb_ctx);
Angie Chiang140b3332017-12-12 17:29:25 -0800624}
625
Jingning Han4b48cd12018-01-11 15:56:42 -0800626void av1_write_coeffs_mb(const AV1_COMMON *const cm, MACROBLOCK *x, int mi_row,
Jingning Hanad54a982018-01-12 14:40:29 -0800627 int mi_col, aom_writer *w, BLOCK_SIZE bsize) {
Angie Chiang140b3332017-12-12 17:29:25 -0800628 MACROBLOCKD *xd = &x->e_mbd;
Jingning Hanad54a982018-01-12 14:40:29 -0800629 const int num_planes = av1_num_planes(cm);
630 int block[MAX_MB_PLANE] = { 0 };
Jingning Han4b48cd12018-01-11 15:56:42 -0800631 int row, col;
Cheng Chen8ab1f442018-04-27 18:01:52 -0700632 assert(bsize == get_plane_block_size(bsize, xd->plane[0].subsampling_x,
633 xd->plane[0].subsampling_y));
Yushin Choca63a8b2018-04-20 16:46:36 -0700634 const int max_blocks_wide = max_block_wide(xd, bsize, 0);
635 const int max_blocks_high = max_block_high(xd, bsize, 0);
636 const BLOCK_SIZE max_unit_bsize = BLOCK_64X64;
Jingning Han4b48cd12018-01-11 15:56:42 -0800637 int mu_blocks_wide = block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0];
638 int mu_blocks_high = block_size_high[max_unit_bsize] >> tx_size_high_log2[0];
639 mu_blocks_wide = AOMMIN(max_blocks_wide, mu_blocks_wide);
640 mu_blocks_high = AOMMIN(max_blocks_high, mu_blocks_high);
641
642 for (row = 0; row < max_blocks_high; row += mu_blocks_high) {
Jingning Han4b48cd12018-01-11 15:56:42 -0800643 for (col = 0; col < max_blocks_wide; col += mu_blocks_wide) {
Jingning Hanad54a982018-01-12 14:40:29 -0800644 for (int plane = 0; plane < num_planes; ++plane) {
645 const struct macroblockd_plane *const pd = &xd->plane[plane];
646 if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x,
647 pd->subsampling_y))
648 continue;
649 const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
650 const int stepr = tx_size_high_unit[tx_size];
651 const int stepc = tx_size_wide_unit[tx_size];
652 const int step = stepr * stepc;
Jingning Han4b48cd12018-01-11 15:56:42 -0800653
Jingning Hanad54a982018-01-12 14:40:29 -0800654 const int unit_height = ROUND_POWER_OF_TWO(
655 AOMMIN(mu_blocks_high + row, max_blocks_high), pd->subsampling_y);
656 const int unit_width = ROUND_POWER_OF_TWO(
657 AOMMIN(mu_blocks_wide + col, max_blocks_wide), pd->subsampling_x);
658 for (int blk_row = row >> pd->subsampling_y; blk_row < unit_height;
659 blk_row += stepr) {
660 for (int blk_col = col >> pd->subsampling_x; blk_col < unit_width;
661 blk_col += stepc) {
662 write_coeffs_txb_wrap(cm, x, w, plane, block[plane], blk_row,
663 blk_col, tx_size);
664 block[plane] += step;
665 }
Jingning Han4b48cd12018-01-11 15:56:42 -0800666 }
667 }
668 }
669 }
Angie Chiangc8af6112017-03-16 16:11:22 -0700670}
671
Urvang Joshi553096a2018-05-10 15:27:14 -0700672// TODO(angiebird): use this function whenever it's possible
673static int get_tx_type_cost(const AV1_COMMON *cm, const MACROBLOCK *x,
674 const MACROBLOCKD *xd, int plane, TX_SIZE tx_size,
675 TX_TYPE tx_type) {
676 if (plane > 0) return 0;
677
678 const TX_SIZE square_tx_size = txsize_sqr_map[tx_size];
679
680 const MB_MODE_INFO *mbmi = xd->mi[0];
681 const int is_inter = is_inter_block(mbmi);
682 if (get_ext_tx_types(tx_size, is_inter, cm->reduced_tx_set_used) > 1 &&
683 !xd->lossless[xd->mi[0]->segment_id]) {
684 const int ext_tx_set =
685 get_ext_tx_set(tx_size, is_inter, cm->reduced_tx_set_used);
686 if (is_inter) {
687 if (ext_tx_set > 0)
688 return x->inter_tx_type_costs[ext_tx_set][square_tx_size][tx_type];
689 } else {
690 if (ext_tx_set > 0) {
691 PREDICTION_MODE intra_dir;
692 if (mbmi->filter_intra_mode_info.use_filter_intra)
693 intra_dir = fimode_to_intradir[mbmi->filter_intra_mode_info
694 .filter_intra_mode];
695 else
696 intra_dir = mbmi->mode;
697 return x->intra_tx_type_costs[ext_tx_set][square_tx_size][intra_dir]
698 [tx_type];
699 }
700 }
701 }
702 return 0;
703}
704
Katsuhisa Yuasa51467032018-04-08 16:16:10 +0900705static AOM_FORCE_INLINE int warehouse_efficients_txb(
706 const AV1_COMMON *const cm, const MACROBLOCK *x, const int plane,
707 const int block, const TX_SIZE tx_size, const TXB_CTX *const txb_ctx,
708 const struct macroblock_plane *p, const int eob,
709 const PLANE_TYPE plane_type, const LV_MAP_COEFF_COST *const coeff_costs,
710 const MACROBLOCKD *const xd, const TX_TYPE tx_type,
711 const TX_CLASS tx_class) {
Angie Chiang47c72182017-02-27 14:30:38 -0800712 const tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
Linfeng Zhangc02b4112017-12-21 13:11:36 -0800713 const int txb_skip_ctx = txb_ctx->txb_skip_ctx;
Angie Chianga9ba58e2017-12-01 19:22:43 -0800714 const int bwl = get_txb_bwl(tx_size);
715 const int width = get_txb_wide(tx_size);
716 const int height = get_txb_high(tx_size);
Yaowu Xuf1e12932018-02-26 15:50:09 -0800717 const SCAN_ORDER *const scan_order = get_scan(tx_size, tx_type);
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -0800718 const int16_t *const scan = scan_order->scan;
Linfeng Zhang679d81e2017-10-31 15:27:42 -0700719 uint8_t levels_buf[TX_PAD_2D];
720 uint8_t *const levels = set_levels(levels_buf, width);
Linfeng Zhangd67c13f2017-12-11 11:49:12 -0800721 DECLARE_ALIGNED(16, int8_t, coeff_contexts[MAX_TX_SQUARE]);
Dake He0db7d0e2017-12-21 15:23:20 -0800722 const int eob_multi_size = txsize_log2_minus4[tx_size];
723 const LV_MAP_EOB_COST *const eob_costs =
724 &x->eob_costs[eob_multi_size][plane_type];
Hui Su18205542018-03-30 11:37:41 -0700725 int cost = coeff_costs->txb_skip_cost[txb_skip_ctx][0];
Angie Chiang47c72182017-02-27 14:30:38 -0800726
Linfeng Zhang1122d7d2017-10-31 15:30:28 -0700727 av1_txb_init_levels(qcoeff, width, height, levels);
Linfeng Zhang1015a342017-10-24 16:20:41 -0700728
Urvang Joshi553096a2018-05-10 15:27:14 -0700729 cost += get_tx_type_cost(cm, x, xd, plane, tx_size, tx_type);
Angie Chiang05917872017-04-15 12:28:56 -0700730
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900731 cost += get_eob_cost(eob, eob_costs, coeff_costs, tx_class);
Linfeng Zhangd67c13f2017-12-11 11:49:12 -0800732
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900733 av1_get_nz_map_contexts(levels, scan, eob, tx_size, tx_class, coeff_contexts);
Linfeng Zhangd67c13f2017-12-11 11:49:12 -0800734
Katsuhisa Yuasa51467032018-04-08 16:16:10 +0900735 const int(*lps_cost)[COEFF_BASE_RANGE + 1] = coeff_costs->lps_cost;
736 int c = eob - 1;
737 {
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -0800738 const int pos = scan[c];
739 const tran_low_t v = qcoeff[pos];
Katsuhisa Yuasa51467032018-04-08 16:16:10 +0900740 const int sign = v >> 31;
741 const int level = (v ^ sign) - sign;
Linfeng Zhangd67c13f2017-12-11 11:49:12 -0800742 const int coeff_ctx = coeff_contexts[pos];
Katsuhisa Yuasa51467032018-04-08 16:16:10 +0900743 cost += coeff_costs->base_eob_cost[coeff_ctx][AOMMIN(level, 3) - 1];
Dake Hea47cd6c2017-10-13 18:09:58 -0700744
Katsuhisa Yuasa51467032018-04-08 16:16:10 +0900745 if (v) {
Dake Hea47cd6c2017-10-13 18:09:58 -0700746 // sign bit cost
Dake Hea47cd6c2017-10-13 18:09:58 -0700747 if (level > NUM_BASE_LEVELS) {
Jim Bankoskife171222019-01-14 08:41:57 -0800748 const int ctx = get_br_ctx_eob(pos, bwl, tx_class);
749 cost += get_br_cost(level, lps_cost[ctx]);
Katsuhisa Yuasa51467032018-04-08 16:16:10 +0900750 }
751 if (c) {
752 cost += av1_cost_literal(1);
753 } else {
754 const int sign01 = (sign ^ sign) - sign;
755 const int dc_sign_ctx = txb_ctx->dc_sign_ctx;
756 cost += coeff_costs->dc_sign_cost[dc_sign_ctx][sign01];
757 return cost;
758 }
759 }
760 }
761 const int(*base_cost)[4] = coeff_costs->base_cost;
762 for (c = eob - 2; c >= 1; --c) {
763 const int pos = scan[c];
764 const int coeff_ctx = coeff_contexts[pos];
765 const tran_low_t v = qcoeff[pos];
766 const int level = abs(v);
767 const int cost0 = base_cost[coeff_ctx][AOMMIN(level, 3)];
768 if (v) {
769 // sign bit cost
770 cost += av1_cost_literal(1);
771 if (level > NUM_BASE_LEVELS) {
772 const int ctx = get_br_ctx(levels, pos, bwl, tx_class);
Jim Bankoskife171222019-01-14 08:41:57 -0800773 cost += get_br_cost(level, lps_cost[ctx]);
Katsuhisa Yuasa51467032018-04-08 16:16:10 +0900774 }
775 }
776 cost += cost0;
777 }
778 if (c == 0) {
779 const int pos = scan[c];
780 const tran_low_t v = qcoeff[pos];
781 const int coeff_ctx = coeff_contexts[pos];
782 const int sign = v >> 31;
783 const int level = (v ^ sign) - sign;
784 cost += base_cost[coeff_ctx][AOMMIN(level, 3)];
Dake Hea47cd6c2017-10-13 18:09:58 -0700785
Katsuhisa Yuasa51467032018-04-08 16:16:10 +0900786 if (v) {
787 // sign bit cost
788 const int sign01 = (sign ^ sign) - sign;
789 const int dc_sign_ctx = txb_ctx->dc_sign_ctx;
790 cost += coeff_costs->dc_sign_cost[dc_sign_ctx][sign01];
791 if (level > NUM_BASE_LEVELS) {
792 const int ctx = get_br_ctx(levels, pos, bwl, tx_class);
Jim Bankoskife171222019-01-14 08:41:57 -0800793 cost += get_br_cost(level, lps_cost[ctx]);
Dake Hea47cd6c2017-10-13 18:09:58 -0700794 }
795 }
796 }
Angie Chiang47c72182017-02-27 14:30:38 -0800797 return cost;
798}
Angie Chiang0397eda2017-03-15 16:57:14 -0700799
Katsuhisa Yuasa51467032018-04-08 16:16:10 +0900800int av1_cost_coeffs_txb(const AV1_COMMON *const cm, const MACROBLOCK *x,
Xing Jin3a43b3b2018-06-25 15:41:38 +0800801 const int plane, const int block, const TX_SIZE tx_size,
802 const TX_TYPE tx_type, const TXB_CTX *const txb_ctx) {
Katsuhisa Yuasa51467032018-04-08 16:16:10 +0900803 const struct macroblock_plane *p = &x->plane[plane];
804 const int eob = p->eobs[block];
805 const TX_SIZE txs_ctx = get_txsize_entropy_ctx(tx_size);
806 const PLANE_TYPE plane_type = get_plane_type(plane);
807 const LV_MAP_COEFF_COST *const coeff_costs =
808 &x->coeff_costs[txs_ctx][plane_type];
809 if (eob == 0) {
810 return coeff_costs->txb_skip_cost[txb_ctx->txb_skip_ctx][1];
811 }
812
813 const MACROBLOCKD *const xd = &x->e_mbd;
Katsuhisa Yuasa51467032018-04-08 16:16:10 +0900814 const TX_CLASS tx_class = tx_type_to_class[tx_type];
815
816#define WAREHOUSE_EFFICIENTS_TXB_CASE(tx_class_literal) \
817 case tx_class_literal: \
818 return warehouse_efficients_txb(cm, x, plane, block, tx_size, txb_ctx, p, \
819 eob, plane_type, coeff_costs, xd, tx_type, \
820 tx_class_literal);
821 switch (tx_class) {
822 WAREHOUSE_EFFICIENTS_TXB_CASE(TX_CLASS_2D);
823 WAREHOUSE_EFFICIENTS_TXB_CASE(TX_CLASS_HORIZ);
824 WAREHOUSE_EFFICIENTS_TXB_CASE(TX_CLASS_VERT);
825#undef WAREHOUSE_EFFICIENTS_TXB_CASE
826 default: assert(false); return 0;
827 }
828}
829
Dake Hea47cd6c2017-10-13 18:09:58 -0700830static int optimize_txb(TxbInfo *txb_info, const LV_MAP_COEFF_COST *txb_costs,
Angie Chiang45385b82018-03-02 15:25:58 -0800831 const LV_MAP_EOB_COST *txb_eob_costs, int *rate_cost) {
Dake Hea47cd6c2017-10-13 18:09:58 -0700832 int update = 0;
833 if (txb_info->eob == 0) return update;
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -0800834 const int16_t *const scan = txb_info->scan_order->scan;
Dake Hea47cd6c2017-10-13 18:09:58 -0700835 // forward optimize the nz_map`
836 const int init_eob = txb_info->eob;
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900837 const TX_CLASS tx_class = tx_type_to_class[txb_info->tx_type];
Yaowu Xu49abec82018-03-13 16:09:01 -0700838 const int eob_cost =
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900839 get_eob_cost(init_eob, txb_eob_costs, txb_costs, tx_class);
Dake Hea47cd6c2017-10-13 18:09:58 -0700840
841 // backward optimize the level-k map
Cheng Chen82775f62018-01-18 12:09:54 -0800842 int accu_rate = eob_cost;
Dake Hea47cd6c2017-10-13 18:09:58 -0700843 int64_t accu_dist = 0;
844 int64_t prev_eob_rd_cost = INT64_MAX;
845 int64_t cur_eob_rd_cost = 0;
846
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800847 {
848 const int si = init_eob - 1;
849 const int coeff_idx = scan[si];
850 LevelDownStats stats;
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900851 get_dist_cost_stats(&stats, si, si == init_eob - 1, txb_costs, txb_info,
852 tx_class);
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800853 if ((stats.rd_low < stats.rd) && (stats.low_qc != 0)) {
854 update = 1;
855 update_coeff(coeff_idx, stats.low_qc, txb_info);
856 accu_rate += stats.rate_low;
857 accu_dist += stats.dist_low;
858 } else {
859 accu_rate += stats.rate;
860 accu_dist += stats.dist;
861 }
862 }
863
864 int si = init_eob - 2;
865 int8_t has_nz_tail = 0;
866 // eob is not fixed
867 for (; si >= 0 && has_nz_tail < 2; --si) {
868 assert(si != init_eob - 1);
Dake Hea47cd6c2017-10-13 18:09:58 -0700869 const int coeff_idx = scan[si];
870 tran_low_t qc = txb_info->qcoeff[coeff_idx];
871
Dake Hea47cd6c2017-10-13 18:09:58 -0700872 if (qc == 0) {
Angie Chiang99b12422018-03-02 17:15:00 -0800873 const int coeff_ctx =
874 get_lower_levels_ctx(txb_info->levels, coeff_idx, txb_info->bwl,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900875 txb_info->tx_size, tx_class);
Angie Chiang99b12422018-03-02 17:15:00 -0800876 accu_rate += txb_costs->base_cost[coeff_ctx][0];
Dake Hea47cd6c2017-10-13 18:09:58 -0700877 } else {
Angie Chiang99b12422018-03-02 17:15:00 -0800878 LevelDownStats stats;
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900879 get_dist_cost_stats_with_eob(&stats, si, txb_costs, txb_info, tx_class);
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800880 // check if it is better to make this the last significant coefficient
Yaowu Xu49abec82018-03-13 16:09:01 -0700881 int cur_eob_rate =
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900882 get_eob_cost(si + 1, txb_eob_costs, txb_costs, tx_class);
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800883 cur_eob_rd_cost = RDCOST(txb_info->rdmult, cur_eob_rate, 0);
884 prev_eob_rd_cost =
885 RDCOST(txb_info->rdmult, accu_rate, accu_dist) + stats.nz_rd;
886 if (cur_eob_rd_cost <= prev_eob_rd_cost) {
887 update = 1;
888 for (int j = si + 1; j < txb_info->eob; j++) {
889 const int coeff_pos_j = scan[j];
890 update_coeff(coeff_pos_j, 0, txb_info);
891 }
892 txb_info->eob = si + 1;
Angie Chiang99b12422018-03-02 17:15:00 -0800893
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800894 // rerun cost calculation due to change of eob
895 accu_rate = cur_eob_rate;
896 accu_dist = 0;
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900897 get_dist_cost_stats(&stats, si, 1, txb_costs, txb_info, tx_class);
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800898 if ((stats.rd_low < stats.rd) && (stats.low_qc != 0)) {
899 update = 1;
900 update_coeff(coeff_idx, stats.low_qc, txb_info);
901 accu_rate += stats.rate_low;
902 accu_dist += stats.dist_low;
Cheng Chenec32a742018-01-12 19:09:39 -0800903 } else {
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800904 accu_rate += stats.rate;
905 accu_dist += stats.dist;
906 }
907
908 // reset non zero tail when new eob is found
909 has_nz_tail = 0;
910 } else {
911 int bUpdCoeff = 0;
912 if (stats.rd_low < stats.rd) {
913 if ((si < txb_info->eob - 1)) {
914 bUpdCoeff = 1;
Cheng Chenec32a742018-01-12 19:09:39 -0800915 update = 1;
Cheng Chenec32a742018-01-12 19:09:39 -0800916 }
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800917 } else {
918 ++has_nz_tail;
919 }
920
921 if (bUpdCoeff) {
922 update_coeff(coeff_idx, stats.low_qc, txb_info);
923 accu_rate += stats.rate_low;
924 accu_dist += stats.dist_low;
925 } else {
926 accu_rate += stats.rate;
927 accu_dist += stats.dist;
Jingning Han8be58fa2017-12-18 09:46:13 -0800928 }
Dake Hea47cd6c2017-10-13 18:09:58 -0700929 }
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800930 }
931 } // for (si)
932
933 // eob is fixed
934 for (; si >= 0; --si) {
935 assert(si != init_eob - 1);
936 const int coeff_idx = scan[si];
937 tran_low_t qc = txb_info->qcoeff[coeff_idx];
938
939 if (qc == 0) {
940 const int coeff_ctx =
941 get_lower_levels_ctx(txb_info->levels, coeff_idx, txb_info->bwl,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900942 txb_info->tx_size, tx_class);
Angie Chiangcbbf4f02018-03-02 18:34:38 -0800943 accu_rate += txb_costs->base_cost[coeff_ctx][0];
944 } else {
945 LevelDownStats stats;
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +0900946 get_dist_cost_stats(&stats, si, 0, txb_costs, txb_info, tx_class);
Dake Hea47cd6c2017-10-13 18:09:58 -0700947
948 int bUpdCoeff = 0;
949 if (stats.rd_low < stats.rd) {
Dake He4d447692017-12-15 09:10:06 -0800950 if ((si < txb_info->eob - 1)) {
Dake Hea47cd6c2017-10-13 18:09:58 -0700951 bUpdCoeff = 1;
952 update = 1;
953 }
954 }
Dake Hea47cd6c2017-10-13 18:09:58 -0700955 if (bUpdCoeff) {
956 update_coeff(coeff_idx, stats.low_qc, txb_info);
957 accu_rate += stats.rate_low;
958 accu_dist += stats.dist_low;
959 } else {
960 accu_rate += stats.rate;
961 accu_dist += stats.dist;
962 }
963 }
964 } // for (si)
Jingning Hana7a6f4e2017-12-13 14:44:08 -0800965
Dake Hea47cd6c2017-10-13 18:09:58 -0700966 int non_zero_blk_rate =
967 txb_costs->txb_skip_cost[txb_info->txb_ctx->txb_skip_ctx][0];
968 prev_eob_rd_cost =
969 RDCOST(txb_info->rdmult, accu_rate + non_zero_blk_rate, accu_dist);
970
971 int zero_blk_rate =
972 txb_costs->txb_skip_cost[txb_info->txb_ctx->txb_skip_ctx][1];
973 int64_t zero_blk_rd_cost = RDCOST(txb_info->rdmult, zero_blk_rate, 0);
974 if (zero_blk_rd_cost <= prev_eob_rd_cost) {
975 update = 1;
976 for (int j = 0; j < txb_info->eob; j++) {
977 const int coeff_pos_j = scan[j];
978 update_coeff(coeff_pos_j, 0, txb_info);
979 }
980 txb_info->eob = 0;
981 }
982
Cheng Chen82775f62018-01-18 12:09:54 -0800983 // record total rate cost
984 *rate_cost = zero_blk_rd_cost <= prev_eob_rd_cost
985 ? zero_blk_rate
986 : accu_rate + non_zero_blk_rate;
Angie Chiang0ed53352018-03-08 12:53:43 -0800987
988 if (txb_info->eob > 0) {
989 *rate_cost += txb_info->tx_type_cost;
990 }
991
Dake Hea47cd6c2017-10-13 18:09:58 -0700992 return update;
993}
994
Sarah Parker427e3b12018-10-12 12:28:44 -0700995static void hbt_init() {
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -0800996 hbt_hash_table =
997 aom_malloc(sizeof(OptTxbQcoeff) * HBT_TABLE_SIZE * HBT_ARRAY_LENGTH);
998 memset(hbt_hash_table, 0,
999 sizeof(OptTxbQcoeff) * HBT_TABLE_SIZE * HBT_ARRAY_LENGTH);
Peng Bin8a204cd2018-04-08 13:07:35 +08001000 av1_crc32c_calculator_init(&crc_calculator); // 31 bit: qc & ctx
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001001
1002 hbt_needs_init = 0;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001003}
1004
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001005void hbt_destroy() { aom_free(hbt_hash_table); }
1006
Sarah Parker427e3b12018-10-12 12:28:44 -07001007static int hbt_hash_miss(uint32_t hbt_ctx_hash, uint32_t hbt_qc_hash,
1008 TxbInfo *txb_info, const LV_MAP_COEFF_COST *txb_costs,
1009 const LV_MAP_EOB_COST *txb_eob_costs,
1010 const struct macroblock_plane *p, int block,
1011 int fast_mode, int *rate_cost) {
Angie Chiang45385b82018-03-02 15:25:58 -08001012 (void)fast_mode;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001013 const int16_t *scan = txb_info->scan_order->scan;
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001014 int prev_eob = txb_info->eob;
1015 assert(HBT_EOB <= 16); // Lengthen array if allowing longer eob.
1016 int32_t prev_coeff[16];
1017 for (int i = 0; i < prev_eob; i++) {
1018 prev_coeff[i] = txb_info->qcoeff[scan[i]];
1019 }
1020 for (int i = prev_eob; i < HBT_EOB; i++) {
1021 prev_coeff[i] = 0; // For compiler piece of mind.
1022 }
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001023
1024 av1_txb_init_levels(txb_info->qcoeff, txb_info->width, txb_info->height,
1025 txb_info->levels);
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001026
Angie Chiang45385b82018-03-02 15:25:58 -08001027 const int update =
1028 optimize_txb(txb_info, txb_costs, txb_eob_costs, rate_cost);
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001029
1030 // Overwrite old entry
1031 uint16_t hbt_table_index = hbt_ctx_hash % HBT_TABLE_SIZE;
1032 uint16_t hbt_array_index = hbt_qc_hash % HBT_ARRAY_LENGTH;
1033 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1034 .rate_cost = *rate_cost;
1035 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index].init = 1;
1036 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1037 .hbt_qc_hash = hbt_qc_hash;
1038 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1039 .hbt_ctx_hash = hbt_ctx_hash;
1040 assert(prev_eob >= txb_info->eob); // eob can't get longer
1041 for (int i = 0; i < txb_info->eob; i++) {
1042 // Record how coeff changed. Convention: towards zero is negative.
1043 if (txb_info->qcoeff[scan[i]] > 0)
1044 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1045 .deltas[i] = txb_info->qcoeff[scan[i]] - prev_coeff[i];
1046 else
1047 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1048 .deltas[i] = prev_coeff[i] - txb_info->qcoeff[scan[i]];
1049 }
1050 for (int i = txb_info->eob; i < prev_eob; i++) {
1051 // If eob got shorter, record that all after it changed to zero.
1052 if (prev_coeff[i] > 0)
1053 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1054 .deltas[i] = -prev_coeff[i];
1055 else
1056 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1057 .deltas[i] = prev_coeff[i];
1058 }
1059 for (int i = prev_eob; i < HBT_EOB; i++) {
1060 // Record 'no change' after optimized coefficients run out.
1061 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1062 .deltas[i] = 0;
1063 }
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001064
1065 if (update) {
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001066 p->eobs[block] = txb_info->eob;
1067 p->txb_entropy_ctx[block] = av1_get_txb_entropy_context(
1068 txb_info->qcoeff, txb_info->scan_order, txb_info->eob);
1069 }
1070 return txb_info->eob;
1071}
1072
Sarah Parker427e3b12018-10-12 12:28:44 -07001073static int hbt_hash_hit(uint32_t hbt_table_index, int hbt_array_index,
1074 TxbInfo *txb_info, const struct macroblock_plane *p,
1075 int block, int *rate_cost) {
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001076 const int16_t *scan = txb_info->scan_order->scan;
1077 int new_eob = 0;
1078 int update = 0;
1079
1080 for (int i = 0; i < txb_info->eob; i++) {
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001081 // Delta convention is negatives go towards zero, so only apply those ones.
1082 if (hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1083 .deltas[i] < 0) {
1084 if (txb_info->qcoeff[scan[i]] > 0)
1085 txb_info->qcoeff[scan[i]] +=
1086 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1087 .deltas[i];
1088 else
1089 txb_info->qcoeff[scan[i]] -=
1090 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1091 .deltas[i];
1092
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001093 update = 1;
1094 update_coeff(scan[i], txb_info->qcoeff[scan[i]], txb_info);
1095 }
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001096 if (txb_info->qcoeff[scan[i]]) new_eob = i + 1;
1097 }
1098
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001099 // Rate_cost can be calculated here instead (av1_cost_coeffs_txb), but
1100 // it is expensive and gives little benefit as long as qc_hash is high bit
1101 *rate_cost =
1102 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1103 .rate_cost;
1104
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001105 if (update) {
1106 txb_info->eob = new_eob;
1107 p->eobs[block] = txb_info->eob;
1108 p->txb_entropy_ctx[block] = av1_get_txb_entropy_context(
1109 txb_info->qcoeff, txb_info->scan_order, txb_info->eob);
1110 }
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001111
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001112 return txb_info->eob;
1113}
1114
Sarah Parker427e3b12018-10-12 12:28:44 -07001115static int hbt_search_match(uint32_t hbt_ctx_hash, uint32_t hbt_qc_hash,
1116 TxbInfo *txb_info,
1117 const LV_MAP_COEFF_COST *txb_costs,
1118 const LV_MAP_EOB_COST *txb_eob_costs,
1119 const struct macroblock_plane *p, int block,
1120 int fast_mode, int *rate_cost) {
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001121 // Check for qcoeff match
1122 int hbt_array_index = hbt_qc_hash % HBT_ARRAY_LENGTH;
1123 int hbt_table_index = hbt_ctx_hash % HBT_TABLE_SIZE;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001124
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001125 if (hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1126 .hbt_qc_hash == hbt_qc_hash &&
1127 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1128 .hbt_ctx_hash == hbt_ctx_hash &&
1129 hbt_hash_table[hbt_table_index * HBT_ARRAY_LENGTH + hbt_array_index]
1130 .init) {
1131 return hbt_hash_hit(hbt_table_index, hbt_array_index, txb_info, p, block,
1132 rate_cost);
1133 } else {
1134 return hbt_hash_miss(hbt_ctx_hash, hbt_qc_hash, txb_info, txb_costs,
1135 txb_eob_costs, p, block, fast_mode, rate_cost);
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001136 }
1137}
1138
Sarah Parker427e3b12018-10-12 12:28:44 -07001139static int hbt_create_hashes(TxbInfo *txb_info,
1140 const LV_MAP_COEFF_COST *txb_costs,
1141 const LV_MAP_EOB_COST *txb_eob_costs,
1142 const struct macroblock_plane *p, int block,
1143 int fast_mode, int *rate_cost) {
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001144 // Initialize hash table if needed.
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001145 if (hbt_needs_init) {
1146 hbt_init();
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001147 }
1148
1149 //// Hash creation
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001150 uint8_t txb_hash_data[256]; // Asserts below to ensure enough space.
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001151 const int16_t *scan = txb_info->scan_order->scan;
1152 uint8_t chunk = 0;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001153 int hash_data_index = 0;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001154
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001155 // Make qc_hash.
1156 int packing_index = 0; // needed for packing.
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001157 for (int i = 0; i < txb_info->eob; i++) {
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001158 tran_low_t prechunk = txb_info->qcoeff[scan[i]];
1159
1160 // Softening: Improves speed. Aligns with signed deltas.
1161 if (prechunk < 0) prechunk *= -1;
1162
1163 // Early kick out: Don't apply feature if there are large coeffs:
1164 // If this kickout value is removed or raised beyond int8_t,
1165 // widen deltas type in OptTxbQcoeff struct.
1166 assert((int8_t)HBT_KICKOUT == HBT_KICKOUT); // If not, widen types.
1167 if (prechunk > HBT_KICKOUT) {
1168 av1_txb_init_levels(txb_info->qcoeff, txb_info->width, txb_info->height,
1169 txb_info->levels);
1170
Angie Chiang45385b82018-03-02 15:25:58 -08001171 const int update =
1172 optimize_txb(txb_info, txb_costs, txb_eob_costs, rate_cost);
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001173
1174 if (update) {
1175 p->eobs[block] = txb_info->eob;
1176 p->txb_entropy_ctx[block] = av1_get_txb_entropy_context(
1177 txb_info->qcoeff, txb_info->scan_order, txb_info->eob);
1178 }
1179 return txb_info->eob;
1180 }
1181
1182 // Since coeffs are 0 to 3, only 2 bits are needed: pack into bytes
1183 if (packing_index == 0) txb_hash_data[hash_data_index] = 0;
1184 chunk = prechunk << packing_index;
1185 packing_index += 2;
1186 txb_hash_data[hash_data_index] |= chunk;
1187
1188 // Full byte:
1189 if (packing_index == 8) {
1190 packing_index = 0;
1191 hash_data_index++;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001192 }
1193 }
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001194 // Needed when packing_index != 0, to include final byte.
1195 hash_data_index++;
1196 assert(hash_data_index <= 64);
1197 // 31 bit qc_hash: index to array
1198 uint32_t hbt_qc_hash =
Peng Bin8a204cd2018-04-08 13:07:35 +08001199 av1_get_crc32c_value(&crc_calculator, txb_hash_data, hash_data_index);
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001200
1201 // Make ctx_hash.
1202 hash_data_index = 0;
1203 tran_low_t prechunk;
1204
1205 for (int i = 0; i < txb_info->eob; i++) {
1206 // Save as magnitudes towards or away from zero.
1207 if (txb_info->tcoeff[scan[i]] >= 0)
1208 prechunk = txb_info->tcoeff[scan[i]] - txb_info->dqcoeff[scan[i]];
1209 else
1210 prechunk = txb_info->dqcoeff[scan[i]] - txb_info->tcoeff[scan[i]];
1211
1212 chunk = prechunk & 0xff;
1213 txb_hash_data[hash_data_index++] = chunk;
1214 }
1215
1216 // Extra ctx data:
1217 // Include dequants.
1218 txb_hash_data[hash_data_index++] = txb_info->dequant[0] & 0xff;
1219 txb_hash_data[hash_data_index++] = txb_info->dequant[1] & 0xff;
1220 chunk = txb_info->txb_ctx->txb_skip_ctx & 0xff;
1221 txb_hash_data[hash_data_index++] = chunk;
1222 chunk = txb_info->txb_ctx->dc_sign_ctx & 0xff;
1223 txb_hash_data[hash_data_index++] = chunk;
1224 // eob
1225 chunk = txb_info->eob & 0xff;
1226 txb_hash_data[hash_data_index++] = chunk;
1227 // rdmult (int64)
1228 chunk = txb_info->rdmult & 0xff;
1229 txb_hash_data[hash_data_index++] = chunk;
1230 // tx_type
1231 chunk = txb_info->tx_type & 0xff;
1232 txb_hash_data[hash_data_index++] = chunk;
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001233 // base_eob_cost
1234 for (int i = 1; i < 3; i++) { // i = 0 are softened away
1235 for (int j = 0; j < SIG_COEF_CONTEXTS_EOB; j++) {
1236 chunk = (txb_costs->base_eob_cost[j][i] & 0xff00) >> 8;
1237 txb_hash_data[hash_data_index++] = chunk;
1238 }
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001239 }
1240 // eob_cost
1241 for (int i = 0; i < 11; i++) {
1242 for (int j = 0; j < 2; j++) {
1243 chunk = (txb_eob_costs->eob_cost[j][i] & 0xff00) >> 8;
1244 txb_hash_data[hash_data_index++] = chunk;
1245 }
1246 }
1247 // dc_sign_cost
1248 for (int i = 0; i < 2; i++) {
1249 for (int j = 0; j < DC_SIGN_CONTEXTS; j++) {
1250 chunk = (txb_costs->dc_sign_cost[j][i] & 0xff00) >> 8;
1251 txb_hash_data[hash_data_index++] = chunk;
1252 }
1253 }
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001254
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001255 assert(hash_data_index <= 256);
1256 // 31 bit ctx_hash: used to index table
1257 uint32_t hbt_ctx_hash =
Peng Bin8a204cd2018-04-08 13:07:35 +08001258 av1_get_crc32c_value(&crc_calculator, txb_hash_data, hash_data_index);
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001259 //// End hash creation
1260
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001261 return hbt_search_match(hbt_ctx_hash, hbt_qc_hash, txb_info, txb_costs,
1262 txb_eob_costs, p, block, fast_mode, rate_cost);
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001263}
1264
Katsuhisa Yuasa9f639962018-04-08 18:00:54 +09001265static AOM_FORCE_INLINE int get_coeff_cost_simple(
1266 int ci, tran_low_t abs_qc, int coeff_ctx,
1267 const LV_MAP_COEFF_COST *txb_costs, int bwl, TX_CLASS tx_class,
1268 const uint8_t *levels) {
Angie Chiang40b07312018-03-30 10:42:55 -07001269 // this simple version assumes the coeff's scan_idx is not DC (scan_idx != 0)
Angie Chiange4ea7482018-03-15 11:36:41 -07001270 // and not the last (scan_idx != eob - 1)
1271 assert(ci > 0);
1272 int cost = txb_costs->base_cost[coeff_ctx][AOMMIN(abs_qc, 3)];
1273 if (abs_qc) {
1274 cost += av1_cost_literal(1);
1275 if (abs_qc > NUM_BASE_LEVELS) {
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001276 const int br_ctx = get_br_ctx(levels, ci, bwl, tx_class);
Jim Bankoskife171222019-01-14 08:41:57 -08001277 cost += get_br_cost(abs_qc, txb_costs->lps_cost[br_ctx]);
Jim Bankoskife171222019-01-14 08:41:57 -08001278 }
1279 }
1280 return cost;
1281}
1282
1283static INLINE int get_coeff_cost_eob(int ci, tran_low_t abs_qc, int sign,
1284 int coeff_ctx, int dc_sign_ctx,
1285 const LV_MAP_COEFF_COST *txb_costs,
1286 int bwl, TX_CLASS tx_class) {
1287 int cost = 0;
1288 cost += txb_costs->base_eob_cost[coeff_ctx][AOMMIN(abs_qc, 3) - 1];
1289 if (abs_qc != 0) {
1290 if (ci == 0) {
1291 cost += txb_costs->dc_sign_cost[dc_sign_ctx][sign];
1292 } else {
1293 cost += av1_cost_literal(1);
1294 }
1295 if (abs_qc > NUM_BASE_LEVELS) {
1296 int br_ctx;
1297 br_ctx = get_br_ctx_eob(ci, bwl, tx_class);
1298 cost += get_br_cost(abs_qc, txb_costs->lps_cost[br_ctx]);
Angie Chiange4ea7482018-03-15 11:36:41 -07001299 }
1300 }
1301 return cost;
1302}
1303
1304static INLINE int get_coeff_cost_general(int is_last, int ci, tran_low_t abs_qc,
Angie Chiang40b07312018-03-30 10:42:55 -07001305 int sign, int coeff_ctx,
Angie Chiange4ea7482018-03-15 11:36:41 -07001306 int dc_sign_ctx,
1307 const LV_MAP_COEFF_COST *txb_costs,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001308 int bwl, TX_CLASS tx_class,
Angie Chiange4ea7482018-03-15 11:36:41 -07001309 const uint8_t *levels) {
1310 int cost = 0;
1311 if (is_last) {
1312 cost += txb_costs->base_eob_cost[coeff_ctx][AOMMIN(abs_qc, 3) - 1];
1313 } else {
1314 cost += txb_costs->base_cost[coeff_ctx][AOMMIN(abs_qc, 3)];
1315 }
1316 if (abs_qc != 0) {
1317 if (ci == 0) {
Angie Chiang40b07312018-03-30 10:42:55 -07001318 cost += txb_costs->dc_sign_cost[dc_sign_ctx][sign];
Angie Chiange4ea7482018-03-15 11:36:41 -07001319 } else {
1320 cost += av1_cost_literal(1);
1321 }
1322 if (abs_qc > NUM_BASE_LEVELS) {
Jim Bankoski95cb0d72019-01-11 15:20:06 -08001323 int br_ctx;
1324 if (is_last)
1325 br_ctx = get_br_ctx_eob(ci, bwl, tx_class);
1326 else
1327 br_ctx = get_br_ctx(levels, ci, bwl, tx_class);
Jim Bankoskife171222019-01-14 08:41:57 -08001328 cost += get_br_cost(abs_qc, txb_costs->lps_cost[br_ctx]);
Angie Chiange4ea7482018-03-15 11:36:41 -07001329 }
1330 }
1331 return cost;
1332}
1333
Angie Chiang40b07312018-03-30 10:42:55 -07001334static INLINE void get_qc_dqc_low(tran_low_t abs_qc, int sign, int dqv,
Angie Chiange4ea7482018-03-15 11:36:41 -07001335 int shift, tran_low_t *qc_low,
1336 tran_low_t *dqc_low) {
1337 tran_low_t abs_qc_low = abs_qc - 1;
Angie Chiang40b07312018-03-30 10:42:55 -07001338 *qc_low = (-sign ^ abs_qc_low) + sign;
1339 assert((sign ? -abs_qc_low : abs_qc_low) == *qc_low);
Angie Chiange4ea7482018-03-15 11:36:41 -07001340 tran_low_t abs_dqc_low = (abs_qc_low * dqv) >> shift;
Angie Chiang40b07312018-03-30 10:42:55 -07001341 *dqc_low = (-sign ^ abs_dqc_low) + sign;
1342 assert((sign ? -abs_dqc_low : abs_dqc_low) == *dqc_low);
Angie Chiange4ea7482018-03-15 11:36:41 -07001343}
1344
1345static INLINE void update_coeff_general(
1346 int *accu_rate, int64_t *accu_dist, int si, int eob, TX_SIZE tx_size,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001347 TX_CLASS tx_class, int bwl, int height, int64_t rdmult, int shift,
Angie Chiange4ea7482018-03-15 11:36:41 -07001348 int dc_sign_ctx, const int16_t *dequant, const int16_t *scan,
1349 const LV_MAP_COEFF_COST *txb_costs, const tran_low_t *tcoeff,
1350 tran_low_t *qcoeff, tran_low_t *dqcoeff, uint8_t *levels) {
1351 const int dqv = dequant[si != 0];
1352 const int ci = scan[si];
1353 const tran_low_t qc = qcoeff[ci];
1354 const int is_last = si == (eob - 1);
1355 const int coeff_ctx = get_lower_levels_ctx_general(
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001356 is_last, si, bwl, height, levels, ci, tx_size, tx_class);
Angie Chiange4ea7482018-03-15 11:36:41 -07001357 if (qc == 0) {
1358 *accu_rate += txb_costs->base_cost[coeff_ctx][0];
1359 } else {
Angie Chiang40b07312018-03-30 10:42:55 -07001360 const int sign = (qc < 0) ? 1 : 0;
Angie Chiange4ea7482018-03-15 11:36:41 -07001361 const tran_low_t abs_qc = abs(qc);
1362 const tran_low_t tqc = tcoeff[ci];
1363 const tran_low_t dqc = dqcoeff[ci];
1364 const int64_t dist = get_coeff_dist(tqc, dqc, shift);
1365 const int64_t dist0 = get_coeff_dist(tqc, 0, shift);
1366 const int rate =
Angie Chiang40b07312018-03-30 10:42:55 -07001367 get_coeff_cost_general(is_last, ci, abs_qc, sign, coeff_ctx,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001368 dc_sign_ctx, txb_costs, bwl, tx_class, levels);
Angie Chiange4ea7482018-03-15 11:36:41 -07001369 const int64_t rd = RDCOST(rdmult, rate, dist);
1370
1371 tran_low_t qc_low, dqc_low;
Angie Chiang40b07312018-03-30 10:42:55 -07001372 get_qc_dqc_low(abs_qc, sign, dqv, shift, &qc_low, &dqc_low);
Angie Chiange4ea7482018-03-15 11:36:41 -07001373 const tran_low_t abs_qc_low = abs_qc - 1;
1374 const int64_t dist_low = get_coeff_dist(tqc, dqc_low, shift);
1375 const int rate_low =
Angie Chiang40b07312018-03-30 10:42:55 -07001376 get_coeff_cost_general(is_last, ci, abs_qc_low, sign, coeff_ctx,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001377 dc_sign_ctx, txb_costs, bwl, tx_class, levels);
Angie Chiange4ea7482018-03-15 11:36:41 -07001378 const int64_t rd_low = RDCOST(rdmult, rate_low, dist_low);
1379 if (rd_low < rd) {
1380 qcoeff[ci] = qc_low;
1381 dqcoeff[ci] = dqc_low;
1382 levels[get_padded_idx(ci, bwl)] = AOMMIN(abs_qc_low, INT8_MAX);
1383 *accu_rate += rate_low;
1384 *accu_dist += dist_low - dist0;
1385 } else {
1386 *accu_rate += rate;
1387 *accu_dist += dist - dist0;
1388 }
1389 }
1390}
1391
Katsuhisa Yuasa9f639962018-04-08 18:00:54 +09001392static AOM_FORCE_INLINE void update_coeff_simple(
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001393 int *accu_rate, int si, int eob, TX_SIZE tx_size, TX_CLASS tx_class,
1394 int bwl, int64_t rdmult, int shift, const int16_t *dequant,
1395 const int16_t *scan, const LV_MAP_COEFF_COST *txb_costs,
1396 const tran_low_t *tcoeff, tran_low_t *qcoeff, tran_low_t *dqcoeff,
1397 uint8_t *levels) {
Angie Chiange4ea7482018-03-15 11:36:41 -07001398 const int dqv = dequant[1];
1399 (void)eob;
Angie Chiang40b07312018-03-30 10:42:55 -07001400 // this simple version assumes the coeff's scan_idx is not DC (scan_idx != 0)
Angie Chiange4ea7482018-03-15 11:36:41 -07001401 // and not the last (scan_idx != eob - 1)
1402 assert(si != eob - 1);
1403 assert(si > 0);
1404 const int ci = scan[si];
1405 const tran_low_t qc = qcoeff[ci];
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001406 const int coeff_ctx =
1407 get_lower_levels_ctx(levels, ci, bwl, tx_size, tx_class);
Angie Chiange4ea7482018-03-15 11:36:41 -07001408 if (qc == 0) {
1409 *accu_rate += txb_costs->base_cost[coeff_ctx][0];
1410 } else {
1411 const tran_low_t abs_qc = abs(qc);
1412 const tran_low_t tqc = tcoeff[ci];
1413 const tran_low_t dqc = dqcoeff[ci];
Angie Chiange4ea7482018-03-15 11:36:41 -07001414 const int rate = get_coeff_cost_simple(ci, abs_qc, coeff_ctx, txb_costs,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001415 bwl, tx_class, levels);
Jingning Han87f5c342018-04-10 23:10:12 -07001416 if (abs(dqc) < abs(tqc)) {
1417 *accu_rate += rate;
1418 return;
1419 }
1420 const int64_t dist = get_coeff_dist(tqc, dqc, shift);
Angie Chiange4ea7482018-03-15 11:36:41 -07001421 const int64_t rd = RDCOST(rdmult, rate, dist);
1422
Angie Chiang40b07312018-03-30 10:42:55 -07001423 const int sign = (qc < 0) ? 1 : 0;
Angie Chiange4ea7482018-03-15 11:36:41 -07001424 tran_low_t qc_low, dqc_low;
Angie Chiang40b07312018-03-30 10:42:55 -07001425 get_qc_dqc_low(abs_qc, sign, dqv, shift, &qc_low, &dqc_low);
Angie Chiange4ea7482018-03-15 11:36:41 -07001426 const tran_low_t abs_qc_low = abs_qc - 1;
1427 const int64_t dist_low = get_coeff_dist(tqc, dqc_low, shift);
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001428 const int rate_low = get_coeff_cost_simple(
1429 ci, abs_qc_low, coeff_ctx, txb_costs, bwl, tx_class, levels);
Angie Chiange4ea7482018-03-15 11:36:41 -07001430 const int64_t rd_low = RDCOST(rdmult, rate_low, dist_low);
1431 if (rd_low < rd) {
1432 qcoeff[ci] = qc_low;
1433 dqcoeff[ci] = dqc_low;
1434 levels[get_padded_idx(ci, bwl)] = AOMMIN(abs_qc_low, INT8_MAX);
1435 *accu_rate += rate_low;
Angie Chiange4ea7482018-03-15 11:36:41 -07001436 } else {
1437 *accu_rate += rate;
Angie Chiange4ea7482018-03-15 11:36:41 -07001438 }
1439 }
1440}
1441
Katsuhisa Yuasa9f639962018-04-08 18:00:54 +09001442static AOM_FORCE_INLINE void update_coeff_eob(
Angie Chiange4ea7482018-03-15 11:36:41 -07001443 int *accu_rate, int64_t *accu_dist, int *eob, int *nz_num, int *nz_ci,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001444 int si, TX_SIZE tx_size, TX_CLASS tx_class, int bwl, int height,
Angie Chiange4ea7482018-03-15 11:36:41 -07001445 int dc_sign_ctx, int64_t rdmult, int shift, const int16_t *dequant,
1446 const int16_t *scan, const LV_MAP_EOB_COST *txb_eob_costs,
1447 const LV_MAP_COEFF_COST *txb_costs, const tran_low_t *tcoeff,
Jim Bankoski855ac462018-06-07 09:05:00 -07001448 tran_low_t *qcoeff, tran_low_t *dqcoeff, uint8_t *levels, int sharpness) {
Angie Chiange4ea7482018-03-15 11:36:41 -07001449 const int dqv = dequant[si != 0];
1450 assert(si != *eob - 1);
1451 const int ci = scan[si];
1452 const tran_low_t qc = qcoeff[ci];
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001453 const int coeff_ctx =
1454 get_lower_levels_ctx(levels, ci, bwl, tx_size, tx_class);
Angie Chiange4ea7482018-03-15 11:36:41 -07001455 if (qc == 0) {
1456 *accu_rate += txb_costs->base_cost[coeff_ctx][0];
1457 } else {
1458 int lower_level = 0;
1459 const tran_low_t abs_qc = abs(qc);
1460 const tran_low_t tqc = tcoeff[ci];
1461 const tran_low_t dqc = dqcoeff[ci];
Angie Chiang40b07312018-03-30 10:42:55 -07001462 const int sign = (qc < 0) ? 1 : 0;
Angie Chiange4ea7482018-03-15 11:36:41 -07001463 const int64_t dist0 = get_coeff_dist(tqc, 0, shift);
1464 int64_t dist = get_coeff_dist(tqc, dqc, shift) - dist0;
1465 int rate =
Angie Chiang40b07312018-03-30 10:42:55 -07001466 get_coeff_cost_general(0, ci, abs_qc, sign, coeff_ctx, dc_sign_ctx,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001467 txb_costs, bwl, tx_class, levels);
Angie Chiange4ea7482018-03-15 11:36:41 -07001468 int64_t rd = RDCOST(rdmult, *accu_rate + rate, *accu_dist + dist);
1469
1470 tran_low_t qc_low, dqc_low;
Angie Chiang40b07312018-03-30 10:42:55 -07001471 get_qc_dqc_low(abs_qc, sign, dqv, shift, &qc_low, &dqc_low);
Angie Chiange4ea7482018-03-15 11:36:41 -07001472 const tran_low_t abs_qc_low = abs_qc - 1;
1473 const int64_t dist_low = get_coeff_dist(tqc, dqc_low, shift) - dist0;
1474 const int rate_low =
Angie Chiang40b07312018-03-30 10:42:55 -07001475 get_coeff_cost_general(0, ci, abs_qc_low, sign, coeff_ctx, dc_sign_ctx,
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001476 txb_costs, bwl, tx_class, levels);
Angie Chiange4ea7482018-03-15 11:36:41 -07001477 const int64_t rd_low =
1478 RDCOST(rdmult, *accu_rate + rate_low, *accu_dist + dist_low);
1479
1480 int lower_level_new_eob = 0;
1481 const int new_eob = si + 1;
wenyao.liu0be59012018-12-24 10:27:31 +08001482 const int coeff_ctx_new_eob = get_lower_levels_ctx_eob(bwl, height, si);
Angie Chiange4ea7482018-03-15 11:36:41 -07001483 const int new_eob_cost =
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001484 get_eob_cost(new_eob, txb_eob_costs, txb_costs, tx_class);
Angie Chiange4ea7482018-03-15 11:36:41 -07001485 int rate_coeff_eob =
Jim Bankoskife171222019-01-14 08:41:57 -08001486 new_eob_cost + get_coeff_cost_eob(ci, abs_qc, sign, coeff_ctx_new_eob,
1487 dc_sign_ctx, txb_costs, bwl,
1488 tx_class);
Angie Chiange4ea7482018-03-15 11:36:41 -07001489 int64_t dist_new_eob = dist;
1490 int64_t rd_new_eob = RDCOST(rdmult, rate_coeff_eob, dist_new_eob);
1491
1492 if (abs_qc_low > 0) {
1493 const int rate_coeff_eob_low =
Jim Bankoskife171222019-01-14 08:41:57 -08001494 new_eob_cost + get_coeff_cost_eob(ci, abs_qc_low, sign,
1495 coeff_ctx_new_eob, dc_sign_ctx,
1496 txb_costs, bwl, tx_class);
Angie Chiange4ea7482018-03-15 11:36:41 -07001497 const int64_t dist_new_eob_low = dist_low;
1498 const int64_t rd_new_eob_low =
1499 RDCOST(rdmult, rate_coeff_eob_low, dist_new_eob_low);
1500 if (rd_new_eob_low < rd_new_eob) {
1501 lower_level_new_eob = 1;
1502 rd_new_eob = rd_new_eob_low;
1503 rate_coeff_eob = rate_coeff_eob_low;
1504 dist_new_eob = dist_new_eob_low;
1505 }
1506 }
1507
1508 if (rd_low < rd) {
1509 lower_level = 1;
1510 rd = rd_low;
1511 rate = rate_low;
1512 dist = dist_low;
1513 }
1514
Jim Bankoski855ac462018-06-07 09:05:00 -07001515 if (sharpness == 0 && rd_new_eob < rd) {
Angie Chiange4ea7482018-03-15 11:36:41 -07001516 for (int ni = 0; ni < *nz_num; ++ni) {
1517 int last_ci = nz_ci[ni];
Jim Bankoski95cb0d72019-01-11 15:20:06 -08001518 levels[get_padded_idx(last_ci, bwl)] = 0;
Angie Chiange4ea7482018-03-15 11:36:41 -07001519 qcoeff[last_ci] = 0;
1520 dqcoeff[last_ci] = 0;
1521 }
1522 *eob = new_eob;
1523 *nz_num = 0;
1524 *accu_rate = rate_coeff_eob;
1525 *accu_dist = dist_new_eob;
1526 lower_level = lower_level_new_eob;
1527 } else {
Angie Chiange4ea7482018-03-15 11:36:41 -07001528 *accu_rate += rate;
1529 *accu_dist += dist;
1530 }
1531
1532 if (lower_level) {
1533 qcoeff[ci] = qc_low;
1534 dqcoeff[ci] = dqc_low;
1535 levels[get_padded_idx(ci, bwl)] = AOMMIN(abs_qc_low, INT8_MAX);
1536 }
1537 if (qcoeff[ci]) {
1538 nz_ci[*nz_num] = ci;
1539 ++*nz_num;
1540 }
1541 }
1542}
1543
Angie Chiangd0397e12018-03-27 19:03:20 -07001544static INLINE void update_skip(int *accu_rate, int64_t accu_dist, int *eob,
1545 int nz_num, int *nz_ci, int64_t rdmult,
1546 int skip_cost, int non_skip_cost,
Jim Bankoski855ac462018-06-07 09:05:00 -07001547 tran_low_t *qcoeff, tran_low_t *dqcoeff,
1548 int sharpness) {
Angie Chiangd0397e12018-03-27 19:03:20 -07001549 const int64_t rd = RDCOST(rdmult, *accu_rate + non_skip_cost, accu_dist);
Angie Chiange4ea7482018-03-15 11:36:41 -07001550 const int64_t rd_new_eob = RDCOST(rdmult, skip_cost, 0);
Jim Bankoski855ac462018-06-07 09:05:00 -07001551 if (sharpness == 0 && rd_new_eob < rd) {
Angie Chiangd0397e12018-03-27 19:03:20 -07001552 for (int i = 0; i < nz_num; ++i) {
1553 const int ci = nz_ci[i];
Angie Chiange4ea7482018-03-15 11:36:41 -07001554 qcoeff[ci] = 0;
1555 dqcoeff[ci] = 0;
Angie Chiangd0397e12018-03-27 19:03:20 -07001556 // no need to set up levels because this is the last step
1557 // levels[get_padded_idx(ci, bwl)] = 0;
Angie Chiange4ea7482018-03-15 11:36:41 -07001558 }
Angie Chiange4ea7482018-03-15 11:36:41 -07001559 *accu_rate = 0;
1560 *eob = 0;
1561 }
1562}
1563
1564int av1_optimize_txb_new(const struct AV1_COMP *cpi, MACROBLOCK *x, int plane,
Xing Jinbd91e942018-06-21 13:43:17 +08001565 int block, TX_SIZE tx_size, TX_TYPE tx_type,
1566 const TXB_CTX *const txb_ctx, int *rate_cost,
1567 int sharpness) {
Angie Chiange4ea7482018-03-15 11:36:41 -07001568 const AV1_COMMON *cm = &cpi->common;
1569 MACROBLOCKD *xd = &x->e_mbd;
1570 const PLANE_TYPE plane_type = get_plane_type(plane);
1571 const TX_SIZE txs_ctx = get_txsize_entropy_ctx(tx_size);
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001572 const TX_CLASS tx_class = tx_type_to_class[tx_type];
Yue Chen53b53f02018-03-29 14:31:23 -07001573 const MB_MODE_INFO *mbmi = xd->mi[0];
Angie Chiange4ea7482018-03-15 11:36:41 -07001574 const struct macroblock_plane *p = &x->plane[plane];
1575 struct macroblockd_plane *pd = &xd->plane[plane];
1576 tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1577 tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1578 const tran_low_t *tcoeff = BLOCK_OFFSET(p->coeff, block);
1579 const int16_t *dequant = p->dequant_QTX;
1580 const int bwl = get_txb_bwl(tx_size);
1581 const int width = get_txb_wide(tx_size);
1582 const int height = get_txb_high(tx_size);
1583 assert(width == (1 << bwl));
1584 const int is_inter = is_inter_block(mbmi);
1585 const SCAN_ORDER *scan_order = get_scan(tx_size, tx_type);
1586 const int16_t *scan = scan_order->scan;
1587 const LV_MAP_COEFF_COST *txb_costs = &x->coeff_costs[txs_ctx][plane_type];
1588 const int eob_multi_size = txsize_log2_minus4[tx_size];
1589 const LV_MAP_EOB_COST *txb_eob_costs =
1590 &x->eob_costs[eob_multi_size][plane_type];
1591
1592 const int shift = av1_get_tx_scale(tx_size);
1593 const int64_t rdmult =
1594 ((x->rdmult * plane_rd_mult[is_inter][plane_type] << (2 * (xd->bd - 8))) +
1595 2) >>
Yue Chende730472018-06-20 10:13:15 -07001596 (sharpness +
1597 (cpi->oxcf.aq_mode == VARIANCE_AQ && mbmi->segment_id < 4
1598 ? 7 - mbmi->segment_id
1599 : 2) +
1600 (cpi->oxcf.aq_mode != VARIANCE_AQ &&
1601 cpi->oxcf.deltaq_mode > NO_DELTA_Q && x->sb_energy_level < 0
1602 ? (3 - x->sb_energy_level)
1603 : 0));
Angie Chiange4ea7482018-03-15 11:36:41 -07001604
1605 uint8_t levels_buf[TX_PAD_2D];
1606 uint8_t *const levels = set_levels(levels_buf, width);
Jim Bankoski102f36b2019-01-14 09:37:05 -08001607 int eob = p->eobs[block];
Jim Bankoski855ac462018-06-07 09:05:00 -07001608
Jim Bankoski102f36b2019-01-14 09:37:05 -08001609 if (eob > 1) av1_txb_init_levels(qcoeff, width, height, levels);
Angie Chiange4ea7482018-03-15 11:36:41 -07001610
1611 // TODO(angirbird): check iqmatrix
1612
1613 const int non_skip_cost = txb_costs->txb_skip_cost[txb_ctx->txb_skip_ctx][0];
1614 const int skip_cost = txb_costs->txb_skip_cost[txb_ctx->txb_skip_ctx][1];
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001615 const int eob_cost = get_eob_cost(eob, txb_eob_costs, txb_costs, tx_class);
Angie Chiange4ea7482018-03-15 11:36:41 -07001616 int accu_rate = eob_cost;
1617 int64_t accu_dist = 0;
1618 int si = eob - 1;
1619 const int ci = scan[si];
1620 const tran_low_t qc = qcoeff[ci];
1621 const tran_low_t abs_qc = abs(qc);
Angie Chiang40b07312018-03-30 10:42:55 -07001622 const int sign = qc < 0;
Angie Chiange4ea7482018-03-15 11:36:41 -07001623 const int max_nz_num = 2;
1624 int nz_num = 1;
1625 int nz_ci[3] = { ci, 0, 0 };
1626 if (abs_qc >= 2) {
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001627 update_coeff_general(&accu_rate, &accu_dist, si, eob, tx_size, tx_class,
1628 bwl, height, rdmult, shift, txb_ctx->dc_sign_ctx,
1629 dequant, scan, txb_costs, tcoeff, qcoeff, dqcoeff,
1630 levels);
Angie Chiange4ea7482018-03-15 11:36:41 -07001631 --si;
1632 } else {
1633 assert(abs_qc == 1);
wenyao.liu0be59012018-12-24 10:27:31 +08001634 const int coeff_ctx = get_lower_levels_ctx_eob(bwl, height, si);
Jim Bankoski102f36b2019-01-14 09:37:05 -08001635 accu_rate +=
1636 get_coeff_cost_eob(ci, abs_qc, sign, coeff_ctx, txb_ctx->dc_sign_ctx,
1637 txb_costs, bwl, tx_class);
Angie Chiange4ea7482018-03-15 11:36:41 -07001638 const tran_low_t tqc = tcoeff[ci];
1639 const tran_low_t dqc = dqcoeff[ci];
1640 const int64_t dist = get_coeff_dist(tqc, dqc, shift);
1641 const int64_t dist0 = get_coeff_dist(tqc, 0, shift);
1642 accu_dist += dist - dist0;
1643 --si;
1644 }
1645
Katsuhisa Yuasa9f639962018-04-08 18:00:54 +09001646#define UPDATE_COEFF_EOB_CASE(tx_class_literal) \
1647 case tx_class_literal: \
1648 for (; si >= 0 && nz_num <= max_nz_num; --si) { \
1649 update_coeff_eob(&accu_rate, &accu_dist, &eob, &nz_num, nz_ci, si, \
1650 tx_size, tx_class_literal, bwl, height, \
1651 txb_ctx->dc_sign_ctx, rdmult, shift, dequant, scan, \
1652 txb_eob_costs, txb_costs, tcoeff, qcoeff, dqcoeff, \
Jim Bankoski855ac462018-06-07 09:05:00 -07001653 levels, sharpness); \
Katsuhisa Yuasa9f639962018-04-08 18:00:54 +09001654 } \
1655 break;
1656 switch (tx_class) {
1657 UPDATE_COEFF_EOB_CASE(TX_CLASS_2D);
1658 UPDATE_COEFF_EOB_CASE(TX_CLASS_HORIZ);
1659 UPDATE_COEFF_EOB_CASE(TX_CLASS_VERT);
1660#undef UPDATE_COEFF_EOB_CASE
1661 default: assert(false);
Angie Chiange4ea7482018-03-15 11:36:41 -07001662 }
1663
Angie Chiangd0397e12018-03-27 19:03:20 -07001664 if (si == -1 && nz_num <= max_nz_num) {
1665 update_skip(&accu_rate, accu_dist, &eob, nz_num, nz_ci, rdmult, skip_cost,
Jim Bankoski855ac462018-06-07 09:05:00 -07001666 non_skip_cost, qcoeff, dqcoeff, sharpness);
Angie Chiangd0397e12018-03-27 19:03:20 -07001667 }
1668
Katsuhisa Yuasa9f639962018-04-08 18:00:54 +09001669#define UPDATE_COEFF_SIMPLE_CASE(tx_class_literal) \
1670 case tx_class_literal: \
1671 for (; si >= 1; --si) { \
1672 update_coeff_simple(&accu_rate, si, eob, tx_size, tx_class_literal, bwl, \
1673 rdmult, shift, dequant, scan, txb_costs, tcoeff, \
1674 qcoeff, dqcoeff, levels); \
1675 } \
1676 break;
1677 switch (tx_class) {
1678 UPDATE_COEFF_SIMPLE_CASE(TX_CLASS_2D);
1679 UPDATE_COEFF_SIMPLE_CASE(TX_CLASS_HORIZ);
1680 UPDATE_COEFF_SIMPLE_CASE(TX_CLASS_VERT);
1681#undef UPDATE_COEFF_SIMPLE_CASE
1682 default: assert(false);
Angie Chiange4ea7482018-03-15 11:36:41 -07001683 }
1684
1685 // DC position
1686 if (si == 0) {
Angie Chiangd0397e12018-03-27 19:03:20 -07001687 // no need to update accu_dist because it's not used after this point
1688 int64_t dummy_dist = 0;
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001689 update_coeff_general(&accu_rate, &dummy_dist, si, eob, tx_size, tx_class,
Angie Chiangd0397e12018-03-27 19:03:20 -07001690 bwl, height, rdmult, shift, txb_ctx->dc_sign_ctx,
1691 dequant, scan, txb_costs, tcoeff, qcoeff, dqcoeff,
1692 levels);
Angie Chiange4ea7482018-03-15 11:36:41 -07001693 }
1694
Urvang Joshi553096a2018-05-10 15:27:14 -07001695 const int tx_type_cost = get_tx_type_cost(cm, x, xd, plane, tx_size, tx_type);
Angie Chiange4ea7482018-03-15 11:36:41 -07001696 if (eob == 0)
1697 accu_rate += skip_cost;
1698 else
1699 accu_rate += non_skip_cost + tx_type_cost;
1700
1701 p->eobs[block] = eob;
1702 p->txb_entropy_ctx[block] =
1703 av1_get_txb_entropy_context(qcoeff, scan_order, p->eobs[block]);
1704
1705 *rate_cost = accu_rate;
1706 return eob;
1707}
1708
Angie Chiang40b07312018-03-30 10:42:55 -07001709// This function is deprecated, but we keep it here because hash trellis
Angie Chiange4ea7482018-03-15 11:36:41 -07001710// is not integrated with av1_optimize_txb_new yet
Yaowu Xuefcf1e92018-01-12 17:05:46 -08001711int av1_optimize_txb(const struct AV1_COMP *cpi, MACROBLOCK *x, int plane,
Jingning Han7eab9ff2017-07-06 10:12:54 -07001712 int blk_row, int blk_col, int block, TX_SIZE tx_size,
Cheng Chen82775f62018-01-18 12:09:54 -08001713 TXB_CTX *txb_ctx, int fast_mode, int *rate_cost) {
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001714 const AV1_COMMON *cm = &cpi->common;
Angie Chiang07c57f32017-05-30 18:18:33 -07001715 MACROBLOCKD *const xd = &x->e_mbd;
1716 const PLANE_TYPE plane_type = get_plane_type(plane);
Debargha Mukherjeeb3eda2f2017-11-28 16:00:20 -08001717 const TX_SIZE txs_ctx = get_txsize_entropy_ctx(tx_size);
Sarah Parker7c71cc02018-01-29 12:27:58 -08001718 const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, blk_row, blk_col,
1719 tx_size, cm->reduced_tx_set_used);
Yue Chen53b53f02018-03-29 14:31:23 -07001720 const MB_MODE_INFO *mbmi = xd->mi[0];
Angie Chiang07c57f32017-05-30 18:18:33 -07001721 const struct macroblock_plane *p = &x->plane[plane];
1722 struct macroblockd_plane *pd = &xd->plane[plane];
1723 const int eob = p->eobs[block];
1724 tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1725 tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1726 const tran_low_t *tcoeff = BLOCK_OFFSET(p->coeff, block);
Monty Montgomery125c0fc2017-10-26 00:44:35 -04001727 const int16_t *dequant = p->dequant_QTX;
Urvang Joshi80893152017-10-27 11:51:14 -07001728 const int seg_eob = av1_get_max_eob(tx_size);
Angie Chianga9ba58e2017-12-01 19:22:43 -08001729 const int bwl = get_txb_bwl(tx_size);
1730 const int width = get_txb_wide(tx_size);
1731 const int height = get_txb_high(tx_size);
Angie Chiang07c57f32017-05-30 18:18:33 -07001732 const int is_inter = is_inter_block(mbmi);
Yaowu Xuf1e12932018-02-26 15:50:09 -08001733 const SCAN_ORDER *const scan_order = get_scan(tx_size, tx_type);
Angie Chiange15d2e32018-03-02 15:49:06 -08001734 const LV_MAP_COEFF_COST *txb_costs = &x->coeff_costs[txs_ctx][plane_type];
Dake He0db7d0e2017-12-21 15:23:20 -08001735 const int eob_multi_size = txsize_log2_minus4[tx_size];
1736 const LV_MAP_EOB_COST txb_eob_costs =
1737 x->eob_costs[eob_multi_size][plane_type];
Angie Chiang07c57f32017-05-30 18:18:33 -07001738
1739 const int shift = av1_get_tx_scale(tx_size);
1740 const int64_t rdmult =
Jingning Hanb433f4c2017-11-17 15:43:59 -08001741 ((x->rdmult * plane_rd_mult[is_inter][plane_type] << (2 * (xd->bd - 8))) +
1742 2) >>
1743 2;
Linfeng Zhang679d81e2017-10-31 15:27:42 -07001744 uint8_t levels_buf[TX_PAD_2D];
1745 uint8_t *const levels = set_levels(levels_buf, width);
Angie Chiangb3167a62018-01-30 19:37:57 -08001746 const TX_SIZE qm_tx_size = av1_get_adjusted_tx_size(tx_size);
1747 const qm_val_t *iqmatrix =
1748 IS_2D_TRANSFORM(tx_type)
1749 ? pd->seg_iqmatrix[mbmi->segment_id][qm_tx_size]
1750 : cm->giqmatrix[NUM_QM_LEVELS - 1][0][qm_tx_size];
Linfeng Zhang1122d7d2017-10-31 15:30:28 -07001751 assert(width == (1 << bwl));
Urvang Joshi553096a2018-05-10 15:27:14 -07001752 const int tx_type_cost = get_tx_type_cost(cm, x, xd, plane, tx_size, tx_type);
Linfeng Zhang1015a342017-10-24 16:20:41 -07001753 TxbInfo txb_info = {
David Turnerb757ce02018-11-12 15:01:28 +00001754 qcoeff, levels, dqcoeff, tcoeff, dequant, shift, tx_size,
1755 txs_ctx, tx_type, bwl, width, height, eob, seg_eob,
1756 scan_order, txb_ctx, rdmult, iqmatrix, tx_type_cost,
Linfeng Zhang1015a342017-10-24 16:20:41 -07001757 };
1758
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001759 // Hash based trellis (hbt) speed feature: avoid expensive optimize_txb calls
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001760 // by storing the coefficient deltas in a hash table.
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001761 // Currently disabled in speedfeatures.c
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001762 if (eob <= HBT_EOB && eob > 0 && cpi->sf.use_hash_based_trellis) {
Angie Chiange15d2e32018-03-02 15:49:06 -08001763 return hbt_create_hashes(&txb_info, txb_costs, &txb_eob_costs, p, block,
Michelle Findlay-Olynykdea531d2017-12-13 14:10:56 -08001764 fast_mode, rate_cost);
Michelle Findlay-Olynykfbab0622017-12-13 14:10:56 -08001765 }
1766
Linfeng Zhang1122d7d2017-10-31 15:30:28 -07001767 av1_txb_init_levels(qcoeff, width, height, levels);
Urvang Joshi70006e42017-06-14 16:08:55 -07001768
Angie Chiang45385b82018-03-02 15:25:58 -08001769 const int update =
Angie Chiange15d2e32018-03-02 15:49:06 -08001770 optimize_txb(&txb_info, txb_costs, &txb_eob_costs, rate_cost);
Angie Chiang07c57f32017-05-30 18:18:33 -07001771
Jingning Hand7e99112017-12-13 09:47:45 -08001772 if (update) {
1773 p->eobs[block] = txb_info.eob;
1774 p->txb_entropy_ctx[block] =
1775 av1_get_txb_entropy_context(qcoeff, scan_order, txb_info.eob);
1776 }
Angie Chiang07c57f32017-05-30 18:18:33 -07001777 return txb_info.eob;
1778}
Jingning Hand7e99112017-12-13 09:47:45 -08001779
Angie Chiang74e23072017-03-24 14:54:23 -07001780int av1_get_txb_entropy_context(const tran_low_t *qcoeff,
1781 const SCAN_ORDER *scan_order, int eob) {
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -08001782 const int16_t *const scan = scan_order->scan;
Angie Chiang74e23072017-03-24 14:54:23 -07001783 int cul_level = 0;
1784 int c;
Jingning Han339cf932017-09-18 10:17:02 -07001785
1786 if (eob == 0) return 0;
Angie Chiang74e23072017-03-24 14:54:23 -07001787 for (c = 0; c < eob; ++c) {
1788 cul_level += abs(qcoeff[scan[c]]);
Jingning Hane3137652018-04-02 11:53:47 -07001789 if (cul_level > COEFF_CONTEXT_MASK) break;
Angie Chiang74e23072017-03-24 14:54:23 -07001790 }
1791
1792 cul_level = AOMMIN(COEFF_CONTEXT_MASK, cul_level);
1793 set_dc_sign(&cul_level, qcoeff[0]);
1794
1795 return cul_level;
1796}
1797
Jingning Han4fe5f672017-05-19 15:46:07 -07001798void av1_update_txb_context_b(int plane, int block, int blk_row, int blk_col,
1799 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
1800 void *arg) {
Jingning Han6171ae72017-05-18 20:15:06 -07001801 struct tokenize_b_args *const args = arg;
Angie Chiang36d616b2017-03-22 13:58:36 -07001802 const AV1_COMP *cpi = args->cpi;
1803 const AV1_COMMON *cm = &cpi->common;
Angie Chiang0397eda2017-03-15 16:57:14 -07001804 ThreadData *const td = args->td;
1805 MACROBLOCK *const x = &td->mb;
1806 MACROBLOCKD *const xd = &x->e_mbd;
1807 struct macroblock_plane *p = &x->plane[plane];
1808 struct macroblockd_plane *pd = &xd->plane[plane];
Angie Chiang36d616b2017-03-22 13:58:36 -07001809 const uint16_t eob = p->eobs[block];
1810 const tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1811 const PLANE_TYPE plane_type = pd->plane_type;
Sarah Parker7c71cc02018-01-29 12:27:58 -08001812 const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, blk_row, blk_col,
1813 tx_size, cm->reduced_tx_set_used);
Yaowu Xuf1e12932018-02-26 15:50:09 -08001814 const SCAN_ORDER *const scan_order = get_scan(tx_size, tx_type);
Hui Sue674dec2018-04-02 13:02:08 -07001815 const int cul_level = av1_get_txb_entropy_context(qcoeff, scan_order, eob);
1816 av1_set_contexts(xd, pd, plane, plane_bsize, tx_size, cul_level, blk_col,
1817 blk_row);
Angie Chiang0397eda2017-03-15 16:57:14 -07001818}
1819
Urvang Joshi553096a2018-05-10 15:27:14 -07001820static void update_tx_type_count(const AV1_COMMON *cm, MACROBLOCKD *xd,
1821 int blk_row, int blk_col, int plane,
1822 TX_SIZE tx_size, FRAME_COUNTS *counts,
1823 uint8_t allow_update_cdf) {
1824 MB_MODE_INFO *mbmi = xd->mi[0];
1825 int is_inter = is_inter_block(mbmi);
1826 FRAME_CONTEXT *fc = xd->tile_ctx;
1827#if !CONFIG_ENTROPY_STATS
1828 (void)counts;
1829#endif // !CONFIG_ENTROPY_STATS
1830
1831 // Only y plane's tx_type is updated
1832 if (plane > 0) return;
1833 TX_TYPE tx_type = av1_get_tx_type(PLANE_TYPE_Y, xd, blk_row, blk_col, tx_size,
1834 cm->reduced_tx_set_used);
1835 if (get_ext_tx_types(tx_size, is_inter, cm->reduced_tx_set_used) > 1 &&
1836 cm->base_qindex > 0 && !mbmi->skip &&
1837 !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
1838 const int eset = get_ext_tx_set(tx_size, is_inter, cm->reduced_tx_set_used);
1839 if (eset > 0) {
1840 const TxSetType tx_set_type =
1841 av1_get_ext_tx_set_type(tx_size, is_inter, cm->reduced_tx_set_used);
1842 if (is_inter) {
1843 if (allow_update_cdf) {
1844 update_cdf(fc->inter_ext_tx_cdf[eset][txsize_sqr_map[tx_size]],
1845 av1_ext_tx_ind[tx_set_type][tx_type],
1846 av1_num_ext_tx_set[tx_set_type]);
1847 }
1848#if CONFIG_ENTROPY_STATS
1849 ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]]
1850 [av1_ext_tx_ind[tx_set_type][tx_type]];
1851#endif // CONFIG_ENTROPY_STATS
1852 } else {
1853 PREDICTION_MODE intra_dir;
1854 if (mbmi->filter_intra_mode_info.use_filter_intra)
1855 intra_dir = fimode_to_intradir[mbmi->filter_intra_mode_info
1856 .filter_intra_mode];
1857 else
1858 intra_dir = mbmi->mode;
1859#if CONFIG_ENTROPY_STATS
1860 ++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][intra_dir]
1861 [av1_ext_tx_ind[tx_set_type][tx_type]];
1862#endif // CONFIG_ENTROPY_STATS
1863 if (allow_update_cdf) {
1864 update_cdf(
1865 fc->intra_ext_tx_cdf[eset][txsize_sqr_map[tx_size]][intra_dir],
1866 av1_ext_tx_ind[tx_set_type][tx_type],
1867 av1_num_ext_tx_set[tx_set_type]);
1868 }
1869 }
1870 }
1871 }
1872}
1873
Jingning Han4fe5f672017-05-19 15:46:07 -07001874void av1_update_and_record_txb_context(int plane, int block, int blk_row,
1875 int blk_col, BLOCK_SIZE plane_bsize,
1876 TX_SIZE tx_size, void *arg) {
Jingning Han6171ae72017-05-18 20:15:06 -07001877 struct tokenize_b_args *const args = arg;
Angie Chiang0397eda2017-03-15 16:57:14 -07001878 const AV1_COMP *cpi = args->cpi;
1879 const AV1_COMMON *cm = &cpi->common;
1880 ThreadData *const td = args->td;
1881 MACROBLOCK *const x = &td->mb;
1882 MACROBLOCKD *const xd = &x->e_mbd;
1883 struct macroblock_plane *p = &x->plane[plane];
1884 struct macroblockd_plane *pd = &xd->plane[plane];
Yue Chen53b53f02018-03-29 14:31:23 -07001885 MB_MODE_INFO *mbmi = xd->mi[0];
Hui Su8763cd32018-04-02 12:29:05 -07001886 const int eob = p->eobs[block];
Angie Chiang85901562017-03-17 12:03:27 -07001887 TXB_CTX txb_ctx;
1888 get_txb_ctx(plane_bsize, tx_size, plane, pd->above_context + blk_col,
1889 pd->left_context + blk_row, &txb_ctx);
Angie Chianga9ba58e2017-12-01 19:22:43 -08001890 const int bwl = get_txb_bwl(tx_size);
1891 const int width = get_txb_wide(tx_size);
1892 const int height = get_txb_high(tx_size);
Yunqing Wang0e141b52017-11-02 15:08:58 -07001893 const uint8_t allow_update_cdf = args->allow_update_cdf;
Hui Su8763cd32018-04-02 12:29:05 -07001894 const TX_SIZE txsize_ctx = get_txsize_entropy_ctx(tx_size);
Jingning Han8f661602017-08-19 08:16:50 -07001895 FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
Yue Chen198738d2018-03-08 17:26:01 -08001896#if CONFIG_ENTROPY_STATS
1897 int cdf_idx = cm->coef_cdf_category;
1898#endif // CONFIG_ENTROPY_STATS
Jingning Han48be0e12017-06-13 12:12:01 -07001899
Hui Su1e959892018-01-22 12:14:43 -08001900#if CONFIG_ENTROPY_STATS
Yue Chen198738d2018-03-08 17:26:01 -08001901 ++td->counts->txb_skip[cdf_idx][txsize_ctx][txb_ctx.txb_skip_ctx][eob == 0];
Hui Su1e959892018-01-22 12:14:43 -08001902#endif // CONFIG_ENTROPY_STATS
Hui Su41d61522018-01-23 10:47:55 -08001903 if (allow_update_cdf) {
1904 update_cdf(ec_ctx->txb_skip_cdf[txsize_ctx][txb_ctx.txb_skip_ctx], eob == 0,
Yunqing Wang0e141b52017-11-02 15:08:58 -07001905 2);
Hui Su41d61522018-01-23 10:47:55 -08001906 }
Angie Chiang0397eda2017-03-15 16:57:14 -07001907
Hui Su8763cd32018-04-02 12:29:05 -07001908 x->mbmi_ext->txb_skip_ctx[plane][block] = txb_ctx.txb_skip_ctx;
Angie Chiang0397eda2017-03-15 16:57:14 -07001909 x->mbmi_ext->eobs[plane][block] = eob;
1910
1911 if (eob == 0) {
Hui Sue674dec2018-04-02 13:02:08 -07001912 av1_set_contexts(xd, pd, plane, plane_bsize, tx_size, 0, blk_col, blk_row);
Angie Chiang0397eda2017-03-15 16:57:14 -07001913 return;
1914 }
1915
Hui Su8763cd32018-04-02 12:29:05 -07001916 tran_low_t *tcoeff = BLOCK_OFFSET(x->mbmi_ext->tcoeff[plane], block);
1917 const int segment_id = mbmi->segment_id;
1918 const int seg_eob = av1_get_tx_eob(&cpi->common.seg, segment_id, tx_size);
1919 const tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1920 memcpy(tcoeff, qcoeff, sizeof(*tcoeff) * seg_eob);
1921
1922 uint8_t levels_buf[TX_PAD_2D];
1923 uint8_t *const levels = set_levels(levels_buf, width);
Linfeng Zhang1122d7d2017-10-31 15:30:28 -07001924 av1_txb_init_levels(tcoeff, width, height, levels);
Urvang Joshi553096a2018-05-10 15:27:14 -07001925 update_tx_type_count(cm, xd, blk_row, blk_col, plane, tx_size, td->counts,
1926 allow_update_cdf);
Hui Su8763cd32018-04-02 12:29:05 -07001927
1928 const PLANE_TYPE plane_type = pd->plane_type;
1929 const TX_TYPE tx_type = av1_get_tx_type(plane_type, xd, blk_row, blk_col,
1930 tx_size, cm->reduced_tx_set_used);
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001931 const TX_CLASS tx_class = tx_type_to_class[tx_type];
Hui Su8763cd32018-04-02 12:29:05 -07001932 const SCAN_ORDER *const scan_order = get_scan(tx_size, tx_type);
1933 const int16_t *const scan = scan_order->scan;
Yue Chen198738d2018-03-08 17:26:01 -08001934#if CONFIG_ENTROPY_STATS
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001935 av1_update_eob_context(cdf_idx, eob, tx_size, tx_class, plane_type, ec_ctx,
Yaowu Xu49abec82018-03-13 16:09:01 -07001936 td->counts, allow_update_cdf);
Yue Chen198738d2018-03-08 17:26:01 -08001937#else
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001938 av1_update_eob_context(eob, tx_size, tx_class, plane_type, ec_ctx,
Yue Chen198738d2018-03-08 17:26:01 -08001939 allow_update_cdf);
1940#endif
Hui Su8763cd32018-04-02 12:29:05 -07001941
1942 DECLARE_ALIGNED(16, int8_t, coeff_contexts[MAX_TX_SQUARE]);
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001943 av1_get_nz_map_contexts(levels, scan, eob, tx_size, tx_class, coeff_contexts);
Linfeng Zhangd67c13f2017-12-11 11:49:12 -08001944
Hui Su8763cd32018-04-02 12:29:05 -07001945 for (int c = eob - 1; c >= 0; --c) {
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -08001946 const int pos = scan[c];
Linfeng Zhangd67c13f2017-12-11 11:49:12 -08001947 const int coeff_ctx = coeff_contexts[pos];
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -08001948 const tran_low_t v = qcoeff[pos];
Angie Chiang2cc5eb32018-02-14 18:37:22 -08001949 const tran_low_t level = abs(v);
Dake He03a32922017-10-31 08:06:45 -07001950
Dake He4d447692017-12-15 09:10:06 -08001951 if (allow_update_cdf) {
1952 if (c == eob - 1) {
1953 assert(coeff_ctx < 4);
1954 update_cdf(
1955 ec_ctx->coeff_base_eob_cdf[txsize_ctx][plane_type][coeff_ctx],
Angie Chiang2cc5eb32018-02-14 18:37:22 -08001956 AOMMIN(level, 3) - 1, 3);
Dake He4d447692017-12-15 09:10:06 -08001957 } else {
1958 update_cdf(ec_ctx->coeff_base_cdf[txsize_ctx][plane_type][coeff_ctx],
Angie Chiang2cc5eb32018-02-14 18:37:22 -08001959 AOMMIN(level, 3), 4);
Dake He4d447692017-12-15 09:10:06 -08001960 }
Dake He3fe369c2017-11-16 17:56:44 -08001961 }
Dake He59881772017-11-24 07:00:02 -08001962 {
Dake He4d447692017-12-15 09:10:06 -08001963 if (c == eob - 1) {
1964 assert(coeff_ctx < 4);
Yue Chen198738d2018-03-08 17:26:01 -08001965#if CONFIG_ENTROPY_STATS
1966 ++td->counts->coeff_base_eob_multi[cdf_idx][txsize_ctx][plane_type]
1967 [coeff_ctx][AOMMIN(level, 3) - 1];
Dake He4d447692017-12-15 09:10:06 -08001968 } else {
Yue Chen198738d2018-03-08 17:26:01 -08001969 ++td->counts->coeff_base_multi[cdf_idx][txsize_ctx][plane_type]
1970 [coeff_ctx][AOMMIN(level, 3)];
1971#endif
Angie Chiang2cc5eb32018-02-14 18:37:22 -08001972 }
1973 }
1974 if (level > NUM_BASE_LEVELS) {
1975 const int base_range = level - 1 - NUM_BASE_LEVELS;
Katsuhisa Yuasa55c95f82018-04-03 00:51:22 +09001976 const int br_ctx = get_br_ctx(levels, pos, bwl, tx_class);
Angie Chiang2cc5eb32018-02-14 18:37:22 -08001977 for (int idx = 0; idx < COEFF_BASE_RANGE; idx += BR_CDF_SIZE - 1) {
1978 const int k = AOMMIN(base_range - idx, BR_CDF_SIZE - 1);
1979 if (allow_update_cdf) {
Angie Chiang2cfb7142018-02-16 11:24:52 -08001980 update_cdf(ec_ctx->coeff_br_cdf[AOMMIN(txsize_ctx, TX_32X32)]
1981 [plane_type][br_ctx],
1982 k, BR_CDF_SIZE);
Angie Chiang2cc5eb32018-02-14 18:37:22 -08001983 }
1984 for (int lps = 0; lps < BR_CDF_SIZE - 1; lps++) {
1985#if CONFIG_ENTROPY_STATS
Angie Chiang2cc5eb32018-02-14 18:37:22 -08001986 ++td->counts->coeff_lps[AOMMIN(txsize_ctx, TX_32X32)][plane_type][lps]
1987 [br_ctx][lps == k];
Angie Chiang2cc5eb32018-02-14 18:37:22 -08001988#endif // CONFIG_ENTROPY_STATS
1989 if (lps == k) break;
1990 }
Yue Chen198738d2018-03-08 17:26:01 -08001991#if CONFIG_ENTROPY_STATS
1992 ++td->counts->coeff_lps_multi[cdf_idx][AOMMIN(txsize_ctx, TX_32X32)]
1993 [plane_type][br_ctx][k];
1994#endif
Angie Chiang2cc5eb32018-02-14 18:37:22 -08001995 if (k < BR_CDF_SIZE - 1) break;
Dake He59881772017-11-24 07:00:02 -08001996 }
1997 }
Dake Hea47cd6c2017-10-13 18:09:58 -07001998 }
Dake Hea47cd6c2017-10-13 18:09:58 -07001999
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -08002000 // Update the context needed to code the DC sign (if applicable)
Linfeng Zhangdb41d1e2017-12-05 11:06:20 -08002001 if (tcoeff[0] != 0) {
Hui Su8763cd32018-04-02 12:29:05 -07002002 const int dc_sign = (tcoeff[0] < 0) ? 1 : 0;
2003 const int dc_sign_ctx = txb_ctx.dc_sign_ctx;
Hui Su1e959892018-01-22 12:14:43 -08002004#if CONFIG_ENTROPY_STATS
Hui Su8763cd32018-04-02 12:29:05 -07002005 ++td->counts->dc_sign[plane_type][dc_sign_ctx][dc_sign];
Hui Su1e959892018-01-22 12:14:43 -08002006#endif // CONFIG_ENTROPY_STATS
Yunqing Wang0e141b52017-11-02 15:08:58 -07002007 if (allow_update_cdf)
Hui Su8763cd32018-04-02 12:29:05 -07002008 update_cdf(ec_ctx->dc_sign_cdf[plane_type][dc_sign_ctx], dc_sign, 2);
Dake He43edb762017-10-26 10:29:46 -07002009 x->mbmi_ext->dc_sign_ctx[plane][block] = dc_sign_ctx;
2010 }
2011
Hui Su8763cd32018-04-02 12:29:05 -07002012 const int cul_level = av1_get_txb_entropy_context(tcoeff, scan_order, eob);
Hui Sue674dec2018-04-02 13:02:08 -07002013 av1_set_contexts(xd, pd, plane, plane_bsize, tx_size, cul_level, blk_col,
2014 blk_row);
Angie Chiang0397eda2017-03-15 16:57:14 -07002015}
2016
2017void av1_update_txb_context(const AV1_COMP *cpi, ThreadData *td,
2018 RUN_TYPE dry_run, BLOCK_SIZE bsize, int *rate,
Yunqing Wang0e141b52017-11-02 15:08:58 -07002019 int mi_row, int mi_col, uint8_t allow_update_cdf) {
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +00002020 const AV1_COMMON *const cm = &cpi->common;
2021 const int num_planes = av1_num_planes(cm);
Angie Chiang0397eda2017-03-15 16:57:14 -07002022 MACROBLOCK *const x = &td->mb;
2023 MACROBLOCKD *const xd = &x->e_mbd;
Yue Chen53b53f02018-03-29 14:31:23 -07002024 MB_MODE_INFO *const mbmi = xd->mi[0];
Yunqing Wang0e141b52017-11-02 15:08:58 -07002025 struct tokenize_b_args arg = { cpi, td, NULL, 0, allow_update_cdf };
Angie Chiang0397eda2017-03-15 16:57:14 -07002026 (void)rate;
2027 (void)mi_row;
2028 (void)mi_col;
2029 if (mbmi->skip) {
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +00002030 av1_reset_skip_context(xd, mi_row, mi_col, bsize, num_planes);
Angie Chiang0397eda2017-03-15 16:57:14 -07002031 return;
2032 }
2033
2034 if (!dry_run) {
Jingning Han94652b82017-04-04 09:45:02 -07002035 av1_foreach_transformed_block(xd, bsize, mi_row, mi_col,
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +00002036 av1_update_and_record_txb_context, &arg,
2037 num_planes);
Angie Chiangc8af6112017-03-16 16:11:22 -07002038 } else if (dry_run == DRY_RUN_NORMAL) {
Jingning Han4fe5f672017-05-19 15:46:07 -07002039 av1_foreach_transformed_block(xd, bsize, mi_row, mi_col,
Imdad Sardharwallaaf8e2642018-01-19 11:46:34 +00002040 av1_update_txb_context_b, &arg, num_planes);
Angie Chiangc8af6112017-03-16 16:11:22 -07002041 } else {
2042 printf("DRY_RUN_COSTCOEFFS is not supported yet\n");
2043 assert(0);
Angie Chiang0397eda2017-03-15 16:57:14 -07002044 }
2045}