blob: 1a872039a725a917dea122f0acc3d100d3794f87 [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * 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.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
Yaowu Xuf883b422016-08-30 14:01:10 -070012#include "./av1_rtcd.h"
13#include "./aom_config.h"
14#include "./aom_dsp_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070015
Nathan E. Egge6675be02016-12-21 13:02:43 -050016#include "aom_dsp/bitwriter.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017#include "aom_dsp/quantize.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070018#include "aom_mem/aom_mem.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070019#include "aom_ports/mem.h"
20
21#include "av1/common/idct.h"
22#include "av1/common/reconinter.h"
23#include "av1/common/reconintra.h"
24#include "av1/common/scan.h"
25
Tom Finegan17ce8b12017-02-08 12:46:31 -080026#include "av1/encoder/av1_quantize.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070027#include "av1/encoder/encodemb.h"
28#include "av1/encoder/hybrid_fwd_txfm.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070029#include "av1/encoder/rd.h"
30#include "av1/encoder/tokenize.h"
31
Yushin Cho77bba8d2016-11-04 16:36:56 -070032#if CONFIG_PVQ
33#include "av1/encoder/encint.h"
34#include "av1/common/partition.h"
35#include "av1/encoder/pvq_encoder.h"
36#endif
37
Jingning Hane325abd2016-12-01 09:35:10 -080038// Check if one needs to use c version subtraction.
39static int check_subtract_block_size(int w, int h) { return w < 4 || h < 4; }
40
Yaowu Xuf883b422016-08-30 14:01:10 -070041void av1_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070042 struct macroblock_plane *const p = &x->plane[plane];
43 const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane];
44 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Hanae5cfde2016-11-30 12:01:44 -080045 const int bw = block_size_wide[plane_bsize];
46 const int bh = block_size_high[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -070047
Jingning Hane325abd2016-12-01 09:35:10 -080048 if (check_subtract_block_size(bw, bh)) {
49#if CONFIG_AOM_HIGHBITDEPTH
50 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
51 aom_highbd_subtract_block_c(bh, bw, p->src_diff, bw, p->src.buf,
52 p->src.stride, pd->dst.buf, pd->dst.stride,
53 x->e_mbd.bd);
54 return;
55 }
56#endif // CONFIG_AOM_HIGHBITDEPTH
57 aom_subtract_block_c(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride,
58 pd->dst.buf, pd->dst.stride);
59
60 return;
61 }
62
Yaowu Xuf883b422016-08-30 14:01:10 -070063#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070064 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -070065 aom_highbd_subtract_block(bh, bw, p->src_diff, bw, p->src.buf,
Yaowu Xuc27fc142016-08-22 16:08:15 -070066 p->src.stride, pd->dst.buf, pd->dst.stride,
67 x->e_mbd.bd);
68 return;
69 }
Yaowu Xuf883b422016-08-30 14:01:10 -070070#endif // CONFIG_AOM_HIGHBITDEPTH
71 aom_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -070072 pd->dst.buf, pd->dst.stride);
73}
74
Yaowu Xuf883b422016-08-30 14:01:10 -070075typedef struct av1_token_state {
Yaowu Xuc27fc142016-08-22 16:08:15 -070076 int rate;
77 int64_t error;
78 int next;
79 int16_t token;
80 tran_low_t qc;
81 tran_low_t dqc;
Yaowu Xuf883b422016-08-30 14:01:10 -070082} av1_token_state;
Yaowu Xuc27fc142016-08-22 16:08:15 -070083
84// These numbers are empirically obtained.
85static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] = {
86 { 10, 6 }, { 8, 5 },
87};
88
89#define UPDATE_RD_COST() \
90 { \
91 rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0); \
92 rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1); \
93 }
94
Angie Chiangff6d8902016-10-21 11:02:09 -070095int av1_optimize_b(const AV1_COMMON *cm, MACROBLOCK *mb, int plane, int block,
96 TX_SIZE tx_size, int ctx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070097 MACROBLOCKD *const xd = &mb->e_mbd;
98 struct macroblock_plane *const p = &mb->plane[plane];
99 struct macroblockd_plane *const pd = &xd->plane[plane];
100 const int ref = is_inter_block(&xd->mi[0]->mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -0700101 av1_token_state tokens[MAX_TX_SQUARE + 1][2];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700102 unsigned best_index[MAX_TX_SQUARE + 1][2];
103 uint8_t token_cache[MAX_TX_SQUARE];
Urvang Joshifeb925f2016-12-05 10:37:29 -0800104 const tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700105 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
106 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
107 const int eob = p->eobs[block];
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700108 const PLANE_TYPE plane_type = pd->plane_type;
Jingning Hande953b92016-10-25 12:35:43 -0700109 const int default_eob = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700110 const int16_t *const dequant_ptr = pd->dequant;
111 const uint8_t *const band_translate = get_band_translate(tx_size);
Urvang Joshifeb925f2016-12-05 10:37:29 -0800112 const int block_raster_idx = av1_block_index_to_raster_order(tx_size, block);
113 TX_TYPE tx_type = get_tx_type(plane_type, xd, block_raster_idx, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -0700114 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -0700115 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Urvang Joshi03f6fdc2016-10-14 15:53:39 -0700116 const int16_t *const scan = scan_order->scan;
117 const int16_t *const nb = scan_order->neighbors;
Thomas Daviese0f8c552016-11-15 17:28:03 +0000118 int dqv;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800119 const int shift = get_tx_scale(tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700120#if CONFIG_AOM_QM
121 int seg_id = xd->mi[0]->mbmi.segment_id;
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700122 const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!ref][tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700123#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700124#if CONFIG_NEW_QUANT
David Barkerd7d78c82016-10-24 10:55:35 +0100125 int dq = get_dq_profile_from_ctx(mb->qindex, ctx, ref, plane_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700126 const dequant_val_type_nuq *dequant_val = pd->dequant_val_nuq[dq];
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800127#elif !CONFIG_AOM_QM
Yaowu Xuc27fc142016-08-22 16:08:15 -0700128 const int dq_step[2] = { dequant_ptr[0] >> shift, dequant_ptr[1] >> shift };
129#endif // CONFIG_NEW_QUANT
130 int next = eob, sz = 0;
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700131 const int64_t rdmult = (mb->rdmult * plane_rd_mult[ref][plane_type]) >> 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700132 const int64_t rddiv = mb->rddiv;
133 int64_t rd_cost0, rd_cost1;
134 int rate0, rate1;
135 int64_t error0, error1;
136 int16_t t0, t1;
137 int best, band = (eob < default_eob) ? band_translate[eob]
138 : band_translate[eob - 1];
139 int pt, i, final_eob;
Yaowu Xuf883b422016-08-30 14:01:10 -0700140#if CONFIG_AOM_HIGHBITDEPTH
141 const int *cat6_high_cost = av1_get_high_cost_table(xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700142#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700143 const int *cat6_high_cost = av1_get_high_cost_table(8);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700144#endif
145 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700146 mb->token_costs[txsize_sqr_map[tx_size]][plane_type][ref];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700147 const uint16_t *band_counts = &band_count_table[tx_size][band];
148 uint16_t band_left = eob - band_cum_count_table[tx_size][band] + 1;
149 int shortcut = 0;
150 int next_shortcut = 0;
151
David Barkerd7d78c82016-10-24 10:55:35 +0100152 assert((mb->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700153
Yaowu Xuc27fc142016-08-22 16:08:15 -0700154 token_costs += band;
155
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700156 assert((!plane_type && !plane) || (plane_type && plane));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700157 assert(eob <= default_eob);
158
159 /* Now set up a Viterbi trellis to evaluate alternative roundings. */
160 /* Initialize the sentinel node of the trellis. */
161 tokens[eob][0].rate = 0;
162 tokens[eob][0].error = 0;
163 tokens[eob][0].next = default_eob;
164 tokens[eob][0].token = EOB_TOKEN;
165 tokens[eob][0].qc = 0;
166 tokens[eob][1] = tokens[eob][0];
167
168 for (i = 0; i < eob; i++) {
169 const int rc = scan[i];
Yaowu Xuf883b422016-08-30 14:01:10 -0700170 tokens[i][0].rate = av1_get_token_cost(qcoeff[rc], &t0, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700171 tokens[i][0].token = t0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700172 token_cache[rc] = av1_pt_energy_class[t0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700173 }
174
175 for (i = eob; i-- > 0;) {
176 int base_bits, dx;
177 int64_t d2;
178 const int rc = scan[i];
Thomas Daviese0f8c552016-11-15 17:28:03 +0000179 int x = qcoeff[rc];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700180#if CONFIG_AOM_QM
181 int iwt = iqmatrix[rc];
Thomas Daviese0f8c552016-11-15 17:28:03 +0000182 dqv = dequant_ptr[rc != 0];
183 dqv = ((iwt * (int)dqv) + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
184#else
185 dqv = dequant_ptr[rc != 0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700186#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700187 next_shortcut = shortcut;
188
189 /* Only add a trellis state for non-zero coefficients. */
190 if (UNLIKELY(x)) {
191 error0 = tokens[next][0].error;
192 error1 = tokens[next][1].error;
193 /* Evaluate the first possibility for this state. */
194 rate0 = tokens[next][0].rate;
195 rate1 = tokens[next][1].rate;
196
197 if (next_shortcut) {
198 /* Consider both possible successor states. */
199 if (next < default_eob) {
200 pt = get_coef_context(nb, token_cache, i + 1);
201 rate0 += (*token_costs)[0][pt][tokens[next][0].token];
202 rate1 += (*token_costs)[0][pt][tokens[next][1].token];
203 }
204 UPDATE_RD_COST();
205 /* And pick the best. */
206 best = rd_cost1 < rd_cost0;
207 } else {
208 if (next < default_eob) {
209 pt = get_coef_context(nb, token_cache, i + 1);
210 rate0 += (*token_costs)[0][pt][tokens[next][0].token];
211 }
212 best = 0;
213 }
214
215 dx = (dqcoeff[rc] - coeff[rc]) * (1 << shift);
Yaowu Xuf883b422016-08-30 14:01:10 -0700216#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700217 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
218 dx >>= xd->bd - 8;
219 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700220#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700221 d2 = (int64_t)dx * dx;
222 tokens[i][0].rate += (best ? rate1 : rate0);
223 tokens[i][0].error = d2 + (best ? error1 : error0);
224 tokens[i][0].next = next;
225 tokens[i][0].qc = x;
226 tokens[i][0].dqc = dqcoeff[rc];
227 best_index[i][0] = best;
228
229 /* Evaluate the second possibility for this state. */
230 rate0 = tokens[next][0].rate;
231 rate1 = tokens[next][1].rate;
232
233 // The threshold of 3 is empirically obtained.
234 if (UNLIKELY(abs(x) > 3)) {
235 shortcut = 0;
236 } else {
237#if CONFIG_NEW_QUANT
Thomas Daviese0f8c552016-11-15 17:28:03 +0000238 shortcut = ((av1_dequant_abscoeff_nuq(abs(x), dqv,
Yaowu Xuf883b422016-08-30 14:01:10 -0700239 dequant_val[band_translate[i]]) >
Yaowu Xuc27fc142016-08-22 16:08:15 -0700240 (abs(coeff[rc]) << shift)) &&
Thomas Daviese0f8c552016-11-15 17:28:03 +0000241 (av1_dequant_abscoeff_nuq(abs(x) - 1, dqv,
Yaowu Xuf883b422016-08-30 14:01:10 -0700242 dequant_val[band_translate[i]]) <
Yaowu Xuc27fc142016-08-22 16:08:15 -0700243 (abs(coeff[rc]) << shift)));
244#else // CONFIG_NEW_QUANT
245#if CONFIG_AOM_QM
246 if ((abs(x) * dequant_ptr[rc != 0] * iwt >
247 ((abs(coeff[rc]) << shift) << AOM_QM_BITS)) &&
248 (abs(x) * dequant_ptr[rc != 0] * iwt <
249 (((abs(coeff[rc]) << shift) + dequant_ptr[rc != 0])
250 << AOM_QM_BITS)))
251#else
252 if ((abs(x) * dequant_ptr[rc != 0] > (abs(coeff[rc]) << shift)) &&
253 (abs(x) * dequant_ptr[rc != 0] <
254 (abs(coeff[rc]) << shift) + dequant_ptr[rc != 0]))
255#endif // CONFIG_AOM_QM
256 shortcut = 1;
257 else
258 shortcut = 0;
259#endif // CONFIG_NEW_QUANT
260 }
261
262 if (shortcut) {
263 sz = -(x < 0);
264 x -= 2 * sz + 1;
265 } else {
266 tokens[i][1] = tokens[i][0];
267 best_index[i][1] = best_index[i][0];
268 next = i;
269
270 if (UNLIKELY(!(--band_left))) {
271 --band_counts;
272 band_left = *band_counts;
273 --token_costs;
274 }
275 continue;
276 }
277
278 /* Consider both possible successor states. */
279 if (!x) {
280 /* If we reduced this coefficient to zero, check to see if
281 * we need to move the EOB back here.
282 */
283 t0 = tokens[next][0].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
284 t1 = tokens[next][1].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
285 base_bits = 0;
286 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700287 base_bits = av1_get_token_cost(x, &t0, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700288 t1 = t0;
289 }
290
291 if (next_shortcut) {
292 if (LIKELY(next < default_eob)) {
293 if (t0 != EOB_TOKEN) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700294 token_cache[rc] = av1_pt_energy_class[t0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700295 pt = get_coef_context(nb, token_cache, i + 1);
296 rate0 += (*token_costs)[!x][pt][tokens[next][0].token];
297 }
298 if (t1 != EOB_TOKEN) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700299 token_cache[rc] = av1_pt_energy_class[t1];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700300 pt = get_coef_context(nb, token_cache, i + 1);
301 rate1 += (*token_costs)[!x][pt][tokens[next][1].token];
302 }
303 }
304
305 UPDATE_RD_COST();
306 /* And pick the best. */
307 best = rd_cost1 < rd_cost0;
308 } else {
309 // The two states in next stage are identical.
310 if (next < default_eob && t0 != EOB_TOKEN) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700311 token_cache[rc] = av1_pt_energy_class[t0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700312 pt = get_coef_context(nb, token_cache, i + 1);
313 rate0 += (*token_costs)[!x][pt][tokens[next][0].token];
314 }
315 best = 0;
316 }
317
318#if CONFIG_NEW_QUANT
Thomas Daviese0f8c552016-11-15 17:28:03 +0000319 dx = av1_dequant_coeff_nuq(x, dqv, dequant_val[band_translate[i]]) -
Yaowu Xuc27fc142016-08-22 16:08:15 -0700320 (coeff[rc] << shift);
Yaowu Xuf883b422016-08-30 14:01:10 -0700321#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700322 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
323 dx >>= xd->bd - 8;
324 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700325#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700326#else // CONFIG_NEW_QUANT
Yaowu Xuf883b422016-08-30 14:01:10 -0700327#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700328 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Thomas Daviese0f8c552016-11-15 17:28:03 +0000329 dx -= ((dqv >> (xd->bd - 8)) + sz) ^ sz;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700330 } else {
Thomas Daviese0f8c552016-11-15 17:28:03 +0000331 dx -= (dqv + sz) ^ sz;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700332 }
333#else
Thomas Daviese0f8c552016-11-15 17:28:03 +0000334 dx -= (dqv + sz) ^ sz;
Yaowu Xuf883b422016-08-30 14:01:10 -0700335#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700336#endif // CONFIG_NEW_QUANT
337 d2 = (int64_t)dx * dx;
338
339 tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
340 tokens[i][1].error = d2 + (best ? error1 : error0);
341 tokens[i][1].next = next;
342 tokens[i][1].token = best ? t1 : t0;
343 tokens[i][1].qc = x;
344
345 if (x) {
346#if CONFIG_NEW_QUANT
Yaowu Xuf883b422016-08-30 14:01:10 -0700347 tokens[i][1].dqc = av1_dequant_abscoeff_nuq(
Thomas Daviese0f8c552016-11-15 17:28:03 +0000348 abs(x), dqv, dequant_val[band_translate[i]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700349 tokens[i][1].dqc = shift ? ROUND_POWER_OF_TWO(tokens[i][1].dqc, shift)
350 : tokens[i][1].dqc;
351 if (sz) tokens[i][1].dqc = -tokens[i][1].dqc;
352#else
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -0800353// The 32x32 transform coefficient uses half quantization step size.
354// Account for the rounding difference in the dequantized coefficeint
355// value when the quantization index is dropped from an even number
356// to an odd number.
Thomas Daviese0f8c552016-11-15 17:28:03 +0000357
358#if CONFIG_AOM_QM
359 tran_low_t offset = dqv >> shift;
360#else
361 tran_low_t offset = dq_step[rc != 0];
362#endif
363 if (shift & x) offset += (dqv & 0x01);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700364
365 if (sz == 0)
366 tokens[i][1].dqc = dqcoeff[rc] - offset;
367 else
368 tokens[i][1].dqc = dqcoeff[rc] + offset;
369#endif // CONFIG_NEW_QUANT
370 } else {
371 tokens[i][1].dqc = 0;
372 }
373
374 best_index[i][1] = best;
375 /* Finally, make this the new head of the trellis. */
376 next = i;
377 } else {
378 /* There's no choice to make for a zero coefficient, so we don't
379 * add a new trellis node, but we do need to update the costs.
380 */
381 t0 = tokens[next][0].token;
382 t1 = tokens[next][1].token;
383 pt = get_coef_context(nb, token_cache, i + 1);
384 /* Update the cost of each path if we're past the EOB token. */
385 if (t0 != EOB_TOKEN) {
386 tokens[next][0].rate += (*token_costs)[1][pt][t0];
387 tokens[next][0].token = ZERO_TOKEN;
388 }
389 if (t1 != EOB_TOKEN) {
390 tokens[next][1].rate += (*token_costs)[1][pt][t1];
391 tokens[next][1].token = ZERO_TOKEN;
392 }
393 best_index[i][0] = best_index[i][1] = 0;
394 shortcut = (tokens[next][0].rate != tokens[next][1].rate);
395 /* Don't update next, because we didn't add a new node. */
396 }
397
398 if (UNLIKELY(!(--band_left))) {
399 --band_counts;
400 band_left = *band_counts;
401 --token_costs;
402 }
403 }
404
405 /* Now pick the best path through the whole trellis. */
406 rate0 = tokens[next][0].rate;
407 rate1 = tokens[next][1].rate;
408 error0 = tokens[next][0].error;
409 error1 = tokens[next][1].error;
410 t0 = tokens[next][0].token;
411 t1 = tokens[next][1].token;
412 rate0 += (*token_costs)[0][ctx][t0];
413 rate1 += (*token_costs)[0][ctx][t1];
414 UPDATE_RD_COST();
415 best = rd_cost1 < rd_cost0;
416
417 final_eob = -1;
418
419 for (i = next; i < eob; i = next) {
420 const int x = tokens[i][best].qc;
421 const int rc = scan[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700422 if (x) final_eob = i;
423 qcoeff[rc] = x;
424 dqcoeff[rc] = tokens[i][best].dqc;
425
426 next = tokens[i][best].next;
427 best = best_index[i][best];
428 }
429 final_eob++;
430
431 mb->plane[plane].eobs[block] = final_eob;
432 assert(final_eob <= default_eob);
433 return final_eob;
434}
435
Yaowu Xuf883b422016-08-30 14:01:10 -0700436#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700437typedef enum QUANT_FUNC {
438 QUANT_FUNC_LOWBD = 0,
439 QUANT_FUNC_HIGHBD = 1,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800440 QUANT_FUNC_TYPES = 2
Yaowu Xuc27fc142016-08-22 16:08:15 -0700441} QUANT_FUNC;
442
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800443static AV1_QUANT_FACADE
444 quant_func_list[AV1_XFORM_QUANT_TYPES][QUANT_FUNC_TYPES] = {
445 { av1_quantize_fp_facade, av1_highbd_quantize_fp_facade },
Yaowu Xuf883b422016-08-30 14:01:10 -0700446 { av1_quantize_b_facade, av1_highbd_quantize_b_facade },
447 { av1_quantize_dc_facade, av1_highbd_quantize_dc_facade },
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800448#if CONFIG_NEW_QUANT
449 { av1_quantize_fp_nuq_facade, av1_highbd_quantize_fp_nuq_facade },
450 { av1_quantize_b_nuq_facade, av1_highbd_quantize_b_nuq_facade },
451 { av1_quantize_dc_nuq_facade, av1_highbd_quantize_dc_nuq_facade },
452#endif // CONFIG_NEW_QUANT
453 { NULL, NULL }
454 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700455
Yaowu Xu02d4c3b2016-11-07 10:45:56 -0800456#elif !CONFIG_PVQ
457
Yaowu Xuc27fc142016-08-22 16:08:15 -0700458typedef enum QUANT_FUNC {
459 QUANT_FUNC_LOWBD = 0,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800460 QUANT_FUNC_TYPES = 1
Yaowu Xuc27fc142016-08-22 16:08:15 -0700461} QUANT_FUNC;
462
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800463static AV1_QUANT_FACADE quant_func_list[AV1_XFORM_QUANT_TYPES]
464 [QUANT_FUNC_TYPES] = {
clang-format67948d32016-09-07 22:40:40 -0700465 { av1_quantize_fp_facade },
466 { av1_quantize_b_facade },
467 { av1_quantize_dc_facade },
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800468#if CONFIG_NEW_QUANT
469 { av1_quantize_fp_nuq_facade },
470 { av1_quantize_b_nuq_facade },
471 { av1_quantize_dc_nuq_facade },
472#endif // CONFIG_NEW_QUANT
clang-format67948d32016-09-07 22:40:40 -0700473 { NULL }
474 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700475#endif
476
Angie Chiangff6d8902016-10-21 11:02:09 -0700477void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
478 int blk_row, int blk_col, BLOCK_SIZE plane_bsize,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800479 TX_SIZE tx_size, int ctx,
480 AV1_XFORM_QUANT xform_quant_idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700481 MACROBLOCKD *const xd = &x->e_mbd;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800482#if !(CONFIG_PVQ || CONFIG_DAALA_DIST)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700483 const struct macroblock_plane *const p = &x->plane[plane];
484 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yushin Cho77bba8d2016-11-04 16:36:56 -0700485#else
486 struct macroblock_plane *const p = &x->plane[plane];
487 struct macroblockd_plane *const pd = &xd->plane[plane];
488#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700489 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
Urvang Joshifeb925f2016-12-05 10:37:29 -0800490 const int block_raster_idx = av1_block_index_to_raster_order(tx_size, block);
491 TX_TYPE tx_type = get_tx_type(plane_type, xd, block_raster_idx, tx_size);
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700492 const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
Angie Chiangff6d8902016-10-21 11:02:09 -0700493 const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700494 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
495 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
496 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
497 uint16_t *const eob = &p->eobs[block];
Jingning Hanae5cfde2016-11-30 12:01:44 -0800498 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700499#if CONFIG_AOM_QM
500 int seg_id = xd->mi[0]->mbmi.segment_id;
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700501 const qm_val_t *qmatrix = pd->seg_qmatrix[seg_id][!is_inter][tx_size];
502 const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!is_inter][tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700503#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700504
505 FWD_TXFM_PARAM fwd_txfm_param;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700506
Yushin Cho7a428ba2017-01-12 16:28:49 -0800507#if CONFIG_PVQ || CONFIG_DAALA_DIST
508 uint8_t *dst;
509 int16_t *pred;
510 const int dst_stride = pd->dst.stride;
511 int tx_blk_size;
512 int i, j;
513#endif
514
Yushin Cho77bba8d2016-11-04 16:36:56 -0700515#if !CONFIG_PVQ
516 const int tx2d_size = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700517 QUANT_PARAM qparam;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700518 const int16_t *src_diff;
519
Jingning Han81492262016-12-05 15:48:47 -0800520 src_diff =
521 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Debargha Mukherjee0e119122016-11-04 12:10:23 -0700522 qparam.log_scale = get_tx_scale(tx_size);
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800523#if CONFIG_NEW_QUANT
524 qparam.tx_size = tx_size;
525 qparam.dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
526#endif // CONFIG_NEW_QUANT
527#if CONFIG_AOM_QM
528 qparam.qmatrix = qmatrix;
529 qparam.iqmatrix = iqmatrix;
530#endif // CONFIG_AOM_QM
Yushin Cho77bba8d2016-11-04 16:36:56 -0700531#else
532 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
533 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700534 int skip = 1;
535 PVQ_INFO *pvq_info = NULL;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800536 uint8_t *src;
537 int16_t *src_int16;
538 const int src_stride = p->src.stride;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700539
540 (void)scan_order;
541 (void)qcoeff;
542
543 if (x->pvq_coded) {
544 assert(block < MAX_PVQ_BLOCKS_IN_SB);
545 pvq_info = &x->pvq[block][plane];
546 }
Jingning Han81492262016-12-05 15:48:47 -0800547 src = &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
548 src_int16 =
549 &p->src_int16[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800550
551 // transform block size in pixels
552 tx_blk_size = tx_size_wide[tx_size];
553
554 for (j = 0; j < tx_blk_size; j++)
555 for (i = 0; i < tx_blk_size; i++)
556 src_int16[diff_stride * j + i] = src[src_stride * j + i];
557#endif
558
559#if CONFIG_PVQ || CONFIG_DAALA_DIST
560 dst = &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
Jingning Han81492262016-12-05 15:48:47 -0800561 pred = &pd->pred[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Yushin Cho77bba8d2016-11-04 16:36:56 -0700562
563 // transform block size in pixels
564 tx_blk_size = tx_size_wide[tx_size];
565
566 // copy uint8 orig and predicted block to int16 buffer
567 // in order to use existing VP10 transform functions
568 for (j = 0; j < tx_blk_size; j++)
569 for (i = 0; i < tx_blk_size; i++) {
Yushin Cho77bba8d2016-11-04 16:36:56 -0700570 pred[diff_stride * j + i] = dst[dst_stride * j + i];
571 }
572#endif
Yushin Cho7a428ba2017-01-12 16:28:49 -0800573
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800574 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700575
576 fwd_txfm_param.tx_type = tx_type;
577 fwd_txfm_param.tx_size = tx_size;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700578 fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
579
Yaowu Xuf883b422016-08-30 14:01:10 -0700580#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700581 fwd_txfm_param.bd = xd->bd;
582 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
583 highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -0700584 if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700585 if (LIKELY(!x->skip_block)) {
586 quant_func_list[xform_quant_idx][QUANT_FUNC_HIGHBD](
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800587 coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700588 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700589 av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700590 }
591 }
592 return;
593 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700594#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700595
Yushin Cho77bba8d2016-11-04 16:36:56 -0700596#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700597 fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -0700598 if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700599 if (LIKELY(!x->skip_block)) {
600 quant_func_list[xform_quant_idx][QUANT_FUNC_LOWBD](
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800601 coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700602 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700603 av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700604 }
605 }
Yushin Cho77bba8d2016-11-04 16:36:56 -0700606#else // #if !CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -0700607
Angie Chiang2cc057c2017-01-03 18:31:47 -0800608 (void)xform_quant_idx;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700609 fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
610 fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
611
612 // PVQ for inter mode block
ltrudeau472f63f2017-01-12 15:22:32 -0500613 if (!x->skip_block) {
ltrudeaue1c09292017-01-20 15:42:13 -0500614 PVQ_SKIP_TYPE ac_dc_coded =
615 av1_pvq_encode_helper(&x->daala_enc,
616 coeff, // target original vector
617 ref_coeff, // reference vector
618 dqcoeff, // de-quantized vector
619 eob, // End of Block marker
620 pd->dequant, // aom's quantizers
621 plane, // image plane
622 tx_size, // block size in log_2 - 2
623 tx_type,
624 &x->rate, // rate measured
625 x->pvq_speed,
626 pvq_info); // PVQ info for a block
627 skip = ac_dc_coded == PVQ_SKIP;
ltrudeau472f63f2017-01-12 15:22:32 -0500628 }
Yushin Cho77bba8d2016-11-04 16:36:56 -0700629 x->pvq_skip[plane] = skip;
630
631 if (!skip) mbmi->skip = 0;
632#endif // #if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700633}
634
Yaowu Xuc27fc142016-08-22 16:08:15 -0700635static void encode_block(int plane, int block, int blk_row, int blk_col,
636 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
637 struct encode_b_args *const args = arg;
Angie Chiangff6d8902016-10-21 11:02:09 -0700638 AV1_COMMON *cm = args->cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700639 MACROBLOCK *const x = args->x;
640 MACROBLOCKD *const xd = &x->e_mbd;
641 int ctx;
642 struct macroblock_plane *const p = &x->plane[plane];
643 struct macroblockd_plane *const pd = &xd->plane[plane];
644 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
645 uint8_t *dst;
646 ENTROPY_CONTEXT *a, *l;
647 INV_TXFM_PARAM inv_txfm_param;
Urvang Joshifeb925f2016-12-05 10:37:29 -0800648 const int block_raster_idx = av1_block_index_to_raster_order(tx_size, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700649#if CONFIG_PVQ
Urvang Joshifeb925f2016-12-05 10:37:29 -0800650 int tx_width_pixels, tx_height_pixels;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700651 int i, j;
652#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700653#if CONFIG_VAR_TX
654 int i;
Jingning Han9ca05b72017-01-03 14:41:36 -0800655 int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700656#endif
Jingning Han81492262016-12-05 15:48:47 -0800657 dst = &pd->dst
658 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700659 a = &args->ta[blk_col];
660 l = &args->tl[blk_row];
661#if CONFIG_VAR_TX
662 ctx = get_entropy_context(tx_size, a, l);
663#else
664 ctx = combine_entropy_contexts(*a, *l);
665#endif
666
667#if CONFIG_VAR_TX
Yue Chena1e48dc2016-08-29 17:29:33 -0700668 // Assert not magic number (uninitialized).
Jingning Han9ca05b72017-01-03 14:41:36 -0800669 assert(x->blk_skip[plane][blk_row * bw + blk_col] != 234);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700670
Jingning Han9ca05b72017-01-03 14:41:36 -0800671 if (x->blk_skip[plane][blk_row * bw + blk_col] == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700672#else
673 {
674#endif
675#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800676 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
677 ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700678#else
Angie Chiangff6d8902016-10-21 11:02:09 -0700679 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800680 ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700681#endif // CONFIG_NEW_QUANT
682 }
683#if CONFIG_VAR_TX
684 else {
685 p->eobs[block] = 0;
686 }
687#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -0700688#if !CONFIG_PVQ
Jingning Handb4c9ba2016-11-30 10:00:25 -0800689 if (p->eobs[block] && !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiangff6d8902016-10-21 11:02:09 -0700690 *a = *l = av1_optimize_b(cm, x, plane, block, tx_size, ctx) > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700691 } else {
692 *a = *l = p->eobs[block] > 0;
693 }
694
695#if CONFIG_VAR_TX
Jingning Hande953b92016-10-25 12:35:43 -0700696 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) a[i] = a[0];
697
698 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) l[i] = l[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700699#endif
700
701 if (p->eobs[block]) *(args->skip) = 0;
702
703 if (p->eobs[block] == 0) return;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700704#else
705 (void)ctx;
706 *a = *l = !x->pvq_skip[plane];
707
708 if (!x->pvq_skip[plane]) *(args->skip) = 0;
709
710 if (x->pvq_skip[plane]) return;
711
712 // transform block size in pixels
Urvang Joshifeb925f2016-12-05 10:37:29 -0800713 tx_width_pixels = tx_size_wide[tx_size];
714 tx_height_pixels = tx_size_high[tx_size];
Yushin Cho77bba8d2016-11-04 16:36:56 -0700715
716 // Since av1 does not have separate function which does inverse transform
717 // but av1_inv_txfm_add_*x*() also does addition of predicted image to
718 // inverse transformed image,
719 // pass blank dummy image to av1_inv_txfm_add_*x*(), i.e. set dst as zeros
Urvang Joshifeb925f2016-12-05 10:37:29 -0800720 for (j = 0; j < tx_height_pixels; j++)
721 for (i = 0; i < tx_width_pixels; i++) dst[j * pd->dst.stride + i] = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700722#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700723
724 // inverse transform parameters
Urvang Joshifeb925f2016-12-05 10:37:29 -0800725 inv_txfm_param.tx_type =
726 get_tx_type(pd->plane_type, xd, block_raster_idx, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700727 inv_txfm_param.tx_size = tx_size;
728 inv_txfm_param.eob = p->eobs[block];
729 inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
730
Yaowu Xuf883b422016-08-30 14:01:10 -0700731#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700732 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
733 inv_txfm_param.bd = xd->bd;
734 highbd_inv_txfm_add(dqcoeff, dst, pd->dst.stride, &inv_txfm_param);
735 return;
736 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700737#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700738 inv_txfm_add(dqcoeff, dst, pd->dst.stride, &inv_txfm_param);
739}
740
741#if CONFIG_VAR_TX
742static void encode_block_inter(int plane, int block, int blk_row, int blk_col,
743 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
744 void *arg) {
745 struct encode_b_args *const args = arg;
746 MACROBLOCK *const x = args->x;
747 MACROBLOCKD *const xd = &x->e_mbd;
748 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
749 const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
750 const struct macroblockd_plane *const pd = &xd->plane[plane];
751 const int tx_row = blk_row >> (1 - pd->subsampling_y);
752 const int tx_col = blk_col >> (1 - pd->subsampling_x);
753 TX_SIZE plane_tx_size;
Jingning Hanf65b8702016-10-31 12:13:20 -0700754 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
755 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700756
757 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
758
Debargha Mukherjee2f123402016-08-30 17:43:38 -0700759 plane_tx_size =
760 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
761 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700762
763 if (tx_size == plane_tx_size) {
764 encode_block(plane, block, blk_row, blk_col, plane_bsize, tx_size, arg);
765 } else {
Jingning Hana9336322016-11-02 15:45:07 -0700766 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
767 // This is the square transform block partition entry point.
768 int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700769 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700770 assert(bsl > 0);
Jingning Hand3fada82016-11-22 10:46:55 -0800771 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700772
773 for (i = 0; i < 4; ++i) {
Jingning Hande953b92016-10-25 12:35:43 -0700774 const int offsetr = blk_row + ((i >> 1) * bsl);
775 const int offsetc = blk_col + ((i & 0x01) * bsl);
Jingning Hande953b92016-10-25 12:35:43 -0700776 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700777
778 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
779
Jingning Han98d6a1f2016-11-03 12:47:47 -0700780 encode_block_inter(plane, block, offsetr, offsetc, plane_bsize, sub_txs,
781 arg);
782 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700783 }
784 }
785}
786#endif
787
Angie Chiangff6d8902016-10-21 11:02:09 -0700788typedef struct encode_block_pass1_args {
789 AV1_COMMON *cm;
790 MACROBLOCK *x;
791} encode_block_pass1_args;
792
Yaowu Xuc27fc142016-08-22 16:08:15 -0700793static void encode_block_pass1(int plane, int block, int blk_row, int blk_col,
794 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
795 void *arg) {
Angie Chiangff6d8902016-10-21 11:02:09 -0700796 encode_block_pass1_args *args = (encode_block_pass1_args *)arg;
797 AV1_COMMON *cm = args->cm;
798 MACROBLOCK *const x = args->x;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700799 MACROBLOCKD *const xd = &x->e_mbd;
800 struct macroblock_plane *const p = &x->plane[plane];
801 struct macroblockd_plane *const pd = &xd->plane[plane];
802 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
803 uint8_t *dst;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800804 int ctx = 0;
Jingning Han81492262016-12-05 15:48:47 -0800805 dst = &pd->dst
806 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700807
808#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800809 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
810 ctx, AV1_XFORM_QUANT_B_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700811#else
Angie Chiangff6d8902016-10-21 11:02:09 -0700812 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800813 ctx, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700814#endif // CONFIG_NEW_QUANT
Yushin Cho77bba8d2016-11-04 16:36:56 -0700815#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700816 if (p->eobs[block] > 0) {
Yushin Cho77bba8d2016-11-04 16:36:56 -0700817#else
818 if (!x->pvq_skip[plane]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -0700819 {
820 int tx_blk_size;
821 int i, j;
822 // transform block size in pixels
823 tx_blk_size = tx_size_wide[tx_size];
824
825 // Since av1 does not have separate function which does inverse transform
826 // but av1_inv_txfm_add_*x*() also does addition of predicted image to
827 // inverse transformed image,
828 // pass blank dummy image to av1_inv_txfm_add_*x*(), i.e. set dst as zeros
829 for (j = 0; j < tx_blk_size; j++)
830 for (i = 0; i < tx_blk_size; i++) dst[j * pd->dst.stride + i] = 0;
831 }
Jingning Handf072642016-11-08 16:43:38 -0800832#endif // !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -0700833#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700834 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
835 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700836 av1_highbd_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block],
837 xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700838 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700839 av1_highbd_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block],
840 xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700841 }
842 return;
843 }
Jingning Hane38d63c2016-11-08 12:05:29 -0800844#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700845 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700846 av1_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700847 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700848 av1_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700849 }
850 }
851}
852
Angie Chiangff6d8902016-10-21 11:02:09 -0700853void av1_encode_sby_pass1(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
854 encode_block_pass1_args args = { cm, x };
Yaowu Xuf883b422016-08-30 14:01:10 -0700855 av1_subtract_plane(x, bsize, 0);
856 av1_foreach_transformed_block_in_plane(&x->e_mbd, bsize, 0,
Angie Chiangff6d8902016-10-21 11:02:09 -0700857 encode_block_pass1, &args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700858}
859
Angie Chiangff6d8902016-10-21 11:02:09 -0700860void av1_encode_sb(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700861 MACROBLOCKD *const xd = &x->e_mbd;
862 struct optimize_ctx ctx;
863 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -0700864 struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700865 int plane;
866
867 mbmi->skip = 1;
868
869 if (x->skip) return;
870
871 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
872#if CONFIG_VAR_TX
873 // TODO(jingning): Clean this up.
874 const struct macroblockd_plane *const pd = &xd->plane[plane];
875 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Hande953b92016-10-25 12:35:43 -0700876 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
877 const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -0800878 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700879 const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
Jingning Hande953b92016-10-25 12:35:43 -0700880 const int bw = block_size_wide[txb_size] >> tx_size_wide_log2[0];
881 const int bh = block_size_high[txb_size] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700882 int idx, idy;
883 int block = 0;
Jingning Hande953b92016-10-25 12:35:43 -0700884 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Jingning Han581d1692017-01-05 16:03:54 -0800885 av1_get_entropy_contexts(bsize, 0, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700886#else
887 const struct macroblockd_plane *const pd = &xd->plane[plane];
888 const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
Yaowu Xuf883b422016-08-30 14:01:10 -0700889 av1_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700890#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -0700891#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -0700892 av1_subtract_plane(x, bsize, plane);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700893#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700894 arg.ta = ctx.ta[plane];
895 arg.tl = ctx.tl[plane];
896
897#if CONFIG_VAR_TX
Jingning Hanfe45b212016-11-22 10:30:23 -0800898 for (idy = 0; idy < mi_height; idy += bh) {
899 for (idx = 0; idx < mi_width; idx += bw) {
900 encode_block_inter(plane, block, idy, idx, plane_bsize, max_tx_size,
901 &arg);
902 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700903 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700904 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700905#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700906 av1_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
907 &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700908#endif
909 }
910}
911
912#if CONFIG_SUPERTX
Angie Chiangff6d8902016-10-21 11:02:09 -0700913void av1_encode_sb_supertx(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700914 MACROBLOCKD *const xd = &x->e_mbd;
915 struct optimize_ctx ctx;
916 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -0700917 struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700918 int plane;
919
920 mbmi->skip = 1;
921 if (x->skip) return;
922
923 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
924 const struct macroblockd_plane *const pd = &xd->plane[plane];
925#if CONFIG_VAR_TX
926 const TX_SIZE tx_size = TX_4X4;
927#else
928 const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
929#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700930 av1_subtract_plane(x, bsize, plane);
931 av1_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700932 arg.ta = ctx.ta[plane];
933 arg.tl = ctx.tl[plane];
Yaowu Xuf883b422016-08-30 14:01:10 -0700934 av1_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
935 &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700936 }
937}
938#endif // CONFIG_SUPERTX
939
Yaowu Xuf883b422016-08-30 14:01:10 -0700940void av1_encode_block_intra(int plane, int block, int blk_row, int blk_col,
941 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
942 void *arg) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700943 struct encode_b_args *const args = arg;
Angie Chiangff6d8902016-10-21 11:02:09 -0700944 AV1_COMMON *cm = args->cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700945 MACROBLOCK *const x = args->x;
946 MACROBLOCKD *const xd = &x->e_mbd;
947 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
948 struct macroblock_plane *const p = &x->plane[plane];
949 struct macroblockd_plane *const pd = &xd->plane[plane];
950 tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
951 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
Urvang Joshifeb925f2016-12-05 10:37:29 -0800952 const int block_raster_idx = av1_block_index_to_raster_order(tx_size, block);
953 const TX_TYPE tx_type =
954 get_tx_type(plane_type, xd, block_raster_idx, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700955 PREDICTION_MODE mode;
Jingning Han62a2b9e2016-10-24 10:32:37 -0700956 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700957 uint8_t *src, *dst;
958 int16_t *src_diff;
959 uint16_t *eob = &p->eobs[block];
960 const int src_stride = p->src.stride;
961 const int dst_stride = pd->dst.stride;
Jingning Han62a2b9e2016-10-24 10:32:37 -0700962 const int tx1d_width = tx_size_wide[tx_size];
963 const int tx1d_height = tx_size_high[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700964 ENTROPY_CONTEXT *a = NULL, *l = NULL;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800965 int ctx = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700966 INV_TXFM_PARAM inv_txfm_param;
Yushin Cho3827fdd2016-11-09 15:50:23 -0800967#if CONFIG_PVQ
Yushin Cho77bba8d2016-11-04 16:36:56 -0700968 int tx_blk_size;
969 int i, j;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700970#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700971
Jingning Han81492262016-12-05 15:48:47 -0800972 dst = &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
973 src = &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
974 src_diff =
975 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Urvang Joshifeb925f2016-12-05 10:37:29 -0800976 mode = (plane == 0) ? get_y_mode(xd->mi[0], block_raster_idx) : mbmi->uv_mode;
David Barker839467f2017-01-19 11:06:15 +0000977 av1_predict_intra_block(xd, pd->width, pd->height, txsize_to_bsize[tx_size],
978 mode, dst, dst_stride, dst, dst_stride, blk_col,
979 blk_row, plane);
Jingning Hane325abd2016-12-01 09:35:10 -0800980
981 if (check_subtract_block_size(tx1d_width, tx1d_height)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700982#if CONFIG_AOM_HIGHBITDEPTH
Jingning Hane325abd2016-12-01 09:35:10 -0800983 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
984 aom_highbd_subtract_block_c(tx1d_height, tx1d_width, src_diff,
985 diff_stride, src, src_stride, dst, dst_stride,
986 xd->bd);
987 } else {
988 aom_subtract_block_c(tx1d_height, tx1d_width, src_diff, diff_stride, src,
989 src_stride, dst, dst_stride);
990 }
991#else
992 aom_subtract_block_c(tx1d_height, tx1d_width, src_diff, diff_stride, src,
993 src_stride, dst, dst_stride);
994#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700995 } else {
Jingning Hane325abd2016-12-01 09:35:10 -0800996#if CONFIG_AOM_HIGHBITDEPTH
997 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
998 aom_highbd_subtract_block(tx1d_height, tx1d_width, src_diff, diff_stride,
999 src, src_stride, dst, dst_stride, xd->bd);
1000 } else {
1001 aom_subtract_block(tx1d_height, tx1d_width, src_diff, diff_stride, src,
1002 src_stride, dst, dst_stride);
1003 }
1004#else
Yaowu Xuf883b422016-08-30 14:01:10 -07001005 aom_subtract_block(tx1d_height, tx1d_width, src_diff, diff_stride, src,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001006 src_stride, dst, dst_stride);
Yaowu Xuf883b422016-08-30 14:01:10 -07001007#endif // CONFIG_AOM_HIGHBITDEPTH
Jingning Hane325abd2016-12-01 09:35:10 -08001008 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07001009
1010 a = &args->ta[blk_col];
1011 l = &args->tl[blk_row];
Yushin Cho3827fdd2016-11-09 15:50:23 -08001012#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -07001013 ctx = combine_entropy_contexts(*a, *l);
1014
1015 if (args->enable_optimize_b) {
1016#if CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001017 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1018 ctx, AV1_XFORM_QUANT_FP_NUQ);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001019#else // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07001020 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001021 ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001022#endif // CONFIG_NEW_QUANT
1023 if (p->eobs[block]) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001024 *a = *l = av1_optimize_b(cm, x, plane, block, tx_size, ctx) > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001025 } else {
1026 *a = *l = 0;
1027 }
1028 } else {
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001029#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07001030 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001031 ctx, AV1_XFORM_QUANT_B_NUQ);
1032#else // CONFIG_NEW_QUANT
1033 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1034 ctx, AV1_XFORM_QUANT_B);
1035#endif // CONFIG_NEW_QUANT
Yaowu Xuc27fc142016-08-22 16:08:15 -07001036 *a = *l = p->eobs[block] > 0;
1037 }
1038
1039 if (*eob) {
1040 // inverse transform
1041 inv_txfm_param.tx_type = tx_type;
1042 inv_txfm_param.tx_size = tx_size;
1043 inv_txfm_param.eob = *eob;
1044 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
Yaowu Xuf883b422016-08-30 14:01:10 -07001045#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001046 inv_txfm_param.bd = xd->bd;
1047 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1048 highbd_inv_txfm_add(dqcoeff, dst, dst_stride, &inv_txfm_param);
1049 } else {
1050 inv_txfm_add(dqcoeff, dst, dst_stride, &inv_txfm_param);
1051 }
1052#else
1053 inv_txfm_add(dqcoeff, dst, dst_stride, &inv_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -07001054#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001055
1056 *(args->skip) = 0;
1057 }
Yaowu Xu859a5272016-11-10 15:32:21 -08001058#else // #if !CONFIG_PVQ
Yushin Cho3827fdd2016-11-09 15:50:23 -08001059
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001060#if CONFIG_NEW_QUANT
Yushin Cho3827fdd2016-11-09 15:50:23 -08001061 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001062 ctx, AV1_XFORM_QUANT_FP_NUQ);
1063#else
1064 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1065 ctx, AV1_XFORM_QUANT_FP);
1066#endif // CONFIG_NEW_QUANT
Yushin Cho3827fdd2016-11-09 15:50:23 -08001067
1068 *a = *l = !x->pvq_skip[plane];
1069
1070 // *(args->skip) == mbmi->skip
1071 if (!x->pvq_skip[plane]) *(args->skip) = 0;
1072
1073 if (x->pvq_skip[plane]) return;
1074
Yushin Cho77bba8d2016-11-04 16:36:56 -07001075 // transform block size in pixels
1076 tx_blk_size = tx_size_wide[tx_size];
1077
Yushin Cho77bba8d2016-11-04 16:36:56 -07001078 // Since av1 does not have separate function which does inverse transform
1079 // but av1_inv_txfm_add_*x*() also does addition of predicted image to
1080 // inverse transformed image,
1081 // pass blank dummy image to av1_inv_txfm_add_*x*(), i.e. set dst as zeros
1082
Yushin Cho3827fdd2016-11-09 15:50:23 -08001083 for (j = 0; j < tx_blk_size; j++)
1084 for (i = 0; i < tx_blk_size; i++) dst[j * dst_stride + i] = 0;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001085
Yushin Cho3827fdd2016-11-09 15:50:23 -08001086 inv_txfm_param.tx_type = tx_type;
1087 inv_txfm_param.tx_size = tx_size;
1088 inv_txfm_param.eob = *eob;
1089 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
1090#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xu859a5272016-11-10 15:32:21 -08001091#error
Yushin Cho3827fdd2016-11-09 15:50:23 -08001092
1093#else
1094 inv_txfm_add(dqcoeff, dst, dst_stride, &inv_txfm_param);
1095#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001096#endif // #if !CONFIG_PVQ
1097
1098#if !CONFIG_PVQ
1099 if (*eob) *(args->skip) = 0;
1100#else
1101// Note : *(args->skip) == mbmi->skip
1102#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001103}
1104
Angie Chiangff6d8902016-10-21 11:02:09 -07001105void av1_encode_intra_block_plane(AV1_COMMON *cm, MACROBLOCK *x,
1106 BLOCK_SIZE bsize, int plane,
Yaowu Xuf883b422016-08-30 14:01:10 -07001107 int enable_optimize_b) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001108 const MACROBLOCKD *const xd = &x->e_mbd;
Guillaume Martrese50d9dd2016-12-18 18:26:47 +01001109 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE] = { 0 };
1110 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001111
Angie Chiangff6d8902016-10-21 11:02:09 -07001112 struct encode_b_args arg = {
1113 cm, x, NULL, &xd->mi[0]->mbmi.skip, ta, tl, enable_optimize_b
1114 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001115 if (enable_optimize_b) {
1116 const struct macroblockd_plane *const pd = &xd->plane[plane];
1117 const TX_SIZE tx_size =
1118 plane ? get_uv_tx_size(&xd->mi[0]->mbmi, pd) : xd->mi[0]->mbmi.tx_size;
Yaowu Xuf883b422016-08-30 14:01:10 -07001119 av1_get_entropy_contexts(bsize, tx_size, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001120 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001121 av1_foreach_transformed_block_in_plane(xd, bsize, plane,
1122 av1_encode_block_intra, &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001123}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001124
1125#if CONFIG_PVQ
ltrudeaue1c09292017-01-20 15:42:13 -05001126PVQ_SKIP_TYPE av1_pvq_encode_helper(
1127 daala_enc_ctx *daala_enc, tran_low_t *const coeff, tran_low_t *ref_coeff,
1128 tran_low_t *const dqcoeff, uint16_t *eob, const int16_t *quant, int plane,
1129 int tx_size, TX_TYPE tx_type, int *rate, int speed, PVQ_INFO *pvq_info) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001130 const int tx_blk_size = tx_size_wide[tx_size];
ltrudeaue1c09292017-01-20 15:42:13 -05001131 PVQ_SKIP_TYPE ac_dc_coded;
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001132 /*TODO(tterribe): Handle CONFIG_AOM_HIGHBITDEPTH.*/
1133 int coeff_shift = 3 - get_tx_scale(tx_size);
1134 int rounding_mask;
Yushin Cho70669122016-12-08 09:53:14 -10001135 int pvq_dc_quant;
1136 int use_activity_masking = daala_enc->use_activity_masking;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001137 int tell;
1138 int has_dc_skip = 1;
1139 int i;
1140 int off = od_qm_offset(tx_size, plane ? 1 : 0);
1141#if PVQ_CHROMA_RD
1142 double save_pvq_lambda;
1143#endif
Yushin Cho70669122016-12-08 09:53:14 -10001144
Thomas Daede1dbda1b2017-02-06 16:06:29 -08001145 DECLARE_ALIGNED(16, tran_low_t, coeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1146 DECLARE_ALIGNED(16, tran_low_t, ref_coeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1147 DECLARE_ALIGNED(16, tran_low_t, dqcoeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001148
Yushin Cho48f84db2016-11-07 21:20:17 -08001149 DECLARE_ALIGNED(16, int32_t, in_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1150 DECLARE_ALIGNED(16, int32_t, ref_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1151 DECLARE_ALIGNED(16, int32_t, out_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001152
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001153 assert(OD_COEFF_SHIFT >= 3);
Yushin Cho70669122016-12-08 09:53:14 -10001154 // DC quantizer for PVQ
1155 if (use_activity_masking)
clang-format55ce9e02017-02-15 22:27:12 -08001156 pvq_dc_quant =
1157 OD_MAXI(1, (quant[0] << (OD_COEFF_SHIFT - 3)) *
1158 daala_enc->state
1159 .pvq_qm_q4[plane][od_qm_get_index(tx_size, 0)] >>
1160 4);
Yushin Cho70669122016-12-08 09:53:14 -10001161 else
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001162 pvq_dc_quant = OD_MAXI(1, quant[0] << (OD_COEFF_SHIFT - 3));
Yushin Cho70669122016-12-08 09:53:14 -10001163
Yushin Cho77bba8d2016-11-04 16:36:56 -07001164 *eob = 0;
1165
Nathan E. Egge6675be02016-12-21 13:02:43 -05001166#if CONFIG_DAALA_EC
1167 tell = od_ec_enc_tell_frac(&daala_enc->w.ec);
1168#else
1169#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
1170#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001171
1172 // Change coefficient ordering for pvq encoding.
1173 od_raster_to_coding_order(coeff_pvq, tx_blk_size, tx_type, coeff,
1174 tx_blk_size);
1175 od_raster_to_coding_order(ref_coeff_pvq, tx_blk_size, tx_type, ref_coeff,
1176 tx_blk_size);
1177
1178 // copy int16 inputs to int32
1179 for (i = 0; i < tx_blk_size * tx_blk_size; i++) {
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001180 ref_int32[i] = ref_coeff_pvq[i] << (OD_COEFF_SHIFT - coeff_shift);
1181 in_int32[i] = coeff_pvq[i] << (OD_COEFF_SHIFT - coeff_shift);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001182 }
1183
1184#if PVQ_CHROMA_RD
1185 if (plane != 0) {
1186 save_pvq_lambda = daala_enc->pvq_norm_lambda;
1187 daala_enc->pvq_norm_lambda *= 0.8;
1188 }
1189#endif
1190 if (abs(in_int32[0] - ref_int32[0]) < pvq_dc_quant * 141 / 256) { /* 0.55 */
1191 out_int32[0] = 0;
1192 } else {
1193 out_int32[0] = OD_DIV_R0(in_int32[0] - ref_int32[0], pvq_dc_quant);
1194 }
1195
ltrudeau472f63f2017-01-12 15:22:32 -05001196 ac_dc_coded = od_pvq_encode(
1197 daala_enc, ref_int32, in_int32, out_int32,
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001198 quant[0] << (OD_COEFF_SHIFT - 3), // scale/quantizer
1199 quant[1] << (OD_COEFF_SHIFT - 3), // scale/quantizer
ltrudeau472f63f2017-01-12 15:22:32 -05001200 plane, tx_size, OD_PVQ_BETA[use_activity_masking][plane][tx_size],
1201 OD_ROBUST_STREAM,
1202 0, // is_keyframe,
1203 0, 0, 0, // q_scaling, bx, by,
1204 daala_enc->state.qm + off, daala_enc->state.qm_inv + off,
1205 speed, // speed
1206 pvq_info);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001207
1208 // Encode residue of DC coeff, if required.
1209 if (!has_dc_skip || out_int32[0]) {
Nathan E. Egge760c27f2016-12-22 12:30:00 -05001210 generic_encode(&daala_enc->w, &daala_enc->state.adapt.model_dc[plane],
Yushin Cho77bba8d2016-11-04 16:36:56 -07001211 abs(out_int32[0]) - has_dc_skip, -1,
1212 &daala_enc->state.adapt.ex_dc[plane][tx_size][0], 2);
1213 }
1214 if (out_int32[0]) {
Nathan E. Egge6675be02016-12-21 13:02:43 -05001215 aom_write_bit(&daala_enc->w, out_int32[0] < 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001216 }
1217
1218 // need to save quantized residue of DC coeff
1219 // so that final pvq bitstream writing can know whether DC is coded.
1220 if (pvq_info) pvq_info->dq_dc_residue = out_int32[0];
1221
1222 out_int32[0] = out_int32[0] * pvq_dc_quant;
1223 out_int32[0] += ref_int32[0];
1224
1225 // copy int32 result back to int16
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001226 assert(OD_COEFF_SHIFT > coeff_shift);
1227 rounding_mask = (1 << (OD_COEFF_SHIFT - coeff_shift - 1)) - 1;
1228 for (i = 0; i < tx_blk_size * tx_blk_size; i++) {
1229 dqcoeff_pvq[i] = (out_int32[i] + (out_int32[i] < 0) + rounding_mask) >>
1230 (OD_COEFF_SHIFT - coeff_shift);
1231 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001232
1233 // Back to original coefficient order
1234 od_coding_order_to_raster(dqcoeff, tx_blk_size, tx_type, dqcoeff_pvq,
1235 tx_blk_size);
1236
1237 *eob = tx_blk_size * tx_blk_size;
1238
Nathan E. Egge6675be02016-12-21 13:02:43 -05001239#if CONFIG_DAALA_EC
1240 *rate = (od_ec_enc_tell_frac(&daala_enc->w.ec) - tell)
Yushin Cho77bba8d2016-11-04 16:36:56 -07001241 << (AV1_PROB_COST_SHIFT - OD_BITRES);
Nathan E. Egge6675be02016-12-21 13:02:43 -05001242#else
1243#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
1244#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001245 assert(*rate >= 0);
1246#if PVQ_CHROMA_RD
1247 if (plane != 0) daala_enc->pvq_norm_lambda = save_pvq_lambda;
1248#endif
ltrudeau472f63f2017-01-12 15:22:32 -05001249 return ac_dc_coded;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001250}
1251
1252void av1_store_pvq_enc_info(PVQ_INFO *pvq_info, int *qg, int *theta,
1253 int *max_theta, int *k, od_coeff *y, int nb_bands,
1254 const int *off, int *size, int skip_rest,
1255 int skip_dir,
1256 int bs) { // block size in log_2 -2
1257 int i;
1258 const int tx_blk_size = tx_size_wide[bs];
1259
1260 for (i = 0; i < nb_bands; i++) {
1261 pvq_info->qg[i] = qg[i];
1262 pvq_info->theta[i] = theta[i];
1263 pvq_info->max_theta[i] = max_theta[i];
1264 pvq_info->k[i] = k[i];
1265 pvq_info->off[i] = off[i];
1266 pvq_info->size[i] = size[i];
1267 }
1268
1269 memcpy(pvq_info->y, y, tx_blk_size * tx_blk_size * sizeof(od_coeff));
1270
1271 pvq_info->nb_bands = nb_bands;
1272 pvq_info->skip_rest = skip_rest;
1273 pvq_info->skip_dir = skip_dir;
1274 pvq_info->bs = bs;
1275}
1276#endif