blob: 03ddf2c1ce6ff386aea33f62e493a4556be588c5 [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
16#include "aom_dsp/quantize.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070017#include "aom_mem/aom_mem.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070018#include "aom_ports/mem.h"
19
20#include "av1/common/idct.h"
21#include "av1/common/reconinter.h"
22#include "av1/common/reconintra.h"
23#include "av1/common/scan.h"
24
25#include "av1/encoder/encodemb.h"
26#include "av1/encoder/hybrid_fwd_txfm.h"
27#include "av1/encoder/quantize.h"
28#include "av1/encoder/rd.h"
29#include "av1/encoder/tokenize.h"
30
Yaowu Xuf883b422016-08-30 14:01:10 -070031void av1_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070032 struct macroblock_plane *const p = &x->plane[plane];
33 const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane];
34 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
35 const int bw = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
36 const int bh = 4 * num_4x4_blocks_high_lookup[plane_bsize];
37
Yaowu Xuf883b422016-08-30 14:01:10 -070038#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -070039 if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -070040 aom_highbd_subtract_block(bh, bw, p->src_diff, bw, p->src.buf,
Yaowu Xuc27fc142016-08-22 16:08:15 -070041 p->src.stride, pd->dst.buf, pd->dst.stride,
42 x->e_mbd.bd);
43 return;
44 }
Yaowu Xuf883b422016-08-30 14:01:10 -070045#endif // CONFIG_AOM_HIGHBITDEPTH
46 aom_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -070047 pd->dst.buf, pd->dst.stride);
48}
49
Yaowu Xuf883b422016-08-30 14:01:10 -070050typedef struct av1_token_state {
Yaowu Xuc27fc142016-08-22 16:08:15 -070051 int rate;
52 int64_t error;
53 int next;
54 int16_t token;
55 tran_low_t qc;
56 tran_low_t dqc;
Yaowu Xuf883b422016-08-30 14:01:10 -070057} av1_token_state;
Yaowu Xuc27fc142016-08-22 16:08:15 -070058
59// These numbers are empirically obtained.
60static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] = {
61 { 10, 6 }, { 8, 5 },
62};
63
64#define UPDATE_RD_COST() \
65 { \
66 rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0); \
67 rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1); \
68 }
69
Angie Chiangff6d8902016-10-21 11:02:09 -070070int av1_optimize_b(const AV1_COMMON *cm, MACROBLOCK *mb, int plane, int block,
71 TX_SIZE tx_size, int ctx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -070072 MACROBLOCKD *const xd = &mb->e_mbd;
73 struct macroblock_plane *const p = &mb->plane[plane];
74 struct macroblockd_plane *const pd = &xd->plane[plane];
75 const int ref = is_inter_block(&xd->mi[0]->mbmi);
Yaowu Xuf883b422016-08-30 14:01:10 -070076 av1_token_state tokens[MAX_TX_SQUARE + 1][2];
Yaowu Xuc27fc142016-08-22 16:08:15 -070077 unsigned best_index[MAX_TX_SQUARE + 1][2];
78 uint8_t token_cache[MAX_TX_SQUARE];
79 const tran_low_t *const coeff = BLOCK_OFFSET(mb->plane[plane].coeff, block);
80 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
81 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
82 const int eob = p->eobs[block];
Debargha Mukherjee3c42c092016-09-29 09:17:36 -070083 const PLANE_TYPE plane_type = pd->plane_type;
Jingning Hande953b92016-10-25 12:35:43 -070084 const int default_eob = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -070085 const int16_t *const dequant_ptr = pd->dequant;
86 const uint8_t *const band_translate = get_band_translate(tx_size);
Debargha Mukherjee3c42c092016-09-29 09:17:36 -070087 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Urvang Joshi03f6fdc2016-10-14 15:53:39 -070088 const SCAN_ORDER *const scan_order =
Angie Chiangff6d8902016-10-21 11:02:09 -070089 get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
Urvang Joshi03f6fdc2016-10-14 15:53:39 -070090 const int16_t *const scan = scan_order->scan;
91 const int16_t *const nb = scan_order->neighbors;
Yaowu Xuc27fc142016-08-22 16:08:15 -070092#if CONFIG_AOM_QM
93 int seg_id = xd->mi[0]->mbmi.segment_id;
Debargha Mukherjee3c42c092016-09-29 09:17:36 -070094 const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!ref][tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -070095#endif
96 const int shift = get_tx_scale(xd, tx_type, tx_size);
97#if CONFIG_NEW_QUANT
David Barkerd7d78c82016-10-24 10:55:35 +010098 int dq = get_dq_profile_from_ctx(mb->qindex, ctx, ref, plane_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -070099 const dequant_val_type_nuq *dequant_val = pd->dequant_val_nuq[dq];
100#else
101 const int dq_step[2] = { dequant_ptr[0] >> shift, dequant_ptr[1] >> shift };
102#endif // CONFIG_NEW_QUANT
103 int next = eob, sz = 0;
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700104 const int64_t rdmult = (mb->rdmult * plane_rd_mult[ref][plane_type]) >> 1;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700105 const int64_t rddiv = mb->rddiv;
106 int64_t rd_cost0, rd_cost1;
107 int rate0, rate1;
108 int64_t error0, error1;
109 int16_t t0, t1;
110 int best, band = (eob < default_eob) ? band_translate[eob]
111 : band_translate[eob - 1];
112 int pt, i, final_eob;
Yaowu Xuf883b422016-08-30 14:01:10 -0700113#if CONFIG_AOM_HIGHBITDEPTH
114 const int *cat6_high_cost = av1_get_high_cost_table(xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700115#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700116 const int *cat6_high_cost = av1_get_high_cost_table(8);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700117#endif
118 unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700119 mb->token_costs[txsize_sqr_map[tx_size]][plane_type][ref];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700120 const uint16_t *band_counts = &band_count_table[tx_size][band];
121 uint16_t band_left = eob - band_cum_count_table[tx_size][band] + 1;
122 int shortcut = 0;
123 int next_shortcut = 0;
124
David Barkerd7d78c82016-10-24 10:55:35 +0100125 assert((mb->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700126
Yaowu Xuc27fc142016-08-22 16:08:15 -0700127 token_costs += band;
128
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700129 assert((!plane_type && !plane) || (plane_type && plane));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700130 assert(eob <= default_eob);
131
132 /* Now set up a Viterbi trellis to evaluate alternative roundings. */
133 /* Initialize the sentinel node of the trellis. */
134 tokens[eob][0].rate = 0;
135 tokens[eob][0].error = 0;
136 tokens[eob][0].next = default_eob;
137 tokens[eob][0].token = EOB_TOKEN;
138 tokens[eob][0].qc = 0;
139 tokens[eob][1] = tokens[eob][0];
140
141 for (i = 0; i < eob; i++) {
142 const int rc = scan[i];
Yaowu Xuf883b422016-08-30 14:01:10 -0700143 tokens[i][0].rate = av1_get_token_cost(qcoeff[rc], &t0, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700144 tokens[i][0].token = t0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700145 token_cache[rc] = av1_pt_energy_class[t0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700146 }
147
148 for (i = eob; i-- > 0;) {
149 int base_bits, dx;
150 int64_t d2;
151 const int rc = scan[i];
152#if CONFIG_AOM_QM
153 int iwt = iqmatrix[rc];
154#endif
155 int x = qcoeff[rc];
156 next_shortcut = shortcut;
157
158 /* Only add a trellis state for non-zero coefficients. */
159 if (UNLIKELY(x)) {
160 error0 = tokens[next][0].error;
161 error1 = tokens[next][1].error;
162 /* Evaluate the first possibility for this state. */
163 rate0 = tokens[next][0].rate;
164 rate1 = tokens[next][1].rate;
165
166 if (next_shortcut) {
167 /* Consider both possible successor states. */
168 if (next < default_eob) {
169 pt = get_coef_context(nb, token_cache, i + 1);
170 rate0 += (*token_costs)[0][pt][tokens[next][0].token];
171 rate1 += (*token_costs)[0][pt][tokens[next][1].token];
172 }
173 UPDATE_RD_COST();
174 /* And pick the best. */
175 best = rd_cost1 < rd_cost0;
176 } else {
177 if (next < default_eob) {
178 pt = get_coef_context(nb, token_cache, i + 1);
179 rate0 += (*token_costs)[0][pt][tokens[next][0].token];
180 }
181 best = 0;
182 }
183
184 dx = (dqcoeff[rc] - coeff[rc]) * (1 << shift);
Yaowu Xuf883b422016-08-30 14:01:10 -0700185#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700186 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
187 dx >>= xd->bd - 8;
188 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700189#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700190 d2 = (int64_t)dx * dx;
191 tokens[i][0].rate += (best ? rate1 : rate0);
192 tokens[i][0].error = d2 + (best ? error1 : error0);
193 tokens[i][0].next = next;
194 tokens[i][0].qc = x;
195 tokens[i][0].dqc = dqcoeff[rc];
196 best_index[i][0] = best;
197
198 /* Evaluate the second possibility for this state. */
199 rate0 = tokens[next][0].rate;
200 rate1 = tokens[next][1].rate;
201
202 // The threshold of 3 is empirically obtained.
203 if (UNLIKELY(abs(x) > 3)) {
204 shortcut = 0;
205 } else {
206#if CONFIG_NEW_QUANT
Yaowu Xuf883b422016-08-30 14:01:10 -0700207 shortcut = ((av1_dequant_abscoeff_nuq(abs(x), dequant_ptr[rc != 0],
208 dequant_val[band_translate[i]]) >
Yaowu Xuc27fc142016-08-22 16:08:15 -0700209 (abs(coeff[rc]) << shift)) &&
Yaowu Xuf883b422016-08-30 14:01:10 -0700210 (av1_dequant_abscoeff_nuq(abs(x) - 1, dequant_ptr[rc != 0],
211 dequant_val[band_translate[i]]) <
Yaowu Xuc27fc142016-08-22 16:08:15 -0700212 (abs(coeff[rc]) << shift)));
213#else // CONFIG_NEW_QUANT
214#if CONFIG_AOM_QM
215 if ((abs(x) * dequant_ptr[rc != 0] * iwt >
216 ((abs(coeff[rc]) << shift) << AOM_QM_BITS)) &&
217 (abs(x) * dequant_ptr[rc != 0] * iwt <
218 (((abs(coeff[rc]) << shift) + dequant_ptr[rc != 0])
219 << AOM_QM_BITS)))
220#else
221 if ((abs(x) * dequant_ptr[rc != 0] > (abs(coeff[rc]) << shift)) &&
222 (abs(x) * dequant_ptr[rc != 0] <
223 (abs(coeff[rc]) << shift) + dequant_ptr[rc != 0]))
224#endif // CONFIG_AOM_QM
225 shortcut = 1;
226 else
227 shortcut = 0;
228#endif // CONFIG_NEW_QUANT
229 }
230
231 if (shortcut) {
232 sz = -(x < 0);
233 x -= 2 * sz + 1;
234 } else {
235 tokens[i][1] = tokens[i][0];
236 best_index[i][1] = best_index[i][0];
237 next = i;
238
239 if (UNLIKELY(!(--band_left))) {
240 --band_counts;
241 band_left = *band_counts;
242 --token_costs;
243 }
244 continue;
245 }
246
247 /* Consider both possible successor states. */
248 if (!x) {
249 /* If we reduced this coefficient to zero, check to see if
250 * we need to move the EOB back here.
251 */
252 t0 = tokens[next][0].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
253 t1 = tokens[next][1].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
254 base_bits = 0;
255 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700256 base_bits = av1_get_token_cost(x, &t0, cat6_high_cost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700257 t1 = t0;
258 }
259
260 if (next_shortcut) {
261 if (LIKELY(next < default_eob)) {
262 if (t0 != EOB_TOKEN) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700263 token_cache[rc] = av1_pt_energy_class[t0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700264 pt = get_coef_context(nb, token_cache, i + 1);
265 rate0 += (*token_costs)[!x][pt][tokens[next][0].token];
266 }
267 if (t1 != EOB_TOKEN) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700268 token_cache[rc] = av1_pt_energy_class[t1];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700269 pt = get_coef_context(nb, token_cache, i + 1);
270 rate1 += (*token_costs)[!x][pt][tokens[next][1].token];
271 }
272 }
273
274 UPDATE_RD_COST();
275 /* And pick the best. */
276 best = rd_cost1 < rd_cost0;
277 } else {
278 // The two states in next stage are identical.
279 if (next < default_eob && t0 != EOB_TOKEN) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700280 token_cache[rc] = av1_pt_energy_class[t0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700281 pt = get_coef_context(nb, token_cache, i + 1);
282 rate0 += (*token_costs)[!x][pt][tokens[next][0].token];
283 }
284 best = 0;
285 }
286
287#if CONFIG_NEW_QUANT
Yaowu Xuf883b422016-08-30 14:01:10 -0700288 dx = av1_dequant_coeff_nuq(x, dequant_ptr[rc != 0],
289 dequant_val[band_translate[i]]) -
Yaowu Xuc27fc142016-08-22 16:08:15 -0700290 (coeff[rc] << shift);
Yaowu Xuf883b422016-08-30 14:01:10 -0700291#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700292 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
293 dx >>= xd->bd - 8;
294 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700295#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700296#else // CONFIG_NEW_QUANT
Yaowu Xuf883b422016-08-30 14:01:10 -0700297#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700298 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
299 dx -= ((dequant_ptr[rc != 0] >> (xd->bd - 8)) + sz) ^ sz;
300 } else {
301 dx -= (dequant_ptr[rc != 0] + sz) ^ sz;
302 }
303#else
304 dx -= (dequant_ptr[rc != 0] + sz) ^ sz;
Yaowu Xuf883b422016-08-30 14:01:10 -0700305#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700306#endif // CONFIG_NEW_QUANT
307 d2 = (int64_t)dx * dx;
308
309 tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
310 tokens[i][1].error = d2 + (best ? error1 : error0);
311 tokens[i][1].next = next;
312 tokens[i][1].token = best ? t1 : t0;
313 tokens[i][1].qc = x;
314
315 if (x) {
316#if CONFIG_NEW_QUANT
Yaowu Xuf883b422016-08-30 14:01:10 -0700317 tokens[i][1].dqc = av1_dequant_abscoeff_nuq(
Yaowu Xuc27fc142016-08-22 16:08:15 -0700318 abs(x), dequant_ptr[rc != 0], dequant_val[band_translate[i]]);
319 tokens[i][1].dqc = shift ? ROUND_POWER_OF_TWO(tokens[i][1].dqc, shift)
320 : tokens[i][1].dqc;
321 if (sz) tokens[i][1].dqc = -tokens[i][1].dqc;
322#else
323 tran_low_t offset = dq_step[rc != 0];
324 // The 32x32 transform coefficient uses half quantization step size.
325 // Account for the rounding difference in the dequantized coefficeint
326 // value when the quantization index is dropped from an even number
327 // to an odd number.
328 if (shift & x) offset += (dequant_ptr[rc != 0] & 0x01);
329
330 if (sz == 0)
331 tokens[i][1].dqc = dqcoeff[rc] - offset;
332 else
333 tokens[i][1].dqc = dqcoeff[rc] + offset;
334#endif // CONFIG_NEW_QUANT
335 } else {
336 tokens[i][1].dqc = 0;
337 }
338
339 best_index[i][1] = best;
340 /* Finally, make this the new head of the trellis. */
341 next = i;
342 } else {
343 /* There's no choice to make for a zero coefficient, so we don't
344 * add a new trellis node, but we do need to update the costs.
345 */
346 t0 = tokens[next][0].token;
347 t1 = tokens[next][1].token;
348 pt = get_coef_context(nb, token_cache, i + 1);
349 /* Update the cost of each path if we're past the EOB token. */
350 if (t0 != EOB_TOKEN) {
351 tokens[next][0].rate += (*token_costs)[1][pt][t0];
352 tokens[next][0].token = ZERO_TOKEN;
353 }
354 if (t1 != EOB_TOKEN) {
355 tokens[next][1].rate += (*token_costs)[1][pt][t1];
356 tokens[next][1].token = ZERO_TOKEN;
357 }
358 best_index[i][0] = best_index[i][1] = 0;
359 shortcut = (tokens[next][0].rate != tokens[next][1].rate);
360 /* Don't update next, because we didn't add a new node. */
361 }
362
363 if (UNLIKELY(!(--band_left))) {
364 --band_counts;
365 band_left = *band_counts;
366 --token_costs;
367 }
368 }
369
370 /* Now pick the best path through the whole trellis. */
371 rate0 = tokens[next][0].rate;
372 rate1 = tokens[next][1].rate;
373 error0 = tokens[next][0].error;
374 error1 = tokens[next][1].error;
375 t0 = tokens[next][0].token;
376 t1 = tokens[next][1].token;
377 rate0 += (*token_costs)[0][ctx][t0];
378 rate1 += (*token_costs)[0][ctx][t1];
379 UPDATE_RD_COST();
380 best = rd_cost1 < rd_cost0;
381
382 final_eob = -1;
383
384 for (i = next; i < eob; i = next) {
385 const int x = tokens[i][best].qc;
386 const int rc = scan[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700387 if (x) final_eob = i;
388 qcoeff[rc] = x;
389 dqcoeff[rc] = tokens[i][best].dqc;
390
391 next = tokens[i][best].next;
392 best = best_index[i][best];
393 }
394 final_eob++;
395
396 mb->plane[plane].eobs[block] = final_eob;
397 assert(final_eob <= default_eob);
398 return final_eob;
399}
400
Yaowu Xuf883b422016-08-30 14:01:10 -0700401#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700402typedef enum QUANT_FUNC {
403 QUANT_FUNC_LOWBD = 0,
404 QUANT_FUNC_HIGHBD = 1,
405 QUANT_FUNC_LAST = 2
406} QUANT_FUNC;
407
Yaowu Xuf883b422016-08-30 14:01:10 -0700408static AV1_QUANT_FACADE quant_func_list[AV1_XFORM_QUANT_LAST][QUANT_FUNC_LAST] =
409 { { av1_quantize_fp_facade, av1_highbd_quantize_fp_facade },
410 { av1_quantize_b_facade, av1_highbd_quantize_b_facade },
411 { av1_quantize_dc_facade, av1_highbd_quantize_dc_facade },
412 { NULL, NULL } };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700413
414#else
415typedef enum QUANT_FUNC {
416 QUANT_FUNC_LOWBD = 0,
417 QUANT_FUNC_LAST = 1
418} QUANT_FUNC;
419
clang-format67948d32016-09-07 22:40:40 -0700420static AV1_QUANT_FACADE quant_func_list[AV1_XFORM_QUANT_LAST]
421 [QUANT_FUNC_LAST] = {
422 { av1_quantize_fp_facade },
423 { av1_quantize_b_facade },
424 { av1_quantize_dc_facade },
425 { NULL }
426 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700427#endif
428
Yaowu Xuf883b422016-08-30 14:01:10 -0700429static FWD_TXFM_OPT fwd_txfm_opt_list[AV1_XFORM_QUANT_LAST] = {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700430 FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_DC, FWD_TXFM_OPT_NORMAL
431};
432
Angie Chiangff6d8902016-10-21 11:02:09 -0700433void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
434 int blk_row, int blk_col, BLOCK_SIZE plane_bsize,
435 TX_SIZE tx_size, AV1_XFORM_QUANT xform_quant_idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700436 MACROBLOCKD *const xd = &x->e_mbd;
437 const struct macroblock_plane *const p = &x->plane[plane];
438 const struct macroblockd_plane *const pd = &xd->plane[plane];
439 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
440 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700441 const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
Angie Chiangff6d8902016-10-21 11:02:09 -0700442 const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700443 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
444 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
445 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
446 uint16_t *const eob = &p->eobs[block];
447 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
448#if CONFIG_AOM_QM
449 int seg_id = xd->mi[0]->mbmi.segment_id;
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700450 const qm_val_t *qmatrix = pd->seg_qmatrix[seg_id][!is_inter][tx_size];
451 const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!is_inter][tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700452#endif
453 const int16_t *src_diff;
Jingning Han7e992972016-10-31 11:03:06 -0700454 const int tx2d_size = tx_size_2d[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700455
456 FWD_TXFM_PARAM fwd_txfm_param;
457 QUANT_PARAM qparam;
458
459 fwd_txfm_param.tx_type = tx_type;
460 fwd_txfm_param.tx_size = tx_size;
461 fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[xform_quant_idx];
462 fwd_txfm_param.rd_transform = x->use_lp32x32fdct;
463 fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
464
465 src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
466
467 qparam.log_scale = get_tx_scale(xd, tx_type, tx_size);
Yaowu Xuf883b422016-08-30 14:01:10 -0700468#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700469 fwd_txfm_param.bd = xd->bd;
470 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
471 highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -0700472 if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700473 if (LIKELY(!x->skip_block)) {
474 quant_func_list[xform_quant_idx][QUANT_FUNC_HIGHBD](
475 coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam
476#if CONFIG_AOM_QM
477 ,
478 qmatrix, iqmatrix
479#endif // CONFIG_AOM_QM
480 );
481 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700482 av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700483 }
484 }
485 return;
486 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700487#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700488
489 fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -0700490 if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700491 if (LIKELY(!x->skip_block)) {
492 quant_func_list[xform_quant_idx][QUANT_FUNC_LOWBD](
493 coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam
494#if CONFIG_AOM_QM
495 ,
496 qmatrix, iqmatrix
497#endif // CONFIG_AOM_QM
498 );
499 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700500 av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700501 }
502 }
503}
504
505#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -0700506void av1_xform_quant_nuq(const AV1_COMMON *cm, MACROBLOCK *x, int plane,
507 int block, int blk_row, int blk_col,
508 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, int ctx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700509 MACROBLOCKD *const xd = &x->e_mbd;
510 const struct macroblock_plane *const p = &x->plane[plane];
511 const struct macroblockd_plane *const pd = &xd->plane[plane];
512 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
513 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Debargha Mukherjee9324d382016-09-23 10:52:13 -0700514 const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
Angie Chiangff6d8902016-10-21 11:02:09 -0700515 const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, is_inter);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700516 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
517 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
518 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
David Barkerd7d78c82016-10-24 10:55:35 +0100519 int dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700520 uint16_t *const eob = &p->eobs[block];
521 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
522 const int16_t *src_diff;
523 const uint8_t *band = get_band_translate(tx_size);
524
525 FWD_TXFM_PARAM fwd_txfm_param;
526
David Barkerd7d78c82016-10-24 10:55:35 +0100527 assert((x->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700528
Yaowu Xuc27fc142016-08-22 16:08:15 -0700529 fwd_txfm_param.tx_type = tx_type;
530 fwd_txfm_param.tx_size = tx_size;
Yaowu Xuf883b422016-08-30 14:01:10 -0700531 fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_FP];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700532 fwd_txfm_param.rd_transform = x->use_lp32x32fdct;
533 fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
534
535 src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
536
537// TODO(sarahparker) add all of these new quant quantize functions
538// to quant_func_list, just trying to get this expr to work for now
Yaowu Xuf883b422016-08-30 14:01:10 -0700539#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700540 fwd_txfm_param.bd = xd->bd;
541 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
542 highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
543 if (tx_size == TX_32X32) {
544 highbd_quantize_32x32_nuq(
Jingning Han7e992972016-10-31 11:03:06 -0700545 coeff, tx_size_2d[tx_size], x->skip_block, p->quant, p->quant_shift,
546 pd->dequant, (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
Yaowu Xuc27fc142016-08-22 16:08:15 -0700547 (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
548 dqcoeff, eob, scan_order->scan, band);
549 } else {
Jingning Han7e992972016-10-31 11:03:06 -0700550 highbd_quantize_nuq(coeff, tx_size_2d[tx_size], x->skip_block, p->quant,
551 p->quant_shift, pd->dequant,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700552 (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
553 (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq],
554 qcoeff, dqcoeff, eob, scan_order->scan, band);
555 }
556 return;
557 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700558#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700559
560 fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
561 if (tx_size == TX_32X32) {
562 quantize_32x32_nuq(coeff, 1024, x->skip_block, p->quant, p->quant_shift,
563 pd->dequant,
564 (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
565 (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq],
566 qcoeff, dqcoeff, eob, scan_order->scan, band);
567 } else {
Jingning Han7e992972016-10-31 11:03:06 -0700568 quantize_nuq(coeff, tx_size_2d[tx_size], x->skip_block, p->quant,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700569 p->quant_shift, pd->dequant,
570 (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
571 (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
572 dqcoeff, eob, scan_order->scan, band);
573 }
574}
575
Angie Chiangff6d8902016-10-21 11:02:09 -0700576void av1_xform_quant_fp_nuq(const AV1_COMMON *cm, MACROBLOCK *x, int plane,
577 int block, int blk_row, int blk_col,
578 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, int ctx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700579 MACROBLOCKD *const xd = &x->e_mbd;
580 const struct macroblock_plane *const p = &x->plane[plane];
581 const struct macroblockd_plane *const pd = &xd->plane[plane];
Debargha Mukherjee9324d382016-09-23 10:52:13 -0700582 const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700583 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
584 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
Angie Chiangff6d8902016-10-21 11:02:09 -0700585 const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, is_inter);
David Barkerd7d78c82016-10-24 10:55:35 +0100586 int dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700587 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
588 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
589 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
590 uint16_t *const eob = &p->eobs[block];
591 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
592 const int16_t *src_diff;
593 const uint8_t *band = get_band_translate(tx_size);
594
595 FWD_TXFM_PARAM fwd_txfm_param;
596
David Barkerd7d78c82016-10-24 10:55:35 +0100597 assert((x->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700598
Yaowu Xuc27fc142016-08-22 16:08:15 -0700599 fwd_txfm_param.tx_type = tx_type;
600 fwd_txfm_param.tx_size = tx_size;
Yaowu Xuf883b422016-08-30 14:01:10 -0700601 fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_FP];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700602 fwd_txfm_param.rd_transform = x->use_lp32x32fdct;
603 fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
604
605 src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
606
607// TODO(sarahparker) add all of these new quant quantize functions
608// to quant_func_list, just trying to get this expr to work for now
Yaowu Xuf883b422016-08-30 14:01:10 -0700609#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700610 fwd_txfm_param.bd = xd->bd;
611 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
612 highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
613 if (tx_size == TX_32X32) {
614 highbd_quantize_32x32_fp_nuq(
Jingning Han7e992972016-10-31 11:03:06 -0700615 coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp, pd->dequant,
616 (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
Yaowu Xuc27fc142016-08-22 16:08:15 -0700617 (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
618 dqcoeff, eob, scan_order->scan, band);
619 } else {
620 highbd_quantize_fp_nuq(
Jingning Han7e992972016-10-31 11:03:06 -0700621 coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp, pd->dequant,
622 (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
Yaowu Xuc27fc142016-08-22 16:08:15 -0700623 (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq], qcoeff,
624 dqcoeff, eob, scan_order->scan, band);
625 }
626 return;
627 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700628#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700629
630 fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
631 if (tx_size == TX_32X32) {
Jingning Han7e992972016-10-31 11:03:06 -0700632 quantize_32x32_fp_nuq(coeff, tx_size_2d[tx_size], x->skip_block,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700633 p->quant_fp, pd->dequant,
634 (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
635 (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq],
636 qcoeff, dqcoeff, eob, scan_order->scan, band);
637 } else {
Jingning Han7e992972016-10-31 11:03:06 -0700638 quantize_fp_nuq(coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700639 pd->dequant,
640 (const cuml_bins_type_nuq *)p->cuml_bins_nuq[dq],
641 (const dequant_val_type_nuq *)pd->dequant_val_nuq[dq],
642 qcoeff, dqcoeff, eob, scan_order->scan, band);
643 }
644}
645
Yaowu Xuf883b422016-08-30 14:01:10 -0700646void av1_xform_quant_dc_nuq(MACROBLOCK *x, int plane, int block, int blk_row,
647 int blk_col, BLOCK_SIZE plane_bsize,
648 TX_SIZE tx_size, int ctx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700649 MACROBLOCKD *const xd = &x->e_mbd;
650 const struct macroblock_plane *const p = &x->plane[plane];
651 const struct macroblockd_plane *const pd = &xd->plane[plane];
652 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
653 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
654 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
655 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
656 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
657 uint16_t *const eob = &p->eobs[block];
658 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
659 const int16_t *src_diff;
Debargha Mukherjee9324d382016-09-23 10:52:13 -0700660 const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
David Barkerd7d78c82016-10-24 10:55:35 +0100661 int dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700662
663 FWD_TXFM_PARAM fwd_txfm_param;
664
David Barkerd7d78c82016-10-24 10:55:35 +0100665 assert((x->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700666
Yaowu Xuc27fc142016-08-22 16:08:15 -0700667 fwd_txfm_param.tx_type = tx_type;
668 fwd_txfm_param.tx_size = tx_size;
Yaowu Xuf883b422016-08-30 14:01:10 -0700669 fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_DC];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700670 fwd_txfm_param.rd_transform = x->use_lp32x32fdct;
671 fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
672
673 src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
674
675// TODO(sarahparker) add all of these new quant quantize functions
676// to quant_func_list, just trying to get this expr to work for now
Yaowu Xuf883b422016-08-30 14:01:10 -0700677#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700678 fwd_txfm_param.bd = xd->bd;
679 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
680 highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
681 if (tx_size == TX_32X32) {
682 highbd_quantize_dc_32x32_nuq(
Jingning Han7e992972016-10-31 11:03:06 -0700683 coeff, tx_size_2d[tx_size], x->skip_block, p->quant[0],
Yaowu Xuc27fc142016-08-22 16:08:15 -0700684 p->quant_shift[0], pd->dequant[0], p->cuml_bins_nuq[dq][0],
685 pd->dequant_val_nuq[dq][0], qcoeff, dqcoeff, eob);
686 } else {
Jingning Han7e992972016-10-31 11:03:06 -0700687 highbd_quantize_dc_nuq(coeff, tx_size_2d[tx_size], x->skip_block,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700688 p->quant[0], p->quant_shift[0], pd->dequant[0],
689 p->cuml_bins_nuq[dq][0],
690 pd->dequant_val_nuq[dq][0], qcoeff, dqcoeff, eob);
691 }
692 return;
693 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700694#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700695
696 fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
697 if (tx_size == TX_32X32) {
Jingning Han7e992972016-10-31 11:03:06 -0700698 quantize_dc_32x32_nuq(coeff, tx_size_2d[tx_size], x->skip_block,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700699 p->quant[0], p->quant_shift[0], pd->dequant[0],
700 p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
701 qcoeff, dqcoeff, eob);
702 } else {
Jingning Han7e992972016-10-31 11:03:06 -0700703 quantize_dc_nuq(coeff, tx_size_2d[tx_size], x->skip_block, p->quant[0],
Yaowu Xuc27fc142016-08-22 16:08:15 -0700704 p->quant_shift[0], pd->dequant[0], p->cuml_bins_nuq[dq][0],
705 pd->dequant_val_nuq[dq][0], qcoeff, dqcoeff, eob);
706 }
707}
708
Yaowu Xuf883b422016-08-30 14:01:10 -0700709void av1_xform_quant_dc_fp_nuq(MACROBLOCK *x, int plane, int block, int blk_row,
710 int blk_col, BLOCK_SIZE plane_bsize,
711 TX_SIZE tx_size, int ctx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700712 MACROBLOCKD *const xd = &x->e_mbd;
713 const struct macroblock_plane *const p = &x->plane[plane];
714 const struct macroblockd_plane *const pd = &xd->plane[plane];
715 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
716 TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
717 tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
718 tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
719 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
720 uint16_t *const eob = &p->eobs[block];
721 const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
722 const int16_t *src_diff;
Debargha Mukherjee9324d382016-09-23 10:52:13 -0700723 const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
David Barkerd7d78c82016-10-24 10:55:35 +0100724 int dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700725
726 FWD_TXFM_PARAM fwd_txfm_param;
727
David Barkerd7d78c82016-10-24 10:55:35 +0100728 assert((x->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
Debargha Mukherjee3c42c092016-09-29 09:17:36 -0700729
Yaowu Xuc27fc142016-08-22 16:08:15 -0700730 fwd_txfm_param.tx_type = tx_type;
731 fwd_txfm_param.tx_size = tx_size;
Yaowu Xuf883b422016-08-30 14:01:10 -0700732 fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[AV1_XFORM_QUANT_DC];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700733 fwd_txfm_param.rd_transform = x->use_lp32x32fdct;
734 fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
735
736 src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
737
738// TODO(sarahparker) add all of these new quant quantize functions
739// to quant_func_list, just trying to get this expr to work for now
Yaowu Xuf883b422016-08-30 14:01:10 -0700740#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700741 fwd_txfm_param.bd = xd->bd;
742 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
743 highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
744 if (tx_size == TX_32X32) {
745 highbd_quantize_dc_32x32_fp_nuq(
Jingning Han7e992972016-10-31 11:03:06 -0700746 coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp[0],
Yaowu Xuc27fc142016-08-22 16:08:15 -0700747 pd->dequant[0], p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
748 qcoeff, dqcoeff, eob);
749 } else {
750 highbd_quantize_dc_fp_nuq(
Jingning Han7e992972016-10-31 11:03:06 -0700751 coeff, tx_size_2d[tx_size], x->skip_block, p->quant_fp[0],
Yaowu Xuc27fc142016-08-22 16:08:15 -0700752 pd->dequant[0], p->cuml_bins_nuq[dq][0], pd->dequant_val_nuq[dq][0],
753 qcoeff, dqcoeff, eob);
754 }
755 return;
756 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700757#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700758
759 fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
760 if (tx_size == TX_32X32) {
Jingning Han7e992972016-10-31 11:03:06 -0700761 quantize_dc_32x32_fp_nuq(coeff, tx_size_2d[tx_size], x->skip_block,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700762 p->quant_fp[0], pd->dequant[0],
763 p->cuml_bins_nuq[dq][0],
764 pd->dequant_val_nuq[dq][0], qcoeff, dqcoeff, eob);
765 } else {
Jingning Han7e992972016-10-31 11:03:06 -0700766 quantize_dc_fp_nuq(coeff, tx_size_2d[tx_size], x->skip_block,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700767 p->quant_fp[0], pd->dequant[0], p->cuml_bins_nuq[dq][0],
768 pd->dequant_val_nuq[dq][0], qcoeff, dqcoeff, eob);
769 }
770}
771#endif // CONFIG_NEW_QUANT
772
773static void encode_block(int plane, int block, int blk_row, int blk_col,
774 BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
775 struct encode_b_args *const args = arg;
Angie Chiangff6d8902016-10-21 11:02:09 -0700776 AV1_COMMON *cm = args->cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700777 MACROBLOCK *const x = args->x;
778 MACROBLOCKD *const xd = &x->e_mbd;
779 int ctx;
780 struct macroblock_plane *const p = &x->plane[plane];
781 struct macroblockd_plane *const pd = &xd->plane[plane];
782 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
783 uint8_t *dst;
784 ENTROPY_CONTEXT *a, *l;
785 INV_TXFM_PARAM inv_txfm_param;
786#if CONFIG_VAR_TX
787 int i;
788 const int bwl = b_width_log2_lookup[plane_bsize];
789#endif
790 dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
791 a = &args->ta[blk_col];
792 l = &args->tl[blk_row];
793#if CONFIG_VAR_TX
794 ctx = get_entropy_context(tx_size, a, l);
795#else
796 ctx = combine_entropy_contexts(*a, *l);
797#endif
798
799#if CONFIG_VAR_TX
Yue Chena1e48dc2016-08-29 17:29:33 -0700800 // Assert not magic number (uninitialized).
Yaowu Xuc27fc142016-08-22 16:08:15 -0700801 assert(x->blk_skip[plane][(blk_row << bwl) + blk_col] != 234);
802
803 if (x->blk_skip[plane][(blk_row << bwl) + blk_col] == 0) {
804#else
805 {
806#endif
807#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -0700808 av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -0700809 tx_size, ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700810#else
Angie Chiangff6d8902016-10-21 11:02:09 -0700811 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -0700812 AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700813#endif // CONFIG_NEW_QUANT
814 }
815#if CONFIG_VAR_TX
816 else {
817 p->eobs[block] = 0;
818 }
819#endif
820
821 if (p->eobs[block]) {
Angie Chiangff6d8902016-10-21 11:02:09 -0700822 *a = *l = av1_optimize_b(cm, x, plane, block, tx_size, ctx) > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700823 } else {
824 *a = *l = p->eobs[block] > 0;
825 }
826
827#if CONFIG_VAR_TX
Jingning Hande953b92016-10-25 12:35:43 -0700828 for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) a[i] = a[0];
829
830 for (i = 0; i < tx_size_high_unit[tx_size]; ++i) l[i] = l[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700831#endif
832
833 if (p->eobs[block]) *(args->skip) = 0;
834
835 if (p->eobs[block] == 0) return;
836
837 // inverse transform parameters
838 inv_txfm_param.tx_type = get_tx_type(pd->plane_type, xd, block, tx_size);
839 inv_txfm_param.tx_size = tx_size;
840 inv_txfm_param.eob = p->eobs[block];
841 inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];
842
Yaowu Xuf883b422016-08-30 14:01:10 -0700843#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700844 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
845 inv_txfm_param.bd = xd->bd;
846 highbd_inv_txfm_add(dqcoeff, dst, pd->dst.stride, &inv_txfm_param);
847 return;
848 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700849#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700850 inv_txfm_add(dqcoeff, dst, pd->dst.stride, &inv_txfm_param);
851}
852
853#if CONFIG_VAR_TX
854static void encode_block_inter(int plane, int block, int blk_row, int blk_col,
855 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
856 void *arg) {
857 struct encode_b_args *const args = arg;
858 MACROBLOCK *const x = args->x;
859 MACROBLOCKD *const xd = &x->e_mbd;
860 MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
861 const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
862 const struct macroblockd_plane *const pd = &xd->plane[plane];
863 const int tx_row = blk_row >> (1 - pd->subsampling_y);
864 const int tx_col = blk_col >> (1 - pd->subsampling_x);
865 TX_SIZE plane_tx_size;
866
867 int max_blocks_high = num_4x4_blocks_high_lookup[plane_bsize];
868 int max_blocks_wide = num_4x4_blocks_wide_lookup[plane_bsize];
869
870 if (xd->mb_to_bottom_edge < 0)
871 max_blocks_high += xd->mb_to_bottom_edge >> (5 + pd->subsampling_y);
872 if (xd->mb_to_right_edge < 0)
873 max_blocks_wide += xd->mb_to_right_edge >> (5 + pd->subsampling_x);
874
875 if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
876
Debargha Mukherjee2f123402016-08-30 17:43:38 -0700877 plane_tx_size =
878 plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
879 : mbmi->inter_tx_size[tx_row][tx_col];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700880
881 if (tx_size == plane_tx_size) {
882 encode_block(plane, block, blk_row, blk_col, plane_bsize, tx_size, arg);
883 } else {
Jingning Hande953b92016-10-25 12:35:43 -0700884 int bsl = block_size_wide[bsize] >> (tx_size_wide_log2[0] + 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700885 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700886 assert(bsl > 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700887#if CONFIG_EXT_TX
888 assert(tx_size < TX_SIZES);
889#endif // CONFIG_EXT_TX
890
891 for (i = 0; i < 4; ++i) {
Jingning Hande953b92016-10-25 12:35:43 -0700892 const int offsetr = blk_row + ((i >> 1) * bsl);
893 const int offsetc = blk_col + ((i & 0x01) * bsl);
894 const TX_SIZE sub_txs = tx_size - 1;
895 int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700896
897 if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
898
899 encode_block_inter(plane, block + i * step, offsetr, offsetc, plane_bsize,
Jingning Hande953b92016-10-25 12:35:43 -0700900 sub_txs, arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700901 }
902 }
903}
904#endif
905
Angie Chiangff6d8902016-10-21 11:02:09 -0700906typedef struct encode_block_pass1_args {
907 AV1_COMMON *cm;
908 MACROBLOCK *x;
909} encode_block_pass1_args;
910
Yaowu Xuc27fc142016-08-22 16:08:15 -0700911static void encode_block_pass1(int plane, int block, int blk_row, int blk_col,
912 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
913 void *arg) {
Angie Chiangff6d8902016-10-21 11:02:09 -0700914 encode_block_pass1_args *args = (encode_block_pass1_args *)arg;
915 AV1_COMMON *cm = args->cm;
916 MACROBLOCK *const x = args->x;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700917 MACROBLOCKD *const xd = &x->e_mbd;
918 struct macroblock_plane *const p = &x->plane[plane];
919 struct macroblockd_plane *const pd = &xd->plane[plane];
920 tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
921 uint8_t *dst;
922#if CONFIG_NEW_QUANT
923 int ctx;
924#endif // CONFIG_NEW_QUANT
925 dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
926
927#if CONFIG_NEW_QUANT
928 ctx = 0;
Angie Chiangff6d8902016-10-21 11:02:09 -0700929 av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -0700930 tx_size, ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700931#else
Angie Chiangff6d8902016-10-21 11:02:09 -0700932 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -0700933 AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700934#endif // CONFIG_NEW_QUANT
935
936 if (p->eobs[block] > 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700937#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700938 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
939 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700940 av1_highbd_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block],
941 xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700942 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700943 av1_highbd_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block],
944 xd->bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700945 }
946 return;
947 }
Yaowu Xuf883b422016-08-30 14:01:10 -0700948#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700949 if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700950 av1_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700951 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700952 av1_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700953 }
954 }
955}
956
Angie Chiangff6d8902016-10-21 11:02:09 -0700957void av1_encode_sby_pass1(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
958 encode_block_pass1_args args = { cm, x };
Yaowu Xuf883b422016-08-30 14:01:10 -0700959 av1_subtract_plane(x, bsize, 0);
960 av1_foreach_transformed_block_in_plane(&x->e_mbd, bsize, 0,
Angie Chiangff6d8902016-10-21 11:02:09 -0700961 encode_block_pass1, &args);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700962}
963
Angie Chiangff6d8902016-10-21 11:02:09 -0700964void av1_encode_sb(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700965 MACROBLOCKD *const xd = &x->e_mbd;
966 struct optimize_ctx ctx;
967 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -0700968 struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Yaowu Xuc27fc142016-08-22 16:08:15 -0700969 int plane;
970
971 mbmi->skip = 1;
972
973 if (x->skip) return;
974
975 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
976#if CONFIG_VAR_TX
977 // TODO(jingning): Clean this up.
978 const struct macroblockd_plane *const pd = &xd->plane[plane];
979 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
Jingning Hande953b92016-10-25 12:35:43 -0700980 const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
981 const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700982 const TX_SIZE max_tx_size = max_txsize_lookup[plane_bsize];
983 const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
Jingning Hande953b92016-10-25 12:35:43 -0700984 const int bw = block_size_wide[txb_size] >> tx_size_wide_log2[0];
985 const int bh = block_size_high[txb_size] >> tx_size_wide_log2[0];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700986 int idx, idy;
987 int block = 0;
Jingning Hande953b92016-10-25 12:35:43 -0700988 int step = tx_size_wide_unit[max_tx_size] * tx_size_high_unit[max_tx_size];
Yaowu Xuf883b422016-08-30 14:01:10 -0700989 av1_get_entropy_contexts(bsize, TX_4X4, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700990#else
991 const struct macroblockd_plane *const pd = &xd->plane[plane];
992 const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
Yaowu Xuf883b422016-08-30 14:01:10 -0700993 av1_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700994#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700995 av1_subtract_plane(x, bsize, plane);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700996 arg.ta = ctx.ta[plane];
997 arg.tl = ctx.tl[plane];
998
999#if CONFIG_VAR_TX
1000#if CONFIG_EXT_TX && CONFIG_RECT_TX
Yue Chena1e48dc2016-08-29 17:29:33 -07001001 if (is_rect_tx(mbmi->tx_size)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001002 av1_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
1003 &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001004 } else {
1005#endif
1006 for (idy = 0; idy < mi_height; idy += bh) {
Jingning Hande953b92016-10-25 12:35:43 -07001007 for (idx = 0; idx < mi_width; idx += bw) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001008 encode_block_inter(plane, block, idy, idx, plane_bsize, max_tx_size,
1009 &arg);
1010 block += step;
1011 }
1012 }
1013#if CONFIG_EXT_TX && CONFIG_RECT_TX
1014 }
1015#endif
1016#else
Yaowu Xuf883b422016-08-30 14:01:10 -07001017 av1_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
1018 &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001019#endif
1020 }
1021}
1022
1023#if CONFIG_SUPERTX
Angie Chiangff6d8902016-10-21 11:02:09 -07001024void av1_encode_sb_supertx(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001025 MACROBLOCKD *const xd = &x->e_mbd;
1026 struct optimize_ctx ctx;
1027 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiangff6d8902016-10-21 11:02:09 -07001028 struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001029 int plane;
1030
1031 mbmi->skip = 1;
1032 if (x->skip) return;
1033
1034 for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
1035 const struct macroblockd_plane *const pd = &xd->plane[plane];
1036#if CONFIG_VAR_TX
1037 const TX_SIZE tx_size = TX_4X4;
1038#else
1039 const TX_SIZE tx_size = plane ? get_uv_tx_size(mbmi, pd) : mbmi->tx_size;
1040#endif
Yaowu Xuf883b422016-08-30 14:01:10 -07001041 av1_subtract_plane(x, bsize, plane);
1042 av1_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001043 arg.ta = ctx.ta[plane];
1044 arg.tl = ctx.tl[plane];
Yaowu Xuf883b422016-08-30 14:01:10 -07001045 av1_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
1046 &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001047 }
1048}
1049#endif // CONFIG_SUPERTX
1050
Yaowu Xuf883b422016-08-30 14:01:10 -07001051void av1_encode_block_intra(int plane, int block, int blk_row, int blk_col,
1052 BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
1053 void *arg) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001054 struct encode_b_args *const args = arg;
Angie Chiangff6d8902016-10-21 11:02:09 -07001055 AV1_COMMON *cm = args->cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001056 MACROBLOCK *const x = args->x;
1057 MACROBLOCKD *const xd = &x->e_mbd;
1058 MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
1059 struct macroblock_plane *const p = &x->plane[plane];
1060 struct macroblockd_plane *const pd = &xd->plane[plane];
1061 tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
1062 PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
1063 const TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
1064 PREDICTION_MODE mode;
Jingning Han62a2b9e2016-10-24 10:32:37 -07001065 const int diff_stride = block_size_wide[plane_bsize];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001066 uint8_t *src, *dst;
1067 int16_t *src_diff;
1068 uint16_t *eob = &p->eobs[block];
1069 const int src_stride = p->src.stride;
1070 const int dst_stride = pd->dst.stride;
Jingning Han62a2b9e2016-10-24 10:32:37 -07001071 const int tx1d_width = tx_size_wide[tx_size];
1072 const int tx1d_height = tx_size_high[tx_size];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001073 ENTROPY_CONTEXT *a = NULL, *l = NULL;
1074 int ctx;
1075
1076 INV_TXFM_PARAM inv_txfm_param;
1077
1078 assert(tx1d_width == tx1d_height);
1079
1080 dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)];
1081 src = &p->src.buf[4 * (blk_row * src_stride + blk_col)];
1082 src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
Yaowu Xuc27fc142016-08-22 16:08:15 -07001083 mode = plane == 0 ? get_y_mode(xd->mi[0], block) : mbmi->uv_mode;
Jingning Hanc4c99da2016-10-24 10:27:28 -07001084 av1_predict_intra_block(xd, pd->width, pd->height, tx_size, mode, dst,
1085 dst_stride, dst, dst_stride, blk_col, blk_row, plane);
Yaowu Xuf883b422016-08-30 14:01:10 -07001086#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001087 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001088 aom_highbd_subtract_block(tx1d_height, tx1d_width, src_diff, diff_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001089 src, src_stride, dst, dst_stride, xd->bd);
1090 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07001091 aom_subtract_block(tx1d_height, tx1d_width, src_diff, diff_stride, src,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001092 src_stride, dst, dst_stride);
1093 }
1094#else
Yaowu Xuf883b422016-08-30 14:01:10 -07001095 aom_subtract_block(tx1d_height, tx1d_width, src_diff, diff_stride, src,
Yaowu Xuc27fc142016-08-22 16:08:15 -07001096 src_stride, dst, dst_stride);
Yaowu Xuf883b422016-08-30 14:01:10 -07001097#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001098
1099 a = &args->ta[blk_col];
1100 l = &args->tl[blk_row];
1101 ctx = combine_entropy_contexts(*a, *l);
1102
1103 if (args->enable_optimize_b) {
1104#if CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07001105 av1_xform_quant_fp_nuq(cm, x, plane, block, blk_row, blk_col, plane_bsize,
Yaowu Xuf883b422016-08-30 14:01:10 -07001106 tx_size, ctx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001107#else // CONFIG_NEW_QUANT
Angie Chiangff6d8902016-10-21 11:02:09 -07001108 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -07001109 AV1_XFORM_QUANT_FP);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001110#endif // CONFIG_NEW_QUANT
1111 if (p->eobs[block]) {
Angie Chiangff6d8902016-10-21 11:02:09 -07001112 *a = *l = av1_optimize_b(cm, x, plane, block, tx_size, ctx) > 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001113 } else {
1114 *a = *l = 0;
1115 }
1116 } else {
Angie Chiangff6d8902016-10-21 11:02:09 -07001117 av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
Yaowu Xuf883b422016-08-30 14:01:10 -07001118 AV1_XFORM_QUANT_B);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001119 *a = *l = p->eobs[block] > 0;
1120 }
1121
1122 if (*eob) {
1123 // inverse transform
1124 inv_txfm_param.tx_type = tx_type;
1125 inv_txfm_param.tx_size = tx_size;
1126 inv_txfm_param.eob = *eob;
1127 inv_txfm_param.lossless = xd->lossless[mbmi->segment_id];
Yaowu Xuf883b422016-08-30 14:01:10 -07001128#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001129 inv_txfm_param.bd = xd->bd;
1130 if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
1131 highbd_inv_txfm_add(dqcoeff, dst, dst_stride, &inv_txfm_param);
1132 } else {
1133 inv_txfm_add(dqcoeff, dst, dst_stride, &inv_txfm_param);
1134 }
1135#else
1136 inv_txfm_add(dqcoeff, dst, dst_stride, &inv_txfm_param);
Yaowu Xuf883b422016-08-30 14:01:10 -07001137#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001138
1139 *(args->skip) = 0;
1140 }
1141}
1142
Angie Chiangff6d8902016-10-21 11:02:09 -07001143void av1_encode_intra_block_plane(AV1_COMMON *cm, MACROBLOCK *x,
1144 BLOCK_SIZE bsize, int plane,
Yaowu Xuf883b422016-08-30 14:01:10 -07001145 int enable_optimize_b) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001146 const MACROBLOCKD *const xd = &x->e_mbd;
1147 ENTROPY_CONTEXT ta[2 * MAX_MIB_SIZE];
1148 ENTROPY_CONTEXT tl[2 * MAX_MIB_SIZE];
1149
Angie Chiangff6d8902016-10-21 11:02:09 -07001150 struct encode_b_args arg = {
1151 cm, x, NULL, &xd->mi[0]->mbmi.skip, ta, tl, enable_optimize_b
1152 };
Yaowu Xuc27fc142016-08-22 16:08:15 -07001153 if (enable_optimize_b) {
1154 const struct macroblockd_plane *const pd = &xd->plane[plane];
1155 const TX_SIZE tx_size =
1156 plane ? get_uv_tx_size(&xd->mi[0]->mbmi, pd) : xd->mi[0]->mbmi.tx_size;
Yaowu Xuf883b422016-08-30 14:01:10 -07001157 av1_get_entropy_contexts(bsize, tx_size, pd, ta, tl);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001158 }
Yaowu Xuf883b422016-08-30 14:01:10 -07001159 av1_foreach_transformed_block_in_plane(xd, bsize, plane,
1160 av1_encode_block_intra, &arg);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001161}