blob: 13bbb7aa845807e29c533d2da9f1ffc773f2a9bd [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"
Angie Chiang74e23072017-03-24 14:54:23 -070028#if CONFIG_LV_MAP
29#include "av1/encoder/encodetxb.h"
30#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070031#include "av1/encoder/hybrid_fwd_txfm.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070032#include "av1/encoder/rd.h"
33#include "av1/encoder/tokenize.h"
34
Yushin Cho77bba8d2016-11-04 16:36:56 -070035#if CONFIG_PVQ
36#include "av1/encoder/encint.h"
37#include "av1/common/partition.h"
38#include "av1/encoder/pvq_encoder.h"
39#endif
40
Jingning Hane325abd2016-12-01 09:35:10 -080041// Check if one needs to use c version subtraction.
42static int check_subtract_block_size(int w, int h) { return w < 4 || h < 4; }
43
Angie Chiang19407b52017-04-02 15:27:57 -070044static void subtract_block(const MACROBLOCKD *xd, int rows, int cols,
45 int16_t *diff, ptrdiff_t diff_stride,
46 const uint8_t *src8, ptrdiff_t src_stride,
47 const uint8_t *pred8, ptrdiff_t pred_stride) {
48#if !CONFIG_AOM_HIGHBITDEPTH
49 (void)xd;
50#endif
51
52 if (check_subtract_block_size(rows, cols)) {
53#if CONFIG_AOM_HIGHBITDEPTH
54 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
55 aom_highbd_subtract_block_c(rows, cols, diff, diff_stride, src8,
56 src_stride, pred8, pred_stride, xd->bd);
57 return;
58 }
59#endif // CONFIG_AOM_HIGHBITDEPTH
60 aom_subtract_block_c(rows, cols, diff, diff_stride, src8, src_stride, pred8,
61 pred_stride);
62
63 return;
64 }
65
66#if CONFIG_AOM_HIGHBITDEPTH
67 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
68 aom_highbd_subtract_block(rows, cols, diff, diff_stride, src8, src_stride,
69 pred8, pred_stride, xd->bd);
70 return;
71 }
72#endif // CONFIG_AOM_HIGHBITDEPTH
73 aom_subtract_block(rows, cols, diff, diff_stride, src8, src_stride, pred8,
74 pred_stride);
75}
76
Angie Chiangf87e43f2017-04-02 16:51:19 -070077void av1_subtract_txb(MACROBLOCK *x, int plane, BLOCK_SIZE plane_bsize,
78 int blk_col, int blk_row, TX_SIZE tx_size) {
79 MACROBLOCKD *const xd = &x->e_mbd;
80 struct macroblock_plane *const p = &x->plane[plane];
81 const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane];
82 const int diff_stride = block_size_wide[plane_bsize];
83 const int src_stride = p->src.stride;
84 const int dst_stride = pd->dst.stride;
85 const int tx1d_width = tx_size_wide[tx_size];
86 const int tx1d_height = tx_size_high[tx_size];
87 uint8_t *dst =
88 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
89 uint8_t *src =
90 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
91 int16_t *src_diff =
92 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
93 subtract_block(xd, tx1d_height, tx1d_width, src_diff, diff_stride, src,
94 src_stride, dst, dst_stride);
95}
96
Yaowu Xuf883b422016-08-30 14:01:10 -070097void av1_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070098 struct macroblock_plane *const p = &x->plane[plane];
99 const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane];
100 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Hanae5cfde2016-11-30 12:01:44 -0800101 const int bw = block_size_wide[plane_bsize];
102 const int bh = block_size_high[plane_bsize];
Angie Chiang19407b52017-04-02 15:27:57 -0700103 const MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700104
Angie Chiang19407b52017-04-02 15:27:57 -0700105 subtract_block(xd, bh, bw, p->src_diff, bw, p->src.buf, p->src.stride,
106 pd->dst.buf, pd->dst.stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700107}
108
Yaowu Xuf883b422016-08-30 14:01:10 -0700109typedef struct av1_token_state {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700110 int64_t error;
Alex Conversec9d2fcc2017-03-17 17:32:56 -0700111 int rate;
112 int16_t next;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700113 int16_t token;
114 tran_low_t qc;
115 tran_low_t dqc;
Alex Conversec9d2fcc2017-03-17 17:32:56 -0700116 uint8_t best_index;
Yaowu Xuf883b422016-08-30 14:01:10 -0700117} av1_token_state;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700118
119// These numbers are empirically obtained.
120static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] = {
Thomas Davies10525752017-03-06 12:10:46 +0000121#if CONFIG_EC_ADAPT
122 { 10, 7 }, { 8, 5 },
123#else
Yaowu Xuc27fc142016-08-22 16:08:15 -0700124 { 10, 6 }, { 8, 5 },
Thomas Davies10525752017-03-06 12:10:46 +0000125#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700126};
127
128#define UPDATE_RD_COST() \
129 { \
130 rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0); \
131 rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1); \
132 }
133
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000134static inline int64_t get_token_bit_costs(
135 unsigned int token_costs[2][COEFF_CONTEXTS][ENTROPY_TOKENS], int skip_eob,
136 int ctx, int token) {
137#if CONFIG_NEW_TOKENSET
138 (void)skip_eob;
139 return token_costs[token == ZERO_TOKEN || token == EOB_TOKEN][ctx][token];
140#else
141 return token_costs[skip_eob][ctx][token];
142#endif
143}
144
Angie Chiangff6d8902016-10-21 11:02:09 -0700145int av1_optimize_b(const AV1_COMMON *cm, MACROBLOCK *mb, int plane, int block,
146 TX_SIZE tx_size, int ctx) {
Angie Chiang57605532017-04-03 11:51:15 -0700147#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700148 MACROBLOCKD *const xd = &mb->e_mbd;
149 struct macroblock_plane *const p = &mb->plane[plane];
150 struct macroblockd_plane *const pd = &xd->plane[plane];
151 const int ref = is_inter_block(&xd->mi[0]->mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -0700152 av1_token_state tokens[MAX_TX_SQUARE + 1][2];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700153 uint8_t token_cache[MAX_TX_SQUARE];
Urvang Joshifeb925f2016-12-05 10:37:29 -0800154 const tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700155 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
156 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
157 const int eob = p->eobs[block];
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700158 const PLANE_TYPE plane_type = pd->plane_type;
Jingning Hande953b92016-10-25 12:35:43 -0700159 const int default_eob = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700160 const int16_t *const dequant_ptr = pd->dequant;
161 const uint8_t *const band_translate = get_band_translate(tx_size);
Angie Chiang752ccce2017-04-09 13:41:13 -0700162 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -0700163 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -0700164 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Urvang Joshi03f6fdc2016-10-14 15:53:39 -0700165 const int16_t *const scan = scan_order->scan;
166 const int16_t *const nb = scan_order->neighbors;
Thomas Daviese0f8c552016-11-15 17:28:03 +0000167 int dqv;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800168 const int shift = get_tx_scale(tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700169#if CONFIG_AOM_QM
170 int seg_id = xd->mi[0]->mbmi.segment_id;
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700171 const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!ref][tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700172#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700173#if CONFIG_NEW_QUANT
David Barkerd7d78c82016-10-24 10:55:35 +0100174 int dq = get_dq_profile_from_ctx(mb->qindex, ctx, ref, plane_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700175 const dequant_val_type_nuq *dequant_val = pd->dequant_val_nuq[dq];
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800176#elif !CONFIG_AOM_QM
Yaowu Xuc27fc142016-08-22 16:08:15 -0700177 const int dq_step[2] = { dequant_ptr[0] >> shift, dequant_ptr[1] >> shift };
178#endif // CONFIG_NEW_QUANT
179 int next = eob, sz = 0;
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700180 const int64_t rdmult = (mb->rdmult * plane_rd_mult[ref][plane_type]) >> 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700181 const int64_t rddiv = mb->rddiv;
182 int64_t rd_cost0, rd_cost1;
183 int rate0, rate1;
184 int64_t error0, error1;
185 int16_t t0, t1;
186 int best, band = (eob < default_eob) ? band_translate[eob]
187 : band_translate[eob - 1];
188 int pt, i, final_eob;
Yaowu Xuf883b422016-08-30 14:01:10 -0700189#if CONFIG_AOM_HIGHBITDEPTH
Alex Converseda3d94f2017-03-15 14:54:29 -0700190 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700191#else
Alex Converseda3d94f2017-03-15 14:54:29 -0700192 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, 8);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700193#endif
194 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700195 mb->token_costs[txsize_sqr_map[tx_size]][plane_type][ref];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700196 const uint16_t *band_counts = &band_count_table[tx_size][band];
197 uint16_t band_left = eob - band_cum_count_table[tx_size][band] + 1;
198 int shortcut = 0;
199 int next_shortcut = 0;
200
David Barkerd7d78c82016-10-24 10:55:35 +0100201 assert((mb->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700202
Yaowu Xuc27fc142016-08-22 16:08:15 -0700203 token_costs += band;
204
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700205 assert((!plane_type && !plane) || (plane_type && plane));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700206 assert(eob <= default_eob);
207
208 /* Now set up a Viterbi trellis to evaluate alternative roundings. */
209 /* Initialize the sentinel node of the trellis. */
210 tokens[eob][0].rate = 0;
211 tokens[eob][0].error = 0;
212 tokens[eob][0].next = default_eob;
213 tokens[eob][0].token = EOB_TOKEN;
214 tokens[eob][0].qc = 0;
215 tokens[eob][1] = tokens[eob][0];
216
217 for (i = 0; i < eob; i++) {
218 const int rc = scan[i];
Alex Converseda3d94f2017-03-15 14:54:29 -0700219 tokens[i][0].rate = av1_get_token_cost(qcoeff[rc], &t0, cat6_bits);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700220 tokens[i][0].token = t0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700221 token_cache[rc] = av1_pt_energy_class[t0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700222 }
223
224 for (i = eob; i-- > 0;) {
225 int base_bits, dx;
226 int64_t d2;
227 const int rc = scan[i];
Thomas Daviese0f8c552016-11-15 17:28:03 +0000228 int x = qcoeff[rc];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700229#if CONFIG_AOM_QM
230 int iwt = iqmatrix[rc];
Thomas Daviese0f8c552016-11-15 17:28:03 +0000231 dqv = dequant_ptr[rc != 0];
232 dqv = ((iwt * (int)dqv) + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
233#else
234 dqv = dequant_ptr[rc != 0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700235#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700236 next_shortcut = shortcut;
237
238 /* Only add a trellis state for non-zero coefficients. */
239 if (UNLIKELY(x)) {
240 error0 = tokens[next][0].error;
241 error1 = tokens[next][1].error;
242 /* Evaluate the first possibility for this state. */
243 rate0 = tokens[next][0].rate;
244 rate1 = tokens[next][1].rate;
245
246 if (next_shortcut) {
247 /* Consider both possible successor states. */
248 if (next < default_eob) {
249 pt = get_coef_context(nb, token_cache, i + 1);
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000250 rate0 +=
251 get_token_bit_costs(*token_costs, 0, pt, tokens[next][0].token);
252 rate1 +=
253 get_token_bit_costs(*token_costs, 0, pt, tokens[next][1].token);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700254 }
255 UPDATE_RD_COST();
256 /* And pick the best. */
257 best = rd_cost1 < rd_cost0;
258 } else {
259 if (next < default_eob) {
260 pt = get_coef_context(nb, token_cache, i + 1);
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000261 rate0 +=
262 get_token_bit_costs(*token_costs, 0, pt, tokens[next][0].token);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700263 }
264 best = 0;
265 }
266
267 dx = (dqcoeff[rc] - coeff[rc]) * (1 << shift);
Yaowu Xuf883b422016-08-30 14:01:10 -0700268#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700269 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
270 dx >>= xd->bd - 8;
271 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700272#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700273 d2 = (int64_t)dx * dx;
274 tokens[i][0].rate += (best ? rate1 : rate0);
275 tokens[i][0].error = d2 + (best ? error1 : error0);
276 tokens[i][0].next = next;
277 tokens[i][0].qc = x;
278 tokens[i][0].dqc = dqcoeff[rc];
Alex Conversec9d2fcc2017-03-17 17:32:56 -0700279 tokens[i][0].best_index = best;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700280
281 /* Evaluate the second possibility for this state. */
282 rate0 = tokens[next][0].rate;
283 rate1 = tokens[next][1].rate;
284
285 // The threshold of 3 is empirically obtained.
286 if (UNLIKELY(abs(x) > 3)) {
287 shortcut = 0;
288 } else {
289#if CONFIG_NEW_QUANT
Thomas Daviese0f8c552016-11-15 17:28:03 +0000290 shortcut = ((av1_dequant_abscoeff_nuq(abs(x), dqv,
Yaowu Xuf883b422016-08-30 14:01:10 -0700291 dequant_val[band_translate[i]]) >
Yaowu Xuc27fc142016-08-22 16:08:15 -0700292 (abs(coeff[rc]) << shift)) &&
Thomas Daviese0f8c552016-11-15 17:28:03 +0000293 (av1_dequant_abscoeff_nuq(abs(x) - 1, dqv,
Yaowu Xuf883b422016-08-30 14:01:10 -0700294 dequant_val[band_translate[i]]) <
Yaowu Xuc27fc142016-08-22 16:08:15 -0700295 (abs(coeff[rc]) << shift)));
296#else // CONFIG_NEW_QUANT
297#if CONFIG_AOM_QM
298 if ((abs(x) * dequant_ptr[rc != 0] * iwt >
299 ((abs(coeff[rc]) << shift) << AOM_QM_BITS)) &&
300 (abs(x) * dequant_ptr[rc != 0] * iwt <
301 (((abs(coeff[rc]) << shift) + dequant_ptr[rc != 0])
302 << AOM_QM_BITS)))
303#else
304 if ((abs(x) * dequant_ptr[rc != 0] > (abs(coeff[rc]) << shift)) &&
305 (abs(x) * dequant_ptr[rc != 0] <
306 (abs(coeff[rc]) << shift) + dequant_ptr[rc != 0]))
307#endif // CONFIG_AOM_QM
308 shortcut = 1;
309 else
310 shortcut = 0;
311#endif // CONFIG_NEW_QUANT
312 }
313
314 if (shortcut) {
315 sz = -(x < 0);
316 x -= 2 * sz + 1;
317 } else {
318 tokens[i][1] = tokens[i][0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700319 next = i;
320
321 if (UNLIKELY(!(--band_left))) {
322 --band_counts;
323 band_left = *band_counts;
324 --token_costs;
325 }
326 continue;
327 }
328
329 /* Consider both possible successor states. */
330 if (!x) {
331 /* If we reduced this coefficient to zero, check to see if
332 * we need to move the EOB back here.
333 */
334 t0 = tokens[next][0].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
335 t1 = tokens[next][1].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
336 base_bits = 0;
337 } else {
Alex Converseda3d94f2017-03-15 14:54:29 -0700338 base_bits = av1_get_token_cost(x, &t0, cat6_bits);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700339 t1 = t0;
340 }
341
342 if (next_shortcut) {
343 if (LIKELY(next < default_eob)) {
344 if (t0 != EOB_TOKEN) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700345 token_cache[rc] = av1_pt_energy_class[t0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700346 pt = get_coef_context(nb, token_cache, i + 1);
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000347 rate0 += get_token_bit_costs(*token_costs, !x, pt,
348 tokens[next][0].token);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700349 }
350 if (t1 != EOB_TOKEN) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700351 token_cache[rc] = av1_pt_energy_class[t1];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700352 pt = get_coef_context(nb, token_cache, i + 1);
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000353 rate1 += get_token_bit_costs(*token_costs, !x, pt,
354 tokens[next][1].token);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700355 }
356 }
357
358 UPDATE_RD_COST();
359 /* And pick the best. */
360 best = rd_cost1 < rd_cost0;
361 } else {
362 // The two states in next stage are identical.
363 if (next < default_eob && t0 != EOB_TOKEN) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700364 token_cache[rc] = av1_pt_energy_class[t0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700365 pt = get_coef_context(nb, token_cache, i + 1);
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000366 rate0 +=
367 get_token_bit_costs(*token_costs, !x, pt, tokens[next][0].token);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700368 }
369 best = 0;
370 }
371
372#if CONFIG_NEW_QUANT
Thomas Daviese0f8c552016-11-15 17:28:03 +0000373 dx = av1_dequant_coeff_nuq(x, dqv, dequant_val[band_translate[i]]) -
Yaowu Xuc27fc142016-08-22 16:08:15 -0700374 (coeff[rc] << shift);
Yaowu Xuf883b422016-08-30 14:01:10 -0700375#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700376 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
377 dx >>= xd->bd - 8;
378 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700379#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700380#else // CONFIG_NEW_QUANT
Yaowu Xuf883b422016-08-30 14:01:10 -0700381#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700382 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Thomas Daviese0f8c552016-11-15 17:28:03 +0000383 dx -= ((dqv >> (xd->bd - 8)) + sz) ^ sz;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700384 } else {
Thomas Daviese0f8c552016-11-15 17:28:03 +0000385 dx -= (dqv + sz) ^ sz;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700386 }
387#else
Thomas Daviese0f8c552016-11-15 17:28:03 +0000388 dx -= (dqv + sz) ^ sz;
Yaowu Xuf883b422016-08-30 14:01:10 -0700389#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700390#endif // CONFIG_NEW_QUANT
391 d2 = (int64_t)dx * dx;
392
393 tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
394 tokens[i][1].error = d2 + (best ? error1 : error0);
395 tokens[i][1].next = next;
396 tokens[i][1].token = best ? t1 : t0;
397 tokens[i][1].qc = x;
398
399 if (x) {
400#if CONFIG_NEW_QUANT
Yaowu Xuf883b422016-08-30 14:01:10 -0700401 tokens[i][1].dqc = av1_dequant_abscoeff_nuq(
Thomas Daviese0f8c552016-11-15 17:28:03 +0000402 abs(x), dqv, dequant_val[band_translate[i]]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700403 tokens[i][1].dqc = shift ? ROUND_POWER_OF_TWO(tokens[i][1].dqc, shift)
404 : tokens[i][1].dqc;
405 if (sz) tokens[i][1].dqc = -tokens[i][1].dqc;
406#else
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -0800407// The 32x32 transform coefficient uses half quantization step size.
408// Account for the rounding difference in the dequantized coefficeint
409// value when the quantization index is dropped from an even number
410// to an odd number.
Thomas Daviese0f8c552016-11-15 17:28:03 +0000411
412#if CONFIG_AOM_QM
413 tran_low_t offset = dqv >> shift;
414#else
415 tran_low_t offset = dq_step[rc != 0];
416#endif
417 if (shift & x) offset += (dqv & 0x01);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700418
419 if (sz == 0)
420 tokens[i][1].dqc = dqcoeff[rc] - offset;
421 else
422 tokens[i][1].dqc = dqcoeff[rc] + offset;
423#endif // CONFIG_NEW_QUANT
424 } else {
425 tokens[i][1].dqc = 0;
426 }
427
Alex Conversec9d2fcc2017-03-17 17:32:56 -0700428 tokens[i][1].best_index = best;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700429 /* Finally, make this the new head of the trellis. */
430 next = i;
431 } else {
432 /* There's no choice to make for a zero coefficient, so we don't
433 * add a new trellis node, but we do need to update the costs.
434 */
435 t0 = tokens[next][0].token;
436 t1 = tokens[next][1].token;
437 pt = get_coef_context(nb, token_cache, i + 1);
438 /* Update the cost of each path if we're past the EOB token. */
439 if (t0 != EOB_TOKEN) {
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000440 tokens[next][0].rate += get_token_bit_costs(*token_costs, 1, pt, t0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700441 tokens[next][0].token = ZERO_TOKEN;
442 }
443 if (t1 != EOB_TOKEN) {
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000444 tokens[next][1].rate += get_token_bit_costs(*token_costs, 1, pt, t1);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700445 tokens[next][1].token = ZERO_TOKEN;
446 }
Alex Conversec9d2fcc2017-03-17 17:32:56 -0700447 tokens[i][0].best_index = tokens[i][1].best_index = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700448 shortcut = (tokens[next][0].rate != tokens[next][1].rate);
449 /* Don't update next, because we didn't add a new node. */
450 }
451
452 if (UNLIKELY(!(--band_left))) {
453 --band_counts;
454 band_left = *band_counts;
455 --token_costs;
456 }
457 }
458
459 /* Now pick the best path through the whole trellis. */
460 rate0 = tokens[next][0].rate;
461 rate1 = tokens[next][1].rate;
462 error0 = tokens[next][0].error;
463 error1 = tokens[next][1].error;
464 t0 = tokens[next][0].token;
465 t1 = tokens[next][1].token;
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000466 rate0 += get_token_bit_costs(*token_costs, 0, ctx, t0);
467 rate1 += get_token_bit_costs(*token_costs, 0, ctx, t1);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700468 UPDATE_RD_COST();
469 best = rd_cost1 < rd_cost0;
470
471 final_eob = -1;
472
473 for (i = next; i < eob; i = next) {
474 const int x = tokens[i][best].qc;
475 const int rc = scan[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700476 if (x) final_eob = i;
477 qcoeff[rc] = x;
478 dqcoeff[rc] = tokens[i][best].dqc;
479
480 next = tokens[i][best].next;
Alex Conversec9d2fcc2017-03-17 17:32:56 -0700481 best = tokens[i][best].best_index;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700482 }
483 final_eob++;
484
485 mb->plane[plane].eobs[block] = final_eob;
486 assert(final_eob <= default_eob);
487 return final_eob;
Angie Chiang57605532017-04-03 11:51:15 -0700488#else // !CONFIG_PVQ
489 (void)cm;
490 (void)tx_size;
491 (void)ctx;
492 struct macroblock_plane *const p = &mb->plane[plane];
493 return p->eobs[block];
494#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700495}
496
Thomas Daede6ff6af62017-02-03 16:29:24 -0800497#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -0700498#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700499typedef enum QUANT_FUNC {
500 QUANT_FUNC_LOWBD = 0,
501 QUANT_FUNC_HIGHBD = 1,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800502 QUANT_FUNC_TYPES = 2
Yaowu Xuc27fc142016-08-22 16:08:15 -0700503} QUANT_FUNC;
504
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800505static AV1_QUANT_FACADE
506 quant_func_list[AV1_XFORM_QUANT_TYPES][QUANT_FUNC_TYPES] = {
Angie Chiang6a71ad12017-04-03 11:19:00 -0700507#if !CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800508 { av1_quantize_fp_facade, av1_highbd_quantize_fp_facade },
Yaowu Xuf883b422016-08-30 14:01:10 -0700509 { av1_quantize_b_facade, av1_highbd_quantize_b_facade },
510 { av1_quantize_dc_facade, av1_highbd_quantize_dc_facade },
Angie Chiang6a71ad12017-04-03 11:19:00 -0700511#else // !CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800512 { av1_quantize_fp_nuq_facade, av1_highbd_quantize_fp_nuq_facade },
513 { av1_quantize_b_nuq_facade, av1_highbd_quantize_b_nuq_facade },
514 { av1_quantize_dc_nuq_facade, av1_highbd_quantize_dc_nuq_facade },
Angie Chiang6a71ad12017-04-03 11:19:00 -0700515#endif // !CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800516 { NULL, NULL }
517 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700518
Thomas Daede6ff6af62017-02-03 16:29:24 -0800519#else
Yaowu Xu02d4c3b2016-11-07 10:45:56 -0800520
Yaowu Xuc27fc142016-08-22 16:08:15 -0700521typedef enum QUANT_FUNC {
522 QUANT_FUNC_LOWBD = 0,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800523 QUANT_FUNC_TYPES = 1
Yaowu Xuc27fc142016-08-22 16:08:15 -0700524} QUANT_FUNC;
525
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800526static AV1_QUANT_FACADE quant_func_list[AV1_XFORM_QUANT_TYPES]
527 [QUANT_FUNC_TYPES] = {
Angie Chiang6a71ad12017-04-03 11:19:00 -0700528#if !CONFIG_NEW_QUANT
clang-format67948d32016-09-07 22:40:40 -0700529 { av1_quantize_fp_facade },
530 { av1_quantize_b_facade },
531 { av1_quantize_dc_facade },
Angie Chiang6a71ad12017-04-03 11:19:00 -0700532#else // !CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800533 { av1_quantize_fp_nuq_facade },
534 { av1_quantize_b_nuq_facade },
535 { av1_quantize_dc_nuq_facade },
Angie Chiang6a71ad12017-04-03 11:19:00 -0700536#endif // !CONFIG_NEW_QUANT
clang-format67948d32016-09-07 22:40:40 -0700537 { NULL }
538 };
Thomas Daede6ff6af62017-02-03 16:29:24 -0800539#endif // CONFIG_AOM_HIGHBITDEPTH
540#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700541
Angie Chiangff6d8902016-10-21 11:02:09 -0700542void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
543 int blk_row, int blk_col, BLOCK_SIZE plane_bsize,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800544 TX_SIZE tx_size, int ctx,
545 AV1_XFORM_QUANT xform_quant_idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700546 MACROBLOCKD *const xd = &x->e_mbd;
Luc Trudeaub6e94d92017-03-13 15:46:15 -0400547 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800548#if !(CONFIG_PVQ || CONFIG_DAALA_DIST)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700549 const struct macroblock_plane *const p = &x->plane[plane];
550 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yushin Cho77bba8d2016-11-04 16:36:56 -0700551#else
552 struct macroblock_plane *const p = &x->plane[plane];
553 struct macroblockd_plane *const pd = &xd->plane[plane];
554#endif
Luc Trudeau005feb62017-02-22 13:34:01 -0500555 PLANE_TYPE plane_type = get_plane_type(plane);
Angie Chiang752ccce2017-04-09 13:41:13 -0700556 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Luc Trudeaub6e94d92017-03-13 15:46:15 -0400557 const int is_inter = is_inter_block(mbmi);
Angie Chiangff6d8902016-10-21 11:02:09 -0700558 const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700559 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
560 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
561 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
562 uint16_t *const eob = &p->eobs[block];
Jingning Hanae5cfde2016-11-30 12:01:44 -0800563 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700564#if CONFIG_AOM_QM
Luc Trudeaub6e94d92017-03-13 15:46:15 -0400565 int seg_id = mbmi->segment_id;
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700566 const qm_val_t *qmatrix = pd->seg_qmatrix[seg_id][!is_inter][tx_size];
567 const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!is_inter][tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700568#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700569
570 FWD_TXFM_PARAM fwd_txfm_param;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700571
Yushin Cho7a428ba2017-01-12 16:28:49 -0800572#if CONFIG_PVQ || CONFIG_DAALA_DIST
573 uint8_t *dst;
574 int16_t *pred;
575 const int dst_stride = pd->dst.stride;
576 int tx_blk_size;
577 int i, j;
578#endif
579
Yushin Cho77bba8d2016-11-04 16:36:56 -0700580#if !CONFIG_PVQ
581 const int tx2d_size = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700582 QUANT_PARAM qparam;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700583 const int16_t *src_diff;
584
Jingning Han81492262016-12-05 15:48:47 -0800585 src_diff =
586 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Debargha Mukherjee0e119122016-11-04 12:10:23 -0700587 qparam.log_scale = get_tx_scale(tx_size);
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800588#if CONFIG_NEW_QUANT
589 qparam.tx_size = tx_size;
590 qparam.dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
591#endif // CONFIG_NEW_QUANT
592#if CONFIG_AOM_QM
593 qparam.qmatrix = qmatrix;
594 qparam.iqmatrix = iqmatrix;
595#endif // CONFIG_AOM_QM
Yushin Cho77bba8d2016-11-04 16:36:56 -0700596#else
Yushin Cho77bba8d2016-11-04 16:36:56 -0700597 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700598 int skip = 1;
599 PVQ_INFO *pvq_info = NULL;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800600 uint8_t *src;
601 int16_t *src_int16;
602 const int src_stride = p->src.stride;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700603
Yushin Cho6341f5c2017-03-24 14:36:28 -0700604 (void)ctx;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700605 (void)scan_order;
606 (void)qcoeff;
607
608 if (x->pvq_coded) {
609 assert(block < MAX_PVQ_BLOCKS_IN_SB);
610 pvq_info = &x->pvq[block][plane];
611 }
Jingning Han81492262016-12-05 15:48:47 -0800612 src = &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
613 src_int16 =
614 &p->src_int16[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800615
616 // transform block size in pixels
617 tx_blk_size = tx_size_wide[tx_size];
Thomas Daede6ff6af62017-02-03 16:29:24 -0800618#if CONFIG_AOM_HIGHBITDEPTH
619 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
620 for (j = 0; j < tx_blk_size; j++)
621 for (i = 0; i < tx_blk_size; i++)
622 src_int16[diff_stride * j + i] =
623 CONVERT_TO_SHORTPTR(src)[src_stride * j + i];
624 } else {
625#endif // CONFIG_AOM_HIGHBITDEPTH
626 for (j = 0; j < tx_blk_size; j++)
627 for (i = 0; i < tx_blk_size; i++)
628 src_int16[diff_stride * j + i] = src[src_stride * j + i];
629#if CONFIG_AOM_HIGHBITDEPTH
630 }
631#endif // CONFIG_AOM_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -0800632#endif
633
634#if CONFIG_PVQ || CONFIG_DAALA_DIST
635 dst = &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
Jingning Han81492262016-12-05 15:48:47 -0800636 pred = &pd->pred[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Yushin Cho77bba8d2016-11-04 16:36:56 -0700637
638 // transform block size in pixels
639 tx_blk_size = tx_size_wide[tx_size];
640
Thomas Daede6ff6af62017-02-03 16:29:24 -0800641// copy uint8 orig and predicted block to int16 buffer
642// in order to use existing VP10 transform functions
643#if CONFIG_AOM_HIGHBITDEPTH
644 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
645 for (j = 0; j < tx_blk_size; j++)
646 for (i = 0; i < tx_blk_size; i++)
647 pred[diff_stride * j + i] =
648 CONVERT_TO_SHORTPTR(dst)[dst_stride * j + i];
649 } else {
650#endif // CONFIG_AOM_HIGHBITDEPTH
651 for (j = 0; j < tx_blk_size; j++)
652 for (i = 0; i < tx_blk_size; i++)
653 pred[diff_stride * j + i] = dst[dst_stride * j + i];
654#if CONFIG_AOM_HIGHBITDEPTH
655 }
656#endif // CONFIG_AOM_HIGHBITDEPTH
Yushin Cho77bba8d2016-11-04 16:36:56 -0700657#endif
Yushin Cho7a428ba2017-01-12 16:28:49 -0800658
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800659 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700660
661 fwd_txfm_param.tx_type = tx_type;
662 fwd_txfm_param.tx_size = tx_size;
Luc Trudeaub6e94d92017-03-13 15:46:15 -0400663 fwd_txfm_param.lossless = xd->lossless[mbmi->segment_id];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700664
Thomas Daede6ff6af62017-02-03 16:29:24 -0800665#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -0700666#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700667 fwd_txfm_param.bd = xd->bd;
668 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
hui suf11fb882017-03-27 14:56:33 -0700669 av1_highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -0700670 if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700671 if (LIKELY(!x->skip_block)) {
672 quant_func_list[xform_quant_idx][QUANT_FUNC_HIGHBD](
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800673 coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700674 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700675 av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700676 }
677 }
Angie Chiang74e23072017-03-24 14:54:23 -0700678#if CONFIG_LV_MAP
679 p->txb_entropy_ctx[block] =
680 (uint8_t)av1_get_txb_entropy_context(qcoeff, scan_order, *eob);
681#endif // CONFIG_LV_MAP
Yaowu Xuc27fc142016-08-22 16:08:15 -0700682 return;
683 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700684#endif // CONFIG_AOM_HIGHBITDEPTH
hui suf11fb882017-03-27 14:56:33 -0700685 av1_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -0700686 if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700687 if (LIKELY(!x->skip_block)) {
688 quant_func_list[xform_quant_idx][QUANT_FUNC_LOWBD](
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800689 coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700690 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700691 av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700692 }
693 }
Angie Chiang74e23072017-03-24 14:54:23 -0700694#if CONFIG_LV_MAP
695 p->txb_entropy_ctx[block] =
696 (uint8_t)av1_get_txb_entropy_context(qcoeff, scan_order, *eob);
697#endif // CONFIG_LV_MAP
698#else // #if !CONFIG_PVQ
Angie Chiang2cc057c2017-01-03 18:31:47 -0800699 (void)xform_quant_idx;
Thomas Daede6ff6af62017-02-03 16:29:24 -0800700#if CONFIG_AOM_HIGHBITDEPTH
701 fwd_txfm_param.bd = xd->bd;
702 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
hui suf11fb882017-03-27 14:56:33 -0700703 av1_highbd_fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
704 av1_highbd_fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
Thomas Daede6ff6af62017-02-03 16:29:24 -0800705 } else {
706#endif
hui suf11fb882017-03-27 14:56:33 -0700707 av1_fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
708 av1_fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
Thomas Daede6ff6af62017-02-03 16:29:24 -0800709#if CONFIG_AOM_HIGHBITDEPTH
710 }
711#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -0700712
713 // PVQ for inter mode block
ltrudeau472f63f2017-01-12 15:22:32 -0500714 if (!x->skip_block) {
ltrudeaue1c09292017-01-20 15:42:13 -0500715 PVQ_SKIP_TYPE ac_dc_coded =
Thomas Daede6ff6af62017-02-03 16:29:24 -0800716 av1_pvq_encode_helper(x,
ltrudeaue1c09292017-01-20 15:42:13 -0500717 coeff, // target original vector
718 ref_coeff, // reference vector
719 dqcoeff, // de-quantized vector
720 eob, // End of Block marker
721 pd->dequant, // aom's quantizers
722 plane, // image plane
723 tx_size, // block size in log_2 - 2
724 tx_type,
725 &x->rate, // rate measured
726 x->pvq_speed,
727 pvq_info); // PVQ info for a block
728 skip = ac_dc_coded == PVQ_SKIP;
ltrudeau472f63f2017-01-12 15:22:32 -0500729 }
Yushin Cho77bba8d2016-11-04 16:36:56 -0700730 x->pvq_skip[plane] = skip;
731
732 if (!skip) mbmi->skip = 0;
733#endif // #if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700734}
735
Yaowu Xuc27fc142016-08-22 16:08:15 -0700736static void encode_block(int plane, int block, int blk_row, int blk_col,
737 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
738 struct encode_b_args *const args = arg;
Angie Chiangff6d8902016-10-21 11:02:09 -0700739 AV1_COMMON *cm = args->cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700740 MACROBLOCK *const x = args->x;
741 MACROBLOCKD *const xd = &x->e_mbd;
742 int ctx;
743 struct macroblock_plane *const p = &x->plane[plane];
744 struct macroblockd_plane *const pd = &xd->plane[plane];
745 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
746 uint8_t *dst;
Yushin Cho6341f5c2017-03-24 14:36:28 -0700747#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700748 ENTROPY_CONTEXT *a, *l;
Yushin Cho6341f5c2017-03-24 14:36:28 -0700749#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700750#if CONFIG_VAR_TX
Jingning Han9ca05b72017-01-03 14:41:36 -0800751 int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700752#endif
Jingning Han81492262016-12-05 15:48:47 -0800753 dst = &pd->dst
754 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Yushin Cho6341f5c2017-03-24 14:36:28 -0700755
756#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700757 a = &args->ta[blk_col];
758 l = &args->tl[blk_row];
759#if CONFIG_VAR_TX
760 ctx = get_entropy_context(tx_size, a, l);
761#else
762 ctx = combine_entropy_contexts(*a, *l);
763#endif
Yushin Cho6341f5c2017-03-24 14:36:28 -0700764#else
765 ctx = 0;
766#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700767
768#if CONFIG_VAR_TX
Yue Chena1e48dc2016-08-29 17:29:33 -0700769 // Assert not magic number (uninitialized).
Jingning Han9ca05b72017-01-03 14:41:36 -0800770 assert(x->blk_skip[plane][blk_row * bw + blk_col] != 234);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700771
Jingning Han9ca05b72017-01-03 14:41:36 -0800772 if (x->blk_skip[plane][blk_row * bw + blk_col] == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700773#else
774 {
775#endif
Angie Chiangff6d8902016-10-21 11:02:09 -0700776 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800777 ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700778 }
779#if CONFIG_VAR_TX
780 else {
781 p->eobs[block] = 0;
782 }
783#endif
Yushin Cho6341f5c2017-03-24 14:36:28 -0700784
Yushin Cho77bba8d2016-11-04 16:36:56 -0700785#if !CONFIG_PVQ
Angie Chiangdb0c7d42017-03-23 16:05:37 -0700786 if (p->eobs[block] && !xd->lossless[xd->mi[0]->mbmi.segment_id])
787 av1_optimize_b(cm, x, plane, block, tx_size, ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700788
Angie Chiangdb0c7d42017-03-23 16:05:37 -0700789 av1_set_txb_context(x, plane, block, tx_size, a, l);
790
Yaowu Xuc27fc142016-08-22 16:08:15 -0700791 if (p->eobs[block]) *(args->skip) = 0;
792
793 if (p->eobs[block] == 0) return;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700794#else
795 (void)ctx;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700796 if (!x->pvq_skip[plane]) *(args->skip) = 0;
797
798 if (x->pvq_skip[plane]) return;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700799#endif
Angie Chiang752ccce2017-04-09 13:41:13 -0700800 TX_TYPE tx_type = get_tx_type(pd->plane_type, xd, block, tx_size);
Angie Chiang44d7e662017-04-06 11:07:53 -0700801 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, dst,
802 pd->dst.stride, p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700803}
804
805#if CONFIG_VAR_TX
806static void encode_block_inter(int plane, int block, int blk_row, int blk_col,
807 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
808 void *arg) {
809 struct encode_b_args *const args = arg;
810 MACROBLOCK *const x = args->x;
811 MACROBLOCKD *const xd = &x->e_mbd;
812 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
813 const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
814 const struct macroblockd_plane *const pd = &xd->plane[plane];
815 const int tx_row = blk_row >> (1 - pd->subsampling_y);
816 const int tx_col = blk_col >> (1 - pd->subsampling_x);
817 TX_SIZE plane_tx_size;
Jingning Hanf65b8702016-10-31 12:13:20 -0700818 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
819 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700820
821 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
822
Debargha Mukherjee2f123402016-08-30 17:43:38 -0700823 plane_tx_size =
824 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
825 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700826
827 if (tx_size == plane_tx_size) {
828 encode_block(plane, block, blk_row, blk_col, plane_bsize, tx_size, arg);
829 } else {
Jingning Hana9336322016-11-02 15:45:07 -0700830 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
831 // This is the square transform block partition entry point.
832 int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700833 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700834 assert(bsl > 0);
Jingning Hand3fada82016-11-22 10:46:55 -0800835 assert(tx_size < TX_SIZES_ALL);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700836
837 for (i = 0; i < 4; ++i) {
Jingning Hande953b92016-10-25 12:35:43 -0700838 const int offsetr = blk_row + ((i >> 1) * bsl);
839 const int offsetc = blk_col + ((i & 0x01) * bsl);
Jingning Hande953b92016-10-25 12:35:43 -0700840 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700841
842 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
843
Jingning Han98d6a1f2016-11-03 12:47:47 -0700844 encode_block_inter(plane, block, offsetr, offsetc, plane_bsize, sub_txs,
845 arg);
846 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700847 }
848 }
849}
850#endif
851
Angie Chiangff6d8902016-10-21 11:02:09 -0700852typedef struct encode_block_pass1_args {
853 AV1_COMMON *cm;
854 MACROBLOCK *x;
855} encode_block_pass1_args;
856
Yaowu Xuc27fc142016-08-22 16:08:15 -0700857static void encode_block_pass1(int plane, int block, int blk_row, int blk_col,
858 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
859 void *arg) {
Angie Chiangff6d8902016-10-21 11:02:09 -0700860 encode_block_pass1_args *args = (encode_block_pass1_args *)arg;
861 AV1_COMMON *cm = args->cm;
862 MACROBLOCK *const x = args->x;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700863 MACROBLOCKD *const xd = &x->e_mbd;
864 struct macroblock_plane *const p = &x->plane[plane];
865 struct macroblockd_plane *const pd = &xd->plane[plane];
866 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
867 uint8_t *dst;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800868 int ctx = 0;
Jingning Han81492262016-12-05 15:48:47 -0800869 dst = &pd->dst
870 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700871
Angie Chiangff6d8902016-10-21 11:02:09 -0700872 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800873 ctx, AV1_XFORM_QUANT_B);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700874#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700875 if (p->eobs[block] > 0) {
Yushin Cho77bba8d2016-11-04 16:36:56 -0700876#else
877 if (!x->pvq_skip[plane]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -0700878 {
879 int tx_blk_size;
880 int i, j;
881 // transform block size in pixels
882 tx_blk_size = tx_size_wide[tx_size];
883
Thomas Daede6ff6af62017-02-03 16:29:24 -0800884// Since av1 does not have separate function which does inverse transform
885// but av1_inv_txfm_add_*x*() also does addition of predicted image to
886// inverse transformed image,
887// pass blank dummy image to av1_inv_txfm_add_*x*(), i.e. set dst as zeros
888#if CONFIG_AOM_HIGHBITDEPTH
889 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
890 for (j = 0; j < tx_blk_size; j++)
891 for (i = 0; i < tx_blk_size; i++)
892 CONVERT_TO_SHORTPTR(dst)[j * pd->dst.stride + i] = 0;
893 } else {
894#endif // CONFIG_AOM_HIGHBITDEPTH
895 for (j = 0; j < tx_blk_size; j++)
896 for (i = 0; i < tx_blk_size; i++) dst[j * pd->dst.stride + i] = 0;
897#if CONFIG_AOM_HIGHBITDEPTH
898 }
899#endif // CONFIG_AOM_HIGHBITDEPTH
Yushin Cho77bba8d2016-11-04 16:36:56 -0700900 }
Jingning Handf072642016-11-08 16:43:38 -0800901#endif // !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -0700902#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700903 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
904 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700905 av1_highbd_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block],
906 xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700907 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700908 av1_highbd_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block],
909 xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700910 }
911 return;
912 }
Jingning Hane38d63c2016-11-08 12:05:29 -0800913#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700914 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700915 av1_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700916 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700917 av1_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700918 }
919 }
920}
921
Angie Chiangff6d8902016-10-21 11:02:09 -0700922void av1_encode_sby_pass1(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
923 encode_block_pass1_args args = { cm, x };
Yaowu Xuf883b422016-08-30 14:01:10 -0700924 av1_subtract_plane(x, bsize, 0);
925 av1_foreach_transformed_block_in_plane(&x->e_mbd, bsize, 0,
Angie Chiangff6d8902016-10-21 11:02:09 -0700926 encode_block_pass1, &args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700927}
928
Jingning Han18c53c82017-02-17 14:49:57 -0800929void av1_encode_sb(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize,
930 const int mi_row, const int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700931 MACROBLOCKD *const xd = &x->e_mbd;
932 struct optimize_ctx ctx;
933 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -0700934 struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700935 int plane;
936
937 mbmi->skip = 1;
938
939 if (x->skip) return;
940
941 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
Jingning Han31b6a4f2017-02-23 11:05:53 -0800942#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han2d2dac22017-04-11 09:41:10 -0700943 const int subsampling_x = xd->plane[plane].subsampling_x;
944 const int subsampling_y = xd->plane[plane].subsampling_y;
945
946 if (!is_chroma_reference(mi_row, mi_col, bsize, subsampling_x,
947 subsampling_y))
Jingning Hanea576f32017-02-21 23:05:09 -0800948 continue;
Jingning Han2d2dac22017-04-11 09:41:10 -0700949
950 bsize = scale_chroma_bsize(bsize, subsampling_x, subsampling_y);
Jingning Hanea576f32017-02-21 23:05:09 -0800951#else
952 (void)mi_row;
953 (void)mi_col;
954#endif
955
Yaowu Xuc27fc142016-08-22 16:08:15 -0700956#if CONFIG_VAR_TX
957 // TODO(jingning): Clean this up.
958 const struct macroblockd_plane *const pd = &xd->plane[plane];
959 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Hande953b92016-10-25 12:35:43 -0700960 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
961 const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
Jingning Han70e5f3f2016-11-09 17:03:07 -0800962 const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700963 const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
Jingning Hande953b92016-10-25 12:35:43 -0700964 const int bw = block_size_wide[txb_size] >> tx_size_wide_log2[0];
965 const int bh = block_size_high[txb_size] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700966 int idx, idy;
967 int block = 0;
Jingning Hande953b92016-10-25 12:35:43 -0700968 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Jingning Han581d1692017-01-05 16:03:54 -0800969 av1_get_entropy_contexts(bsize, 0, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700970#else
971 const struct macroblockd_plane *const pd = &xd->plane[plane];
Angie Chiang7fcfee42017-02-24 15:51:03 -0800972 const TX_SIZE tx_size = get_tx_size(plane, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -0700973 av1_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700974#endif
Jingning Hanea576f32017-02-21 23:05:09 -0800975
Yushin Cho77bba8d2016-11-04 16:36:56 -0700976#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -0700977 av1_subtract_plane(x, bsize, plane);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700978#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700979 arg.ta = ctx.ta[plane];
980 arg.tl = ctx.tl[plane];
981
982#if CONFIG_VAR_TX
Jingning Hanfe45b212016-11-22 10:30:23 -0800983 for (idy = 0; idy < mi_height; idy += bh) {
984 for (idx = 0; idx < mi_width; idx += bw) {
985 encode_block_inter(plane, block, idy, idx, plane_bsize, max_tx_size,
986 &arg);
987 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700988 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700989 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700990#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700991 av1_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
992 &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700993#endif
994 }
995}
996
997#if CONFIG_SUPERTX
Angie Chiangff6d8902016-10-21 11:02:09 -0700998void av1_encode_sb_supertx(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700999 MACROBLOCKD *const xd = &x->e_mbd;
1000 struct optimize_ctx ctx;
1001 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001002 struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001003 int plane;
1004
1005 mbmi->skip = 1;
1006 if (x->skip) return;
1007
1008 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1009 const struct macroblockd_plane *const pd = &xd->plane[plane];
1010#if CONFIG_VAR_TX
1011 const TX_SIZE tx_size = TX_4X4;
1012#else
Angie Chiang7fcfee42017-02-24 15:51:03 -08001013 const TX_SIZE tx_size = get_tx_size(plane, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001014#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001015 av1_subtract_plane(x, bsize, plane);
1016 av1_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001017 arg.ta = ctx.ta[plane];
1018 arg.tl = ctx.tl[plane];
Yaowu Xuf883b422016-08-30 14:01:10 -07001019 av1_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
1020 &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001021 }
1022}
1023#endif // CONFIG_SUPERTX
1024
Yushin Cho6341f5c2017-03-24 14:36:28 -07001025#if !CONFIG_PVQ
Angie Chiangdb0c7d42017-03-23 16:05:37 -07001026void av1_set_txb_context(MACROBLOCK *x, int plane, int block, TX_SIZE tx_size,
Angie Chiang36aca332017-03-23 14:16:24 -07001027 ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
Angie Chiang36aca332017-03-23 14:16:24 -07001028 (void)tx_size;
Angie Chiang36aca332017-03-23 14:16:24 -07001029 struct macroblock_plane *p = &x->plane[plane];
Yushin Cho6341f5c2017-03-24 14:36:28 -07001030
Angie Chiang74e23072017-03-24 14:54:23 -07001031#if !CONFIG_LV_MAP
Angie Chiang36aca332017-03-23 14:16:24 -07001032 *a = *l = p->eobs[block] > 0;
Angie Chiang74e23072017-03-24 14:54:23 -07001033#else // !CONFIG_LV_MAP
1034 *a = *l = p->txb_entropy_ctx[block];
1035#endif // !CONFIG_LV_MAP
Angie Chiangdb0c7d42017-03-23 16:05:37 -07001036
1037#if CONFIG_VAR_TX || CONFIG_LV_MAP
1038 int i;
1039 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) a[i] = a[0];
1040
1041 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) l[i] = l[0];
1042#endif
Angie Chiang36aca332017-03-23 14:16:24 -07001043}
Yushin Cho6341f5c2017-03-24 14:36:28 -07001044#endif
Angie Chiang36aca332017-03-23 14:16:24 -07001045
1046static void encode_block_intra_and_set_context(int plane, int block,
1047 int blk_row, int blk_col,
1048 BLOCK_SIZE plane_bsize,
1049 TX_SIZE tx_size, void *arg) {
1050 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
1051 arg);
Yushin Cho6341f5c2017-03-24 14:36:28 -07001052#if !CONFIG_PVQ
Angie Chiang36aca332017-03-23 14:16:24 -07001053 struct encode_b_args *const args = arg;
1054 MACROBLOCK *x = args->x;
1055 ENTROPY_CONTEXT *a = &args->ta[blk_col];
1056 ENTROPY_CONTEXT *l = &args->tl[blk_row];
Angie Chiangdb0c7d42017-03-23 16:05:37 -07001057 av1_set_txb_context(x, plane, block, tx_size, a, l);
Yushin Cho6341f5c2017-03-24 14:36:28 -07001058#endif
Angie Chiang36aca332017-03-23 14:16:24 -07001059}
1060
Yaowu Xuf883b422016-08-30 14:01:10 -07001061void av1_encode_block_intra(int plane, int block, int blk_row, int blk_col,
1062 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
1063 void *arg) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001064 struct encode_b_args *const args = arg;
Angie Chiangff6d8902016-10-21 11:02:09 -07001065 AV1_COMMON *cm = args->cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001066 MACROBLOCK *const x = args->x;
1067 MACROBLOCKD *const xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001068 struct macroblock_plane *const p = &x->plane[plane];
1069 struct macroblockd_plane *const pd = &xd->plane[plane];
1070 tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05001071 PLANE_TYPE plane_type = get_plane_type(plane);
Angie Chiang752ccce2017-04-09 13:41:13 -07001072 const TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001073 uint16_t *eob = &p->eobs[block];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001074 const int dst_stride = pd->dst.stride;
Angie Chiangf87e43f2017-04-02 16:51:19 -07001075 uint8_t *dst =
1076 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
Angie Chiang752ccce2017-04-09 13:41:13 -07001077 av1_predict_intra_block_facade(xd, plane, block, blk_col, blk_row, tx_size);
Angie Chiangf87e43f2017-04-02 16:51:19 -07001078 av1_subtract_txb(x, plane, plane_bsize, blk_col, blk_row, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001079
Angie Chiang36aca332017-03-23 14:16:24 -07001080 const ENTROPY_CONTEXT *a = &args->ta[blk_col];
1081 const ENTROPY_CONTEXT *l = &args->tl[blk_row];
Angie Chiang57605532017-04-03 11:51:15 -07001082 int ctx = combine_entropy_contexts(*a, *l);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001083 if (args->enable_optimize_b) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001084 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001085 ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001086 if (p->eobs[block]) {
Angie Chiang36aca332017-03-23 14:16:24 -07001087 av1_optimize_b(cm, x, plane, block, tx_size, ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001088 }
1089 } else {
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001090 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1091 ctx, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001092 }
1093
Angie Chiang57605532017-04-03 11:51:15 -07001094#if CONFIG_PVQ
Yushin Cho3827fdd2016-11-09 15:50:23 -08001095 // *(args->skip) == mbmi->skip
1096 if (!x->pvq_skip[plane]) *(args->skip) = 0;
1097
1098 if (x->pvq_skip[plane]) return;
Angie Chiang50910f62017-04-03 12:31:34 -07001099#endif // CONFIG_PVQ
Angie Chiangd92d4bf2017-04-02 17:49:18 -07001100 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, dst, dst_stride,
1101 *eob);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001102#if !CONFIG_PVQ
1103 if (*eob) *(args->skip) = 0;
1104#else
1105// Note : *(args->skip) == mbmi->skip
1106#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001107}
1108
Angie Chiangff6d8902016-10-21 11:02:09 -07001109void av1_encode_intra_block_plane(AV1_COMMON *cm, MACROBLOCK *x,
1110 BLOCK_SIZE bsize, int plane,
Jingning Han18c53c82017-02-17 14:49:57 -08001111 int enable_optimize_b, const int mi_row,
1112 const int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001113 const MACROBLOCKD *const xd = &x->e_mbd;
Guillaume Martrese50d9dd2016-12-18 18:26:47 +01001114 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE] = { 0 };
1115 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001116
Angie Chiangff6d8902016-10-21 11:02:09 -07001117 struct encode_b_args arg = {
1118 cm, x, NULL, &xd->mi[0]->mbmi.skip, ta, tl, enable_optimize_b
1119 };
Jingning Han18c53c82017-02-17 14:49:57 -08001120
1121#if CONFIG_CB4X4
Jingning Hand3a64432017-04-06 17:04:17 -07001122 if (!is_chroma_reference(mi_row, mi_col, bsize,
1123 xd->plane[plane].subsampling_x,
1124 xd->plane[plane].subsampling_y))
Jingning Han18c53c82017-02-17 14:49:57 -08001125 return;
1126#else
1127 (void)mi_row;
1128 (void)mi_col;
1129#endif
1130
Yaowu Xuc27fc142016-08-22 16:08:15 -07001131 if (enable_optimize_b) {
1132 const struct macroblockd_plane *const pd = &xd->plane[plane];
Angie Chiang7fcfee42017-02-24 15:51:03 -08001133 const TX_SIZE tx_size = get_tx_size(plane, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07001134 av1_get_entropy_contexts(bsize, tx_size, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001135 }
Angie Chiang36aca332017-03-23 14:16:24 -07001136 av1_foreach_transformed_block_in_plane(
1137 xd, bsize, plane, encode_block_intra_and_set_context, &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001138}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001139
1140#if CONFIG_PVQ
Thomas Daede6ff6af62017-02-03 16:29:24 -08001141PVQ_SKIP_TYPE av1_pvq_encode_helper(MACROBLOCK *x, tran_low_t *const coeff,
1142 tran_low_t *ref_coeff,
1143 tran_low_t *const dqcoeff, uint16_t *eob,
1144 const int16_t *quant, int plane,
1145 int tx_size, TX_TYPE tx_type, int *rate,
1146 int speed, PVQ_INFO *pvq_info) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001147 const int tx_blk_size = tx_size_wide[tx_size];
Thomas Daede6ff6af62017-02-03 16:29:24 -08001148 daala_enc_ctx *daala_enc = &x->daala_enc;
ltrudeaue1c09292017-01-20 15:42:13 -05001149 PVQ_SKIP_TYPE ac_dc_coded;
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001150 int coeff_shift = 3 - get_tx_scale(tx_size);
Thomas Daede6ff6af62017-02-03 16:29:24 -08001151 int hbd_downshift = 0;
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001152 int rounding_mask;
Yushin Cho70669122016-12-08 09:53:14 -10001153 int pvq_dc_quant;
1154 int use_activity_masking = daala_enc->use_activity_masking;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001155 int tell;
1156 int has_dc_skip = 1;
1157 int i;
1158 int off = od_qm_offset(tx_size, plane ? 1 : 0);
Yushin Cho70669122016-12-08 09:53:14 -10001159
Thomas Daede1dbda1b2017-02-06 16:06:29 -08001160 DECLARE_ALIGNED(16, tran_low_t, coeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1161 DECLARE_ALIGNED(16, tran_low_t, ref_coeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1162 DECLARE_ALIGNED(16, tran_low_t, dqcoeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001163
Yushin Cho48f84db2016-11-07 21:20:17 -08001164 DECLARE_ALIGNED(16, int32_t, in_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1165 DECLARE_ALIGNED(16, int32_t, ref_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1166 DECLARE_ALIGNED(16, int32_t, out_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001167
Thomas Daede6ff6af62017-02-03 16:29:24 -08001168#if CONFIG_AOM_HIGHBITDEPTH
1169 hbd_downshift = x->e_mbd.bd - 8;
1170#endif
1171
1172 assert(OD_COEFF_SHIFT >= 4);
Yushin Cho70669122016-12-08 09:53:14 -10001173 // DC quantizer for PVQ
1174 if (use_activity_masking)
clang-format55ce9e02017-02-15 22:27:12 -08001175 pvq_dc_quant =
Thomas Daede6ff6af62017-02-03 16:29:24 -08001176 OD_MAXI(1, (quant[0] << (OD_COEFF_SHIFT - 3) >> hbd_downshift) *
clang-format55ce9e02017-02-15 22:27:12 -08001177 daala_enc->state
1178 .pvq_qm_q4[plane][od_qm_get_index(tx_size, 0)] >>
1179 4);
Yushin Cho70669122016-12-08 09:53:14 -10001180 else
Thomas Daede6ff6af62017-02-03 16:29:24 -08001181 pvq_dc_quant =
1182 OD_MAXI(1, quant[0] << (OD_COEFF_SHIFT - 3) >> hbd_downshift);
Yushin Cho70669122016-12-08 09:53:14 -10001183
Yushin Cho77bba8d2016-11-04 16:36:56 -07001184 *eob = 0;
1185
Nathan E. Egge6675be02016-12-21 13:02:43 -05001186#if CONFIG_DAALA_EC
1187 tell = od_ec_enc_tell_frac(&daala_enc->w.ec);
1188#else
1189#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
1190#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001191
1192 // Change coefficient ordering for pvq encoding.
1193 od_raster_to_coding_order(coeff_pvq, tx_blk_size, tx_type, coeff,
1194 tx_blk_size);
1195 od_raster_to_coding_order(ref_coeff_pvq, tx_blk_size, tx_type, ref_coeff,
1196 tx_blk_size);
1197
1198 // copy int16 inputs to int32
1199 for (i = 0; i < tx_blk_size * tx_blk_size; i++) {
Timothy B. Terriberry4e6a8f32017-02-24 11:00:59 -08001200 ref_int32[i] =
Thomas Daede6ff6af62017-02-03 16:29:24 -08001201 AOM_SIGNED_SHL(ref_coeff_pvq[i], OD_COEFF_SHIFT - coeff_shift) >>
1202 hbd_downshift;
1203 in_int32[i] = AOM_SIGNED_SHL(coeff_pvq[i], OD_COEFF_SHIFT - coeff_shift) >>
1204 hbd_downshift;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001205 }
1206
Yushin Cho77bba8d2016-11-04 16:36:56 -07001207 if (abs(in_int32[0] - ref_int32[0]) < pvq_dc_quant * 141 / 256) { /* 0.55 */
1208 out_int32[0] = 0;
1209 } else {
1210 out_int32[0] = OD_DIV_R0(in_int32[0] - ref_int32[0], pvq_dc_quant);
1211 }
1212
Thomas Daede6ff6af62017-02-03 16:29:24 -08001213 ac_dc_coded =
1214 od_pvq_encode(daala_enc, ref_int32, in_int32, out_int32,
1215 OD_MAXI(1, quant[0] << (OD_COEFF_SHIFT - 3) >>
1216 hbd_downshift), // scale/quantizer
1217 OD_MAXI(1, quant[1] << (OD_COEFF_SHIFT - 3) >>
1218 hbd_downshift), // scale/quantizer
1219 plane,
1220 tx_size, OD_PVQ_BETA[use_activity_masking][plane][tx_size],
1221 OD_ROBUST_STREAM,
Yushin Cho31b980a2017-03-23 10:28:09 -07001222 0, // is_keyframe,
Thomas Daede6ff6af62017-02-03 16:29:24 -08001223 daala_enc->state.qm + off, daala_enc->state.qm_inv + off,
1224 speed, // speed
1225 pvq_info);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001226
1227 // Encode residue of DC coeff, if required.
1228 if (!has_dc_skip || out_int32[0]) {
Yushin Choc49ef3a2017-03-13 17:27:25 -07001229 generic_encode(&daala_enc->w, &daala_enc->state.adapt->model_dc[plane],
Yushin Cho77bba8d2016-11-04 16:36:56 -07001230 abs(out_int32[0]) - has_dc_skip, -1,
Yushin Choc49ef3a2017-03-13 17:27:25 -07001231 &daala_enc->state.adapt->ex_dc[plane][tx_size][0], 2);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001232 }
1233 if (out_int32[0]) {
Nathan E. Egge6675be02016-12-21 13:02:43 -05001234 aom_write_bit(&daala_enc->w, out_int32[0] < 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001235 }
1236
1237 // need to save quantized residue of DC coeff
1238 // so that final pvq bitstream writing can know whether DC is coded.
1239 if (pvq_info) pvq_info->dq_dc_residue = out_int32[0];
1240
1241 out_int32[0] = out_int32[0] * pvq_dc_quant;
1242 out_int32[0] += ref_int32[0];
1243
1244 // copy int32 result back to int16
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001245 assert(OD_COEFF_SHIFT > coeff_shift);
1246 rounding_mask = (1 << (OD_COEFF_SHIFT - coeff_shift - 1)) - 1;
1247 for (i = 0; i < tx_blk_size * tx_blk_size; i++) {
Thomas Daede6ff6af62017-02-03 16:29:24 -08001248 out_int32[i] = AOM_SIGNED_SHL(out_int32[i], hbd_downshift);
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001249 dqcoeff_pvq[i] = (out_int32[i] + (out_int32[i] < 0) + rounding_mask) >>
1250 (OD_COEFF_SHIFT - coeff_shift);
1251 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001252
1253 // Back to original coefficient order
1254 od_coding_order_to_raster(dqcoeff, tx_blk_size, tx_type, dqcoeff_pvq,
1255 tx_blk_size);
1256
1257 *eob = tx_blk_size * tx_blk_size;
1258
Nathan E. Egge6675be02016-12-21 13:02:43 -05001259#if CONFIG_DAALA_EC
1260 *rate = (od_ec_enc_tell_frac(&daala_enc->w.ec) - tell)
Yushin Cho77bba8d2016-11-04 16:36:56 -07001261 << (AV1_PROB_COST_SHIFT - OD_BITRES);
Nathan E. Egge6675be02016-12-21 13:02:43 -05001262#else
1263#error "CONFIG_PVQ currently requires CONFIG_DAALA_EC."
1264#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001265 assert(*rate >= 0);
Yushin Cho5c207292017-02-16 15:01:33 -08001266
ltrudeau472f63f2017-01-12 15:22:32 -05001267 return ac_dc_coded;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001268}
1269
1270void av1_store_pvq_enc_info(PVQ_INFO *pvq_info, int *qg, int *theta,
1271 int *max_theta, int *k, od_coeff *y, int nb_bands,
1272 const int *off, int *size, int skip_rest,
1273 int skip_dir,
1274 int bs) { // block size in log_2 -2
1275 int i;
1276 const int tx_blk_size = tx_size_wide[bs];
1277
1278 for (i = 0; i < nb_bands; i++) {
1279 pvq_info->qg[i] = qg[i];
1280 pvq_info->theta[i] = theta[i];
1281 pvq_info->max_theta[i] = max_theta[i];
1282 pvq_info->k[i] = k[i];
1283 pvq_info->off[i] = off[i];
1284 pvq_info->size[i] = size[i];
1285 }
1286
1287 memcpy(pvq_info->y, y, tx_blk_size * tx_blk_size * sizeof(od_coeff));
1288
1289 pvq_info->nb_bands = nb_bands;
1290 pvq_info->skip_rest = skip_rest;
1291 pvq_info->skip_dir = skip_dir;
1292 pvq_info->bs = bs;
1293}
1294#endif