blob: e7f4d313d05e52faab1b6010724ed219593d67f9 [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
Luc Trudeaue3980282017-04-25 23:17:21 -040041#if CONFIG_CFL
42#include "av1/common/cfl.h"
43#endif
44
Jingning Hane325abd2016-12-01 09:35:10 -080045// Check if one needs to use c version subtraction.
46static int check_subtract_block_size(int w, int h) { return w < 4 || h < 4; }
47
Angie Chiang19407b52017-04-02 15:27:57 -070048static void subtract_block(const MACROBLOCKD *xd, int rows, int cols,
49 int16_t *diff, ptrdiff_t diff_stride,
50 const uint8_t *src8, ptrdiff_t src_stride,
51 const uint8_t *pred8, ptrdiff_t pred_stride) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020052#if !CONFIG_HIGHBITDEPTH
Angie Chiang19407b52017-04-02 15:27:57 -070053 (void)xd;
54#endif
55
56 if (check_subtract_block_size(rows, cols)) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020057#if CONFIG_HIGHBITDEPTH
Angie Chiang19407b52017-04-02 15:27:57 -070058 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
59 aom_highbd_subtract_block_c(rows, cols, diff, diff_stride, src8,
60 src_stride, pred8, pred_stride, xd->bd);
61 return;
62 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020063#endif // CONFIG_HIGHBITDEPTH
Angie Chiang19407b52017-04-02 15:27:57 -070064 aom_subtract_block_c(rows, cols, diff, diff_stride, src8, src_stride, pred8,
65 pred_stride);
66
67 return;
68 }
69
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020070#if CONFIG_HIGHBITDEPTH
Angie Chiang19407b52017-04-02 15:27:57 -070071 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
72 aom_highbd_subtract_block(rows, cols, diff, diff_stride, src8, src_stride,
73 pred8, pred_stride, xd->bd);
74 return;
75 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +020076#endif // CONFIG_HIGHBITDEPTH
Angie Chiang19407b52017-04-02 15:27:57 -070077 aom_subtract_block(rows, cols, diff, diff_stride, src8, src_stride, pred8,
78 pred_stride);
79}
80
Angie Chiangf87e43f2017-04-02 16:51:19 -070081void av1_subtract_txb(MACROBLOCK *x, int plane, BLOCK_SIZE plane_bsize,
82 int blk_col, int blk_row, TX_SIZE tx_size) {
83 MACROBLOCKD *const xd = &x->e_mbd;
84 struct macroblock_plane *const p = &x->plane[plane];
85 const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane];
86 const int diff_stride = block_size_wide[plane_bsize];
87 const int src_stride = p->src.stride;
88 const int dst_stride = pd->dst.stride;
89 const int tx1d_width = tx_size_wide[tx_size];
90 const int tx1d_height = tx_size_high[tx_size];
91 uint8_t *dst =
92 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
93 uint8_t *src =
94 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
95 int16_t *src_diff =
96 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
97 subtract_block(xd, tx1d_height, tx1d_width, src_diff, diff_stride, src,
98 src_stride, dst, dst_stride);
99}
100
Yaowu Xuf883b422016-08-30 14:01:10 -0700101void av1_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700102 struct macroblock_plane *const p = &x->plane[plane];
103 const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane];
104 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Hanae5cfde2016-11-30 12:01:44 -0800105 const int bw = block_size_wide[plane_bsize];
106 const int bh = block_size_high[plane_bsize];
Angie Chiang19407b52017-04-02 15:27:57 -0700107 const MACROBLOCKD *xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700108
Angie Chiang19407b52017-04-02 15:27:57 -0700109 subtract_block(xd, bh, bw, p->src_diff, bw, p->src.buf, p->src.stride,
110 pd->dst.buf, pd->dst.stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700111}
112
Yaowu Xuc27fc142016-08-22 16:08:15 -0700113// These numbers are empirically obtained.
114static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] = {
Thomas Davies10525752017-03-06 12:10:46 +0000115 { 10, 7 }, { 8, 5 },
Yaowu Xuc27fc142016-08-22 16:08:15 -0700116};
117
Yaowu Xu42350322017-05-05 11:12:19 -0700118static INLINE unsigned int get_token_bit_costs(
119 unsigned int token_costs[2][COEFF_CONTEXTS][ENTROPY_TOKENS], int skip_eob,
120 int ctx, int token) {
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000121 (void)skip_eob;
122 return token_costs[token == ZERO_TOKEN || token == EOB_TOKEN][ctx][token];
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000123}
124
Angie Chiang1c96e822017-05-31 14:40:55 -0700125#if !CONFIG_LV_MAP
Dake He97f56642017-03-29 16:46:51 -0700126
Angie Chiang7dec6c42017-05-03 17:58:17 -0700127static int optimize_b_greedy(const AV1_COMMON *cm, MACROBLOCK *mb, int plane,
Jingning Han19b5c8f2017-07-06 15:10:12 -0700128 int blk_row, int blk_col, int block,
129 TX_SIZE tx_size, int ctx) {
Dake He97f56642017-03-29 16:46:51 -0700130 MACROBLOCKD *const xd = &mb->e_mbd;
131 struct macroblock_plane *const p = &mb->plane[plane];
132 struct macroblockd_plane *const pd = &xd->plane[plane];
133 const int ref = is_inter_block(&xd->mi[0]->mbmi);
Dake He97f56642017-03-29 16:46:51 -0700134 uint8_t token_cache[MAX_TX_SQUARE];
135 const tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
136 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
137 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
138 const int eob = p->eobs[block];
139 const PLANE_TYPE plane_type = pd->plane_type;
140 const int16_t *const dequant_ptr = pd->dequant;
141 const uint8_t *const band_translate = get_band_translate(tx_size);
Jingning Han19b5c8f2017-07-06 15:10:12 -0700142 TX_TYPE tx_type =
143 av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, tx_size);
Dake He97f56642017-03-29 16:46:51 -0700144 const SCAN_ORDER *const scan_order =
Angie Chiangbd99b382017-06-20 15:11:16 -0700145 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
Dake He97f56642017-03-29 16:46:51 -0700146 const int16_t *const scan = scan_order->scan;
147 const int16_t *const nb = scan_order->neighbors;
148 int dqv;
Jingning Hanff705452017-04-27 11:32:15 -0700149 const int shift = av1_get_tx_scale(tx_size);
Dake He97f56642017-03-29 16:46:51 -0700150#if CONFIG_AOM_QM
151 int seg_id = xd->mi[0]->mbmi.segment_id;
Thomas Daviesbe44e512017-06-07 11:41:07 +0100152 // Use a flat matrix (i.e. no weighting) for 1D and Identity transforms
153 const qm_val_t *iqmatrix =
154 IS_2D_TRANSFORM(tx_type)
155 ? pd->seg_iqmatrix[seg_id][!ref][tx_size]
156 : cm->giqmatrix[NUM_QM_LEVELS - 1][0][0][tx_size];
Dake He97f56642017-03-29 16:46:51 -0700157#endif
158#if CONFIG_NEW_QUANT
159 int dq = get_dq_profile_from_ctx(mb->qindex, ctx, ref, plane_type);
160 const dequant_val_type_nuq *dequant_val = pd->dequant_val_nuq[dq];
Dake He97f56642017-03-29 16:46:51 -0700161#endif // CONFIG_NEW_QUANT
162 int sz = 0;
Dake He97f56642017-03-29 16:46:51 -0700163 int64_t rd_cost0, rd_cost1;
164 int16_t t0, t1;
165 int i, final_eob;
Dake He97f56642017-03-29 16:46:51 -0700166 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
Dake He97f56642017-03-29 16:46:51 -0700167 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
168 mb->token_costs[txsize_sqr_map[tx_size]][plane_type][ref];
169 const int default_eob = tx_size_2d[tx_size];
170
Angie Chiang7dec6c42017-05-03 17:58:17 -0700171 assert(mb->qindex > 0);
Dake He97f56642017-03-29 16:46:51 -0700172
173 assert((!plane_type && !plane) || (plane_type && plane));
174 assert(eob <= default_eob);
175
176 int64_t rdmult = (mb->rdmult * plane_rd_mult[ref][plane_type]) >> 1;
Dake He97f56642017-03-29 16:46:51 -0700177
178 int64_t rate0, rate1;
179 for (i = 0; i < eob; i++) {
180 const int rc = scan[i];
Kyle Siefring627e2fd2017-07-02 15:43:07 -0400181 token_cache[rc] = av1_pt_energy_class[av1_get_token(qcoeff[rc])];
Dake He97f56642017-03-29 16:46:51 -0700182 }
Dake He97f56642017-03-29 16:46:51 -0700183
184 unsigned int(*token_costs_ptr)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
185 token_costs;
186
187 final_eob = 0;
188
189 int64_t eob_cost0, eob_cost1;
Kyle Siefring627e2fd2017-07-02 15:43:07 -0400190 tran_low_t before_best_eob_qc = 0;
191 tran_low_t before_best_eob_dqc = 0;
Dake He97f56642017-03-29 16:46:51 -0700192
193 const int ctx0 = ctx;
194 /* Record the r-d cost */
195 int64_t accu_rate = 0;
Urvang Joshi6eb35eb2017-06-14 13:28:56 -0700196 // Initialized to the worst possible error for the largest transform size.
197 // This ensures that it never goes negative.
198 int64_t accu_error = ((int64_t)1) << 50;
Dake He97f56642017-03-29 16:46:51 -0700199
200 rate0 = get_token_bit_costs(*(token_costs_ptr + band_translate[0]), 0, ctx0,
201 EOB_TOKEN);
Urvang Joshi70006e42017-06-14 16:08:55 -0700202 int64_t best_block_rd_cost = RDCOST(rdmult, rate0, accu_error);
Dake He97f56642017-03-29 16:46:51 -0700203
204 // int64_t best_block_rd_cost_all0 = best_block_rd_cost;
Dake He97f56642017-03-29 16:46:51 -0700205 int x_prev = 1;
Dake He97f56642017-03-29 16:46:51 -0700206 for (i = 0; i < eob; i++) {
207 const int rc = scan[i];
208 int x = qcoeff[rc];
209 sz = -(x < 0);
210
211 int band_cur = band_translate[i];
212 int ctx_cur = (i == 0) ? ctx : get_coef_context(nb, token_cache, i);
213 int token_tree_sel_cur = (x_prev == 0);
214
215 if (x == 0) {
216 // no need to search when x == 0
Kyle Siefring627e2fd2017-07-02 15:43:07 -0400217 int token = av1_get_token(x);
218 rate0 = get_token_bit_costs(*(token_costs_ptr + band_cur),
219 token_tree_sel_cur, ctx_cur, token);
Dake He97f56642017-03-29 16:46:51 -0700220 accu_rate += rate0;
221 x_prev = 0;
222 // accu_error does not change when x==0
223 } else {
224 /* Computing distortion
225 */
226 // compute the distortion for the first candidate
227 // and the distortion for quantizing to 0.
Jingning Han32d26bc2017-06-11 07:50:39 -0700228 int dx0 = abs(coeff[rc]) * (1 << shift);
Dake He97f56642017-03-29 16:46:51 -0700229#if CONFIG_HIGHBITDEPTH
230 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
231 dx0 >>= xd->bd - 8;
232 }
233#endif
234 int64_t d0 = (int64_t)dx0 * dx0;
235
236 int x_a = x - 2 * sz - 1;
237 int64_t d2, d2_a;
238
239 int dx;
240
241#if CONFIG_AOM_QM
242 int iwt = iqmatrix[rc];
243 dqv = dequant_ptr[rc != 0];
244 dqv = ((iwt * (int)dqv) + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
245#else
246 dqv = dequant_ptr[rc != 0];
247#endif
248
249 dx = (dqcoeff[rc] - coeff[rc]) * (1 << shift);
250#if CONFIG_HIGHBITDEPTH
251 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Jingning Han32d26bc2017-06-11 07:50:39 -0700252 int dx_sign = dx < 0 ? 1 : 0;
253 dx = abs(dx) >> (xd->bd - 8);
254 if (dx_sign) dx = -dx;
Dake He97f56642017-03-29 16:46:51 -0700255 }
256#endif // CONFIG_HIGHBITDEPTH
257 d2 = (int64_t)dx * dx;
258
259 /* compute the distortion for the second candidate
260 * x_a = x - 2 * sz + 1;
261 */
262 if (x_a != 0) {
263#if CONFIG_NEW_QUANT
264 dx = av1_dequant_coeff_nuq(x, dqv, dequant_val[band_translate[i]]) -
265 (coeff[rc] << shift);
266#if CONFIG_HIGHBITDEPTH
267 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
268 dx >>= xd->bd - 8;
269 }
270#endif // CONFIG_HIGHBITDEPTH
271#else // CONFIG_NEW_QUANT
272#if CONFIG_HIGHBITDEPTH
273 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
274 dx -= ((dqv >> (xd->bd - 8)) + sz) ^ sz;
275 } else {
276 dx -= (dqv + sz) ^ sz;
277 }
278#else
279 dx -= (dqv + sz) ^ sz;
280#endif // CONFIG_HIGHBITDEPTH
281#endif // CONFIG_NEW_QUANT
282 d2_a = (int64_t)dx * dx;
283 } else {
284 d2_a = d0;
285 }
286 /* Computing rates and r-d cost
287 */
288
289 int best_x, best_eob_x;
290 int64_t base_bits, next_bits0, next_bits1;
291 int64_t next_eob_bits0, next_eob_bits1;
292
293 // rate cost of x
294 base_bits = av1_get_token_cost(x, &t0, cat6_bits);
295 rate0 = base_bits + get_token_bit_costs(*(token_costs_ptr + band_cur),
296 token_tree_sel_cur, ctx_cur, t0);
297
298 base_bits = av1_get_token_cost(x_a, &t1, cat6_bits);
299 rate1 = base_bits + get_token_bit_costs(*(token_costs_ptr + band_cur),
300 token_tree_sel_cur, ctx_cur, t1);
301
302 next_bits0 = 0;
303 next_bits1 = 0;
304 next_eob_bits0 = 0;
305 next_eob_bits1 = 0;
306
307 if (i < default_eob - 1) {
308 int ctx_next, token_tree_sel_next;
309 int band_next = band_translate[i + 1];
Kyle Siefring627e2fd2017-07-02 15:43:07 -0400310 int token_next =
311 i + 1 != eob ? av1_get_token(qcoeff[scan[i + 1]]) : EOB_TOKEN;
Dake He97f56642017-03-29 16:46:51 -0700312
313 token_cache[rc] = av1_pt_energy_class[t0];
314 ctx_next = get_coef_context(nb, token_cache, i + 1);
315 token_tree_sel_next = (x == 0);
316
Kyle Siefring627e2fd2017-07-02 15:43:07 -0400317 next_bits0 =
318 get_token_bit_costs(*(token_costs_ptr + band_next),
319 token_tree_sel_next, ctx_next, token_next);
Dake He97f56642017-03-29 16:46:51 -0700320 next_eob_bits0 =
321 get_token_bit_costs(*(token_costs_ptr + band_next),
322 token_tree_sel_next, ctx_next, EOB_TOKEN);
323
324 token_cache[rc] = av1_pt_energy_class[t1];
325 ctx_next = get_coef_context(nb, token_cache, i + 1);
326 token_tree_sel_next = (x_a == 0);
327
Kyle Siefring627e2fd2017-07-02 15:43:07 -0400328 next_bits1 =
329 get_token_bit_costs(*(token_costs_ptr + band_next),
330 token_tree_sel_next, ctx_next, token_next);
Dake He97f56642017-03-29 16:46:51 -0700331
332 if (x_a != 0) {
333 next_eob_bits1 =
334 get_token_bit_costs(*(token_costs_ptr + band_next),
335 token_tree_sel_next, ctx_next, EOB_TOKEN);
336 }
337 }
338
Urvang Joshi70006e42017-06-14 16:08:55 -0700339 rd_cost0 = RDCOST(rdmult, (rate0 + next_bits0), d2);
340 rd_cost1 = RDCOST(rdmult, (rate1 + next_bits1), d2_a);
Dake He97f56642017-03-29 16:46:51 -0700341
342 best_x = (rd_cost1 < rd_cost0);
343
Urvang Joshi70006e42017-06-14 16:08:55 -0700344 eob_cost0 = RDCOST(rdmult, (accu_rate + rate0 + next_eob_bits0),
Dake He97f56642017-03-29 16:46:51 -0700345 (accu_error + d2 - d0));
346 eob_cost1 = eob_cost0;
347 if (x_a != 0) {
Urvang Joshi70006e42017-06-14 16:08:55 -0700348 eob_cost1 = RDCOST(rdmult, (accu_rate + rate1 + next_eob_bits1),
Dake He97f56642017-03-29 16:46:51 -0700349 (accu_error + d2_a - d0));
350 best_eob_x = (eob_cost1 < eob_cost0);
351 } else {
352 best_eob_x = 0;
353 }
354
355 int dqc, dqc_a = 0;
356
357 dqc = dqcoeff[rc];
358 if (best_x + best_eob_x) {
359 if (x_a != 0) {
360#if CONFIG_NEW_QUANT
361 dqc_a = av1_dequant_abscoeff_nuq(abs(x_a), dqv,
362 dequant_val[band_translate[i]]);
363 dqc_a = shift ? ROUND_POWER_OF_TWO(dqc_a, shift) : dqc_a;
364 if (sz) dqc_a = -dqc_a;
365#else
David Barkerc747a782017-05-24 12:46:08 +0100366 if (x_a < 0)
367 dqc_a = -((-x_a * dqv) >> shift);
Dake He97f56642017-03-29 16:46:51 -0700368 else
David Barkerc747a782017-05-24 12:46:08 +0100369 dqc_a = (x_a * dqv) >> shift;
Dake He97f56642017-03-29 16:46:51 -0700370#endif // CONFIG_NEW_QUANT
371 } else {
372 dqc_a = 0;
373 } // if (x_a != 0)
374 }
375
376 // record the better quantized value
377 if (best_x) {
378 qcoeff[rc] = x_a;
379 dqcoeff[rc] = dqc_a;
380
381 accu_rate += rate1;
382 accu_error += d2_a - d0;
383 assert(d2_a <= d0);
384
385 token_cache[rc] = av1_pt_energy_class[t1];
386 } else {
387 accu_rate += rate0;
388 accu_error += d2 - d0;
389 assert(d2 <= d0);
390
391 token_cache[rc] = av1_pt_energy_class[t0];
392 }
Urvang Joshi6eb35eb2017-06-14 13:28:56 -0700393 assert(accu_error >= 0);
Dake He97f56642017-03-29 16:46:51 -0700394
395 x_prev = qcoeff[rc];
396
397 // determine whether to move the eob position to i+1
Kyle Siefring627e2fd2017-07-02 15:43:07 -0400398 int use_a = (x_a != 0) && (best_eob_x);
399 int64_t best_eob_cost_i = use_a ? eob_cost1 : eob_cost0;
Dake He97f56642017-03-29 16:46:51 -0700400
401 if (best_eob_cost_i < best_block_rd_cost) {
402 best_block_rd_cost = best_eob_cost_i;
403 final_eob = i + 1;
Kyle Siefring627e2fd2017-07-02 15:43:07 -0400404 if (use_a) {
405 before_best_eob_qc = x_a;
406 before_best_eob_dqc = dqc_a;
407 } else {
408 before_best_eob_qc = x;
409 before_best_eob_dqc = dqc;
410 }
Dake He97f56642017-03-29 16:46:51 -0700411 }
412 } // if (x==0)
413 } // for (i)
414
415 assert(final_eob <= eob);
416 if (final_eob > 0) {
Kyle Siefring627e2fd2017-07-02 15:43:07 -0400417 assert(before_best_eob_qc != 0);
Dake He97f56642017-03-29 16:46:51 -0700418 i = final_eob - 1;
419 int rc = scan[i];
Kyle Siefring627e2fd2017-07-02 15:43:07 -0400420 qcoeff[rc] = before_best_eob_qc;
421 dqcoeff[rc] = before_best_eob_dqc;
Dake He97f56642017-03-29 16:46:51 -0700422 }
423
424 for (i = final_eob; i < eob; i++) {
425 int rc = scan[i];
426 qcoeff[rc] = 0;
427 dqcoeff[rc] = 0;
428 }
429
430 mb->plane[plane].eobs[block] = final_eob;
431 return final_eob;
Dake He97f56642017-03-29 16:46:51 -0700432}
Angie Chiang1c96e822017-05-31 14:40:55 -0700433#endif // !CONFIG_LV_MAP
Dake He97f56642017-03-29 16:46:51 -0700434
Jingning Han7eab9ff2017-07-06 10:12:54 -0700435int av1_optimize_b(const AV1_COMMON *cm, MACROBLOCK *mb, int plane, int blk_row,
436 int blk_col, int block, BLOCK_SIZE plane_bsize,
437 TX_SIZE tx_size, const ENTROPY_CONTEXT *a,
438 const ENTROPY_CONTEXT *l) {
Angie Chiang7dec6c42017-05-03 17:58:17 -0700439 MACROBLOCKD *const xd = &mb->e_mbd;
440 struct macroblock_plane *const p = &mb->plane[plane];
441 const int eob = p->eobs[block];
442 assert((mb->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
443 if (eob == 0) return eob;
444 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return eob;
Jingning Hanaba246d2017-06-14 12:00:16 -0700445
Angie Chiang1c96e822017-05-31 14:40:55 -0700446#if CONFIG_PVQ
447 (void)cm;
448 (void)tx_size;
449 (void)a;
450 (void)l;
451 return eob;
452#endif
Angie Chiang3511c372017-05-31 12:47:07 -0700453
Angie Chiang1c96e822017-05-31 14:40:55 -0700454#if !CONFIG_LV_MAP
455 (void)plane_bsize;
Jingning Han7eab9ff2017-07-06 10:12:54 -0700456 (void)blk_row;
457 (void)blk_col;
Angie Chiang3511c372017-05-31 12:47:07 -0700458#if CONFIG_VAR_TX
459 int ctx = get_entropy_context(tx_size, a, l);
460#else
461 int ctx = combine_entropy_contexts(*a, *l);
Urvang Joshi09302f52017-06-08 14:24:59 -0700462#endif // CONFIG_VAR_TX
Jingning Han19b5c8f2017-07-06 15:10:12 -0700463 return optimize_b_greedy(cm, mb, plane, blk_row, blk_col, block, tx_size,
464 ctx);
Angie Chiang1c96e822017-05-31 14:40:55 -0700465#else // !CONFIG_LV_MAP
466 TXB_CTX txb_ctx;
467 get_txb_ctx(plane_bsize, tx_size, plane, a, l, &txb_ctx);
Jingning Han7eab9ff2017-07-06 10:12:54 -0700468 return av1_optimize_txb(cm, mb, plane, blk_row, blk_col, block, tx_size,
469 &txb_ctx);
Angie Chiang1c96e822017-05-31 14:40:55 -0700470#endif // !CONFIG_LV_MAP
Angie Chiang7dec6c42017-05-03 17:58:17 -0700471}
472
Thomas Daede6ff6af62017-02-03 16:29:24 -0800473#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700474typedef enum QUANT_FUNC {
475 QUANT_FUNC_LOWBD = 0,
476 QUANT_FUNC_HIGHBD = 1,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800477 QUANT_FUNC_TYPES = 2
Yaowu Xuc27fc142016-08-22 16:08:15 -0700478} QUANT_FUNC;
479
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800480static AV1_QUANT_FACADE
481 quant_func_list[AV1_XFORM_QUANT_TYPES][QUANT_FUNC_TYPES] = {
Angie Chiang6a71ad12017-04-03 11:19:00 -0700482#if !CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800483 { av1_quantize_fp_facade, av1_highbd_quantize_fp_facade },
Yaowu Xuf883b422016-08-30 14:01:10 -0700484 { av1_quantize_b_facade, av1_highbd_quantize_b_facade },
485 { av1_quantize_dc_facade, av1_highbd_quantize_dc_facade },
Angie Chiang6a71ad12017-04-03 11:19:00 -0700486#else // !CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800487 { av1_quantize_fp_nuq_facade, av1_highbd_quantize_fp_nuq_facade },
488 { av1_quantize_b_nuq_facade, av1_highbd_quantize_b_nuq_facade },
489 { av1_quantize_dc_nuq_facade, av1_highbd_quantize_dc_nuq_facade },
Angie Chiang6a71ad12017-04-03 11:19:00 -0700490#endif // !CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800491 { NULL, NULL }
492 };
Yi Luo0f4195c2017-06-27 16:07:28 -0700493#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700494
Yi Luo0f4195c2017-06-27 16:07:28 -0700495typedef void (*fwdTxfmFunc)(const int16_t *diff, tran_low_t *coeff, int stride,
Lester Lu27319b62017-07-10 16:57:15 -0700496 TxfmParam *txfm_param);
Yi Luo0f4195c2017-06-27 16:07:28 -0700497static const fwdTxfmFunc fwd_txfm_func[2] = { av1_fwd_txfm,
498 av1_highbd_fwd_txfm };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700499
Angie Chiangff6d8902016-10-21 11:02:09 -0700500void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
501 int blk_row, int blk_col, BLOCK_SIZE plane_bsize,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800502 TX_SIZE tx_size, int ctx,
503 AV1_XFORM_QUANT xform_quant_idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700504 MACROBLOCKD *const xd = &x->e_mbd;
Luc Trudeaub6e94d92017-03-13 15:46:15 -0400505 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yushin Chob7b60c52017-07-14 16:18:52 -0700506#if !(CONFIG_PVQ || CONFIG_DIST_8X8)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700507 const struct macroblock_plane *const p = &x->plane[plane];
508 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yushin Cho77bba8d2016-11-04 16:36:56 -0700509#else
510 struct macroblock_plane *const p = &x->plane[plane];
511 struct macroblockd_plane *const pd = &xd->plane[plane];
512#endif
Luc Trudeau005feb62017-02-22 13:34:01 -0500513 PLANE_TYPE plane_type = get_plane_type(plane);
Jingning Han19b5c8f2017-07-06 15:10:12 -0700514 TX_TYPE tx_type =
515 av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, tx_size);
Angie Chiangbd99b382017-06-20 15:11:16 -0700516
517#if CONFIG_AOM_QM || CONFIG_NEW_QUANT
Luc Trudeaub6e94d92017-03-13 15:46:15 -0400518 const int is_inter = is_inter_block(mbmi);
Angie Chiangbd99b382017-06-20 15:11:16 -0700519#endif
520
521 const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700522 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
523 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
524 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
525 uint16_t *const eob = &p->eobs[block];
Jingning Hanae5cfde2016-11-30 12:01:44 -0800526 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700527#if CONFIG_AOM_QM
Luc Trudeaub6e94d92017-03-13 15:46:15 -0400528 int seg_id = mbmi->segment_id;
Thomas Daviesbe44e512017-06-07 11:41:07 +0100529 // Use a flat matrix (i.e. no weighting) for 1D and Identity transforms
530 const qm_val_t *qmatrix =
531 IS_2D_TRANSFORM(tx_type) ? pd->seg_qmatrix[seg_id][!is_inter][tx_size]
532 : cm->gqmatrix[NUM_QM_LEVELS - 1][0][0][tx_size];
533 const qm_val_t *iqmatrix =
534 IS_2D_TRANSFORM(tx_type)
535 ? pd->seg_iqmatrix[seg_id][!is_inter][tx_size]
536 : cm->giqmatrix[NUM_QM_LEVELS - 1][0][0][tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700537#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700538
Lester Lu27319b62017-07-10 16:57:15 -0700539 TxfmParam txfm_param;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700540
Sarah Parker5b8e6d22017-07-24 15:30:53 -0700541#if CONFIG_PVQ || CONFIG_DIST_8X8 || CONFIG_LGT || CONFIG_MRC_TX
Yushin Cho7a428ba2017-01-12 16:28:49 -0800542 uint8_t *dst;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800543 const int dst_stride = pd->dst.stride;
Yushin Chob7b60c52017-07-14 16:18:52 -0700544#if CONFIG_PVQ || CONFIG_DIST_8X8
Lester Lu708c1ec2017-06-14 14:54:49 -0700545 int16_t *pred;
Yushin Cho1c602b32017-06-07 17:57:14 -0700546 const int txw = tx_size_wide[tx_size];
547 const int txh = tx_size_high[tx_size];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800548 int i, j;
549#endif
Lester Lu708c1ec2017-06-14 14:54:49 -0700550#endif
Yushin Cho7a428ba2017-01-12 16:28:49 -0800551
Yushin Cho77bba8d2016-11-04 16:36:56 -0700552#if !CONFIG_PVQ
553 const int tx2d_size = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700554 QUANT_PARAM qparam;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700555 const int16_t *src_diff;
556
Jingning Han81492262016-12-05 15:48:47 -0800557 src_diff =
558 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Jingning Hanff705452017-04-27 11:32:15 -0700559 qparam.log_scale = av1_get_tx_scale(tx_size);
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800560#if CONFIG_NEW_QUANT
561 qparam.tx_size = tx_size;
562 qparam.dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
563#endif // CONFIG_NEW_QUANT
564#if CONFIG_AOM_QM
565 qparam.qmatrix = qmatrix;
566 qparam.iqmatrix = iqmatrix;
567#endif // CONFIG_AOM_QM
Yushin Cho77bba8d2016-11-04 16:36:56 -0700568#else
Yushin Cho77bba8d2016-11-04 16:36:56 -0700569 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700570 int skip = 1;
571 PVQ_INFO *pvq_info = NULL;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800572 uint8_t *src;
573 int16_t *src_int16;
574 const int src_stride = p->src.stride;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700575
Yushin Cho6341f5c2017-03-24 14:36:28 -0700576 (void)ctx;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700577 (void)scan_order;
578 (void)qcoeff;
579
580 if (x->pvq_coded) {
581 assert(block < MAX_PVQ_BLOCKS_IN_SB);
582 pvq_info = &x->pvq[block][plane];
583 }
Jingning Han81492262016-12-05 15:48:47 -0800584 src = &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
585 src_int16 =
586 &p->src_int16[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800587
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200588#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800589 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yushin Cho1c602b32017-06-07 17:57:14 -0700590 for (j = 0; j < txh; j++)
591 for (i = 0; i < txw; i++)
Thomas Daede6ff6af62017-02-03 16:29:24 -0800592 src_int16[diff_stride * j + i] =
593 CONVERT_TO_SHORTPTR(src)[src_stride * j + i];
594 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200595#endif // CONFIG_HIGHBITDEPTH
Yushin Cho1c602b32017-06-07 17:57:14 -0700596 for (j = 0; j < txh; j++)
597 for (i = 0; i < txw; i++)
Thomas Daede6ff6af62017-02-03 16:29:24 -0800598 src_int16[diff_stride * j + i] = src[src_stride * j + i];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200599#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800600 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200601#endif // CONFIG_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -0800602#endif
603
Sarah Parker5b8e6d22017-07-24 15:30:53 -0700604#if CONFIG_PVQ || CONFIG_DIST_8X8 || CONFIG_LGT || CONFIG_MRC_TX
Yushin Cho7a428ba2017-01-12 16:28:49 -0800605 dst = &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
Yushin Chob7b60c52017-07-14 16:18:52 -0700606#if CONFIG_PVQ || CONFIG_DIST_8X8
Jingning Han81492262016-12-05 15:48:47 -0800607 pred = &pd->pred[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Yushin Cho77bba8d2016-11-04 16:36:56 -0700608
Thomas Daede6ff6af62017-02-03 16:29:24 -0800609// copy uint8 orig and predicted block to int16 buffer
610// in order to use existing VP10 transform functions
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200611#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800612 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yushin Cho1c602b32017-06-07 17:57:14 -0700613 for (j = 0; j < txh; j++)
614 for (i = 0; i < txw; i++)
Thomas Daede6ff6af62017-02-03 16:29:24 -0800615 pred[diff_stride * j + i] =
616 CONVERT_TO_SHORTPTR(dst)[dst_stride * j + i];
617 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200618#endif // CONFIG_HIGHBITDEPTH
Yushin Cho1c602b32017-06-07 17:57:14 -0700619 for (j = 0; j < txh; j++)
620 for (i = 0; i < txw; i++)
Thomas Daede6ff6af62017-02-03 16:29:24 -0800621 pred[diff_stride * j + i] = dst[dst_stride * j + i];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200622#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800623 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200624#endif // CONFIG_HIGHBITDEPTH
Yushin Chob7b60c52017-07-14 16:18:52 -0700625#endif // CONFIG_PVQ || CONFIG_DIST_8X8
Sarah Parker5b8e6d22017-07-24 15:30:53 -0700626#endif // CONFIG_PVQ || CONFIG_DIST_8X8 || CONFIG_LGT || CONFIG_MRC_TX
Yushin Cho7a428ba2017-01-12 16:28:49 -0800627
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800628 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700629
Lester Lu27319b62017-07-10 16:57:15 -0700630 txfm_param.tx_type = tx_type;
631 txfm_param.tx_size = tx_size;
632 txfm_param.lossless = xd->lossless[mbmi->segment_id];
Sarah Parker5b8e6d22017-07-24 15:30:53 -0700633#if CONFIG_MRC_TX || CONFIG_LGT
Lester Lu27319b62017-07-10 16:57:15 -0700634 txfm_param.dst = dst;
635 txfm_param.stride = dst_stride;
Sarah Parker5b8e6d22017-07-24 15:30:53 -0700636#endif // CONFIG_MRC_TX || CONFIG_LGT
637#if CONFIG_LGT
638 txfm_param.is_inter = is_inter_block(mbmi);
Lester Lu27319b62017-07-10 16:57:15 -0700639 txfm_param.mode = get_prediction_mode(xd->mi[0], plane, tx_size, block);
Lester Lu708c1ec2017-06-14 14:54:49 -0700640#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700641
Thomas Daede6ff6af62017-02-03 16:29:24 -0800642#if !CONFIG_PVQ
Lester Lu27319b62017-07-10 16:57:15 -0700643 txfm_param.bd = xd->bd;
Yi Luo0f4195c2017-06-27 16:07:28 -0700644 const int is_hbd = get_bitdepth_data_path_index(xd);
Lester Lu27319b62017-07-10 16:57:15 -0700645 fwd_txfm_func[is_hbd](src_diff, coeff, diff_stride, &txfm_param);
Yi Luo0f4195c2017-06-27 16:07:28 -0700646
Yaowu Xuf883b422016-08-30 14:01:10 -0700647 if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700648 if (LIKELY(!x->skip_block)) {
Yi Luo0f4195c2017-06-27 16:07:28 -0700649 quant_func_list[xform_quant_idx][is_hbd](
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800650 coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700651 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700652 av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700653 }
654 }
Angie Chiang74e23072017-03-24 14:54:23 -0700655#if CONFIG_LV_MAP
656 p->txb_entropy_ctx[block] =
657 (uint8_t)av1_get_txb_entropy_context(qcoeff, scan_order, *eob);
658#endif // CONFIG_LV_MAP
Yi Luo0f4195c2017-06-27 16:07:28 -0700659 return;
660#else // CONFIG_PVQ
Angie Chiang2cc057c2017-01-03 18:31:47 -0800661 (void)xform_quant_idx;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200662#if CONFIG_HIGHBITDEPTH
Lester Lu27319b62017-07-10 16:57:15 -0700663 txfm_param.bd = xd->bd;
Thomas Daede6ff6af62017-02-03 16:29:24 -0800664 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Lester Lu27319b62017-07-10 16:57:15 -0700665 av1_highbd_fwd_txfm(src_int16, coeff, diff_stride, &txfm_param);
666 av1_highbd_fwd_txfm(pred, ref_coeff, diff_stride, &txfm_param);
Thomas Daede6ff6af62017-02-03 16:29:24 -0800667 } else {
668#endif
Lester Lu27319b62017-07-10 16:57:15 -0700669 av1_fwd_txfm(src_int16, coeff, diff_stride, &txfm_param);
670 av1_fwd_txfm(pred, ref_coeff, diff_stride, &txfm_param);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200671#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800672 }
673#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -0700674
675 // PVQ for inter mode block
ltrudeau472f63f2017-01-12 15:22:32 -0500676 if (!x->skip_block) {
ltrudeaue1c09292017-01-20 15:42:13 -0500677 PVQ_SKIP_TYPE ac_dc_coded =
Thomas Daede6ff6af62017-02-03 16:29:24 -0800678 av1_pvq_encode_helper(x,
ltrudeaue1c09292017-01-20 15:42:13 -0500679 coeff, // target original vector
680 ref_coeff, // reference vector
681 dqcoeff, // de-quantized vector
682 eob, // End of Block marker
683 pd->dequant, // aom's quantizers
684 plane, // image plane
685 tx_size, // block size in log_2 - 2
686 tx_type,
687 &x->rate, // rate measured
688 x->pvq_speed,
689 pvq_info); // PVQ info for a block
690 skip = ac_dc_coded == PVQ_SKIP;
ltrudeau472f63f2017-01-12 15:22:32 -0500691 }
Yushin Cho77bba8d2016-11-04 16:36:56 -0700692 x->pvq_skip[plane] = skip;
693
694 if (!skip) mbmi->skip = 0;
695#endif // #if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700696}
697
Yaowu Xuc27fc142016-08-22 16:08:15 -0700698static void encode_block(int plane, int block, int blk_row, int blk_col,
699 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
700 struct encode_b_args *const args = arg;
Angie Chiangff6d8902016-10-21 11:02:09 -0700701 AV1_COMMON *cm = args->cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700702 MACROBLOCK *const x = args->x;
703 MACROBLOCKD *const xd = &x->e_mbd;
704 int ctx;
705 struct macroblock_plane *const p = &x->plane[plane];
706 struct macroblockd_plane *const pd = &xd->plane[plane];
707 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
708 uint8_t *dst;
Yushin Cho6341f5c2017-03-24 14:36:28 -0700709#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700710 ENTROPY_CONTEXT *a, *l;
Yushin Cho6341f5c2017-03-24 14:36:28 -0700711#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700712#if CONFIG_VAR_TX
Jingning Han9ca05b72017-01-03 14:41:36 -0800713 int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700714#endif
Jingning Han81492262016-12-05 15:48:47 -0800715 dst = &pd->dst
716 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Yushin Cho6341f5c2017-03-24 14:36:28 -0700717
718#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700719 a = &args->ta[blk_col];
720 l = &args->tl[blk_row];
721#if CONFIG_VAR_TX
722 ctx = get_entropy_context(tx_size, a, l);
723#else
724 ctx = combine_entropy_contexts(*a, *l);
725#endif
Yushin Cho6341f5c2017-03-24 14:36:28 -0700726#else
727 ctx = 0;
728#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700729
730#if CONFIG_VAR_TX
Yue Chena1e48dc2016-08-29 17:29:33 -0700731 // Assert not magic number (uninitialized).
Jingning Han9ca05b72017-01-03 14:41:36 -0800732 assert(x->blk_skip[plane][blk_row * bw + blk_col] != 234);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700733
Jingning Han9ca05b72017-01-03 14:41:36 -0800734 if (x->blk_skip[plane][blk_row * bw + blk_col] == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700735#else
736 {
737#endif
Angie Chiangff6d8902016-10-21 11:02:09 -0700738 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800739 ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700740 }
741#if CONFIG_VAR_TX
742 else {
743 p->eobs[block] = 0;
744 }
745#endif
Yushin Cho6341f5c2017-03-24 14:36:28 -0700746
Yushin Cho77bba8d2016-11-04 16:36:56 -0700747#if !CONFIG_PVQ
Jingning Han7eab9ff2017-07-06 10:12:54 -0700748 av1_optimize_b(cm, x, plane, blk_row, blk_col, block, plane_bsize, tx_size, a,
749 l);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700750
Angie Chiangdb0c7d42017-03-23 16:05:37 -0700751 av1_set_txb_context(x, plane, block, tx_size, a, l);
752
Yaowu Xuc27fc142016-08-22 16:08:15 -0700753 if (p->eobs[block]) *(args->skip) = 0;
754
755 if (p->eobs[block] == 0) return;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700756#else
757 (void)ctx;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700758 if (!x->pvq_skip[plane]) *(args->skip) = 0;
759
760 if (x->pvq_skip[plane]) return;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700761#endif
Jingning Han19b5c8f2017-07-06 15:10:12 -0700762 TX_TYPE tx_type =
763 av1_get_tx_type(pd->plane_type, xd, blk_row, blk_col, block, tx_size);
Lester Lu708c1ec2017-06-14 14:54:49 -0700764#if CONFIG_LGT
765 PREDICTION_MODE mode = get_prediction_mode(xd->mi[0], plane, tx_size, block);
766 av1_inverse_transform_block(xd, dqcoeff, mode, tx_type, tx_size, dst,
767 pd->dst.stride, p->eobs[block]);
768#else
Angie Chiang44d7e662017-04-06 11:07:53 -0700769 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, dst,
770 pd->dst.stride, p->eobs[block]);
Lester Lu708c1ec2017-06-14 14:54:49 -0700771#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700772}
773
774#if CONFIG_VAR_TX
775static void encode_block_inter(int plane, int block, int blk_row, int blk_col,
776 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
777 void *arg) {
778 struct encode_b_args *const args = arg;
779 MACROBLOCK *const x = args->x;
780 MACROBLOCKD *const xd = &x->e_mbd;
781 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
782 const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
783 const struct macroblockd_plane *const pd = &xd->plane[plane];
784 const int tx_row = blk_row >> (1 - pd->subsampling_y);
785 const int tx_col = blk_col >> (1 - pd->subsampling_x);
786 TX_SIZE plane_tx_size;
Jingning Hanf65b8702016-10-31 12:13:20 -0700787 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
788 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700789
790 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
791
Debargha Mukherjee2f123402016-08-30 17:43:38 -0700792 plane_tx_size =
793 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
794 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700795
796 if (tx_size == plane_tx_size) {
797 encode_block(plane, block, blk_row, blk_col, plane_bsize, tx_size, arg);
798 } else {
Alex Conversee16b2662017-05-24 14:00:00 -0700799 assert(tx_size < TX_SIZES_ALL);
Yue Chend6bdd462017-07-19 16:05:43 -0700800#if CONFIG_RECT_TX_EXT
801 int is_qttx = plane_tx_size == quarter_txsize_lookup[plane_bsize];
802 const TX_SIZE sub_txs = is_qttx ? plane_tx_size : sub_tx_size_map[tx_size];
803 if (is_qttx) assert(blk_row == 0 && blk_col == 0 && block == 0);
804#else
Jingning Hana9336322016-11-02 15:45:07 -0700805 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
Alex Conversee16b2662017-05-24 14:00:00 -0700806 assert(sub_txs < tx_size);
Yue Chend6bdd462017-07-19 16:05:43 -0700807#endif
Jingning Hana9336322016-11-02 15:45:07 -0700808 // This is the square transform block partition entry point.
809 int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700810 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700811 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700812
813 for (i = 0; i < 4; ++i) {
Yue Chend6bdd462017-07-19 16:05:43 -0700814#if CONFIG_RECT_TX_EXT
815 int is_wide_tx = tx_size_wide_unit[sub_txs] > tx_size_high_unit[sub_txs];
816 const int offsetr =
817 is_qttx ? (is_wide_tx ? i * tx_size_high_unit[sub_txs] : 0)
818 : blk_row + ((i >> 1) * bsl);
819 const int offsetc =
820 is_qttx ? (is_wide_tx ? 0 : i * tx_size_wide_unit[sub_txs])
821 : blk_col + ((i & 0x01) * bsl);
822#else
Jingning Hande953b92016-10-25 12:35:43 -0700823 const int offsetr = blk_row + ((i >> 1) * bsl);
824 const int offsetc = blk_col + ((i & 0x01) * bsl);
Yue Chend6bdd462017-07-19 16:05:43 -0700825#endif
Jingning Hande953b92016-10-25 12:35:43 -0700826 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700827
828 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
829
Jingning Han98d6a1f2016-11-03 12:47:47 -0700830 encode_block_inter(plane, block, offsetr, offsetc, plane_bsize, sub_txs,
831 arg);
832 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700833 }
834 }
835}
836#endif
837
Angie Chiangff6d8902016-10-21 11:02:09 -0700838typedef struct encode_block_pass1_args {
839 AV1_COMMON *cm;
840 MACROBLOCK *x;
841} encode_block_pass1_args;
842
Yaowu Xuc27fc142016-08-22 16:08:15 -0700843static void encode_block_pass1(int plane, int block, int blk_row, int blk_col,
844 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
845 void *arg) {
Angie Chiangff6d8902016-10-21 11:02:09 -0700846 encode_block_pass1_args *args = (encode_block_pass1_args *)arg;
847 AV1_COMMON *cm = args->cm;
848 MACROBLOCK *const x = args->x;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700849 MACROBLOCKD *const xd = &x->e_mbd;
850 struct macroblock_plane *const p = &x->plane[plane];
851 struct macroblockd_plane *const pd = &xd->plane[plane];
852 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Lester Lu27319b62017-07-10 16:57:15 -0700853 TxfmParam txfm_param;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700854 uint8_t *dst;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800855 int ctx = 0;
Jingning Han81492262016-12-05 15:48:47 -0800856 dst = &pd->dst
857 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700858
Angie Chiangff6d8902016-10-21 11:02:09 -0700859 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800860 ctx, AV1_XFORM_QUANT_B);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700861#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700862 if (p->eobs[block] > 0) {
Yushin Cho77bba8d2016-11-04 16:36:56 -0700863#else
864 if (!x->pvq_skip[plane]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -0700865 {
866 int tx_blk_size;
867 int i, j;
868 // transform block size in pixels
869 tx_blk_size = tx_size_wide[tx_size];
870
Thomas Daede6ff6af62017-02-03 16:29:24 -0800871// Since av1 does not have separate function which does inverse transform
872// but av1_inv_txfm_add_*x*() also does addition of predicted image to
873// inverse transformed image,
874// pass blank dummy image to av1_inv_txfm_add_*x*(), i.e. set dst as zeros
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200875#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800876 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
877 for (j = 0; j < tx_blk_size; j++)
878 for (i = 0; i < tx_blk_size; i++)
879 CONVERT_TO_SHORTPTR(dst)[j * pd->dst.stride + i] = 0;
880 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200881#endif // CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800882 for (j = 0; j < tx_blk_size; j++)
883 for (i = 0; i < tx_blk_size; i++) dst[j * pd->dst.stride + i] = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200884#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800885 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200886#endif // CONFIG_HIGHBITDEPTH
Yushin Cho77bba8d2016-11-04 16:36:56 -0700887 }
Jingning Handf072642016-11-08 16:43:38 -0800888#endif // !CONFIG_PVQ
Lester Lu27319b62017-07-10 16:57:15 -0700889 txfm_param.bd = xd->bd;
890 txfm_param.tx_type = DCT_DCT;
891 txfm_param.eob = p->eobs[block];
892 txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
Monty Montgomery554d2c32017-07-11 21:01:07 -0400893#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700894 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Lester Lu27319b62017-07-10 16:57:15 -0700895 av1_highbd_inv_txfm_add_4x4(dqcoeff, dst, pd->dst.stride, &txfm_param);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700896 return;
897 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200898#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700899 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Lester Lu27319b62017-07-10 16:57:15 -0700900 av1_iwht4x4_add(dqcoeff, dst, pd->dst.stride, &txfm_param);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700901 } else {
Lester Lu27319b62017-07-10 16:57:15 -0700902 av1_idct4x4_add(dqcoeff, dst, pd->dst.stride, &txfm_param);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700903 }
904 }
905}
906
Angie Chiangff6d8902016-10-21 11:02:09 -0700907void av1_encode_sby_pass1(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
908 encode_block_pass1_args args = { cm, x };
Yaowu Xuf883b422016-08-30 14:01:10 -0700909 av1_subtract_plane(x, bsize, 0);
910 av1_foreach_transformed_block_in_plane(&x->e_mbd, bsize, 0,
Angie Chiangff6d8902016-10-21 11:02:09 -0700911 encode_block_pass1, &args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700912}
913
Yaowu Xu1e4e5b92017-05-05 11:06:42 -0700914void av1_encode_sb(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row,
915 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700916 MACROBLOCKD *const xd = &x->e_mbd;
917 struct optimize_ctx ctx;
918 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -0700919 struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700920 int plane;
921
922 mbmi->skip = 1;
923
924 if (x->skip) return;
925
926 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
Jingning Han31b6a4f2017-02-23 11:05:53 -0800927#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han2d2dac22017-04-11 09:41:10 -0700928 const int subsampling_x = xd->plane[plane].subsampling_x;
929 const int subsampling_y = xd->plane[plane].subsampling_y;
930
931 if (!is_chroma_reference(mi_row, mi_col, bsize, subsampling_x,
932 subsampling_y))
Jingning Hanea576f32017-02-21 23:05:09 -0800933 continue;
Jingning Han2d2dac22017-04-11 09:41:10 -0700934
935 bsize = scale_chroma_bsize(bsize, subsampling_x, subsampling_y);
Jingning Hanea576f32017-02-21 23:05:09 -0800936#else
937 (void)mi_row;
938 (void)mi_col;
939#endif
940
Yaowu Xuc27fc142016-08-22 16:08:15 -0700941#if CONFIG_VAR_TX
942 // TODO(jingning): Clean this up.
943 const struct macroblockd_plane *const pd = &xd->plane[plane];
944 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Hande953b92016-10-25 12:35:43 -0700945 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
946 const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
Sarah Parker106b3cb2017-04-21 12:13:37 -0700947 const TX_SIZE max_tx_size = get_vartx_max_txsize(mbmi, plane_bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948 const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
Jingning Hande953b92016-10-25 12:35:43 -0700949 const int bw = block_size_wide[txb_size] >> tx_size_wide_log2[0];
950 const int bh = block_size_high[txb_size] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700951 int idx, idy;
952 int block = 0;
Jingning Hande953b92016-10-25 12:35:43 -0700953 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Jingning Han581d1692017-01-05 16:03:54 -0800954 av1_get_entropy_contexts(bsize, 0, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700955#else
956 const struct macroblockd_plane *const pd = &xd->plane[plane];
hui su0c6244b2017-07-12 17:11:43 -0700957 const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -0700958 av1_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700959#endif
Jingning Hanea576f32017-02-21 23:05:09 -0800960
Yushin Cho77bba8d2016-11-04 16:36:56 -0700961#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -0700962 av1_subtract_plane(x, bsize, plane);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700963#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700964 arg.ta = ctx.ta[plane];
965 arg.tl = ctx.tl[plane];
966
967#if CONFIG_VAR_TX
Jingning Hanc2b797f2017-07-19 09:37:11 -0700968 const BLOCK_SIZE max_unit_bsize = get_plane_block_size(BLOCK_64X64, pd);
969 int mu_blocks_wide =
970 block_size_wide[max_unit_bsize] >> tx_size_wide_log2[0];
971 int mu_blocks_high =
972 block_size_high[max_unit_bsize] >> tx_size_high_log2[0];
973
974 mu_blocks_wide = AOMMIN(mi_width, mu_blocks_wide);
975 mu_blocks_high = AOMMIN(mi_height, mu_blocks_high);
976
977 for (idy = 0; idy < mi_height; idy += mu_blocks_high) {
978 for (idx = 0; idx < mi_width; idx += mu_blocks_wide) {
979 int blk_row, blk_col;
980 const int unit_height = AOMMIN(mu_blocks_high + idy, mi_height);
981 const int unit_width = AOMMIN(mu_blocks_wide + idx, mi_width);
982 for (blk_row = idy; blk_row < unit_height; blk_row += bh) {
983 for (blk_col = idx; blk_col < unit_width; blk_col += bw) {
984 encode_block_inter(plane, block, blk_row, blk_col, plane_bsize,
985 max_tx_size, &arg);
986 block += step;
987 }
988 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700989 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700990 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700991#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700992 av1_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
993 &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700994#endif
995 }
996}
997
998#if CONFIG_SUPERTX
Angie Chiangff6d8902016-10-21 11:02:09 -0700999void av1_encode_sb_supertx(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001000 MACROBLOCKD *const xd = &x->e_mbd;
1001 struct optimize_ctx ctx;
1002 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001003 struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001004 int plane;
1005
1006 mbmi->skip = 1;
1007 if (x->skip) return;
1008
1009 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1010 const struct macroblockd_plane *const pd = &xd->plane[plane];
1011#if CONFIG_VAR_TX
1012 const TX_SIZE tx_size = TX_4X4;
1013#else
hui su0c6244b2017-07-12 17:11:43 -07001014 const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001015#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001016 av1_subtract_plane(x, bsize, plane);
1017 av1_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001018 arg.ta = ctx.ta[plane];
1019 arg.tl = ctx.tl[plane];
Yaowu Xuf883b422016-08-30 14:01:10 -07001020 av1_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
1021 &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001022 }
1023}
1024#endif // CONFIG_SUPERTX
1025
Yushin Cho6341f5c2017-03-24 14:36:28 -07001026#if !CONFIG_PVQ
Angie Chiangdb0c7d42017-03-23 16:05:37 -07001027void av1_set_txb_context(MACROBLOCK *x, int plane, int block, TX_SIZE tx_size,
Angie Chiang36aca332017-03-23 14:16:24 -07001028 ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
Angie Chiang36aca332017-03-23 14:16:24 -07001029 (void)tx_size;
Angie Chiang36aca332017-03-23 14:16:24 -07001030 struct macroblock_plane *p = &x->plane[plane];
Yushin Cho6341f5c2017-03-24 14:36:28 -07001031
Angie Chiang74e23072017-03-24 14:54:23 -07001032#if !CONFIG_LV_MAP
Angie Chiang36aca332017-03-23 14:16:24 -07001033 *a = *l = p->eobs[block] > 0;
Angie Chiang74e23072017-03-24 14:54:23 -07001034#else // !CONFIG_LV_MAP
1035 *a = *l = p->txb_entropy_ctx[block];
1036#endif // !CONFIG_LV_MAP
Angie Chiangdb0c7d42017-03-23 16:05:37 -07001037
1038#if CONFIG_VAR_TX || CONFIG_LV_MAP
1039 int i;
1040 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) a[i] = a[0];
1041
1042 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) l[i] = l[0];
1043#endif
Angie Chiang36aca332017-03-23 14:16:24 -07001044}
Yushin Cho6341f5c2017-03-24 14:36:28 -07001045#endif
Angie Chiang36aca332017-03-23 14:16:24 -07001046
1047static void encode_block_intra_and_set_context(int plane, int block,
1048 int blk_row, int blk_col,
1049 BLOCK_SIZE plane_bsize,
1050 TX_SIZE tx_size, void *arg) {
1051 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
1052 arg);
Yushin Cho6341f5c2017-03-24 14:36:28 -07001053#if !CONFIG_PVQ
Angie Chiang36aca332017-03-23 14:16:24 -07001054 struct encode_b_args *const args = arg;
1055 MACROBLOCK *x = args->x;
1056 ENTROPY_CONTEXT *a = &args->ta[blk_col];
1057 ENTROPY_CONTEXT *l = &args->tl[blk_row];
Angie Chiangdb0c7d42017-03-23 16:05:37 -07001058 av1_set_txb_context(x, plane, block, tx_size, a, l);
Yushin Cho6341f5c2017-03-24 14:36:28 -07001059#endif
Angie Chiang36aca332017-03-23 14:16:24 -07001060}
1061
hui sub8a6fd62017-05-10 10:57:57 -07001062#if CONFIG_DPCM_INTRA
1063static int get_eob(const tran_low_t *qcoeff, intptr_t n_coeffs,
1064 const int16_t *scan) {
1065 int eob = -1;
1066 for (int i = (int)n_coeffs - 1; i >= 0; i--) {
1067 const int rc = scan[i];
1068 if (qcoeff[rc]) {
1069 eob = i;
1070 break;
1071 }
1072 }
1073 return eob + 1;
1074}
1075
1076static void quantize_scaler(int coeff, int16_t zbin, int16_t round_value,
1077 int16_t quant, int16_t quant_shift, int16_t dequant,
1078 int log_scale, tran_low_t *const qcoeff,
1079 tran_low_t *const dqcoeff) {
1080 zbin = ROUND_POWER_OF_TWO(zbin, log_scale);
1081 round_value = ROUND_POWER_OF_TWO(round_value, log_scale);
1082 const int coeff_sign = (coeff >> 31);
1083 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
1084 if (abs_coeff >= zbin) {
1085 int tmp = clamp(abs_coeff + round_value, INT16_MIN, INT16_MAX);
1086 tmp = ((((tmp * quant) >> 16) + tmp) * quant_shift) >> (16 - log_scale);
1087 *qcoeff = (tmp ^ coeff_sign) - coeff_sign;
1088 *dqcoeff = (*qcoeff * dequant) / (1 << log_scale);
1089 }
1090}
1091
Sarah Parker31c66502017-05-19 16:51:07 -07001092#if CONFIG_HIGHBITDEPTH
1093typedef void (*hbd_dpcm_fwd_tx_func)(const int16_t *input, int stride,
1094 TX_TYPE_1D tx_type, tran_low_t *output,
1095 int dir);
1096
1097static hbd_dpcm_fwd_tx_func get_hbd_dpcm_fwd_tx_func(int tx_length) {
1098 switch (tx_length) {
1099 case 4: return av1_hbd_dpcm_ft4_c;
1100 case 8: return av1_hbd_dpcm_ft8_c;
1101 case 16: return av1_hbd_dpcm_ft16_c;
1102 case 32:
1103 return av1_hbd_dpcm_ft32_c;
1104 // TODO(huisu): add support for TX_64X64.
1105 default: assert(0); return NULL;
1106 }
1107}
1108#endif // CONFIG_HIGHBITDEPTH
1109
hui sub8a6fd62017-05-10 10:57:57 -07001110typedef void (*dpcm_fwd_tx_func)(const int16_t *input, int stride,
1111 TX_TYPE_1D tx_type, tran_low_t *output);
1112
1113static dpcm_fwd_tx_func get_dpcm_fwd_tx_func(int tx_length) {
1114 switch (tx_length) {
1115 case 4: return av1_dpcm_ft4_c;
1116 case 8: return av1_dpcm_ft8_c;
1117 case 16: return av1_dpcm_ft16_c;
1118 case 32:
1119 return av1_dpcm_ft32_c;
1120 // TODO(huisu): add support for TX_64X64.
1121 default: assert(0); return NULL;
1122 }
1123}
1124
1125static void process_block_dpcm_vert(TX_SIZE tx_size, TX_TYPE_1D tx_type_1d,
1126 struct macroblockd_plane *const pd,
1127 struct macroblock_plane *const p,
1128 uint8_t *src, int src_stride, uint8_t *dst,
1129 int dst_stride, int16_t *src_diff,
1130 int diff_stride, tran_low_t *coeff,
1131 tran_low_t *qcoeff, tran_low_t *dqcoeff) {
1132 const int tx1d_width = tx_size_wide[tx_size];
1133 dpcm_fwd_tx_func forward_tx = get_dpcm_fwd_tx_func(tx1d_width);
1134 dpcm_inv_txfm_add_func inverse_tx =
1135 av1_get_dpcm_inv_txfm_add_func(tx1d_width);
1136 const int tx1d_height = tx_size_high[tx_size];
1137 const int log_scale = av1_get_tx_scale(tx_size);
1138 int q_idx = 0;
1139 for (int r = 0; r < tx1d_height; ++r) {
1140 // Update prediction.
1141 if (r > 0) memcpy(dst, dst - dst_stride, tx1d_width * sizeof(dst[0]));
1142 // Subtraction.
1143 for (int c = 0; c < tx1d_width; ++c) src_diff[c] = src[c] - dst[c];
1144 // Forward transform.
1145 forward_tx(src_diff, 1, tx_type_1d, coeff);
1146 // Quantization.
1147 for (int c = 0; c < tx1d_width; ++c) {
1148 quantize_scaler(coeff[c], p->zbin[q_idx], p->round[q_idx],
1149 p->quant[q_idx], p->quant_shift[q_idx],
1150 pd->dequant[q_idx], log_scale, &qcoeff[c], &dqcoeff[c]);
1151 q_idx = 1;
1152 }
1153 // Inverse transform.
1154 inverse_tx(dqcoeff, 1, tx_type_1d, dst);
1155 // Move to the next row.
1156 coeff += tx1d_width;
1157 qcoeff += tx1d_width;
1158 dqcoeff += tx1d_width;
1159 src_diff += diff_stride;
1160 dst += dst_stride;
1161 src += src_stride;
1162 }
1163}
1164
1165static void process_block_dpcm_horz(TX_SIZE tx_size, TX_TYPE_1D tx_type_1d,
1166 struct macroblockd_plane *const pd,
1167 struct macroblock_plane *const p,
1168 uint8_t *src, int src_stride, uint8_t *dst,
1169 int dst_stride, int16_t *src_diff,
1170 int diff_stride, tran_low_t *coeff,
1171 tran_low_t *qcoeff, tran_low_t *dqcoeff) {
1172 const int tx1d_height = tx_size_high[tx_size];
1173 dpcm_fwd_tx_func forward_tx = get_dpcm_fwd_tx_func(tx1d_height);
1174 dpcm_inv_txfm_add_func inverse_tx =
1175 av1_get_dpcm_inv_txfm_add_func(tx1d_height);
1176 const int tx1d_width = tx_size_wide[tx_size];
1177 const int log_scale = av1_get_tx_scale(tx_size);
1178 int q_idx = 0;
1179 for (int c = 0; c < tx1d_width; ++c) {
1180 for (int r = 0; r < tx1d_height; ++r) {
1181 // Update prediction.
1182 if (c > 0) dst[r * dst_stride] = dst[r * dst_stride - 1];
1183 // Subtraction.
1184 src_diff[r * diff_stride] = src[r * src_stride] - dst[r * dst_stride];
1185 }
1186 // Forward transform.
1187 tran_low_t tx_buff[64];
1188 forward_tx(src_diff, diff_stride, tx_type_1d, tx_buff);
1189 for (int r = 0; r < tx1d_height; ++r) coeff[r * tx1d_width] = tx_buff[r];
1190 // Quantization.
1191 for (int r = 0; r < tx1d_height; ++r) {
1192 quantize_scaler(coeff[r * tx1d_width], p->zbin[q_idx], p->round[q_idx],
1193 p->quant[q_idx], p->quant_shift[q_idx],
1194 pd->dequant[q_idx], log_scale, &qcoeff[r * tx1d_width],
1195 &dqcoeff[r * tx1d_width]);
1196 q_idx = 1;
1197 }
1198 // Inverse transform.
1199 for (int r = 0; r < tx1d_height; ++r) tx_buff[r] = dqcoeff[r * tx1d_width];
1200 inverse_tx(tx_buff, dst_stride, tx_type_1d, dst);
1201 // Move to the next column.
1202 ++coeff, ++qcoeff, ++dqcoeff, ++src_diff, ++dst, ++src;
1203 }
1204}
1205
1206#if CONFIG_HIGHBITDEPTH
1207static void hbd_process_block_dpcm_vert(
1208 TX_SIZE tx_size, TX_TYPE_1D tx_type_1d, int bd,
1209 struct macroblockd_plane *const pd, struct macroblock_plane *const p,
1210 uint8_t *src8, int src_stride, uint8_t *dst8, int dst_stride,
1211 int16_t *src_diff, int diff_stride, tran_low_t *coeff, tran_low_t *qcoeff,
1212 tran_low_t *dqcoeff) {
1213 const int tx1d_width = tx_size_wide[tx_size];
Sarah Parker31c66502017-05-19 16:51:07 -07001214 hbd_dpcm_fwd_tx_func forward_tx = get_hbd_dpcm_fwd_tx_func(tx1d_width);
hui sub8a6fd62017-05-10 10:57:57 -07001215 hbd_dpcm_inv_txfm_add_func inverse_tx =
1216 av1_get_hbd_dpcm_inv_txfm_add_func(tx1d_width);
1217 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
1218 uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
1219 const int tx1d_height = tx_size_high[tx_size];
1220 const int log_scale = av1_get_tx_scale(tx_size);
1221 int q_idx = 0;
1222 for (int r = 0; r < tx1d_height; ++r) {
1223 // Update prediction.
1224 if (r > 0) memcpy(dst, dst - dst_stride, tx1d_width * sizeof(dst[0]));
1225 // Subtraction.
1226 for (int c = 0; c < tx1d_width; ++c) src_diff[c] = src[c] - dst[c];
1227 // Forward transform.
Sarah Parker31c66502017-05-19 16:51:07 -07001228 forward_tx(src_diff, 1, tx_type_1d, coeff, 1);
hui sub8a6fd62017-05-10 10:57:57 -07001229 // Quantization.
1230 for (int c = 0; c < tx1d_width; ++c) {
1231 quantize_scaler(coeff[c], p->zbin[q_idx], p->round[q_idx],
1232 p->quant[q_idx], p->quant_shift[q_idx],
1233 pd->dequant[q_idx], log_scale, &qcoeff[c], &dqcoeff[c]);
1234 q_idx = 1;
1235 }
1236 // Inverse transform.
Sarah Parker31c66502017-05-19 16:51:07 -07001237 inverse_tx(dqcoeff, 1, tx_type_1d, bd, dst, 1);
hui sub8a6fd62017-05-10 10:57:57 -07001238 // Move to the next row.
1239 coeff += tx1d_width;
1240 qcoeff += tx1d_width;
1241 dqcoeff += tx1d_width;
1242 src_diff += diff_stride;
1243 dst += dst_stride;
1244 src += src_stride;
1245 }
1246}
1247
1248static void hbd_process_block_dpcm_horz(
1249 TX_SIZE tx_size, TX_TYPE_1D tx_type_1d, int bd,
1250 struct macroblockd_plane *const pd, struct macroblock_plane *const p,
1251 uint8_t *src8, int src_stride, uint8_t *dst8, int dst_stride,
1252 int16_t *src_diff, int diff_stride, tran_low_t *coeff, tran_low_t *qcoeff,
1253 tran_low_t *dqcoeff) {
1254 const int tx1d_height = tx_size_high[tx_size];
Sarah Parker31c66502017-05-19 16:51:07 -07001255 hbd_dpcm_fwd_tx_func forward_tx = get_hbd_dpcm_fwd_tx_func(tx1d_height);
hui sub8a6fd62017-05-10 10:57:57 -07001256 hbd_dpcm_inv_txfm_add_func inverse_tx =
1257 av1_get_hbd_dpcm_inv_txfm_add_func(tx1d_height);
1258 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
1259 uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
1260 const int tx1d_width = tx_size_wide[tx_size];
1261 const int log_scale = av1_get_tx_scale(tx_size);
1262 int q_idx = 0;
1263 for (int c = 0; c < tx1d_width; ++c) {
1264 for (int r = 0; r < tx1d_height; ++r) {
1265 // Update prediction.
1266 if (c > 0) dst[r * dst_stride] = dst[r * dst_stride - 1];
1267 // Subtraction.
1268 src_diff[r * diff_stride] = src[r * src_stride] - dst[r * dst_stride];
1269 }
1270 // Forward transform.
1271 tran_low_t tx_buff[64];
Sarah Parker31c66502017-05-19 16:51:07 -07001272 forward_tx(src_diff, diff_stride, tx_type_1d, tx_buff, 0);
hui sub8a6fd62017-05-10 10:57:57 -07001273 for (int r = 0; r < tx1d_height; ++r) coeff[r * tx1d_width] = tx_buff[r];
1274 // Quantization.
1275 for (int r = 0; r < tx1d_height; ++r) {
1276 quantize_scaler(coeff[r * tx1d_width], p->zbin[q_idx], p->round[q_idx],
1277 p->quant[q_idx], p->quant_shift[q_idx],
1278 pd->dequant[q_idx], log_scale, &qcoeff[r * tx1d_width],
1279 &dqcoeff[r * tx1d_width]);
1280 q_idx = 1;
1281 }
1282 // Inverse transform.
1283 for (int r = 0; r < tx1d_height; ++r) tx_buff[r] = dqcoeff[r * tx1d_width];
Sarah Parker31c66502017-05-19 16:51:07 -07001284 inverse_tx(tx_buff, dst_stride, tx_type_1d, bd, dst, 0);
hui sub8a6fd62017-05-10 10:57:57 -07001285 // Move to the next column.
1286 ++coeff, ++qcoeff, ++dqcoeff, ++src_diff, ++dst, ++src;
1287 }
1288}
1289#endif // CONFIG_HIGHBITDEPTH
1290
1291void av1_encode_block_intra_dpcm(const AV1_COMMON *cm, MACROBLOCK *x,
1292 PREDICTION_MODE mode, int plane, int block,
1293 int blk_row, int blk_col,
1294 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
1295 TX_TYPE tx_type, ENTROPY_CONTEXT *ta,
1296 ENTROPY_CONTEXT *tl, int8_t *skip) {
1297 MACROBLOCKD *const xd = &x->e_mbd;
1298 struct macroblock_plane *const p = &x->plane[plane];
1299 struct macroblockd_plane *const pd = &xd->plane[plane];
1300 tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1301 const int diff_stride = block_size_wide[plane_bsize];
1302 const int src_stride = p->src.stride;
1303 const int dst_stride = pd->dst.stride;
1304 const int tx1d_width = tx_size_wide[tx_size];
1305 const int tx1d_height = tx_size_high[tx_size];
Angie Chiangbd99b382017-06-20 15:11:16 -07001306 const SCAN_ORDER *const scan_order =
1307 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
hui sub8a6fd62017-05-10 10:57:57 -07001308 tran_low_t *coeff = BLOCK_OFFSET(p->coeff, block);
1309 tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1310 uint8_t *dst =
1311 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1312 uint8_t *src =
1313 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
1314 int16_t *src_diff =
1315 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
1316 uint16_t *eob = &p->eobs[block];
1317 *eob = 0;
1318 memset(qcoeff, 0, tx1d_height * tx1d_width * sizeof(*qcoeff));
1319 memset(dqcoeff, 0, tx1d_height * tx1d_width * sizeof(*dqcoeff));
1320
1321 if (LIKELY(!x->skip_block)) {
1322 TX_TYPE_1D tx_type_1d = DCT_1D;
1323 switch (tx_type) {
1324 case IDTX: tx_type_1d = IDTX_1D; break;
1325 case V_DCT:
1326 assert(mode == H_PRED);
1327 tx_type_1d = DCT_1D;
1328 break;
1329 case H_DCT:
1330 assert(mode == V_PRED);
1331 tx_type_1d = DCT_1D;
1332 break;
1333 default: assert(0);
1334 }
1335 switch (mode) {
1336 case V_PRED:
1337#if CONFIG_HIGHBITDEPTH
1338 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1339 hbd_process_block_dpcm_vert(tx_size, tx_type_1d, xd->bd, pd, p, src,
1340 src_stride, dst, dst_stride, src_diff,
1341 diff_stride, coeff, qcoeff, dqcoeff);
1342 } else {
1343#endif // CONFIG_HIGHBITDEPTH
1344 process_block_dpcm_vert(tx_size, tx_type_1d, pd, p, src, src_stride,
1345 dst, dst_stride, src_diff, diff_stride, coeff,
1346 qcoeff, dqcoeff);
1347#if CONFIG_HIGHBITDEPTH
1348 }
1349#endif // CONFIG_HIGHBITDEPTH
1350 break;
1351 case H_PRED:
1352#if CONFIG_HIGHBITDEPTH
1353 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1354 hbd_process_block_dpcm_horz(tx_size, tx_type_1d, xd->bd, pd, p, src,
1355 src_stride, dst, dst_stride, src_diff,
1356 diff_stride, coeff, qcoeff, dqcoeff);
1357 } else {
1358#endif // CONFIG_HIGHBITDEPTH
1359 process_block_dpcm_horz(tx_size, tx_type_1d, pd, p, src, src_stride,
1360 dst, dst_stride, src_diff, diff_stride, coeff,
1361 qcoeff, dqcoeff);
1362#if CONFIG_HIGHBITDEPTH
1363 }
1364#endif // CONFIG_HIGHBITDEPTH
1365 break;
1366 default: assert(0);
1367 }
1368 *eob = get_eob(qcoeff, tx1d_height * tx1d_width, scan_order->scan);
1369 }
1370
1371 ta[blk_col] = tl[blk_row] = *eob > 0;
1372 if (*eob) *skip = 0;
1373}
1374#endif // CONFIG_DPCM_INTRA
1375
Yaowu Xuf883b422016-08-30 14:01:10 -07001376void av1_encode_block_intra(int plane, int block, int blk_row, int blk_col,
1377 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
1378 void *arg) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001379 struct encode_b_args *const args = arg;
Angie Chiangff6d8902016-10-21 11:02:09 -07001380 AV1_COMMON *cm = args->cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001381 MACROBLOCK *const x = args->x;
1382 MACROBLOCKD *const xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001383 struct macroblock_plane *const p = &x->plane[plane];
1384 struct macroblockd_plane *const pd = &xd->plane[plane];
1385 tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05001386 PLANE_TYPE plane_type = get_plane_type(plane);
Jingning Han19b5c8f2017-07-06 15:10:12 -07001387 const TX_TYPE tx_type =
1388 av1_get_tx_type(plane_type, xd, blk_row, blk_col, block, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001389 uint16_t *eob = &p->eobs[block];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001390 const int dst_stride = pd->dst.stride;
Angie Chiangf87e43f2017-04-02 16:51:19 -07001391 uint8_t *dst =
1392 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04001393
Angie Chiang752ccce2017-04-09 13:41:13 -07001394 av1_predict_intra_block_facade(xd, plane, block, blk_col, blk_row, tx_size);
hui sub8a6fd62017-05-10 10:57:57 -07001395
Lester Lu708c1ec2017-06-14 14:54:49 -07001396#if CONFIG_DPCM_INTRA || CONFIG_LGT
hui sub8a6fd62017-05-10 10:57:57 -07001397 const PREDICTION_MODE mode =
Lester Lu708c1ec2017-06-14 14:54:49 -07001398 get_prediction_mode(xd->mi[0], plane, tx_size, block);
1399#if CONFIG_DPCM_INTRA
1400 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
hui sub8a6fd62017-05-10 10:57:57 -07001401 if (av1_use_dpcm_intra(plane, mode, tx_type, mbmi)) {
1402 av1_encode_block_intra_dpcm(cm, x, mode, plane, block, blk_row, blk_col,
1403 plane_bsize, tx_size, tx_type, args->ta,
1404 args->tl, args->skip);
1405 return;
1406 }
1407#endif // CONFIG_DPCM_INTRA
Lester Lu708c1ec2017-06-14 14:54:49 -07001408#endif // CONFIG_DPCM_INTRA || CONFIG_LGT
hui sub8a6fd62017-05-10 10:57:57 -07001409
Angie Chiangf87e43f2017-04-02 16:51:19 -07001410 av1_subtract_txb(x, plane, plane_bsize, blk_col, blk_row, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001411
Angie Chiang36aca332017-03-23 14:16:24 -07001412 const ENTROPY_CONTEXT *a = &args->ta[blk_col];
1413 const ENTROPY_CONTEXT *l = &args->tl[blk_row];
Angie Chiang57605532017-04-03 11:51:15 -07001414 int ctx = combine_entropy_contexts(*a, *l);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001415 if (args->enable_optimize_b) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001416 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001417 ctx, AV1_XFORM_QUANT_FP);
Jingning Han7eab9ff2017-07-06 10:12:54 -07001418 av1_optimize_b(cm, x, plane, blk_row, blk_col, block, plane_bsize, tx_size,
1419 a, l);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001420 } else {
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001421 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1422 ctx, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001423 }
1424
Angie Chiang57605532017-04-03 11:51:15 -07001425#if CONFIG_PVQ
Yushin Cho3827fdd2016-11-09 15:50:23 -08001426 // *(args->skip) == mbmi->skip
1427 if (!x->pvq_skip[plane]) *(args->skip) = 0;
1428
1429 if (x->pvq_skip[plane]) return;
Angie Chiang50910f62017-04-03 12:31:34 -07001430#endif // CONFIG_PVQ
Lester Lu708c1ec2017-06-14 14:54:49 -07001431 av1_inverse_transform_block(xd, dqcoeff,
1432#if CONFIG_LGT
1433 mode,
1434#endif
1435 tx_type, tx_size, dst, dst_stride, *eob);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001436#if !CONFIG_PVQ
1437 if (*eob) *(args->skip) = 0;
1438#else
1439// Note : *(args->skip) == mbmi->skip
1440#endif
Luc Trudeaue3980282017-04-25 23:17:21 -04001441#if CONFIG_CFL
1442 if (plane == AOM_PLANE_Y && x->cfl_store_y) {
Luc Trudeau780d2492017-06-15 22:26:41 -04001443 // TODO (ltrudeau) Store sub-8x8 inter blocks when bottom right block is
1444 // intra predicted.
1445 cfl_store(xd->cfl, dst, dst_stride, blk_row, blk_col, tx_size, plane_bsize);
Luc Trudeaue3980282017-04-25 23:17:21 -04001446 }
1447#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001448}
1449
Angie Chiangff6d8902016-10-21 11:02:09 -07001450void av1_encode_intra_block_plane(AV1_COMMON *cm, MACROBLOCK *x,
1451 BLOCK_SIZE bsize, int plane,
Yaowu Xu1e4e5b92017-05-05 11:06:42 -07001452 int enable_optimize_b, int mi_row,
1453 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001454 const MACROBLOCKD *const xd = &x->e_mbd;
Guillaume Martrese50d9dd2016-12-18 18:26:47 +01001455 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE] = { 0 };
1456 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001457
Angie Chiangff6d8902016-10-21 11:02:09 -07001458 struct encode_b_args arg = {
1459 cm, x, NULL, &xd->mi[0]->mbmi.skip, ta, tl, enable_optimize_b
1460 };
Jingning Han18c53c82017-02-17 14:49:57 -08001461
1462#if CONFIG_CB4X4
Jingning Hand3a64432017-04-06 17:04:17 -07001463 if (!is_chroma_reference(mi_row, mi_col, bsize,
1464 xd->plane[plane].subsampling_x,
1465 xd->plane[plane].subsampling_y))
Jingning Han18c53c82017-02-17 14:49:57 -08001466 return;
1467#else
1468 (void)mi_row;
1469 (void)mi_col;
1470#endif
1471
Yaowu Xuc27fc142016-08-22 16:08:15 -07001472 if (enable_optimize_b) {
1473 const struct macroblockd_plane *const pd = &xd->plane[plane];
hui su0c6244b2017-07-12 17:11:43 -07001474 const TX_SIZE tx_size = av1_get_tx_size(plane, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07001475 av1_get_entropy_contexts(bsize, tx_size, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001476 }
Angie Chiang36aca332017-03-23 14:16:24 -07001477 av1_foreach_transformed_block_in_plane(
1478 xd, bsize, plane, encode_block_intra_and_set_context, &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001479}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001480
1481#if CONFIG_PVQ
Thomas Daede6ff6af62017-02-03 16:29:24 -08001482PVQ_SKIP_TYPE av1_pvq_encode_helper(MACROBLOCK *x, tran_low_t *const coeff,
1483 tran_low_t *ref_coeff,
1484 tran_low_t *const dqcoeff, uint16_t *eob,
1485 const int16_t *quant, int plane,
1486 int tx_size, TX_TYPE tx_type, int *rate,
1487 int speed, PVQ_INFO *pvq_info) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001488 const int tx_blk_size = tx_size_wide[tx_size];
Thomas Daede6ff6af62017-02-03 16:29:24 -08001489 daala_enc_ctx *daala_enc = &x->daala_enc;
ltrudeaue1c09292017-01-20 15:42:13 -05001490 PVQ_SKIP_TYPE ac_dc_coded;
Jingning Hanff705452017-04-27 11:32:15 -07001491 int coeff_shift = 3 - av1_get_tx_scale(tx_size);
Thomas Daede6ff6af62017-02-03 16:29:24 -08001492 int hbd_downshift = 0;
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001493 int rounding_mask;
Yushin Cho70669122016-12-08 09:53:14 -10001494 int pvq_dc_quant;
1495 int use_activity_masking = daala_enc->use_activity_masking;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001496 int tell;
1497 int has_dc_skip = 1;
1498 int i;
1499 int off = od_qm_offset(tx_size, plane ? 1 : 0);
Yushin Cho70669122016-12-08 09:53:14 -10001500
Thomas Daede1dbda1b2017-02-06 16:06:29 -08001501 DECLARE_ALIGNED(16, tran_low_t, coeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1502 DECLARE_ALIGNED(16, tran_low_t, ref_coeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1503 DECLARE_ALIGNED(16, tran_low_t, dqcoeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001504
Yushin Cho48f84db2016-11-07 21:20:17 -08001505 DECLARE_ALIGNED(16, int32_t, in_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1506 DECLARE_ALIGNED(16, int32_t, ref_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1507 DECLARE_ALIGNED(16, int32_t, out_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001508
Thomas Daede6ff6af62017-02-03 16:29:24 -08001509 hbd_downshift = x->e_mbd.bd - 8;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001510
1511 assert(OD_COEFF_SHIFT >= 4);
Yushin Cho70669122016-12-08 09:53:14 -10001512 // DC quantizer for PVQ
1513 if (use_activity_masking)
clang-format55ce9e02017-02-15 22:27:12 -08001514 pvq_dc_quant =
Thomas Daede6ff6af62017-02-03 16:29:24 -08001515 OD_MAXI(1, (quant[0] << (OD_COEFF_SHIFT - 3) >> hbd_downshift) *
clang-format55ce9e02017-02-15 22:27:12 -08001516 daala_enc->state
1517 .pvq_qm_q4[plane][od_qm_get_index(tx_size, 0)] >>
1518 4);
Yushin Cho70669122016-12-08 09:53:14 -10001519 else
Thomas Daede6ff6af62017-02-03 16:29:24 -08001520 pvq_dc_quant =
1521 OD_MAXI(1, quant[0] << (OD_COEFF_SHIFT - 3) >> hbd_downshift);
Yushin Cho70669122016-12-08 09:53:14 -10001522
Yushin Cho77bba8d2016-11-04 16:36:56 -07001523 *eob = 0;
1524
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001525#if !CONFIG_ANS
Nathan E. Egge6675be02016-12-21 13:02:43 -05001526 tell = od_ec_enc_tell_frac(&daala_enc->w.ec);
1527#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001528#error "CONFIG_PVQ currently requires !CONFIG_ANS."
Nathan E. Egge6675be02016-12-21 13:02:43 -05001529#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001530
1531 // Change coefficient ordering for pvq encoding.
1532 od_raster_to_coding_order(coeff_pvq, tx_blk_size, tx_type, coeff,
1533 tx_blk_size);
1534 od_raster_to_coding_order(ref_coeff_pvq, tx_blk_size, tx_type, ref_coeff,
1535 tx_blk_size);
1536
1537 // copy int16 inputs to int32
1538 for (i = 0; i < tx_blk_size * tx_blk_size; i++) {
Timothy B. Terriberry4e6a8f32017-02-24 11:00:59 -08001539 ref_int32[i] =
Thomas Daede6ff6af62017-02-03 16:29:24 -08001540 AOM_SIGNED_SHL(ref_coeff_pvq[i], OD_COEFF_SHIFT - coeff_shift) >>
1541 hbd_downshift;
1542 in_int32[i] = AOM_SIGNED_SHL(coeff_pvq[i], OD_COEFF_SHIFT - coeff_shift) >>
1543 hbd_downshift;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001544 }
1545
Yushin Cho77bba8d2016-11-04 16:36:56 -07001546 if (abs(in_int32[0] - ref_int32[0]) < pvq_dc_quant * 141 / 256) { /* 0.55 */
1547 out_int32[0] = 0;
1548 } else {
1549 out_int32[0] = OD_DIV_R0(in_int32[0] - ref_int32[0], pvq_dc_quant);
1550 }
1551
Thomas Daede6ff6af62017-02-03 16:29:24 -08001552 ac_dc_coded =
1553 od_pvq_encode(daala_enc, ref_int32, in_int32, out_int32,
1554 OD_MAXI(1, quant[0] << (OD_COEFF_SHIFT - 3) >>
1555 hbd_downshift), // scale/quantizer
1556 OD_MAXI(1, quant[1] << (OD_COEFF_SHIFT - 3) >>
1557 hbd_downshift), // scale/quantizer
1558 plane,
1559 tx_size, OD_PVQ_BETA[use_activity_masking][plane][tx_size],
Yushin Cho31b980a2017-03-23 10:28:09 -07001560 0, // is_keyframe,
Thomas Daede6ff6af62017-02-03 16:29:24 -08001561 daala_enc->state.qm + off, daala_enc->state.qm_inv + off,
1562 speed, // speed
1563 pvq_info);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001564
1565 // Encode residue of DC coeff, if required.
1566 if (!has_dc_skip || out_int32[0]) {
Yushin Choc49ef3a2017-03-13 17:27:25 -07001567 generic_encode(&daala_enc->w, &daala_enc->state.adapt->model_dc[plane],
Timothy B. Terriberry44bb6d02017-04-07 15:44:14 -07001568 abs(out_int32[0]) - has_dc_skip,
Yushin Choc49ef3a2017-03-13 17:27:25 -07001569 &daala_enc->state.adapt->ex_dc[plane][tx_size][0], 2);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001570 }
1571 if (out_int32[0]) {
Nathan E. Egge6675be02016-12-21 13:02:43 -05001572 aom_write_bit(&daala_enc->w, out_int32[0] < 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001573 }
1574
1575 // need to save quantized residue of DC coeff
1576 // so that final pvq bitstream writing can know whether DC is coded.
1577 if (pvq_info) pvq_info->dq_dc_residue = out_int32[0];
1578
1579 out_int32[0] = out_int32[0] * pvq_dc_quant;
1580 out_int32[0] += ref_int32[0];
1581
1582 // copy int32 result back to int16
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001583 assert(OD_COEFF_SHIFT > coeff_shift);
1584 rounding_mask = (1 << (OD_COEFF_SHIFT - coeff_shift - 1)) - 1;
1585 for (i = 0; i < tx_blk_size * tx_blk_size; i++) {
Thomas Daede6ff6af62017-02-03 16:29:24 -08001586 out_int32[i] = AOM_SIGNED_SHL(out_int32[i], hbd_downshift);
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001587 dqcoeff_pvq[i] = (out_int32[i] + (out_int32[i] < 0) + rounding_mask) >>
1588 (OD_COEFF_SHIFT - coeff_shift);
1589 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001590
1591 // Back to original coefficient order
1592 od_coding_order_to_raster(dqcoeff, tx_blk_size, tx_type, dqcoeff_pvq,
1593 tx_blk_size);
1594
1595 *eob = tx_blk_size * tx_blk_size;
1596
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001597#if !CONFIG_ANS
Nathan E. Egge6675be02016-12-21 13:02:43 -05001598 *rate = (od_ec_enc_tell_frac(&daala_enc->w.ec) - tell)
Yushin Cho77bba8d2016-11-04 16:36:56 -07001599 << (AV1_PROB_COST_SHIFT - OD_BITRES);
Nathan E. Egge6675be02016-12-21 13:02:43 -05001600#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001601#error "CONFIG_PVQ currently requires !CONFIG_ANS."
Nathan E. Egge6675be02016-12-21 13:02:43 -05001602#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001603 assert(*rate >= 0);
Yushin Cho5c207292017-02-16 15:01:33 -08001604
ltrudeau472f63f2017-01-12 15:22:32 -05001605 return ac_dc_coded;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001606}
1607
Timothy B. Terriberry44bb6d02017-04-07 15:44:14 -07001608void av1_store_pvq_enc_info(PVQ_INFO *pvq_info, int *qg, int *theta, int *k,
1609 od_coeff *y, int nb_bands, const int *off,
1610 int *size, int skip_rest, int skip_dir,
Yushin Cho77bba8d2016-11-04 16:36:56 -07001611 int bs) { // block size in log_2 -2
1612 int i;
1613 const int tx_blk_size = tx_size_wide[bs];
1614
1615 for (i = 0; i < nb_bands; i++) {
1616 pvq_info->qg[i] = qg[i];
1617 pvq_info->theta[i] = theta[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001618 pvq_info->k[i] = k[i];
1619 pvq_info->off[i] = off[i];
1620 pvq_info->size[i] = size[i];
1621 }
1622
1623 memcpy(pvq_info->y, y, tx_blk_size * tx_blk_size * sizeof(od_coeff));
1624
1625 pvq_info->nb_bands = nb_bands;
1626 pvq_info->skip_rest = skip_rest;
1627 pvq_info->skip_dir = skip_dir;
1628 pvq_info->bs = bs;
1629}
1630#endif