blob: 1a6098580dc702e55f5c11bf0873d0d7c90196ba [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#if CONFIG_EC_ADAPT
116 { 10, 7 }, { 8, 5 },
117#else
Angie Chiangebcdb252017-05-05 18:15:10 -0700118 { 10, 6 }, { 8, 6 },
Thomas Davies10525752017-03-06 12:10:46 +0000119#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700120};
121
Urvang Joshi70006e42017-06-14 16:08:55 -0700122#define UPDATE_RD_COST() \
123 { \
124 rd_cost0 = RDCOST(rdmult, rate0, error0); \
125 rd_cost1 = RDCOST(rdmult, rate1, error1); \
Yaowu Xuc27fc142016-08-22 16:08:15 -0700126 }
127
Yaowu Xu42350322017-05-05 11:12:19 -0700128static INLINE unsigned int get_token_bit_costs(
129 unsigned int token_costs[2][COEFF_CONTEXTS][ENTROPY_TOKENS], int skip_eob,
130 int ctx, int token) {
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000131 (void)skip_eob;
132 return token_costs[token == ZERO_TOKEN || token == EOB_TOKEN][ctx][token];
Thomas Daviesed8e2d22017-01-04 16:42:09 +0000133}
134
Angie Chiang1c96e822017-05-31 14:40:55 -0700135#if !CONFIG_LV_MAP
Dake He97f56642017-03-29 16:46:51 -0700136
Angie Chiang7dec6c42017-05-03 17:58:17 -0700137typedef struct av1_token_state_greedy {
Dake He97f56642017-03-29 16:46:51 -0700138 int16_t token;
139 tran_low_t qc;
140 tran_low_t dqc;
Angie Chiang7dec6c42017-05-03 17:58:17 -0700141} av1_token_state_greedy;
Dake He97f56642017-03-29 16:46:51 -0700142
Angie Chiang7dec6c42017-05-03 17:58:17 -0700143static int optimize_b_greedy(const AV1_COMMON *cm, MACROBLOCK *mb, int plane,
144 int block, TX_SIZE tx_size, int ctx) {
Dake He97f56642017-03-29 16:46:51 -0700145 MACROBLOCKD *const xd = &mb->e_mbd;
146 struct macroblock_plane *const p = &mb->plane[plane];
147 struct macroblockd_plane *const pd = &xd->plane[plane];
148 const int ref = is_inter_block(&xd->mi[0]->mbmi);
Angie Chiang7dec6c42017-05-03 17:58:17 -0700149 av1_token_state_greedy tokens[MAX_TX_SQUARE + 1][2];
Dake He97f56642017-03-29 16:46:51 -0700150 uint8_t token_cache[MAX_TX_SQUARE];
151 const tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
152 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
153 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
154 const int eob = p->eobs[block];
155 const PLANE_TYPE plane_type = pd->plane_type;
156 const int16_t *const dequant_ptr = pd->dequant;
157 const uint8_t *const band_translate = get_band_translate(tx_size);
158 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
159 const SCAN_ORDER *const scan_order =
Angie Chiangbd99b382017-06-20 15:11:16 -0700160 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
Dake He97f56642017-03-29 16:46:51 -0700161 const int16_t *const scan = scan_order->scan;
162 const int16_t *const nb = scan_order->neighbors;
163 int dqv;
Jingning Hanff705452017-04-27 11:32:15 -0700164 const int shift = av1_get_tx_scale(tx_size);
Dake He97f56642017-03-29 16:46:51 -0700165#if CONFIG_AOM_QM
166 int seg_id = xd->mi[0]->mbmi.segment_id;
Thomas Daviesbe44e512017-06-07 11:41:07 +0100167 // Use a flat matrix (i.e. no weighting) for 1D and Identity transforms
168 const qm_val_t *iqmatrix =
169 IS_2D_TRANSFORM(tx_type)
170 ? pd->seg_iqmatrix[seg_id][!ref][tx_size]
171 : cm->giqmatrix[NUM_QM_LEVELS - 1][0][0][tx_size];
Dake He97f56642017-03-29 16:46:51 -0700172#endif
173#if CONFIG_NEW_QUANT
174 int dq = get_dq_profile_from_ctx(mb->qindex, ctx, ref, plane_type);
175 const dequant_val_type_nuq *dequant_val = pd->dequant_val_nuq[dq];
Dake He97f56642017-03-29 16:46:51 -0700176#endif // CONFIG_NEW_QUANT
177 int sz = 0;
Dake He97f56642017-03-29 16:46:51 -0700178 int64_t rd_cost0, rd_cost1;
179 int16_t t0, t1;
180 int i, final_eob;
Dake He97f56642017-03-29 16:46:51 -0700181 const int cat6_bits = av1_get_cat6_extrabits_size(tx_size, xd->bd);
Dake He97f56642017-03-29 16:46:51 -0700182 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
183 mb->token_costs[txsize_sqr_map[tx_size]][plane_type][ref];
184 const int default_eob = tx_size_2d[tx_size];
185
Angie Chiang7dec6c42017-05-03 17:58:17 -0700186 assert(mb->qindex > 0);
Dake He97f56642017-03-29 16:46:51 -0700187
188 assert((!plane_type && !plane) || (plane_type && plane));
189 assert(eob <= default_eob);
190
191 int64_t rdmult = (mb->rdmult * plane_rd_mult[ref][plane_type]) >> 1;
Dake He97f56642017-03-29 16:46:51 -0700192
193 int64_t rate0, rate1;
194 for (i = 0; i < eob; i++) {
195 const int rc = scan[i];
196 int x = qcoeff[rc];
197 t0 = av1_get_token(x);
198
199 tokens[i][0].qc = x;
200 tokens[i][0].token = t0;
201 tokens[i][0].dqc = dqcoeff[rc];
202
203 token_cache[rc] = av1_pt_energy_class[t0];
204 }
205 tokens[eob][0].token = EOB_TOKEN;
206 tokens[eob][0].qc = 0;
207 tokens[eob][0].dqc = 0;
208 tokens[eob][1] = tokens[eob][0];
209
210 unsigned int(*token_costs_ptr)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
211 token_costs;
212
213 final_eob = 0;
214
215 int64_t eob_cost0, eob_cost1;
216
217 const int ctx0 = ctx;
218 /* Record the r-d cost */
219 int64_t accu_rate = 0;
Urvang Joshi6eb35eb2017-06-14 13:28:56 -0700220 // Initialized to the worst possible error for the largest transform size.
221 // This ensures that it never goes negative.
222 int64_t accu_error = ((int64_t)1) << 50;
Dake He97f56642017-03-29 16:46:51 -0700223
224 rate0 = get_token_bit_costs(*(token_costs_ptr + band_translate[0]), 0, ctx0,
225 EOB_TOKEN);
Urvang Joshi70006e42017-06-14 16:08:55 -0700226 int64_t best_block_rd_cost = RDCOST(rdmult, rate0, accu_error);
Dake He97f56642017-03-29 16:46:51 -0700227
228 // int64_t best_block_rd_cost_all0 = best_block_rd_cost;
229
230 int x_prev = 1;
231
232 for (i = 0; i < eob; i++) {
233 const int rc = scan[i];
234 int x = qcoeff[rc];
235 sz = -(x < 0);
236
237 int band_cur = band_translate[i];
238 int ctx_cur = (i == 0) ? ctx : get_coef_context(nb, token_cache, i);
239 int token_tree_sel_cur = (x_prev == 0);
240
241 if (x == 0) {
242 // no need to search when x == 0
243 rate0 =
244 get_token_bit_costs(*(token_costs_ptr + band_cur), token_tree_sel_cur,
245 ctx_cur, tokens[i][0].token);
246 accu_rate += rate0;
247 x_prev = 0;
248 // accu_error does not change when x==0
249 } else {
250 /* Computing distortion
251 */
252 // compute the distortion for the first candidate
253 // and the distortion for quantizing to 0.
Jingning Han32d26bc2017-06-11 07:50:39 -0700254 int dx0 = abs(coeff[rc]) * (1 << shift);
Dake He97f56642017-03-29 16:46:51 -0700255#if CONFIG_HIGHBITDEPTH
256 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
257 dx0 >>= xd->bd - 8;
258 }
259#endif
260 int64_t d0 = (int64_t)dx0 * dx0;
261
262 int x_a = x - 2 * sz - 1;
263 int64_t d2, d2_a;
264
265 int dx;
266
267#if CONFIG_AOM_QM
268 int iwt = iqmatrix[rc];
269 dqv = dequant_ptr[rc != 0];
270 dqv = ((iwt * (int)dqv) + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
271#else
272 dqv = dequant_ptr[rc != 0];
273#endif
274
275 dx = (dqcoeff[rc] - coeff[rc]) * (1 << shift);
276#if CONFIG_HIGHBITDEPTH
277 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Jingning Han32d26bc2017-06-11 07:50:39 -0700278 int dx_sign = dx < 0 ? 1 : 0;
279 dx = abs(dx) >> (xd->bd - 8);
280 if (dx_sign) dx = -dx;
Dake He97f56642017-03-29 16:46:51 -0700281 }
282#endif // CONFIG_HIGHBITDEPTH
283 d2 = (int64_t)dx * dx;
284
285 /* compute the distortion for the second candidate
286 * x_a = x - 2 * sz + 1;
287 */
288 if (x_a != 0) {
289#if CONFIG_NEW_QUANT
290 dx = av1_dequant_coeff_nuq(x, dqv, dequant_val[band_translate[i]]) -
291 (coeff[rc] << shift);
292#if CONFIG_HIGHBITDEPTH
293 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
294 dx >>= xd->bd - 8;
295 }
296#endif // CONFIG_HIGHBITDEPTH
297#else // CONFIG_NEW_QUANT
298#if CONFIG_HIGHBITDEPTH
299 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
300 dx -= ((dqv >> (xd->bd - 8)) + sz) ^ sz;
301 } else {
302 dx -= (dqv + sz) ^ sz;
303 }
304#else
305 dx -= (dqv + sz) ^ sz;
306#endif // CONFIG_HIGHBITDEPTH
307#endif // CONFIG_NEW_QUANT
308 d2_a = (int64_t)dx * dx;
309 } else {
310 d2_a = d0;
311 }
312 /* Computing rates and r-d cost
313 */
314
315 int best_x, best_eob_x;
316 int64_t base_bits, next_bits0, next_bits1;
317 int64_t next_eob_bits0, next_eob_bits1;
318
319 // rate cost of x
320 base_bits = av1_get_token_cost(x, &t0, cat6_bits);
321 rate0 = base_bits + get_token_bit_costs(*(token_costs_ptr + band_cur),
322 token_tree_sel_cur, ctx_cur, t0);
323
324 base_bits = av1_get_token_cost(x_a, &t1, cat6_bits);
325 rate1 = base_bits + get_token_bit_costs(*(token_costs_ptr + band_cur),
326 token_tree_sel_cur, ctx_cur, t1);
327
328 next_bits0 = 0;
329 next_bits1 = 0;
330 next_eob_bits0 = 0;
331 next_eob_bits1 = 0;
332
333 if (i < default_eob - 1) {
334 int ctx_next, token_tree_sel_next;
335 int band_next = band_translate[i + 1];
336
337 token_cache[rc] = av1_pt_energy_class[t0];
338 ctx_next = get_coef_context(nb, token_cache, i + 1);
339 token_tree_sel_next = (x == 0);
340
341 next_bits0 = get_token_bit_costs(*(token_costs_ptr + band_next),
342 token_tree_sel_next, ctx_next,
343 tokens[i + 1][0].token);
344 next_eob_bits0 =
345 get_token_bit_costs(*(token_costs_ptr + band_next),
346 token_tree_sel_next, ctx_next, EOB_TOKEN);
347
348 token_cache[rc] = av1_pt_energy_class[t1];
349 ctx_next = get_coef_context(nb, token_cache, i + 1);
350 token_tree_sel_next = (x_a == 0);
351
352 next_bits1 = get_token_bit_costs(*(token_costs_ptr + band_next),
353 token_tree_sel_next, ctx_next,
354 tokens[i + 1][0].token);
355
356 if (x_a != 0) {
357 next_eob_bits1 =
358 get_token_bit_costs(*(token_costs_ptr + band_next),
359 token_tree_sel_next, ctx_next, EOB_TOKEN);
360 }
361 }
362
Urvang Joshi70006e42017-06-14 16:08:55 -0700363 rd_cost0 = RDCOST(rdmult, (rate0 + next_bits0), d2);
364 rd_cost1 = RDCOST(rdmult, (rate1 + next_bits1), d2_a);
Dake He97f56642017-03-29 16:46:51 -0700365
366 best_x = (rd_cost1 < rd_cost0);
367
Urvang Joshi70006e42017-06-14 16:08:55 -0700368 eob_cost0 = RDCOST(rdmult, (accu_rate + rate0 + next_eob_bits0),
Dake He97f56642017-03-29 16:46:51 -0700369 (accu_error + d2 - d0));
370 eob_cost1 = eob_cost0;
371 if (x_a != 0) {
Urvang Joshi70006e42017-06-14 16:08:55 -0700372 eob_cost1 = RDCOST(rdmult, (accu_rate + rate1 + next_eob_bits1),
Dake He97f56642017-03-29 16:46:51 -0700373 (accu_error + d2_a - d0));
374 best_eob_x = (eob_cost1 < eob_cost0);
375 } else {
376 best_eob_x = 0;
377 }
378
379 int dqc, dqc_a = 0;
380
381 dqc = dqcoeff[rc];
382 if (best_x + best_eob_x) {
383 if (x_a != 0) {
384#if CONFIG_NEW_QUANT
385 dqc_a = av1_dequant_abscoeff_nuq(abs(x_a), dqv,
386 dequant_val[band_translate[i]]);
387 dqc_a = shift ? ROUND_POWER_OF_TWO(dqc_a, shift) : dqc_a;
388 if (sz) dqc_a = -dqc_a;
389#else
David Barkerc747a782017-05-24 12:46:08 +0100390 if (x_a < 0)
391 dqc_a = -((-x_a * dqv) >> shift);
Dake He97f56642017-03-29 16:46:51 -0700392 else
David Barkerc747a782017-05-24 12:46:08 +0100393 dqc_a = (x_a * dqv) >> shift;
Dake He97f56642017-03-29 16:46:51 -0700394#endif // CONFIG_NEW_QUANT
395 } else {
396 dqc_a = 0;
397 } // if (x_a != 0)
398 }
399
400 // record the better quantized value
401 if (best_x) {
402 qcoeff[rc] = x_a;
403 dqcoeff[rc] = dqc_a;
404
405 accu_rate += rate1;
406 accu_error += d2_a - d0;
407 assert(d2_a <= d0);
408
409 token_cache[rc] = av1_pt_energy_class[t1];
410 } else {
411 accu_rate += rate0;
412 accu_error += d2 - d0;
413 assert(d2 <= d0);
414
415 token_cache[rc] = av1_pt_energy_class[t0];
416 }
Urvang Joshi6eb35eb2017-06-14 13:28:56 -0700417 assert(accu_error >= 0);
Dake He97f56642017-03-29 16:46:51 -0700418
419 x_prev = qcoeff[rc];
420
421 // determine whether to move the eob position to i+1
422 int64_t best_eob_cost_i = eob_cost0;
423
424 tokens[i][1].token = t0;
425 tokens[i][1].qc = x;
426 tokens[i][1].dqc = dqc;
427
428 if ((x_a != 0) && (best_eob_x)) {
429 best_eob_cost_i = eob_cost1;
430
431 tokens[i][1].token = t1;
432 tokens[i][1].qc = x_a;
433 tokens[i][1].dqc = dqc_a;
434 }
435
436 if (best_eob_cost_i < best_block_rd_cost) {
437 best_block_rd_cost = best_eob_cost_i;
438 final_eob = i + 1;
439 }
440 } // if (x==0)
441 } // for (i)
442
443 assert(final_eob <= eob);
444 if (final_eob > 0) {
445 assert(tokens[final_eob - 1][1].qc != 0);
446 i = final_eob - 1;
447 int rc = scan[i];
448 qcoeff[rc] = tokens[i][1].qc;
449 dqcoeff[rc] = tokens[i][1].dqc;
450 }
451
452 for (i = final_eob; i < eob; i++) {
453 int rc = scan[i];
454 qcoeff[rc] = 0;
455 dqcoeff[rc] = 0;
456 }
457
458 mb->plane[plane].eobs[block] = final_eob;
459 return final_eob;
Dake He97f56642017-03-29 16:46:51 -0700460}
Angie Chiang1c96e822017-05-31 14:40:55 -0700461#endif // !CONFIG_LV_MAP
Dake He97f56642017-03-29 16:46:51 -0700462
Angie Chiang7dec6c42017-05-03 17:58:17 -0700463int av1_optimize_b(const AV1_COMMON *cm, MACROBLOCK *mb, int plane, int block,
Angie Chiang3511c372017-05-31 12:47:07 -0700464 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
465 const ENTROPY_CONTEXT *a, const ENTROPY_CONTEXT *l) {
Angie Chiang7dec6c42017-05-03 17:58:17 -0700466 MACROBLOCKD *const xd = &mb->e_mbd;
467 struct macroblock_plane *const p = &mb->plane[plane];
468 const int eob = p->eobs[block];
469 assert((mb->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
470 if (eob == 0) return eob;
471 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return eob;
Jingning Hanaba246d2017-06-14 12:00:16 -0700472
Angie Chiang1c96e822017-05-31 14:40:55 -0700473#if CONFIG_PVQ
474 (void)cm;
475 (void)tx_size;
476 (void)a;
477 (void)l;
478 return eob;
479#endif
Angie Chiang3511c372017-05-31 12:47:07 -0700480
Angie Chiang1c96e822017-05-31 14:40:55 -0700481#if !CONFIG_LV_MAP
482 (void)plane_bsize;
Angie Chiang3511c372017-05-31 12:47:07 -0700483#if CONFIG_VAR_TX
484 int ctx = get_entropy_context(tx_size, a, l);
485#else
486 int ctx = combine_entropy_contexts(*a, *l);
Urvang Joshi09302f52017-06-08 14:24:59 -0700487#endif // CONFIG_VAR_TX
Angie Chiang7dec6c42017-05-03 17:58:17 -0700488 return optimize_b_greedy(cm, mb, plane, block, tx_size, ctx);
Angie Chiang1c96e822017-05-31 14:40:55 -0700489#else // !CONFIG_LV_MAP
490 TXB_CTX txb_ctx;
491 get_txb_ctx(plane_bsize, tx_size, plane, a, l, &txb_ctx);
492 return av1_optimize_txb(cm, mb, plane, block, tx_size, &txb_ctx);
493#endif // !CONFIG_LV_MAP
Angie Chiang7dec6c42017-05-03 17:58:17 -0700494}
495
Thomas Daede6ff6af62017-02-03 16:29:24 -0800496#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700497typedef enum QUANT_FUNC {
498 QUANT_FUNC_LOWBD = 0,
499 QUANT_FUNC_HIGHBD = 1,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800500 QUANT_FUNC_TYPES = 2
Yaowu Xuc27fc142016-08-22 16:08:15 -0700501} QUANT_FUNC;
502
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800503static AV1_QUANT_FACADE
504 quant_func_list[AV1_XFORM_QUANT_TYPES][QUANT_FUNC_TYPES] = {
Angie Chiang6a71ad12017-04-03 11:19:00 -0700505#if !CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800506 { av1_quantize_fp_facade, av1_highbd_quantize_fp_facade },
Yaowu Xuf883b422016-08-30 14:01:10 -0700507 { av1_quantize_b_facade, av1_highbd_quantize_b_facade },
508 { av1_quantize_dc_facade, av1_highbd_quantize_dc_facade },
Angie Chiang6a71ad12017-04-03 11:19:00 -0700509#else // !CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800510 { av1_quantize_fp_nuq_facade, av1_highbd_quantize_fp_nuq_facade },
511 { av1_quantize_b_nuq_facade, av1_highbd_quantize_b_nuq_facade },
512 { av1_quantize_dc_nuq_facade, av1_highbd_quantize_dc_nuq_facade },
Angie Chiang6a71ad12017-04-03 11:19:00 -0700513#endif // !CONFIG_NEW_QUANT
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800514 { NULL, NULL }
515 };
Yi Luo0f4195c2017-06-27 16:07:28 -0700516#endif // !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700517
Yi Luo0f4195c2017-06-27 16:07:28 -0700518typedef void (*fwdTxfmFunc)(const int16_t *diff, tran_low_t *coeff, int stride,
519 FWD_TXFM_PARAM *param);
520static const fwdTxfmFunc fwd_txfm_func[2] = { av1_fwd_txfm,
521 av1_highbd_fwd_txfm };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700522
Angie Chiangff6d8902016-10-21 11:02:09 -0700523void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
524 int blk_row, int blk_col, BLOCK_SIZE plane_bsize,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800525 TX_SIZE tx_size, int ctx,
526 AV1_XFORM_QUANT xform_quant_idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700527 MACROBLOCKD *const xd = &x->e_mbd;
Luc Trudeaub6e94d92017-03-13 15:46:15 -0400528 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800529#if !(CONFIG_PVQ || CONFIG_DAALA_DIST)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700530 const struct macroblock_plane *const p = &x->plane[plane];
531 const struct macroblockd_plane *const pd = &xd->plane[plane];
Yushin Cho77bba8d2016-11-04 16:36:56 -0700532#else
533 struct macroblock_plane *const p = &x->plane[plane];
534 struct macroblockd_plane *const pd = &xd->plane[plane];
535#endif
Luc Trudeau005feb62017-02-22 13:34:01 -0500536 PLANE_TYPE plane_type = get_plane_type(plane);
Angie Chiang752ccce2017-04-09 13:41:13 -0700537 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiangbd99b382017-06-20 15:11:16 -0700538
539#if CONFIG_AOM_QM || CONFIG_NEW_QUANT
Luc Trudeaub6e94d92017-03-13 15:46:15 -0400540 const int is_inter = is_inter_block(mbmi);
Angie Chiangbd99b382017-06-20 15:11:16 -0700541#endif
542
543 const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700544 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
545 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
546 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
547 uint16_t *const eob = &p->eobs[block];
Jingning Hanae5cfde2016-11-30 12:01:44 -0800548 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700549#if CONFIG_AOM_QM
Luc Trudeaub6e94d92017-03-13 15:46:15 -0400550 int seg_id = mbmi->segment_id;
Thomas Daviesbe44e512017-06-07 11:41:07 +0100551 // Use a flat matrix (i.e. no weighting) for 1D and Identity transforms
552 const qm_val_t *qmatrix =
553 IS_2D_TRANSFORM(tx_type) ? pd->seg_qmatrix[seg_id][!is_inter][tx_size]
554 : cm->gqmatrix[NUM_QM_LEVELS - 1][0][0][tx_size];
555 const qm_val_t *iqmatrix =
556 IS_2D_TRANSFORM(tx_type)
557 ? pd->seg_iqmatrix[seg_id][!is_inter][tx_size]
558 : cm->giqmatrix[NUM_QM_LEVELS - 1][0][0][tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700559#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700560
561 FWD_TXFM_PARAM fwd_txfm_param;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700562
Yushin Cho7a428ba2017-01-12 16:28:49 -0800563#if CONFIG_PVQ || CONFIG_DAALA_DIST
564 uint8_t *dst;
565 int16_t *pred;
566 const int dst_stride = pd->dst.stride;
Yushin Cho1c602b32017-06-07 17:57:14 -0700567 const int txw = tx_size_wide[tx_size];
568 const int txh = tx_size_high[tx_size];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800569 int i, j;
570#endif
571
Yushin Cho77bba8d2016-11-04 16:36:56 -0700572#if !CONFIG_PVQ
573 const int tx2d_size = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700574 QUANT_PARAM qparam;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700575 const int16_t *src_diff;
576
Jingning Han81492262016-12-05 15:48:47 -0800577 src_diff =
578 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Jingning Hanff705452017-04-27 11:32:15 -0700579 qparam.log_scale = av1_get_tx_scale(tx_size);
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800580#if CONFIG_NEW_QUANT
581 qparam.tx_size = tx_size;
582 qparam.dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
583#endif // CONFIG_NEW_QUANT
584#if CONFIG_AOM_QM
585 qparam.qmatrix = qmatrix;
586 qparam.iqmatrix = iqmatrix;
587#endif // CONFIG_AOM_QM
Yushin Cho77bba8d2016-11-04 16:36:56 -0700588#else
Yushin Cho77bba8d2016-11-04 16:36:56 -0700589 tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700590 int skip = 1;
591 PVQ_INFO *pvq_info = NULL;
Yushin Cho7a428ba2017-01-12 16:28:49 -0800592 uint8_t *src;
593 int16_t *src_int16;
594 const int src_stride = p->src.stride;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700595
Yushin Cho6341f5c2017-03-24 14:36:28 -0700596 (void)ctx;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700597 (void)scan_order;
598 (void)qcoeff;
599
600 if (x->pvq_coded) {
601 assert(block < MAX_PVQ_BLOCKS_IN_SB);
602 pvq_info = &x->pvq[block][plane];
603 }
Jingning Han81492262016-12-05 15:48:47 -0800604 src = &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
605 src_int16 =
606 &p->src_int16[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Yushin Cho7a428ba2017-01-12 16:28:49 -0800607
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200608#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800609 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yushin Cho1c602b32017-06-07 17:57:14 -0700610 for (j = 0; j < txh; j++)
611 for (i = 0; i < txw; i++)
Thomas Daede6ff6af62017-02-03 16:29:24 -0800612 src_int16[diff_stride * j + i] =
613 CONVERT_TO_SHORTPTR(src)[src_stride * j + i];
614 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200615#endif // CONFIG_HIGHBITDEPTH
Yushin Cho1c602b32017-06-07 17:57:14 -0700616 for (j = 0; j < txh; j++)
617 for (i = 0; i < txw; i++)
Thomas Daede6ff6af62017-02-03 16:29:24 -0800618 src_int16[diff_stride * j + i] = src[src_stride * j + i];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200619#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800620 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200621#endif // CONFIG_HIGHBITDEPTH
Yushin Cho7a428ba2017-01-12 16:28:49 -0800622#endif
623
624#if CONFIG_PVQ || CONFIG_DAALA_DIST
625 dst = &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
Jingning Han81492262016-12-05 15:48:47 -0800626 pred = &pd->pred[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
Yushin Cho77bba8d2016-11-04 16:36:56 -0700627
Thomas Daede6ff6af62017-02-03 16:29:24 -0800628// copy uint8 orig and predicted block to int16 buffer
629// in order to use existing VP10 transform functions
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200630#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800631 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yushin Cho1c602b32017-06-07 17:57:14 -0700632 for (j = 0; j < txh; j++)
633 for (i = 0; i < txw; i++)
Thomas Daede6ff6af62017-02-03 16:29:24 -0800634 pred[diff_stride * j + i] =
635 CONVERT_TO_SHORTPTR(dst)[dst_stride * j + i];
636 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200637#endif // CONFIG_HIGHBITDEPTH
Yushin Cho1c602b32017-06-07 17:57:14 -0700638 for (j = 0; j < txh; j++)
639 for (i = 0; i < txw; i++)
Thomas Daede6ff6af62017-02-03 16:29:24 -0800640 pred[diff_stride * j + i] = dst[dst_stride * j + i];
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200641#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800642 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200643#endif // CONFIG_HIGHBITDEPTH
Yushin Cho77bba8d2016-11-04 16:36:56 -0700644#endif
Yushin Cho7a428ba2017-01-12 16:28:49 -0800645
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800646 (void)ctx;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700647
648 fwd_txfm_param.tx_type = tx_type;
649 fwd_txfm_param.tx_size = tx_size;
Luc Trudeaub6e94d92017-03-13 15:46:15 -0400650 fwd_txfm_param.lossless = xd->lossless[mbmi->segment_id];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700651
Thomas Daede6ff6af62017-02-03 16:29:24 -0800652#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700653 fwd_txfm_param.bd = xd->bd;
Yi Luo0f4195c2017-06-27 16:07:28 -0700654 const int is_hbd = get_bitdepth_data_path_index(xd);
655 fwd_txfm_func[is_hbd](src_diff, coeff, diff_stride, &fwd_txfm_param);
656
Yaowu Xuf883b422016-08-30 14:01:10 -0700657 if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700658 if (LIKELY(!x->skip_block)) {
Yi Luo0f4195c2017-06-27 16:07:28 -0700659 quant_func_list[xform_quant_idx][is_hbd](
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800660 coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700661 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700662 av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700663 }
664 }
Angie Chiang74e23072017-03-24 14:54:23 -0700665#if CONFIG_LV_MAP
666 p->txb_entropy_ctx[block] =
667 (uint8_t)av1_get_txb_entropy_context(qcoeff, scan_order, *eob);
668#endif // CONFIG_LV_MAP
Yi Luo0f4195c2017-06-27 16:07:28 -0700669 return;
670#else // CONFIG_PVQ
Angie Chiang2cc057c2017-01-03 18:31:47 -0800671 (void)xform_quant_idx;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200672#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800673 fwd_txfm_param.bd = xd->bd;
674 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
hui suf11fb882017-03-27 14:56:33 -0700675 av1_highbd_fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
676 av1_highbd_fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
Thomas Daede6ff6af62017-02-03 16:29:24 -0800677 } else {
678#endif
hui suf11fb882017-03-27 14:56:33 -0700679 av1_fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
680 av1_fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200681#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800682 }
683#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -0700684
685 // PVQ for inter mode block
ltrudeau472f63f2017-01-12 15:22:32 -0500686 if (!x->skip_block) {
ltrudeaue1c09292017-01-20 15:42:13 -0500687 PVQ_SKIP_TYPE ac_dc_coded =
Thomas Daede6ff6af62017-02-03 16:29:24 -0800688 av1_pvq_encode_helper(x,
ltrudeaue1c09292017-01-20 15:42:13 -0500689 coeff, // target original vector
690 ref_coeff, // reference vector
691 dqcoeff, // de-quantized vector
692 eob, // End of Block marker
693 pd->dequant, // aom's quantizers
694 plane, // image plane
695 tx_size, // block size in log_2 - 2
696 tx_type,
697 &x->rate, // rate measured
698 x->pvq_speed,
699 pvq_info); // PVQ info for a block
700 skip = ac_dc_coded == PVQ_SKIP;
ltrudeau472f63f2017-01-12 15:22:32 -0500701 }
Yushin Cho77bba8d2016-11-04 16:36:56 -0700702 x->pvq_skip[plane] = skip;
703
704 if (!skip) mbmi->skip = 0;
705#endif // #if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700706}
707
Yaowu Xuc27fc142016-08-22 16:08:15 -0700708static void encode_block(int plane, int block, int blk_row, int blk_col,
709 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
710 struct encode_b_args *const args = arg;
Angie Chiangff6d8902016-10-21 11:02:09 -0700711 AV1_COMMON *cm = args->cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700712 MACROBLOCK *const x = args->x;
713 MACROBLOCKD *const xd = &x->e_mbd;
714 int ctx;
715 struct macroblock_plane *const p = &x->plane[plane];
716 struct macroblockd_plane *const pd = &xd->plane[plane];
717 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
718 uint8_t *dst;
Yushin Cho6341f5c2017-03-24 14:36:28 -0700719#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700720 ENTROPY_CONTEXT *a, *l;
Yushin Cho6341f5c2017-03-24 14:36:28 -0700721#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700722#if CONFIG_VAR_TX
Jingning Han9ca05b72017-01-03 14:41:36 -0800723 int bw = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700724#endif
Jingning Han81492262016-12-05 15:48:47 -0800725 dst = &pd->dst
726 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Yushin Cho6341f5c2017-03-24 14:36:28 -0700727
728#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700729 a = &args->ta[blk_col];
730 l = &args->tl[blk_row];
731#if CONFIG_VAR_TX
732 ctx = get_entropy_context(tx_size, a, l);
733#else
734 ctx = combine_entropy_contexts(*a, *l);
735#endif
Yushin Cho6341f5c2017-03-24 14:36:28 -0700736#else
737 ctx = 0;
738#endif // CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700739
740#if CONFIG_VAR_TX
Yue Chena1e48dc2016-08-29 17:29:33 -0700741 // Assert not magic number (uninitialized).
Jingning Han9ca05b72017-01-03 14:41:36 -0800742 assert(x->blk_skip[plane][blk_row * bw + blk_col] != 234);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700743
Jingning Han9ca05b72017-01-03 14:41:36 -0800744 if (x->blk_skip[plane][blk_row * bw + blk_col] == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700745#else
746 {
747#endif
Angie Chiangff6d8902016-10-21 11:02:09 -0700748 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800749 ctx, AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700750 }
751#if CONFIG_VAR_TX
752 else {
753 p->eobs[block] = 0;
754 }
755#endif
Yushin Cho6341f5c2017-03-24 14:36:28 -0700756
Yushin Cho77bba8d2016-11-04 16:36:56 -0700757#if !CONFIG_PVQ
Angie Chiang3511c372017-05-31 12:47:07 -0700758 av1_optimize_b(cm, x, plane, block, plane_bsize, tx_size, a, l);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700759
Angie Chiangdb0c7d42017-03-23 16:05:37 -0700760 av1_set_txb_context(x, plane, block, tx_size, a, l);
761
Yaowu Xuc27fc142016-08-22 16:08:15 -0700762 if (p->eobs[block]) *(args->skip) = 0;
763
764 if (p->eobs[block] == 0) return;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700765#else
766 (void)ctx;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700767 if (!x->pvq_skip[plane]) *(args->skip) = 0;
768
769 if (x->pvq_skip[plane]) return;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700770#endif
Angie Chiang752ccce2017-04-09 13:41:13 -0700771 TX_TYPE tx_type = get_tx_type(pd->plane_type, xd, block, tx_size);
Angie Chiang44d7e662017-04-06 11:07:53 -0700772 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, dst,
773 pd->dst.stride, p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700774}
775
776#if CONFIG_VAR_TX
777static void encode_block_inter(int plane, int block, int blk_row, int blk_col,
778 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
779 void *arg) {
780 struct encode_b_args *const args = arg;
781 MACROBLOCK *const x = args->x;
782 MACROBLOCKD *const xd = &x->e_mbd;
783 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
784 const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
785 const struct macroblockd_plane *const pd = &xd->plane[plane];
786 const int tx_row = blk_row >> (1 - pd->subsampling_y);
787 const int tx_col = blk_col >> (1 - pd->subsampling_x);
788 TX_SIZE plane_tx_size;
Jingning Hanf65b8702016-10-31 12:13:20 -0700789 const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
790 const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700791
792 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
793
Debargha Mukherjee2f123402016-08-30 17:43:38 -0700794 plane_tx_size =
795 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
796 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700797
798 if (tx_size == plane_tx_size) {
799 encode_block(plane, block, blk_row, blk_col, plane_bsize, tx_size, arg);
800 } else {
Alex Conversee16b2662017-05-24 14:00:00 -0700801 assert(tx_size < TX_SIZES_ALL);
Jingning Hana9336322016-11-02 15:45:07 -0700802 const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
Alex Conversee16b2662017-05-24 14:00:00 -0700803 assert(sub_txs < tx_size);
Jingning Hana9336322016-11-02 15:45:07 -0700804 // This is the square transform block partition entry point.
805 int bsl = tx_size_wide_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700806 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700807 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700808
809 for (i = 0; i < 4; ++i) {
Jingning Hande953b92016-10-25 12:35:43 -0700810 const int offsetr = blk_row + ((i >> 1) * bsl);
811 const int offsetc = blk_col + ((i & 0x01) * bsl);
Jingning Hande953b92016-10-25 12:35:43 -0700812 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700813
814 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
815
Jingning Han98d6a1f2016-11-03 12:47:47 -0700816 encode_block_inter(plane, block, offsetr, offsetc, plane_bsize, sub_txs,
817 arg);
818 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700819 }
820 }
821}
822#endif
823
Angie Chiangff6d8902016-10-21 11:02:09 -0700824typedef struct encode_block_pass1_args {
825 AV1_COMMON *cm;
826 MACROBLOCK *x;
827} encode_block_pass1_args;
828
Yaowu Xuc27fc142016-08-22 16:08:15 -0700829static void encode_block_pass1(int plane, int block, int blk_row, int blk_col,
830 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
831 void *arg) {
Angie Chiangff6d8902016-10-21 11:02:09 -0700832 encode_block_pass1_args *args = (encode_block_pass1_args *)arg;
833 AV1_COMMON *cm = args->cm;
834 MACROBLOCK *const x = args->x;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700835 MACROBLOCKD *const xd = &x->e_mbd;
836 struct macroblock_plane *const p = &x->plane[plane];
837 struct macroblockd_plane *const pd = &xd->plane[plane];
838 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
839 uint8_t *dst;
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800840 int ctx = 0;
Jingning Han81492262016-12-05 15:48:47 -0800841 dst = &pd->dst
842 .buf[(blk_row * pd->dst.stride + blk_col) << tx_size_wide_log2[0]];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700843
Angie Chiangff6d8902016-10-21 11:02:09 -0700844 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -0800845 ctx, AV1_XFORM_QUANT_B);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700846#if !CONFIG_PVQ
Yaowu Xuc27fc142016-08-22 16:08:15 -0700847 if (p->eobs[block] > 0) {
Yushin Cho77bba8d2016-11-04 16:36:56 -0700848#else
849 if (!x->pvq_skip[plane]) {
Yushin Cho77bba8d2016-11-04 16:36:56 -0700850 {
851 int tx_blk_size;
852 int i, j;
853 // transform block size in pixels
854 tx_blk_size = tx_size_wide[tx_size];
855
Thomas Daede6ff6af62017-02-03 16:29:24 -0800856// Since av1 does not have separate function which does inverse transform
857// but av1_inv_txfm_add_*x*() also does addition of predicted image to
858// inverse transformed image,
859// pass blank dummy image to av1_inv_txfm_add_*x*(), i.e. set dst as zeros
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200860#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800861 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
862 for (j = 0; j < tx_blk_size; j++)
863 for (i = 0; i < tx_blk_size; i++)
864 CONVERT_TO_SHORTPTR(dst)[j * pd->dst.stride + i] = 0;
865 } else {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200866#endif // CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800867 for (j = 0; j < tx_blk_size; j++)
868 for (i = 0; i < tx_blk_size; i++) dst[j * pd->dst.stride + i] = 0;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200869#if CONFIG_HIGHBITDEPTH
Thomas Daede6ff6af62017-02-03 16:29:24 -0800870 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200871#endif // CONFIG_HIGHBITDEPTH
Yushin Cho77bba8d2016-11-04 16:36:56 -0700872 }
Jingning Handf072642016-11-08 16:43:38 -0800873#endif // !CONFIG_PVQ
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200874#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700875 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Frederic Barbier05b45e62017-06-26 09:57:40 +0200876 av1_highbd_inv_txfm_add_4x4(dqcoeff, dst, pd->dst.stride, p->eobs[block],
877 xd->bd, DCT_DCT,
878 xd->lossless[xd->mi[0]->mbmi.segment_id]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700879 return;
880 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200881#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700882 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700883 av1_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700884 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700885 av1_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700886 }
887 }
888}
889
Angie Chiangff6d8902016-10-21 11:02:09 -0700890void av1_encode_sby_pass1(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
891 encode_block_pass1_args args = { cm, x };
Yaowu Xuf883b422016-08-30 14:01:10 -0700892 av1_subtract_plane(x, bsize, 0);
893 av1_foreach_transformed_block_in_plane(&x->e_mbd, bsize, 0,
Angie Chiangff6d8902016-10-21 11:02:09 -0700894 encode_block_pass1, &args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700895}
896
Yaowu Xu1e4e5b92017-05-05 11:06:42 -0700897void av1_encode_sb(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row,
898 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700899 MACROBLOCKD *const xd = &x->e_mbd;
900 struct optimize_ctx ctx;
901 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -0700902 struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700903 int plane;
904
905 mbmi->skip = 1;
906
907 if (x->skip) return;
908
909 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
Jingning Han31b6a4f2017-02-23 11:05:53 -0800910#if CONFIG_CB4X4 && !CONFIG_CHROMA_2X2
Jingning Han2d2dac22017-04-11 09:41:10 -0700911 const int subsampling_x = xd->plane[plane].subsampling_x;
912 const int subsampling_y = xd->plane[plane].subsampling_y;
913
914 if (!is_chroma_reference(mi_row, mi_col, bsize, subsampling_x,
915 subsampling_y))
Jingning Hanea576f32017-02-21 23:05:09 -0800916 continue;
Jingning Han2d2dac22017-04-11 09:41:10 -0700917
918 bsize = scale_chroma_bsize(bsize, subsampling_x, subsampling_y);
Jingning Hanea576f32017-02-21 23:05:09 -0800919#else
920 (void)mi_row;
921 (void)mi_col;
922#endif
923
Yaowu Xuc27fc142016-08-22 16:08:15 -0700924#if CONFIG_VAR_TX
925 // TODO(jingning): Clean this up.
926 const struct macroblockd_plane *const pd = &xd->plane[plane];
927 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Hande953b92016-10-25 12:35:43 -0700928 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
929 const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
Sarah Parker106b3cb2017-04-21 12:13:37 -0700930 const TX_SIZE max_tx_size = get_vartx_max_txsize(mbmi, plane_bsize);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700931 const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
Jingning Hande953b92016-10-25 12:35:43 -0700932 const int bw = block_size_wide[txb_size] >> tx_size_wide_log2[0];
933 const int bh = block_size_high[txb_size] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700934 int idx, idy;
935 int block = 0;
Jingning Hande953b92016-10-25 12:35:43 -0700936 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Jingning Han581d1692017-01-05 16:03:54 -0800937 av1_get_entropy_contexts(bsize, 0, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700938#else
939 const struct macroblockd_plane *const pd = &xd->plane[plane];
Angie Chiang7fcfee42017-02-24 15:51:03 -0800940 const TX_SIZE tx_size = get_tx_size(plane, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -0700941 av1_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700942#endif
Jingning Hanea576f32017-02-21 23:05:09 -0800943
Yushin Cho77bba8d2016-11-04 16:36:56 -0700944#if !CONFIG_PVQ
Yaowu Xuf883b422016-08-30 14:01:10 -0700945 av1_subtract_plane(x, bsize, plane);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700946#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700947 arg.ta = ctx.ta[plane];
948 arg.tl = ctx.tl[plane];
949
950#if CONFIG_VAR_TX
Jingning Hanfe45b212016-11-22 10:30:23 -0800951 for (idy = 0; idy < mi_height; idy += bh) {
952 for (idx = 0; idx < mi_width; idx += bw) {
953 encode_block_inter(plane, block, idy, idx, plane_bsize, max_tx_size,
954 &arg);
955 block += step;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700956 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700957 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700958#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700959 av1_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
960 &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700961#endif
962 }
963}
964
965#if CONFIG_SUPERTX
Angie Chiangff6d8902016-10-21 11:02:09 -0700966void av1_encode_sb_supertx(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700967 MACROBLOCKD *const xd = &x->e_mbd;
968 struct optimize_ctx ctx;
969 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -0700970 struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700971 int plane;
972
973 mbmi->skip = 1;
974 if (x->skip) return;
975
976 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
977 const struct macroblockd_plane *const pd = &xd->plane[plane];
978#if CONFIG_VAR_TX
979 const TX_SIZE tx_size = TX_4X4;
980#else
Angie Chiang7fcfee42017-02-24 15:51:03 -0800981 const TX_SIZE tx_size = get_tx_size(plane, xd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700982#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700983 av1_subtract_plane(x, bsize, plane);
984 av1_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700985 arg.ta = ctx.ta[plane];
986 arg.tl = ctx.tl[plane];
Yaowu Xuf883b422016-08-30 14:01:10 -0700987 av1_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
988 &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700989 }
990}
991#endif // CONFIG_SUPERTX
992
Yushin Cho6341f5c2017-03-24 14:36:28 -0700993#if !CONFIG_PVQ
Angie Chiangdb0c7d42017-03-23 16:05:37 -0700994void av1_set_txb_context(MACROBLOCK *x, int plane, int block, TX_SIZE tx_size,
Angie Chiang36aca332017-03-23 14:16:24 -0700995 ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
Angie Chiang36aca332017-03-23 14:16:24 -0700996 (void)tx_size;
Angie Chiang36aca332017-03-23 14:16:24 -0700997 struct macroblock_plane *p = &x->plane[plane];
Yushin Cho6341f5c2017-03-24 14:36:28 -0700998
Angie Chiang74e23072017-03-24 14:54:23 -0700999#if !CONFIG_LV_MAP
Angie Chiang36aca332017-03-23 14:16:24 -07001000 *a = *l = p->eobs[block] > 0;
Angie Chiang74e23072017-03-24 14:54:23 -07001001#else // !CONFIG_LV_MAP
1002 *a = *l = p->txb_entropy_ctx[block];
1003#endif // !CONFIG_LV_MAP
Angie Chiangdb0c7d42017-03-23 16:05:37 -07001004
1005#if CONFIG_VAR_TX || CONFIG_LV_MAP
1006 int i;
1007 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) a[i] = a[0];
1008
1009 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) l[i] = l[0];
1010#endif
Angie Chiang36aca332017-03-23 14:16:24 -07001011}
Yushin Cho6341f5c2017-03-24 14:36:28 -07001012#endif
Angie Chiang36aca332017-03-23 14:16:24 -07001013
1014static void encode_block_intra_and_set_context(int plane, int block,
1015 int blk_row, int blk_col,
1016 BLOCK_SIZE plane_bsize,
1017 TX_SIZE tx_size, void *arg) {
1018 av1_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
1019 arg);
Yushin Cho6341f5c2017-03-24 14:36:28 -07001020#if !CONFIG_PVQ
Angie Chiang36aca332017-03-23 14:16:24 -07001021 struct encode_b_args *const args = arg;
1022 MACROBLOCK *x = args->x;
1023 ENTROPY_CONTEXT *a = &args->ta[blk_col];
1024 ENTROPY_CONTEXT *l = &args->tl[blk_row];
Angie Chiangdb0c7d42017-03-23 16:05:37 -07001025 av1_set_txb_context(x, plane, block, tx_size, a, l);
Yushin Cho6341f5c2017-03-24 14:36:28 -07001026#endif
Angie Chiang36aca332017-03-23 14:16:24 -07001027}
1028
hui sub8a6fd62017-05-10 10:57:57 -07001029#if CONFIG_DPCM_INTRA
1030static int get_eob(const tran_low_t *qcoeff, intptr_t n_coeffs,
1031 const int16_t *scan) {
1032 int eob = -1;
1033 for (int i = (int)n_coeffs - 1; i >= 0; i--) {
1034 const int rc = scan[i];
1035 if (qcoeff[rc]) {
1036 eob = i;
1037 break;
1038 }
1039 }
1040 return eob + 1;
1041}
1042
1043static void quantize_scaler(int coeff, int16_t zbin, int16_t round_value,
1044 int16_t quant, int16_t quant_shift, int16_t dequant,
1045 int log_scale, tran_low_t *const qcoeff,
1046 tran_low_t *const dqcoeff) {
1047 zbin = ROUND_POWER_OF_TWO(zbin, log_scale);
1048 round_value = ROUND_POWER_OF_TWO(round_value, log_scale);
1049 const int coeff_sign = (coeff >> 31);
1050 const int abs_coeff = (coeff ^ coeff_sign) - coeff_sign;
1051 if (abs_coeff >= zbin) {
1052 int tmp = clamp(abs_coeff + round_value, INT16_MIN, INT16_MAX);
1053 tmp = ((((tmp * quant) >> 16) + tmp) * quant_shift) >> (16 - log_scale);
1054 *qcoeff = (tmp ^ coeff_sign) - coeff_sign;
1055 *dqcoeff = (*qcoeff * dequant) / (1 << log_scale);
1056 }
1057}
1058
Sarah Parker31c66502017-05-19 16:51:07 -07001059#if CONFIG_HIGHBITDEPTH
1060typedef void (*hbd_dpcm_fwd_tx_func)(const int16_t *input, int stride,
1061 TX_TYPE_1D tx_type, tran_low_t *output,
1062 int dir);
1063
1064static hbd_dpcm_fwd_tx_func get_hbd_dpcm_fwd_tx_func(int tx_length) {
1065 switch (tx_length) {
1066 case 4: return av1_hbd_dpcm_ft4_c;
1067 case 8: return av1_hbd_dpcm_ft8_c;
1068 case 16: return av1_hbd_dpcm_ft16_c;
1069 case 32:
1070 return av1_hbd_dpcm_ft32_c;
1071 // TODO(huisu): add support for TX_64X64.
1072 default: assert(0); return NULL;
1073 }
1074}
1075#endif // CONFIG_HIGHBITDEPTH
1076
hui sub8a6fd62017-05-10 10:57:57 -07001077typedef void (*dpcm_fwd_tx_func)(const int16_t *input, int stride,
1078 TX_TYPE_1D tx_type, tran_low_t *output);
1079
1080static dpcm_fwd_tx_func get_dpcm_fwd_tx_func(int tx_length) {
1081 switch (tx_length) {
1082 case 4: return av1_dpcm_ft4_c;
1083 case 8: return av1_dpcm_ft8_c;
1084 case 16: return av1_dpcm_ft16_c;
1085 case 32:
1086 return av1_dpcm_ft32_c;
1087 // TODO(huisu): add support for TX_64X64.
1088 default: assert(0); return NULL;
1089 }
1090}
1091
1092static void process_block_dpcm_vert(TX_SIZE tx_size, TX_TYPE_1D tx_type_1d,
1093 struct macroblockd_plane *const pd,
1094 struct macroblock_plane *const p,
1095 uint8_t *src, int src_stride, uint8_t *dst,
1096 int dst_stride, int16_t *src_diff,
1097 int diff_stride, tran_low_t *coeff,
1098 tran_low_t *qcoeff, tran_low_t *dqcoeff) {
1099 const int tx1d_width = tx_size_wide[tx_size];
1100 dpcm_fwd_tx_func forward_tx = get_dpcm_fwd_tx_func(tx1d_width);
1101 dpcm_inv_txfm_add_func inverse_tx =
1102 av1_get_dpcm_inv_txfm_add_func(tx1d_width);
1103 const int tx1d_height = tx_size_high[tx_size];
1104 const int log_scale = av1_get_tx_scale(tx_size);
1105 int q_idx = 0;
1106 for (int r = 0; r < tx1d_height; ++r) {
1107 // Update prediction.
1108 if (r > 0) memcpy(dst, dst - dst_stride, tx1d_width * sizeof(dst[0]));
1109 // Subtraction.
1110 for (int c = 0; c < tx1d_width; ++c) src_diff[c] = src[c] - dst[c];
1111 // Forward transform.
1112 forward_tx(src_diff, 1, tx_type_1d, coeff);
1113 // Quantization.
1114 for (int c = 0; c < tx1d_width; ++c) {
1115 quantize_scaler(coeff[c], p->zbin[q_idx], p->round[q_idx],
1116 p->quant[q_idx], p->quant_shift[q_idx],
1117 pd->dequant[q_idx], log_scale, &qcoeff[c], &dqcoeff[c]);
1118 q_idx = 1;
1119 }
1120 // Inverse transform.
1121 inverse_tx(dqcoeff, 1, tx_type_1d, dst);
1122 // Move to the next row.
1123 coeff += tx1d_width;
1124 qcoeff += tx1d_width;
1125 dqcoeff += tx1d_width;
1126 src_diff += diff_stride;
1127 dst += dst_stride;
1128 src += src_stride;
1129 }
1130}
1131
1132static void process_block_dpcm_horz(TX_SIZE tx_size, TX_TYPE_1D tx_type_1d,
1133 struct macroblockd_plane *const pd,
1134 struct macroblock_plane *const p,
1135 uint8_t *src, int src_stride, uint8_t *dst,
1136 int dst_stride, int16_t *src_diff,
1137 int diff_stride, tran_low_t *coeff,
1138 tran_low_t *qcoeff, tran_low_t *dqcoeff) {
1139 const int tx1d_height = tx_size_high[tx_size];
1140 dpcm_fwd_tx_func forward_tx = get_dpcm_fwd_tx_func(tx1d_height);
1141 dpcm_inv_txfm_add_func inverse_tx =
1142 av1_get_dpcm_inv_txfm_add_func(tx1d_height);
1143 const int tx1d_width = tx_size_wide[tx_size];
1144 const int log_scale = av1_get_tx_scale(tx_size);
1145 int q_idx = 0;
1146 for (int c = 0; c < tx1d_width; ++c) {
1147 for (int r = 0; r < tx1d_height; ++r) {
1148 // Update prediction.
1149 if (c > 0) dst[r * dst_stride] = dst[r * dst_stride - 1];
1150 // Subtraction.
1151 src_diff[r * diff_stride] = src[r * src_stride] - dst[r * dst_stride];
1152 }
1153 // Forward transform.
1154 tran_low_t tx_buff[64];
1155 forward_tx(src_diff, diff_stride, tx_type_1d, tx_buff);
1156 for (int r = 0; r < tx1d_height; ++r) coeff[r * tx1d_width] = tx_buff[r];
1157 // Quantization.
1158 for (int r = 0; r < tx1d_height; ++r) {
1159 quantize_scaler(coeff[r * tx1d_width], p->zbin[q_idx], p->round[q_idx],
1160 p->quant[q_idx], p->quant_shift[q_idx],
1161 pd->dequant[q_idx], log_scale, &qcoeff[r * tx1d_width],
1162 &dqcoeff[r * tx1d_width]);
1163 q_idx = 1;
1164 }
1165 // Inverse transform.
1166 for (int r = 0; r < tx1d_height; ++r) tx_buff[r] = dqcoeff[r * tx1d_width];
1167 inverse_tx(tx_buff, dst_stride, tx_type_1d, dst);
1168 // Move to the next column.
1169 ++coeff, ++qcoeff, ++dqcoeff, ++src_diff, ++dst, ++src;
1170 }
1171}
1172
1173#if CONFIG_HIGHBITDEPTH
1174static void hbd_process_block_dpcm_vert(
1175 TX_SIZE tx_size, TX_TYPE_1D tx_type_1d, int bd,
1176 struct macroblockd_plane *const pd, struct macroblock_plane *const p,
1177 uint8_t *src8, int src_stride, uint8_t *dst8, int dst_stride,
1178 int16_t *src_diff, int diff_stride, tran_low_t *coeff, tran_low_t *qcoeff,
1179 tran_low_t *dqcoeff) {
1180 const int tx1d_width = tx_size_wide[tx_size];
Sarah Parker31c66502017-05-19 16:51:07 -07001181 hbd_dpcm_fwd_tx_func forward_tx = get_hbd_dpcm_fwd_tx_func(tx1d_width);
hui sub8a6fd62017-05-10 10:57:57 -07001182 hbd_dpcm_inv_txfm_add_func inverse_tx =
1183 av1_get_hbd_dpcm_inv_txfm_add_func(tx1d_width);
1184 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
1185 uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
1186 const int tx1d_height = tx_size_high[tx_size];
1187 const int log_scale = av1_get_tx_scale(tx_size);
1188 int q_idx = 0;
1189 for (int r = 0; r < tx1d_height; ++r) {
1190 // Update prediction.
1191 if (r > 0) memcpy(dst, dst - dst_stride, tx1d_width * sizeof(dst[0]));
1192 // Subtraction.
1193 for (int c = 0; c < tx1d_width; ++c) src_diff[c] = src[c] - dst[c];
1194 // Forward transform.
Sarah Parker31c66502017-05-19 16:51:07 -07001195 forward_tx(src_diff, 1, tx_type_1d, coeff, 1);
hui sub8a6fd62017-05-10 10:57:57 -07001196 // Quantization.
1197 for (int c = 0; c < tx1d_width; ++c) {
1198 quantize_scaler(coeff[c], p->zbin[q_idx], p->round[q_idx],
1199 p->quant[q_idx], p->quant_shift[q_idx],
1200 pd->dequant[q_idx], log_scale, &qcoeff[c], &dqcoeff[c]);
1201 q_idx = 1;
1202 }
1203 // Inverse transform.
Sarah Parker31c66502017-05-19 16:51:07 -07001204 inverse_tx(dqcoeff, 1, tx_type_1d, bd, dst, 1);
hui sub8a6fd62017-05-10 10:57:57 -07001205 // Move to the next row.
1206 coeff += tx1d_width;
1207 qcoeff += tx1d_width;
1208 dqcoeff += tx1d_width;
1209 src_diff += diff_stride;
1210 dst += dst_stride;
1211 src += src_stride;
1212 }
1213}
1214
1215static void hbd_process_block_dpcm_horz(
1216 TX_SIZE tx_size, TX_TYPE_1D tx_type_1d, int bd,
1217 struct macroblockd_plane *const pd, struct macroblock_plane *const p,
1218 uint8_t *src8, int src_stride, uint8_t *dst8, int dst_stride,
1219 int16_t *src_diff, int diff_stride, tran_low_t *coeff, tran_low_t *qcoeff,
1220 tran_low_t *dqcoeff) {
1221 const int tx1d_height = tx_size_high[tx_size];
Sarah Parker31c66502017-05-19 16:51:07 -07001222 hbd_dpcm_fwd_tx_func forward_tx = get_hbd_dpcm_fwd_tx_func(tx1d_height);
hui sub8a6fd62017-05-10 10:57:57 -07001223 hbd_dpcm_inv_txfm_add_func inverse_tx =
1224 av1_get_hbd_dpcm_inv_txfm_add_func(tx1d_height);
1225 uint16_t *src = CONVERT_TO_SHORTPTR(src8);
1226 uint16_t *dst = CONVERT_TO_SHORTPTR(dst8);
1227 const int tx1d_width = tx_size_wide[tx_size];
1228 const int log_scale = av1_get_tx_scale(tx_size);
1229 int q_idx = 0;
1230 for (int c = 0; c < tx1d_width; ++c) {
1231 for (int r = 0; r < tx1d_height; ++r) {
1232 // Update prediction.
1233 if (c > 0) dst[r * dst_stride] = dst[r * dst_stride - 1];
1234 // Subtraction.
1235 src_diff[r * diff_stride] = src[r * src_stride] - dst[r * dst_stride];
1236 }
1237 // Forward transform.
1238 tran_low_t tx_buff[64];
Sarah Parker31c66502017-05-19 16:51:07 -07001239 forward_tx(src_diff, diff_stride, tx_type_1d, tx_buff, 0);
hui sub8a6fd62017-05-10 10:57:57 -07001240 for (int r = 0; r < tx1d_height; ++r) coeff[r * tx1d_width] = tx_buff[r];
1241 // Quantization.
1242 for (int r = 0; r < tx1d_height; ++r) {
1243 quantize_scaler(coeff[r * tx1d_width], p->zbin[q_idx], p->round[q_idx],
1244 p->quant[q_idx], p->quant_shift[q_idx],
1245 pd->dequant[q_idx], log_scale, &qcoeff[r * tx1d_width],
1246 &dqcoeff[r * tx1d_width]);
1247 q_idx = 1;
1248 }
1249 // Inverse transform.
1250 for (int r = 0; r < tx1d_height; ++r) tx_buff[r] = dqcoeff[r * tx1d_width];
Sarah Parker31c66502017-05-19 16:51:07 -07001251 inverse_tx(tx_buff, dst_stride, tx_type_1d, bd, dst, 0);
hui sub8a6fd62017-05-10 10:57:57 -07001252 // Move to the next column.
1253 ++coeff, ++qcoeff, ++dqcoeff, ++src_diff, ++dst, ++src;
1254 }
1255}
1256#endif // CONFIG_HIGHBITDEPTH
1257
1258void av1_encode_block_intra_dpcm(const AV1_COMMON *cm, MACROBLOCK *x,
1259 PREDICTION_MODE mode, int plane, int block,
1260 int blk_row, int blk_col,
1261 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
1262 TX_TYPE tx_type, ENTROPY_CONTEXT *ta,
1263 ENTROPY_CONTEXT *tl, int8_t *skip) {
1264 MACROBLOCKD *const xd = &x->e_mbd;
1265 struct macroblock_plane *const p = &x->plane[plane];
1266 struct macroblockd_plane *const pd = &xd->plane[plane];
1267 tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1268 const int diff_stride = block_size_wide[plane_bsize];
1269 const int src_stride = p->src.stride;
1270 const int dst_stride = pd->dst.stride;
1271 const int tx1d_width = tx_size_wide[tx_size];
1272 const int tx1d_height = tx_size_high[tx_size];
Angie Chiangbd99b382017-06-20 15:11:16 -07001273 const SCAN_ORDER *const scan_order =
1274 get_scan(cm, tx_size, tx_type, &xd->mi[0]->mbmi);
hui sub8a6fd62017-05-10 10:57:57 -07001275 tran_low_t *coeff = BLOCK_OFFSET(p->coeff, block);
1276 tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
1277 uint8_t *dst =
1278 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
1279 uint8_t *src =
1280 &p->src.buf[(blk_row * src_stride + blk_col) << tx_size_wide_log2[0]];
1281 int16_t *src_diff =
1282 &p->src_diff[(blk_row * diff_stride + blk_col) << tx_size_wide_log2[0]];
1283 uint16_t *eob = &p->eobs[block];
1284 *eob = 0;
1285 memset(qcoeff, 0, tx1d_height * tx1d_width * sizeof(*qcoeff));
1286 memset(dqcoeff, 0, tx1d_height * tx1d_width * sizeof(*dqcoeff));
1287
1288 if (LIKELY(!x->skip_block)) {
1289 TX_TYPE_1D tx_type_1d = DCT_1D;
1290 switch (tx_type) {
1291 case IDTX: tx_type_1d = IDTX_1D; break;
1292 case V_DCT:
1293 assert(mode == H_PRED);
1294 tx_type_1d = DCT_1D;
1295 break;
1296 case H_DCT:
1297 assert(mode == V_PRED);
1298 tx_type_1d = DCT_1D;
1299 break;
1300 default: assert(0);
1301 }
1302 switch (mode) {
1303 case V_PRED:
1304#if CONFIG_HIGHBITDEPTH
1305 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1306 hbd_process_block_dpcm_vert(tx_size, tx_type_1d, xd->bd, pd, p, src,
1307 src_stride, dst, dst_stride, src_diff,
1308 diff_stride, coeff, qcoeff, dqcoeff);
1309 } else {
1310#endif // CONFIG_HIGHBITDEPTH
1311 process_block_dpcm_vert(tx_size, tx_type_1d, pd, p, src, src_stride,
1312 dst, dst_stride, src_diff, diff_stride, coeff,
1313 qcoeff, dqcoeff);
1314#if CONFIG_HIGHBITDEPTH
1315 }
1316#endif // CONFIG_HIGHBITDEPTH
1317 break;
1318 case H_PRED:
1319#if CONFIG_HIGHBITDEPTH
1320 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1321 hbd_process_block_dpcm_horz(tx_size, tx_type_1d, xd->bd, pd, p, src,
1322 src_stride, dst, dst_stride, src_diff,
1323 diff_stride, coeff, qcoeff, dqcoeff);
1324 } else {
1325#endif // CONFIG_HIGHBITDEPTH
1326 process_block_dpcm_horz(tx_size, tx_type_1d, pd, p, src, src_stride,
1327 dst, dst_stride, src_diff, diff_stride, coeff,
1328 qcoeff, dqcoeff);
1329#if CONFIG_HIGHBITDEPTH
1330 }
1331#endif // CONFIG_HIGHBITDEPTH
1332 break;
1333 default: assert(0);
1334 }
1335 *eob = get_eob(qcoeff, tx1d_height * tx1d_width, scan_order->scan);
1336 }
1337
1338 ta[blk_col] = tl[blk_row] = *eob > 0;
1339 if (*eob) *skip = 0;
1340}
1341#endif // CONFIG_DPCM_INTRA
1342
Yaowu Xuf883b422016-08-30 14:01:10 -07001343void av1_encode_block_intra(int plane, int block, int blk_row, int blk_col,
1344 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
1345 void *arg) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001346 struct encode_b_args *const args = arg;
Angie Chiangff6d8902016-10-21 11:02:09 -07001347 AV1_COMMON *cm = args->cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001348 MACROBLOCK *const x = args->x;
1349 MACROBLOCKD *const xd = &x->e_mbd;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001350 struct macroblock_plane *const p = &x->plane[plane];
1351 struct macroblockd_plane *const pd = &xd->plane[plane];
1352 tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
Luc Trudeau005feb62017-02-22 13:34:01 -05001353 PLANE_TYPE plane_type = get_plane_type(plane);
Angie Chiang752ccce2017-04-09 13:41:13 -07001354 const TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001355 uint16_t *eob = &p->eobs[block];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001356 const int dst_stride = pd->dst.stride;
Angie Chiangf87e43f2017-04-02 16:51:19 -07001357 uint8_t *dst =
1358 &pd->dst.buf[(blk_row * dst_stride + blk_col) << tx_size_wide_log2[0]];
Luc Trudeauf5334002017-04-25 12:21:26 -04001359#if CONFIG_CFL
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04001360
1361#if CONFIG_EC_ADAPT
1362 FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
1363#else
1364 FRAME_CONTEXT *const ec_ctx = cm->fc;
1365#endif // CONFIG_EC_ADAPT
1366
Luc Trudeau3dc55e02017-06-22 14:03:47 -04001367#if CONFIG_DEBUG
1368 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1369// av1_predict_intra_block_facade does not pass plane_bsize, we need to validate
1370// that we will get the same value of plane_bsize on the other side.
1371#if CONFIG_CHROMA_SUB8X8
1372 const BLOCK_SIZE plane_bsize_val =
1373 AOMMAX(BLOCK_4X4, get_plane_block_size(mbmi->sb_type, &xd->plane[plane]));
1374#else
1375 const BLOCK_SIZE plane_bsize_val =
1376 get_plane_block_size(mbmi->sb_type, &xd->plane[plane]);
1377#endif // CONFIG_CHROMA_SUB8X8
1378 assert(plane_bsize == plane_bsize_val);
1379#endif // CONFIG_DEBUG
1380
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04001381 av1_predict_intra_block_encoder_facade(x, ec_ctx, plane, block, blk_col,
Luc Trudeau3dc55e02017-06-22 14:03:47 -04001382 blk_row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04001383#else
Angie Chiang752ccce2017-04-09 13:41:13 -07001384 av1_predict_intra_block_facade(xd, plane, block, blk_col, blk_row, tx_size);
Luc Trudeauf5334002017-04-25 12:21:26 -04001385#endif
hui sub8a6fd62017-05-10 10:57:57 -07001386
1387#if CONFIG_DPCM_INTRA
1388 const int block_raster_idx = av1_block_index_to_raster_order(tx_size, block);
1389 const MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
1390 const PREDICTION_MODE mode =
1391 (plane == 0) ? get_y_mode(xd->mi[0], block_raster_idx) : mbmi->uv_mode;
1392 if (av1_use_dpcm_intra(plane, mode, tx_type, mbmi)) {
1393 av1_encode_block_intra_dpcm(cm, x, mode, plane, block, blk_row, blk_col,
1394 plane_bsize, tx_size, tx_type, args->ta,
1395 args->tl, args->skip);
1396 return;
1397 }
1398#endif // CONFIG_DPCM_INTRA
1399
Angie Chiangf87e43f2017-04-02 16:51:19 -07001400 av1_subtract_txb(x, plane, plane_bsize, blk_col, blk_row, tx_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001401
Angie Chiang36aca332017-03-23 14:16:24 -07001402 const ENTROPY_CONTEXT *a = &args->ta[blk_col];
1403 const ENTROPY_CONTEXT *l = &args->tl[blk_row];
Angie Chiang57605532017-04-03 11:51:15 -07001404 int ctx = combine_entropy_contexts(*a, *l);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001405 if (args->enable_optimize_b) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001406 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001407 ctx, AV1_XFORM_QUANT_FP);
Angie Chiang3511c372017-05-31 12:47:07 -07001408 av1_optimize_b(cm, x, plane, block, plane_bsize, tx_size, a, l);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001409 } else {
Debargha Mukherjeef0305582016-11-24 09:55:34 -08001410 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
1411 ctx, AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001412 }
1413
Angie Chiang57605532017-04-03 11:51:15 -07001414#if CONFIG_PVQ
Yushin Cho3827fdd2016-11-09 15:50:23 -08001415 // *(args->skip) == mbmi->skip
1416 if (!x->pvq_skip[plane]) *(args->skip) = 0;
1417
1418 if (x->pvq_skip[plane]) return;
Angie Chiang50910f62017-04-03 12:31:34 -07001419#endif // CONFIG_PVQ
Angie Chiangd92d4bf2017-04-02 17:49:18 -07001420 av1_inverse_transform_block(xd, dqcoeff, tx_type, tx_size, dst, dst_stride,
1421 *eob);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001422#if !CONFIG_PVQ
1423 if (*eob) *(args->skip) = 0;
1424#else
1425// Note : *(args->skip) == mbmi->skip
1426#endif
Luc Trudeaue3980282017-04-25 23:17:21 -04001427#if CONFIG_CFL
1428 if (plane == AOM_PLANE_Y && x->cfl_store_y) {
1429 cfl_store(xd->cfl, dst, dst_stride, blk_row, blk_col, tx_size);
1430 }
1431#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001432}
1433
Luc Trudeauf5334002017-04-25 12:21:26 -04001434#if CONFIG_CFL
Luc Trudeau3dc55e02017-06-22 14:03:47 -04001435static int cfl_alpha_dist(const uint8_t *y_pix, int y_stride,
1436 const double y_average, const uint8_t *src,
1437 int src_stride, int width, int height,
1438 TX_SIZE tx_size, double dc_pred, double alpha,
1439 int *dist_neg_out) {
David Michael Barrd3b01b82017-04-27 19:58:52 +09001440 const double dc_pred_bias = dc_pred + 0.5;
1441 int dist = 0;
1442 int diff;
Luc Trudeauf5334002017-04-25 12:21:26 -04001443
David Michael Barrd3b01b82017-04-27 19:58:52 +09001444 if (alpha == 0.0) {
1445 const int dc_pred_i = (int)dc_pred_bias;
Luc Trudeau8fb4c9e2017-06-12 16:23:16 -04001446 for (int j = 0; j < height; j++) {
1447 for (int i = 0; i < width; i++) {
David Michael Barrd3b01b82017-04-27 19:58:52 +09001448 diff = src[i] - dc_pred_i;
1449 dist += diff * diff;
1450 }
1451 src += src_stride;
1452 }
1453
1454 if (dist_neg_out) *dist_neg_out = dist;
1455
1456 return dist;
1457 }
1458
1459 int dist_neg = 0;
Luc Trudeau8fb4c9e2017-06-12 16:23:16 -04001460 const int tx_height = tx_size_high[tx_size];
1461 const int tx_width = tx_size_wide[tx_size];
Luc Trudeau3dc55e02017-06-22 14:03:47 -04001462 const int y_block_row_off = y_stride * tx_height;
1463 const int src_block_row_off = src_stride * tx_height;
Luc Trudeau8fb4c9e2017-06-12 16:23:16 -04001464 const uint8_t *t_y_pix;
1465 const uint8_t *t_src;
1466 for (int b_j = 0; b_j < height; b_j += tx_height) {
1467 const int h = b_j + tx_height;
1468 for (int b_i = 0; b_i < width; b_i += tx_width) {
1469 const int w = b_i + tx_width;
1470 t_y_pix = y_pix;
1471 t_src = src;
1472 for (int t_j = b_j; t_j < h; t_j++) {
1473 for (int t_i = b_i; t_i < w; t_i++) {
Luc Trudeau3dc55e02017-06-22 14:03:47 -04001474 const double scaled_luma = alpha * (t_y_pix[t_i] - y_average);
Luc Trudeau8fb4c9e2017-06-12 16:23:16 -04001475 const int uv = t_src[t_i];
1476 diff = uv - (int)(scaled_luma + dc_pred_bias);
1477 dist += diff * diff;
1478 diff = uv + (int)(scaled_luma - dc_pred_bias);
1479 dist_neg += diff * diff;
1480 }
1481 t_y_pix += y_stride;
1482 t_src += src_stride;
1483 }
David Michael Barrd3b01b82017-04-27 19:58:52 +09001484 }
Luc Trudeau3dc55e02017-06-22 14:03:47 -04001485 y_pix += y_block_row_off;
1486 src += src_block_row_off;
David Michael Barrd3b01b82017-04-27 19:58:52 +09001487 }
1488
1489 if (dist_neg_out) *dist_neg_out = dist_neg;
1490
1491 return dist;
1492}
1493
Luc Trudeau1a474302017-05-12 10:21:31 -04001494static inline void cfl_update_costs(CFL_CTX *cfl, FRAME_CONTEXT *ec_ctx) {
1495 assert(ec_ctx->cfl_alpha_cdf[CFL_ALPHABET_SIZE - 1] ==
1496 AOM_ICDF(CDF_PROB_TOP));
1497 const int prob_den = CDF_PROB_TOP;
1498
1499 int prob_num = AOM_ICDF(ec_ctx->cfl_alpha_cdf[0]);
1500 cfl->costs[0] = av1_cost_zero(get_prob(prob_num, prob_den));
1501
1502 for (int c = 1; c < CFL_ALPHABET_SIZE; c++) {
David Michael Barr84a44db2017-05-16 23:31:09 +09001503 int sign_bit_cost = (cfl_alpha_codes[c][CFL_PRED_U] != 0) +
1504 (cfl_alpha_codes[c][CFL_PRED_V] != 0);
Luc Trudeau1a474302017-05-12 10:21:31 -04001505 prob_num = AOM_ICDF(ec_ctx->cfl_alpha_cdf[c]) -
1506 AOM_ICDF(ec_ctx->cfl_alpha_cdf[c - 1]);
1507 cfl->costs[c] = av1_cost_zero(get_prob(prob_num, prob_den)) +
1508 av1_cost_literal(sign_bit_cost);
1509 }
1510}
1511
Luc Trudeau3dc55e02017-06-22 14:03:47 -04001512static void cfl_compute_alpha_ind(MACROBLOCK *const x, FRAME_CONTEXT *ec_ctx,
1513 TX_SIZE tx_size) {
1514 const struct macroblock_plane *const p_u = &x->plane[AOM_PLANE_U];
1515 const struct macroblock_plane *const p_v = &x->plane[AOM_PLANE_V];
1516 const uint8_t *const src_u = p_u->src.buf;
1517 const uint8_t *const src_v = p_v->src.buf;
1518 const int src_stride_u = p_u->src.stride;
1519 const int src_stride_v = p_v->src.stride;
1520
1521 MACROBLOCKD *const xd = &x->e_mbd;
1522 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1523
1524 CFL_CTX *const cfl = xd->cfl;
1525 cfl_compute_parameters(xd, tx_size);
1526 const int width = cfl->uv_width;
1527 const int height = cfl->uv_height;
1528 const double dc_pred_u = cfl->dc_pred[CFL_PRED_U];
1529 const double dc_pred_v = cfl->dc_pred[CFL_PRED_V];
1530 const double y_average = cfl->y_average;
1531 const uint8_t *y_pix = cfl->y_down_pix;
1532
1533 CFL_SIGN_TYPE *signs = mbmi->cfl_alpha_signs;
1534
1535 cfl_update_costs(cfl, ec_ctx);
1536
1537 int sse[CFL_PRED_PLANES][CFL_MAGS_SIZE];
1538 sse[CFL_PRED_U][0] =
1539 cfl_alpha_dist(y_pix, MAX_SB_SIZE, y_average, src_u, src_stride_u, width,
1540 height, tx_size, dc_pred_u, 0, NULL);
1541 sse[CFL_PRED_V][0] =
1542 cfl_alpha_dist(y_pix, MAX_SB_SIZE, y_average, src_v, src_stride_v, width,
1543 height, tx_size, dc_pred_v, 0, NULL);
1544 for (int m = 1; m < CFL_MAGS_SIZE; m += 2) {
1545 assert(cfl_alpha_mags[m + 1] == -cfl_alpha_mags[m]);
1546 sse[CFL_PRED_U][m] = cfl_alpha_dist(
1547 y_pix, MAX_SB_SIZE, y_average, src_u, src_stride_u, width, height,
1548 tx_size, dc_pred_u, cfl_alpha_mags[m], &sse[CFL_PRED_U][m + 1]);
1549 sse[CFL_PRED_V][m] = cfl_alpha_dist(
1550 y_pix, MAX_SB_SIZE, y_average, src_v, src_stride_v, width, height,
1551 tx_size, dc_pred_v, cfl_alpha_mags[m], &sse[CFL_PRED_V][m + 1]);
1552 }
1553
1554 int dist;
1555 int64_t cost;
1556 int64_t best_cost;
1557
1558 // Compute least squares parameter of the entire block
1559 // IMPORTANT: We assume that the first code is 0,0
1560 int ind = 0;
1561 signs[CFL_PRED_U] = CFL_SIGN_POS;
1562 signs[CFL_PRED_V] = CFL_SIGN_POS;
1563
1564 dist = sse[CFL_PRED_U][0] + sse[CFL_PRED_V][0];
1565 dist *= 16;
1566 best_cost = RDCOST(x->rdmult, cfl->costs[0], dist);
1567
1568 for (int c = 1; c < CFL_ALPHABET_SIZE; c++) {
1569 const int idx_u = cfl_alpha_codes[c][CFL_PRED_U];
1570 const int idx_v = cfl_alpha_codes[c][CFL_PRED_V];
1571 for (CFL_SIGN_TYPE sign_u = idx_u == 0; sign_u < CFL_SIGNS; sign_u++) {
1572 for (CFL_SIGN_TYPE sign_v = idx_v == 0; sign_v < CFL_SIGNS; sign_v++) {
1573 dist = sse[CFL_PRED_U][idx_u + (sign_u == CFL_SIGN_NEG)] +
1574 sse[CFL_PRED_V][idx_v + (sign_v == CFL_SIGN_NEG)];
1575 dist *= 16;
1576 cost = RDCOST(x->rdmult, cfl->costs[c], dist);
1577 if (cost < best_cost) {
1578 best_cost = cost;
1579 ind = c;
1580 signs[CFL_PRED_U] = sign_u;
1581 signs[CFL_PRED_V] = sign_v;
1582 }
1583 }
1584 }
1585 }
1586
1587 mbmi->cfl_alpha_idx = ind;
1588}
1589
Luc Trudeaue8dfbcf2017-05-12 09:57:50 -04001590void av1_predict_intra_block_encoder_facade(MACROBLOCK *x,
1591 FRAME_CONTEXT *ec_ctx, int plane,
David Michael Barrd3b01b82017-04-27 19:58:52 +09001592 int block_idx, int blk_col,
Luc Trudeau3dc55e02017-06-22 14:03:47 -04001593 int blk_row, TX_SIZE tx_size) {
David Michael Barrd3b01b82017-04-27 19:58:52 +09001594 MACROBLOCKD *const xd = &x->e_mbd;
1595 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
David Michael Barrd3b01b82017-04-27 19:58:52 +09001596 if (plane != AOM_PLANE_Y && mbmi->uv_mode == DC_PRED) {
1597 if (blk_col == 0 && blk_row == 0 && plane == AOM_PLANE_U) {
Luc Trudeau3dc55e02017-06-22 14:03:47 -04001598 cfl_compute_alpha_ind(x, ec_ctx, tx_size);
David Michael Barrd3b01b82017-04-27 19:58:52 +09001599 }
1600 }
Luc Trudeauf5334002017-04-25 12:21:26 -04001601 av1_predict_intra_block_facade(xd, plane, block_idx, blk_col, blk_row,
1602 tx_size);
1603}
1604#endif
1605
Angie Chiangff6d8902016-10-21 11:02:09 -07001606void av1_encode_intra_block_plane(AV1_COMMON *cm, MACROBLOCK *x,
1607 BLOCK_SIZE bsize, int plane,
Yaowu Xu1e4e5b92017-05-05 11:06:42 -07001608 int enable_optimize_b, int mi_row,
1609 int mi_col) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001610 const MACROBLOCKD *const xd = &x->e_mbd;
Guillaume Martrese50d9dd2016-12-18 18:26:47 +01001611 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE] = { 0 };
1612 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE] = { 0 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001613
Angie Chiangff6d8902016-10-21 11:02:09 -07001614 struct encode_b_args arg = {
1615 cm, x, NULL, &xd->mi[0]->mbmi.skip, ta, tl, enable_optimize_b
1616 };
Jingning Han18c53c82017-02-17 14:49:57 -08001617
1618#if CONFIG_CB4X4
Jingning Hand3a64432017-04-06 17:04:17 -07001619 if (!is_chroma_reference(mi_row, mi_col, bsize,
1620 xd->plane[plane].subsampling_x,
1621 xd->plane[plane].subsampling_y))
Jingning Han18c53c82017-02-17 14:49:57 -08001622 return;
1623#else
1624 (void)mi_row;
1625 (void)mi_col;
1626#endif
1627
Yaowu Xuc27fc142016-08-22 16:08:15 -07001628 if (enable_optimize_b) {
1629 const struct macroblockd_plane *const pd = &xd->plane[plane];
Angie Chiang7fcfee42017-02-24 15:51:03 -08001630 const TX_SIZE tx_size = get_tx_size(plane, xd);
Yaowu Xuf883b422016-08-30 14:01:10 -07001631 av1_get_entropy_contexts(bsize, tx_size, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001632 }
Angie Chiang36aca332017-03-23 14:16:24 -07001633 av1_foreach_transformed_block_in_plane(
1634 xd, bsize, plane, encode_block_intra_and_set_context, &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001635}
Yushin Cho77bba8d2016-11-04 16:36:56 -07001636
1637#if CONFIG_PVQ
Thomas Daede6ff6af62017-02-03 16:29:24 -08001638PVQ_SKIP_TYPE av1_pvq_encode_helper(MACROBLOCK *x, tran_low_t *const coeff,
1639 tran_low_t *ref_coeff,
1640 tran_low_t *const dqcoeff, uint16_t *eob,
1641 const int16_t *quant, int plane,
1642 int tx_size, TX_TYPE tx_type, int *rate,
1643 int speed, PVQ_INFO *pvq_info) {
Yushin Cho77bba8d2016-11-04 16:36:56 -07001644 const int tx_blk_size = tx_size_wide[tx_size];
Thomas Daede6ff6af62017-02-03 16:29:24 -08001645 daala_enc_ctx *daala_enc = &x->daala_enc;
ltrudeaue1c09292017-01-20 15:42:13 -05001646 PVQ_SKIP_TYPE ac_dc_coded;
Jingning Hanff705452017-04-27 11:32:15 -07001647 int coeff_shift = 3 - av1_get_tx_scale(tx_size);
Thomas Daede6ff6af62017-02-03 16:29:24 -08001648 int hbd_downshift = 0;
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001649 int rounding_mask;
Yushin Cho70669122016-12-08 09:53:14 -10001650 int pvq_dc_quant;
1651 int use_activity_masking = daala_enc->use_activity_masking;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001652 int tell;
1653 int has_dc_skip = 1;
1654 int i;
1655 int off = od_qm_offset(tx_size, plane ? 1 : 0);
Yushin Cho70669122016-12-08 09:53:14 -10001656
Thomas Daede1dbda1b2017-02-06 16:06:29 -08001657 DECLARE_ALIGNED(16, tran_low_t, coeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1658 DECLARE_ALIGNED(16, tran_low_t, ref_coeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1659 DECLARE_ALIGNED(16, tran_low_t, dqcoeff_pvq[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001660
Yushin Cho48f84db2016-11-07 21:20:17 -08001661 DECLARE_ALIGNED(16, int32_t, in_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1662 DECLARE_ALIGNED(16, int32_t, ref_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
1663 DECLARE_ALIGNED(16, int32_t, out_int32[OD_TXSIZE_MAX * OD_TXSIZE_MAX]);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001664
Thomas Daede6ff6af62017-02-03 16:29:24 -08001665 hbd_downshift = x->e_mbd.bd - 8;
Thomas Daede6ff6af62017-02-03 16:29:24 -08001666
1667 assert(OD_COEFF_SHIFT >= 4);
Yushin Cho70669122016-12-08 09:53:14 -10001668 // DC quantizer for PVQ
1669 if (use_activity_masking)
clang-format55ce9e02017-02-15 22:27:12 -08001670 pvq_dc_quant =
Thomas Daede6ff6af62017-02-03 16:29:24 -08001671 OD_MAXI(1, (quant[0] << (OD_COEFF_SHIFT - 3) >> hbd_downshift) *
clang-format55ce9e02017-02-15 22:27:12 -08001672 daala_enc->state
1673 .pvq_qm_q4[plane][od_qm_get_index(tx_size, 0)] >>
1674 4);
Yushin Cho70669122016-12-08 09:53:14 -10001675 else
Thomas Daede6ff6af62017-02-03 16:29:24 -08001676 pvq_dc_quant =
1677 OD_MAXI(1, quant[0] << (OD_COEFF_SHIFT - 3) >> hbd_downshift);
Yushin Cho70669122016-12-08 09:53:14 -10001678
Yushin Cho77bba8d2016-11-04 16:36:56 -07001679 *eob = 0;
1680
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001681#if !CONFIG_ANS
Nathan E. Egge6675be02016-12-21 13:02:43 -05001682 tell = od_ec_enc_tell_frac(&daala_enc->w.ec);
1683#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001684#error "CONFIG_PVQ currently requires !CONFIG_ANS."
Nathan E. Egge6675be02016-12-21 13:02:43 -05001685#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001686
1687 // Change coefficient ordering for pvq encoding.
1688 od_raster_to_coding_order(coeff_pvq, tx_blk_size, tx_type, coeff,
1689 tx_blk_size);
1690 od_raster_to_coding_order(ref_coeff_pvq, tx_blk_size, tx_type, ref_coeff,
1691 tx_blk_size);
1692
1693 // copy int16 inputs to int32
1694 for (i = 0; i < tx_blk_size * tx_blk_size; i++) {
Timothy B. Terriberry4e6a8f32017-02-24 11:00:59 -08001695 ref_int32[i] =
Thomas Daede6ff6af62017-02-03 16:29:24 -08001696 AOM_SIGNED_SHL(ref_coeff_pvq[i], OD_COEFF_SHIFT - coeff_shift) >>
1697 hbd_downshift;
1698 in_int32[i] = AOM_SIGNED_SHL(coeff_pvq[i], OD_COEFF_SHIFT - coeff_shift) >>
1699 hbd_downshift;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001700 }
1701
Yushin Cho77bba8d2016-11-04 16:36:56 -07001702 if (abs(in_int32[0] - ref_int32[0]) < pvq_dc_quant * 141 / 256) { /* 0.55 */
1703 out_int32[0] = 0;
1704 } else {
1705 out_int32[0] = OD_DIV_R0(in_int32[0] - ref_int32[0], pvq_dc_quant);
1706 }
1707
Thomas Daede6ff6af62017-02-03 16:29:24 -08001708 ac_dc_coded =
1709 od_pvq_encode(daala_enc, ref_int32, in_int32, out_int32,
1710 OD_MAXI(1, quant[0] << (OD_COEFF_SHIFT - 3) >>
1711 hbd_downshift), // scale/quantizer
1712 OD_MAXI(1, quant[1] << (OD_COEFF_SHIFT - 3) >>
1713 hbd_downshift), // scale/quantizer
1714 plane,
1715 tx_size, OD_PVQ_BETA[use_activity_masking][plane][tx_size],
Yushin Cho31b980a2017-03-23 10:28:09 -07001716 0, // is_keyframe,
Thomas Daede6ff6af62017-02-03 16:29:24 -08001717 daala_enc->state.qm + off, daala_enc->state.qm_inv + off,
1718 speed, // speed
1719 pvq_info);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001720
1721 // Encode residue of DC coeff, if required.
1722 if (!has_dc_skip || out_int32[0]) {
Yushin Choc49ef3a2017-03-13 17:27:25 -07001723 generic_encode(&daala_enc->w, &daala_enc->state.adapt->model_dc[plane],
Timothy B. Terriberry44bb6d02017-04-07 15:44:14 -07001724 abs(out_int32[0]) - has_dc_skip,
Yushin Choc49ef3a2017-03-13 17:27:25 -07001725 &daala_enc->state.adapt->ex_dc[plane][tx_size][0], 2);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001726 }
1727 if (out_int32[0]) {
Nathan E. Egge6675be02016-12-21 13:02:43 -05001728 aom_write_bit(&daala_enc->w, out_int32[0] < 0);
Yushin Cho77bba8d2016-11-04 16:36:56 -07001729 }
1730
1731 // need to save quantized residue of DC coeff
1732 // so that final pvq bitstream writing can know whether DC is coded.
1733 if (pvq_info) pvq_info->dq_dc_residue = out_int32[0];
1734
1735 out_int32[0] = out_int32[0] * pvq_dc_quant;
1736 out_int32[0] += ref_int32[0];
1737
1738 // copy int32 result back to int16
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001739 assert(OD_COEFF_SHIFT > coeff_shift);
1740 rounding_mask = (1 << (OD_COEFF_SHIFT - coeff_shift - 1)) - 1;
1741 for (i = 0; i < tx_blk_size * tx_blk_size; i++) {
Thomas Daede6ff6af62017-02-03 16:29:24 -08001742 out_int32[i] = AOM_SIGNED_SHL(out_int32[i], hbd_downshift);
Timothy B. Terriberrye93acb22017-02-06 13:55:53 -08001743 dqcoeff_pvq[i] = (out_int32[i] + (out_int32[i] < 0) + rounding_mask) >>
1744 (OD_COEFF_SHIFT - coeff_shift);
1745 }
Yushin Cho77bba8d2016-11-04 16:36:56 -07001746
1747 // Back to original coefficient order
1748 od_coding_order_to_raster(dqcoeff, tx_blk_size, tx_type, dqcoeff_pvq,
1749 tx_blk_size);
1750
1751 *eob = tx_blk_size * tx_blk_size;
1752
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001753#if !CONFIG_ANS
Nathan E. Egge6675be02016-12-21 13:02:43 -05001754 *rate = (od_ec_enc_tell_frac(&daala_enc->w.ec) - tell)
Yushin Cho77bba8d2016-11-04 16:36:56 -07001755 << (AV1_PROB_COST_SHIFT - OD_BITRES);
Nathan E. Egge6675be02016-12-21 13:02:43 -05001756#else
Nathan E. Egge476c63c2017-05-18 18:35:16 -04001757#error "CONFIG_PVQ currently requires !CONFIG_ANS."
Nathan E. Egge6675be02016-12-21 13:02:43 -05001758#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -07001759 assert(*rate >= 0);
Yushin Cho5c207292017-02-16 15:01:33 -08001760
ltrudeau472f63f2017-01-12 15:22:32 -05001761 return ac_dc_coded;
Yushin Cho77bba8d2016-11-04 16:36:56 -07001762}
1763
Timothy B. Terriberry44bb6d02017-04-07 15:44:14 -07001764void av1_store_pvq_enc_info(PVQ_INFO *pvq_info, int *qg, int *theta, int *k,
1765 od_coeff *y, int nb_bands, const int *off,
1766 int *size, int skip_rest, int skip_dir,
Yushin Cho77bba8d2016-11-04 16:36:56 -07001767 int bs) { // block size in log_2 -2
1768 int i;
1769 const int tx_blk_size = tx_size_wide[bs];
1770
1771 for (i = 0; i < nb_bands; i++) {
1772 pvq_info->qg[i] = qg[i];
1773 pvq_info->theta[i] = theta[i];
Yushin Cho77bba8d2016-11-04 16:36:56 -07001774 pvq_info->k[i] = k[i];
1775 pvq_info->off[i] = off[i];
1776 pvq_info->size[i] = size[i];
1777 }
1778
1779 memcpy(pvq_info->y, y, tx_blk_size * tx_blk_size * sizeof(od_coeff));
1780
1781 pvq_info->nb_bands = nb_bands;
1782 pvq_info->skip_rest = skip_rest;
1783 pvq_info->skip_dir = skip_dir;
1784 pvq_info->bs = bs;
1785}
1786#endif