1*fb1b10abSAndroid Build Coastguard Worker /*
2*fb1b10abSAndroid Build Coastguard Worker * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3*fb1b10abSAndroid Build Coastguard Worker *
4*fb1b10abSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*fb1b10abSAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*fb1b10abSAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*fb1b10abSAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*fb1b10abSAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*fb1b10abSAndroid Build Coastguard Worker */
10*fb1b10abSAndroid Build Coastguard Worker
11*fb1b10abSAndroid Build Coastguard Worker #include "./vp9_rtcd.h"
12*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_config.h"
13*fb1b10abSAndroid Build Coastguard Worker #include "./vpx_dsp_rtcd.h"
14*fb1b10abSAndroid Build Coastguard Worker
15*fb1b10abSAndroid Build Coastguard Worker #include "vpx_dsp/quantize.h"
16*fb1b10abSAndroid Build Coastguard Worker #include "vpx_mem/vpx_mem.h"
17*fb1b10abSAndroid Build Coastguard Worker #include "vpx_ports/mem.h"
18*fb1b10abSAndroid Build Coastguard Worker
19*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MISMATCH_DEBUG
20*fb1b10abSAndroid Build Coastguard Worker #include "vpx_util/vpx_debug_util.h"
21*fb1b10abSAndroid Build Coastguard Worker #endif
22*fb1b10abSAndroid Build Coastguard Worker
23*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_idct.h"
24*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_reconinter.h"
25*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_reconintra.h"
26*fb1b10abSAndroid Build Coastguard Worker #include "vp9/common/vp9_scan.h"
27*fb1b10abSAndroid Build Coastguard Worker
28*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encodemb.h"
29*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_encoder.h"
30*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_rd.h"
31*fb1b10abSAndroid Build Coastguard Worker #include "vp9/encoder/vp9_tokenize.h"
32*fb1b10abSAndroid Build Coastguard Worker
33*fb1b10abSAndroid Build Coastguard Worker struct optimize_ctx {
34*fb1b10abSAndroid Build Coastguard Worker ENTROPY_CONTEXT ta[MAX_MB_PLANE][16];
35*fb1b10abSAndroid Build Coastguard Worker ENTROPY_CONTEXT tl[MAX_MB_PLANE][16];
36*fb1b10abSAndroid Build Coastguard Worker };
37*fb1b10abSAndroid Build Coastguard Worker
vp9_subtract_plane(MACROBLOCK * x,BLOCK_SIZE bsize,int plane)38*fb1b10abSAndroid Build Coastguard Worker void vp9_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
39*fb1b10abSAndroid Build Coastguard Worker struct macroblock_plane *const p = &x->plane[plane];
40*fb1b10abSAndroid Build Coastguard Worker const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane];
41*fb1b10abSAndroid Build Coastguard Worker const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
42*fb1b10abSAndroid Build Coastguard Worker const int bw = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
43*fb1b10abSAndroid Build Coastguard Worker const int bh = 4 * num_4x4_blocks_high_lookup[plane_bsize];
44*fb1b10abSAndroid Build Coastguard Worker
45*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
46*fb1b10abSAndroid Build Coastguard Worker if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
47*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_subtract_block(bh, bw, p->src_diff, bw, p->src.buf,
48*fb1b10abSAndroid Build Coastguard Worker p->src.stride, pd->dst.buf, pd->dst.stride,
49*fb1b10abSAndroid Build Coastguard Worker x->e_mbd.bd);
50*fb1b10abSAndroid Build Coastguard Worker return;
51*fb1b10abSAndroid Build Coastguard Worker }
52*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
53*fb1b10abSAndroid Build Coastguard Worker vpx_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride,
54*fb1b10abSAndroid Build Coastguard Worker pd->dst.buf, pd->dst.stride);
55*fb1b10abSAndroid Build Coastguard Worker }
56*fb1b10abSAndroid Build Coastguard Worker
57*fb1b10abSAndroid Build Coastguard Worker static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] = {
58*fb1b10abSAndroid Build Coastguard Worker { 10, 6 },
59*fb1b10abSAndroid Build Coastguard Worker { 8, 5 },
60*fb1b10abSAndroid Build Coastguard Worker };
61*fb1b10abSAndroid Build Coastguard Worker
62*fb1b10abSAndroid Build Coastguard Worker // 'num' can be negative, but 'shift' must be non-negative.
63*fb1b10abSAndroid Build Coastguard Worker #define RIGHT_SHIFT_POSSIBLY_NEGATIVE(num, shift) \
64*fb1b10abSAndroid Build Coastguard Worker (((num) >= 0) ? (num) >> (shift) : -((-(num)) >> (shift)))
65*fb1b10abSAndroid Build Coastguard Worker
vp9_optimize_b(MACROBLOCK * mb,int plane,int block,TX_SIZE tx_size,int ctx)66*fb1b10abSAndroid Build Coastguard Worker int vp9_optimize_b(MACROBLOCK *mb, int plane, int block, TX_SIZE tx_size,
67*fb1b10abSAndroid Build Coastguard Worker int ctx) {
68*fb1b10abSAndroid Build Coastguard Worker MACROBLOCKD *const xd = &mb->e_mbd;
69*fb1b10abSAndroid Build Coastguard Worker struct macroblock_plane *const p = &mb->plane[plane];
70*fb1b10abSAndroid Build Coastguard Worker struct macroblockd_plane *const pd = &xd->plane[plane];
71*fb1b10abSAndroid Build Coastguard Worker const int ref = is_inter_block(xd->mi[0]);
72*fb1b10abSAndroid Build Coastguard Worker uint8_t token_cache[1024];
73*fb1b10abSAndroid Build Coastguard Worker const tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
74*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
75*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
76*fb1b10abSAndroid Build Coastguard Worker const int eob = p->eobs[block];
77*fb1b10abSAndroid Build Coastguard Worker const PLANE_TYPE plane_type = get_plane_type(plane);
78*fb1b10abSAndroid Build Coastguard Worker const int default_eob = 16 << (tx_size << 1);
79*fb1b10abSAndroid Build Coastguard Worker const int shift = (tx_size == TX_32X32);
80*fb1b10abSAndroid Build Coastguard Worker const int16_t *const dequant_ptr = pd->dequant;
81*fb1b10abSAndroid Build Coastguard Worker const uint8_t *const band_translate = get_band_translate(tx_size);
82*fb1b10abSAndroid Build Coastguard Worker const ScanOrder *const so = get_scan(xd, tx_size, plane_type, block);
83*fb1b10abSAndroid Build Coastguard Worker const int16_t *const scan = so->scan;
84*fb1b10abSAndroid Build Coastguard Worker const int16_t *const nb = so->neighbors;
85*fb1b10abSAndroid Build Coastguard Worker const MODE_INFO *mbmi = xd->mi[0];
86*fb1b10abSAndroid Build Coastguard Worker const int sharpness = mb->sharpness;
87*fb1b10abSAndroid Build Coastguard Worker const int64_t rdadj = (int64_t)mb->rdmult * plane_rd_mult[ref][plane_type];
88*fb1b10abSAndroid Build Coastguard Worker const int64_t rdmult =
89*fb1b10abSAndroid Build Coastguard Worker (sharpness == 0 ? rdadj >> 1
90*fb1b10abSAndroid Build Coastguard Worker : (rdadj * (8 - sharpness + mbmi->segment_id)) >> 4);
91*fb1b10abSAndroid Build Coastguard Worker
92*fb1b10abSAndroid Build Coastguard Worker const int64_t rddiv = mb->rddiv;
93*fb1b10abSAndroid Build Coastguard Worker int64_t rd_cost0, rd_cost1;
94*fb1b10abSAndroid Build Coastguard Worker int64_t rate0, rate1;
95*fb1b10abSAndroid Build Coastguard Worker int16_t t0, t1;
96*fb1b10abSAndroid Build Coastguard Worker int i, final_eob;
97*fb1b10abSAndroid Build Coastguard Worker int count_high_values_after_eob = 0;
98*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
99*fb1b10abSAndroid Build Coastguard Worker const uint16_t *cat6_high_cost = vp9_get_high_cost_table(xd->bd);
100*fb1b10abSAndroid Build Coastguard Worker #else
101*fb1b10abSAndroid Build Coastguard Worker const uint16_t *cat6_high_cost = vp9_get_high_cost_table(8);
102*fb1b10abSAndroid Build Coastguard Worker #endif
103*fb1b10abSAndroid Build Coastguard Worker unsigned int(*const token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
104*fb1b10abSAndroid Build Coastguard Worker mb->token_costs[tx_size][plane_type][ref];
105*fb1b10abSAndroid Build Coastguard Worker unsigned int(*token_costs_cur)[2][COEFF_CONTEXTS][ENTROPY_TOKENS];
106*fb1b10abSAndroid Build Coastguard Worker int64_t eob_cost0, eob_cost1;
107*fb1b10abSAndroid Build Coastguard Worker const int ctx0 = ctx;
108*fb1b10abSAndroid Build Coastguard Worker int64_t accu_rate = 0;
109*fb1b10abSAndroid Build Coastguard Worker // Initialized to the worst possible error for the largest transform size.
110*fb1b10abSAndroid Build Coastguard Worker // This ensures that it never goes negative.
111*fb1b10abSAndroid Build Coastguard Worker int64_t accu_error = ((int64_t)1) << 50;
112*fb1b10abSAndroid Build Coastguard Worker int64_t best_block_rd_cost = INT64_MAX;
113*fb1b10abSAndroid Build Coastguard Worker int x_prev = 1;
114*fb1b10abSAndroid Build Coastguard Worker tran_low_t before_best_eob_qc = 0;
115*fb1b10abSAndroid Build Coastguard Worker tran_low_t before_best_eob_dqc = 0;
116*fb1b10abSAndroid Build Coastguard Worker
117*fb1b10abSAndroid Build Coastguard Worker assert((!plane_type && !plane) || (plane_type && plane));
118*fb1b10abSAndroid Build Coastguard Worker assert(eob <= default_eob);
119*fb1b10abSAndroid Build Coastguard Worker
120*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < eob; i++) {
121*fb1b10abSAndroid Build Coastguard Worker const int rc = scan[i];
122*fb1b10abSAndroid Build Coastguard Worker token_cache[rc] = vp9_pt_energy_class[vp9_get_token(qcoeff[rc])];
123*fb1b10abSAndroid Build Coastguard Worker }
124*fb1b10abSAndroid Build Coastguard Worker final_eob = 0;
125*fb1b10abSAndroid Build Coastguard Worker
126*fb1b10abSAndroid Build Coastguard Worker // Initial RD cost.
127*fb1b10abSAndroid Build Coastguard Worker token_costs_cur = token_costs + band_translate[0];
128*fb1b10abSAndroid Build Coastguard Worker rate0 = (*token_costs_cur)[0][ctx0][EOB_TOKEN];
129*fb1b10abSAndroid Build Coastguard Worker best_block_rd_cost = RDCOST(rdmult, rddiv, rate0, accu_error);
130*fb1b10abSAndroid Build Coastguard Worker
131*fb1b10abSAndroid Build Coastguard Worker // For each token, pick one of two choices greedily:
132*fb1b10abSAndroid Build Coastguard Worker // (i) First candidate: Keep current quantized value, OR
133*fb1b10abSAndroid Build Coastguard Worker // (ii) Second candidate: Reduce quantized value by 1.
134*fb1b10abSAndroid Build Coastguard Worker for (i = 0; i < eob; i++) {
135*fb1b10abSAndroid Build Coastguard Worker const int rc = scan[i];
136*fb1b10abSAndroid Build Coastguard Worker const int x = qcoeff[rc];
137*fb1b10abSAndroid Build Coastguard Worker const int band_cur = band_translate[i];
138*fb1b10abSAndroid Build Coastguard Worker const int ctx_cur = (i == 0) ? ctx : get_coef_context(nb, token_cache, i);
139*fb1b10abSAndroid Build Coastguard Worker const int token_tree_sel_cur = (x_prev == 0);
140*fb1b10abSAndroid Build Coastguard Worker token_costs_cur = token_costs + band_cur;
141*fb1b10abSAndroid Build Coastguard Worker if (x == 0) { // No need to search
142*fb1b10abSAndroid Build Coastguard Worker const int token = vp9_get_token(x);
143*fb1b10abSAndroid Build Coastguard Worker rate0 = (*token_costs_cur)[token_tree_sel_cur][ctx_cur][token];
144*fb1b10abSAndroid Build Coastguard Worker accu_rate += rate0;
145*fb1b10abSAndroid Build Coastguard Worker x_prev = 0;
146*fb1b10abSAndroid Build Coastguard Worker // Note: accu_error does not change.
147*fb1b10abSAndroid Build Coastguard Worker } else {
148*fb1b10abSAndroid Build Coastguard Worker const int dqv = dequant_ptr[rc != 0];
149*fb1b10abSAndroid Build Coastguard Worker // Compute the distortion for quantizing to 0.
150*fb1b10abSAndroid Build Coastguard Worker const int diff_for_zero_raw = (0 - coeff[rc]) * (1 << shift);
151*fb1b10abSAndroid Build Coastguard Worker const int diff_for_zero =
152*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
153*fb1b10abSAndroid Build Coastguard Worker (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
154*fb1b10abSAndroid Build Coastguard Worker ? RIGHT_SHIFT_POSSIBLY_NEGATIVE(diff_for_zero_raw, xd->bd - 8)
155*fb1b10abSAndroid Build Coastguard Worker :
156*fb1b10abSAndroid Build Coastguard Worker #endif
157*fb1b10abSAndroid Build Coastguard Worker diff_for_zero_raw;
158*fb1b10abSAndroid Build Coastguard Worker const int64_t distortion_for_zero =
159*fb1b10abSAndroid Build Coastguard Worker (int64_t)diff_for_zero * diff_for_zero;
160*fb1b10abSAndroid Build Coastguard Worker
161*fb1b10abSAndroid Build Coastguard Worker // Compute the distortion for the first candidate
162*fb1b10abSAndroid Build Coastguard Worker const int diff0_raw = (dqcoeff[rc] - coeff[rc]) * (1 << shift);
163*fb1b10abSAndroid Build Coastguard Worker const int diff0 =
164*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
165*fb1b10abSAndroid Build Coastguard Worker (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
166*fb1b10abSAndroid Build Coastguard Worker ? RIGHT_SHIFT_POSSIBLY_NEGATIVE(diff0_raw, xd->bd - 8)
167*fb1b10abSAndroid Build Coastguard Worker :
168*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
169*fb1b10abSAndroid Build Coastguard Worker diff0_raw;
170*fb1b10abSAndroid Build Coastguard Worker const int64_t distortion0 = (int64_t)diff0 * diff0;
171*fb1b10abSAndroid Build Coastguard Worker
172*fb1b10abSAndroid Build Coastguard Worker // Compute the distortion for the second candidate
173*fb1b10abSAndroid Build Coastguard Worker const int sign = -(x < 0); // -1 if x is negative and 0 otherwise.
174*fb1b10abSAndroid Build Coastguard Worker const int x1 = x - 2 * sign - 1; // abs(x1) = abs(x) - 1.
175*fb1b10abSAndroid Build Coastguard Worker int64_t distortion1;
176*fb1b10abSAndroid Build Coastguard Worker if (x1 != 0) {
177*fb1b10abSAndroid Build Coastguard Worker const int dqv_step =
178*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
179*fb1b10abSAndroid Build Coastguard Worker (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) ? dqv >> (xd->bd - 8)
180*fb1b10abSAndroid Build Coastguard Worker :
181*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
182*fb1b10abSAndroid Build Coastguard Worker dqv;
183*fb1b10abSAndroid Build Coastguard Worker const int diff_step = (dqv_step + sign) ^ sign;
184*fb1b10abSAndroid Build Coastguard Worker const int diff1 = diff0 - diff_step;
185*fb1b10abSAndroid Build Coastguard Worker assert(dqv > 0); // We aren't right shifting a negative number above.
186*fb1b10abSAndroid Build Coastguard Worker distortion1 = (int64_t)diff1 * diff1;
187*fb1b10abSAndroid Build Coastguard Worker } else {
188*fb1b10abSAndroid Build Coastguard Worker distortion1 = distortion_for_zero;
189*fb1b10abSAndroid Build Coastguard Worker }
190*fb1b10abSAndroid Build Coastguard Worker {
191*fb1b10abSAndroid Build Coastguard Worker // Calculate RDCost for current coeff for the two candidates.
192*fb1b10abSAndroid Build Coastguard Worker const int64_t base_bits0 = vp9_get_token_cost(x, &t0, cat6_high_cost);
193*fb1b10abSAndroid Build Coastguard Worker const int64_t base_bits1 = vp9_get_token_cost(x1, &t1, cat6_high_cost);
194*fb1b10abSAndroid Build Coastguard Worker rate0 =
195*fb1b10abSAndroid Build Coastguard Worker base_bits0 + (*token_costs_cur)[token_tree_sel_cur][ctx_cur][t0];
196*fb1b10abSAndroid Build Coastguard Worker rate1 =
197*fb1b10abSAndroid Build Coastguard Worker base_bits1 + (*token_costs_cur)[token_tree_sel_cur][ctx_cur][t1];
198*fb1b10abSAndroid Build Coastguard Worker }
199*fb1b10abSAndroid Build Coastguard Worker {
200*fb1b10abSAndroid Build Coastguard Worker int rdcost_better_for_x1, eob_rdcost_better_for_x1;
201*fb1b10abSAndroid Build Coastguard Worker int dqc0, dqc1;
202*fb1b10abSAndroid Build Coastguard Worker int64_t best_eob_cost_cur;
203*fb1b10abSAndroid Build Coastguard Worker int use_x1;
204*fb1b10abSAndroid Build Coastguard Worker
205*fb1b10abSAndroid Build Coastguard Worker // Calculate RD Cost effect on the next coeff for the two candidates.
206*fb1b10abSAndroid Build Coastguard Worker int64_t next_bits0 = 0;
207*fb1b10abSAndroid Build Coastguard Worker int64_t next_bits1 = 0;
208*fb1b10abSAndroid Build Coastguard Worker int64_t next_eob_bits0 = 0;
209*fb1b10abSAndroid Build Coastguard Worker int64_t next_eob_bits1 = 0;
210*fb1b10abSAndroid Build Coastguard Worker if (i < default_eob - 1) {
211*fb1b10abSAndroid Build Coastguard Worker int ctx_next, token_tree_sel_next;
212*fb1b10abSAndroid Build Coastguard Worker const int band_next = band_translate[i + 1];
213*fb1b10abSAndroid Build Coastguard Worker const int token_next =
214*fb1b10abSAndroid Build Coastguard Worker (i + 1 != eob) ? vp9_get_token(qcoeff[scan[i + 1]]) : EOB_TOKEN;
215*fb1b10abSAndroid Build Coastguard Worker unsigned int(*const token_costs_next)[2][COEFF_CONTEXTS]
216*fb1b10abSAndroid Build Coastguard Worker [ENTROPY_TOKENS] =
217*fb1b10abSAndroid Build Coastguard Worker token_costs + band_next;
218*fb1b10abSAndroid Build Coastguard Worker token_cache[rc] = vp9_pt_energy_class[t0];
219*fb1b10abSAndroid Build Coastguard Worker ctx_next = get_coef_context(nb, token_cache, i + 1);
220*fb1b10abSAndroid Build Coastguard Worker token_tree_sel_next = (x == 0);
221*fb1b10abSAndroid Build Coastguard Worker next_bits0 =
222*fb1b10abSAndroid Build Coastguard Worker (*token_costs_next)[token_tree_sel_next][ctx_next][token_next];
223*fb1b10abSAndroid Build Coastguard Worker next_eob_bits0 =
224*fb1b10abSAndroid Build Coastguard Worker (*token_costs_next)[token_tree_sel_next][ctx_next][EOB_TOKEN];
225*fb1b10abSAndroid Build Coastguard Worker token_cache[rc] = vp9_pt_energy_class[t1];
226*fb1b10abSAndroid Build Coastguard Worker ctx_next = get_coef_context(nb, token_cache, i + 1);
227*fb1b10abSAndroid Build Coastguard Worker token_tree_sel_next = (x1 == 0);
228*fb1b10abSAndroid Build Coastguard Worker next_bits1 =
229*fb1b10abSAndroid Build Coastguard Worker (*token_costs_next)[token_tree_sel_next][ctx_next][token_next];
230*fb1b10abSAndroid Build Coastguard Worker if (x1 != 0) {
231*fb1b10abSAndroid Build Coastguard Worker next_eob_bits1 =
232*fb1b10abSAndroid Build Coastguard Worker (*token_costs_next)[token_tree_sel_next][ctx_next][EOB_TOKEN];
233*fb1b10abSAndroid Build Coastguard Worker }
234*fb1b10abSAndroid Build Coastguard Worker }
235*fb1b10abSAndroid Build Coastguard Worker
236*fb1b10abSAndroid Build Coastguard Worker // Compare the total RD costs for two candidates.
237*fb1b10abSAndroid Build Coastguard Worker rd_cost0 = RDCOST(rdmult, rddiv, (rate0 + next_bits0), distortion0);
238*fb1b10abSAndroid Build Coastguard Worker rd_cost1 = RDCOST(rdmult, rddiv, (rate1 + next_bits1), distortion1);
239*fb1b10abSAndroid Build Coastguard Worker rdcost_better_for_x1 = (rd_cost1 < rd_cost0);
240*fb1b10abSAndroid Build Coastguard Worker eob_cost0 = RDCOST(rdmult, rddiv, (accu_rate + rate0 + next_eob_bits0),
241*fb1b10abSAndroid Build Coastguard Worker (accu_error + distortion0 - distortion_for_zero));
242*fb1b10abSAndroid Build Coastguard Worker eob_cost1 = eob_cost0;
243*fb1b10abSAndroid Build Coastguard Worker if (x1 != 0) {
244*fb1b10abSAndroid Build Coastguard Worker eob_cost1 =
245*fb1b10abSAndroid Build Coastguard Worker RDCOST(rdmult, rddiv, (accu_rate + rate1 + next_eob_bits1),
246*fb1b10abSAndroid Build Coastguard Worker (accu_error + distortion1 - distortion_for_zero));
247*fb1b10abSAndroid Build Coastguard Worker eob_rdcost_better_for_x1 = (eob_cost1 < eob_cost0);
248*fb1b10abSAndroid Build Coastguard Worker } else {
249*fb1b10abSAndroid Build Coastguard Worker eob_rdcost_better_for_x1 = 0;
250*fb1b10abSAndroid Build Coastguard Worker }
251*fb1b10abSAndroid Build Coastguard Worker
252*fb1b10abSAndroid Build Coastguard Worker // Calculate the two candidate de-quantized values.
253*fb1b10abSAndroid Build Coastguard Worker dqc0 = dqcoeff[rc];
254*fb1b10abSAndroid Build Coastguard Worker dqc1 = 0;
255*fb1b10abSAndroid Build Coastguard Worker if (rdcost_better_for_x1 + eob_rdcost_better_for_x1) {
256*fb1b10abSAndroid Build Coastguard Worker if (x1 != 0) {
257*fb1b10abSAndroid Build Coastguard Worker dqc1 = RIGHT_SHIFT_POSSIBLY_NEGATIVE(x1 * dqv, shift);
258*fb1b10abSAndroid Build Coastguard Worker } else {
259*fb1b10abSAndroid Build Coastguard Worker dqc1 = 0;
260*fb1b10abSAndroid Build Coastguard Worker }
261*fb1b10abSAndroid Build Coastguard Worker }
262*fb1b10abSAndroid Build Coastguard Worker
263*fb1b10abSAndroid Build Coastguard Worker // Pick and record the better quantized and de-quantized values.
264*fb1b10abSAndroid Build Coastguard Worker if (rdcost_better_for_x1) {
265*fb1b10abSAndroid Build Coastguard Worker qcoeff[rc] = x1;
266*fb1b10abSAndroid Build Coastguard Worker dqcoeff[rc] = dqc1;
267*fb1b10abSAndroid Build Coastguard Worker accu_rate += rate1;
268*fb1b10abSAndroid Build Coastguard Worker accu_error += distortion1 - distortion_for_zero;
269*fb1b10abSAndroid Build Coastguard Worker assert(distortion1 <= distortion_for_zero);
270*fb1b10abSAndroid Build Coastguard Worker token_cache[rc] = vp9_pt_energy_class[t1];
271*fb1b10abSAndroid Build Coastguard Worker } else {
272*fb1b10abSAndroid Build Coastguard Worker accu_rate += rate0;
273*fb1b10abSAndroid Build Coastguard Worker accu_error += distortion0 - distortion_for_zero;
274*fb1b10abSAndroid Build Coastguard Worker assert(distortion0 <= distortion_for_zero);
275*fb1b10abSAndroid Build Coastguard Worker token_cache[rc] = vp9_pt_energy_class[t0];
276*fb1b10abSAndroid Build Coastguard Worker }
277*fb1b10abSAndroid Build Coastguard Worker if (sharpness > 0 && abs(qcoeff[rc]) > 1) count_high_values_after_eob++;
278*fb1b10abSAndroid Build Coastguard Worker assert(accu_error >= 0);
279*fb1b10abSAndroid Build Coastguard Worker x_prev = qcoeff[rc]; // Update based on selected quantized value.
280*fb1b10abSAndroid Build Coastguard Worker
281*fb1b10abSAndroid Build Coastguard Worker use_x1 = (x1 != 0) && eob_rdcost_better_for_x1;
282*fb1b10abSAndroid Build Coastguard Worker best_eob_cost_cur = use_x1 ? eob_cost1 : eob_cost0;
283*fb1b10abSAndroid Build Coastguard Worker
284*fb1b10abSAndroid Build Coastguard Worker // Determine whether to move the eob position to i+1
285*fb1b10abSAndroid Build Coastguard Worker if (best_eob_cost_cur < best_block_rd_cost) {
286*fb1b10abSAndroid Build Coastguard Worker best_block_rd_cost = best_eob_cost_cur;
287*fb1b10abSAndroid Build Coastguard Worker final_eob = i + 1;
288*fb1b10abSAndroid Build Coastguard Worker count_high_values_after_eob = 0;
289*fb1b10abSAndroid Build Coastguard Worker if (use_x1) {
290*fb1b10abSAndroid Build Coastguard Worker before_best_eob_qc = x1;
291*fb1b10abSAndroid Build Coastguard Worker before_best_eob_dqc = dqc1;
292*fb1b10abSAndroid Build Coastguard Worker } else {
293*fb1b10abSAndroid Build Coastguard Worker before_best_eob_qc = x;
294*fb1b10abSAndroid Build Coastguard Worker before_best_eob_dqc = dqc0;
295*fb1b10abSAndroid Build Coastguard Worker }
296*fb1b10abSAndroid Build Coastguard Worker }
297*fb1b10abSAndroid Build Coastguard Worker }
298*fb1b10abSAndroid Build Coastguard Worker }
299*fb1b10abSAndroid Build Coastguard Worker }
300*fb1b10abSAndroid Build Coastguard Worker if (count_high_values_after_eob > 0) {
301*fb1b10abSAndroid Build Coastguard Worker final_eob = eob - 1;
302*fb1b10abSAndroid Build Coastguard Worker for (; final_eob >= 0; final_eob--) {
303*fb1b10abSAndroid Build Coastguard Worker const int rc = scan[final_eob];
304*fb1b10abSAndroid Build Coastguard Worker const int x = qcoeff[rc];
305*fb1b10abSAndroid Build Coastguard Worker if (x) {
306*fb1b10abSAndroid Build Coastguard Worker break;
307*fb1b10abSAndroid Build Coastguard Worker }
308*fb1b10abSAndroid Build Coastguard Worker }
309*fb1b10abSAndroid Build Coastguard Worker final_eob++;
310*fb1b10abSAndroid Build Coastguard Worker } else {
311*fb1b10abSAndroid Build Coastguard Worker assert(final_eob <= eob);
312*fb1b10abSAndroid Build Coastguard Worker if (final_eob > 0) {
313*fb1b10abSAndroid Build Coastguard Worker int rc;
314*fb1b10abSAndroid Build Coastguard Worker assert(before_best_eob_qc != 0);
315*fb1b10abSAndroid Build Coastguard Worker i = final_eob - 1;
316*fb1b10abSAndroid Build Coastguard Worker rc = scan[i];
317*fb1b10abSAndroid Build Coastguard Worker qcoeff[rc] = before_best_eob_qc;
318*fb1b10abSAndroid Build Coastguard Worker dqcoeff[rc] = before_best_eob_dqc;
319*fb1b10abSAndroid Build Coastguard Worker }
320*fb1b10abSAndroid Build Coastguard Worker for (i = final_eob; i < eob; i++) {
321*fb1b10abSAndroid Build Coastguard Worker int rc = scan[i];
322*fb1b10abSAndroid Build Coastguard Worker qcoeff[rc] = 0;
323*fb1b10abSAndroid Build Coastguard Worker dqcoeff[rc] = 0;
324*fb1b10abSAndroid Build Coastguard Worker }
325*fb1b10abSAndroid Build Coastguard Worker }
326*fb1b10abSAndroid Build Coastguard Worker mb->plane[plane].eobs[block] = final_eob;
327*fb1b10abSAndroid Build Coastguard Worker return final_eob;
328*fb1b10abSAndroid Build Coastguard Worker }
329*fb1b10abSAndroid Build Coastguard Worker #undef RIGHT_SHIFT_POSSIBLY_NEGATIVE
330*fb1b10abSAndroid Build Coastguard Worker
fdct32x32(int rd_transform,const int16_t * src,tran_low_t * dst,int src_stride)331*fb1b10abSAndroid Build Coastguard Worker static INLINE void fdct32x32(int rd_transform, const int16_t *src,
332*fb1b10abSAndroid Build Coastguard Worker tran_low_t *dst, int src_stride) {
333*fb1b10abSAndroid Build Coastguard Worker if (rd_transform)
334*fb1b10abSAndroid Build Coastguard Worker vpx_fdct32x32_rd(src, dst, src_stride);
335*fb1b10abSAndroid Build Coastguard Worker else
336*fb1b10abSAndroid Build Coastguard Worker vpx_fdct32x32(src, dst, src_stride);
337*fb1b10abSAndroid Build Coastguard Worker }
338*fb1b10abSAndroid Build Coastguard Worker
339*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
highbd_fdct32x32(int rd_transform,const int16_t * src,tran_low_t * dst,int src_stride)340*fb1b10abSAndroid Build Coastguard Worker static INLINE void highbd_fdct32x32(int rd_transform, const int16_t *src,
341*fb1b10abSAndroid Build Coastguard Worker tran_low_t *dst, int src_stride) {
342*fb1b10abSAndroid Build Coastguard Worker if (rd_transform)
343*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_fdct32x32_rd(src, dst, src_stride);
344*fb1b10abSAndroid Build Coastguard Worker else
345*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_fdct32x32(src, dst, src_stride);
346*fb1b10abSAndroid Build Coastguard Worker }
347*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
348*fb1b10abSAndroid Build Coastguard Worker
vp9_xform_quant_fp(MACROBLOCK * x,int plane,int block,int row,int col,BLOCK_SIZE plane_bsize,TX_SIZE tx_size)349*fb1b10abSAndroid Build Coastguard Worker void vp9_xform_quant_fp(MACROBLOCK *x, int plane, int block, int row, int col,
350*fb1b10abSAndroid Build Coastguard Worker BLOCK_SIZE plane_bsize, TX_SIZE tx_size) {
351*fb1b10abSAndroid Build Coastguard Worker MACROBLOCKD *const xd = &x->e_mbd;
352*fb1b10abSAndroid Build Coastguard Worker const struct macroblock_plane *const p = &x->plane[plane];
353*fb1b10abSAndroid Build Coastguard Worker const struct macroblockd_plane *const pd = &xd->plane[plane];
354*fb1b10abSAndroid Build Coastguard Worker const ScanOrder *const scan_order = &vp9_default_scan_orders[tx_size];
355*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
356*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
357*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
358*fb1b10abSAndroid Build Coastguard Worker uint16_t *const eob = &p->eobs[block];
359*fb1b10abSAndroid Build Coastguard Worker const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
360*fb1b10abSAndroid Build Coastguard Worker const int16_t *src_diff;
361*fb1b10abSAndroid Build Coastguard Worker src_diff = &p->src_diff[4 * (row * diff_stride + col)];
362*fb1b10abSAndroid Build Coastguard Worker // skip block condition should be handled before this is called.
363*fb1b10abSAndroid Build Coastguard Worker assert(!x->skip_block);
364*fb1b10abSAndroid Build Coastguard Worker
365*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
366*fb1b10abSAndroid Build Coastguard Worker if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
367*fb1b10abSAndroid Build Coastguard Worker switch (tx_size) {
368*fb1b10abSAndroid Build Coastguard Worker case TX_32X32:
369*fb1b10abSAndroid Build Coastguard Worker highbd_fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride);
370*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_quantize_fp_32x32(coeff, 1024, p, qcoeff, dqcoeff,
371*fb1b10abSAndroid Build Coastguard Worker pd->dequant, eob, scan_order);
372*fb1b10abSAndroid Build Coastguard Worker break;
373*fb1b10abSAndroid Build Coastguard Worker case TX_16X16:
374*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_fdct16x16(src_diff, coeff, diff_stride);
375*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_quantize_fp(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, eob,
376*fb1b10abSAndroid Build Coastguard Worker scan_order);
377*fb1b10abSAndroid Build Coastguard Worker break;
378*fb1b10abSAndroid Build Coastguard Worker case TX_8X8:
379*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_fdct8x8(src_diff, coeff, diff_stride);
380*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_quantize_fp(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob,
381*fb1b10abSAndroid Build Coastguard Worker scan_order);
382*fb1b10abSAndroid Build Coastguard Worker break;
383*fb1b10abSAndroid Build Coastguard Worker default:
384*fb1b10abSAndroid Build Coastguard Worker assert(tx_size == TX_4X4);
385*fb1b10abSAndroid Build Coastguard Worker x->fwd_txfm4x4(src_diff, coeff, diff_stride);
386*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_quantize_fp(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob,
387*fb1b10abSAndroid Build Coastguard Worker scan_order);
388*fb1b10abSAndroid Build Coastguard Worker break;
389*fb1b10abSAndroid Build Coastguard Worker }
390*fb1b10abSAndroid Build Coastguard Worker return;
391*fb1b10abSAndroid Build Coastguard Worker }
392*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
393*fb1b10abSAndroid Build Coastguard Worker
394*fb1b10abSAndroid Build Coastguard Worker switch (tx_size) {
395*fb1b10abSAndroid Build Coastguard Worker case TX_32X32:
396*fb1b10abSAndroid Build Coastguard Worker fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride);
397*fb1b10abSAndroid Build Coastguard Worker vp9_quantize_fp_32x32(coeff, 1024, p, qcoeff, dqcoeff, pd->dequant, eob,
398*fb1b10abSAndroid Build Coastguard Worker scan_order);
399*fb1b10abSAndroid Build Coastguard Worker break;
400*fb1b10abSAndroid Build Coastguard Worker case TX_16X16:
401*fb1b10abSAndroid Build Coastguard Worker vpx_fdct16x16(src_diff, coeff, diff_stride);
402*fb1b10abSAndroid Build Coastguard Worker vp9_quantize_fp(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, eob,
403*fb1b10abSAndroid Build Coastguard Worker scan_order);
404*fb1b10abSAndroid Build Coastguard Worker break;
405*fb1b10abSAndroid Build Coastguard Worker case TX_8X8:
406*fb1b10abSAndroid Build Coastguard Worker vpx_fdct8x8(src_diff, coeff, diff_stride);
407*fb1b10abSAndroid Build Coastguard Worker vp9_quantize_fp(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob,
408*fb1b10abSAndroid Build Coastguard Worker scan_order);
409*fb1b10abSAndroid Build Coastguard Worker
410*fb1b10abSAndroid Build Coastguard Worker break;
411*fb1b10abSAndroid Build Coastguard Worker default:
412*fb1b10abSAndroid Build Coastguard Worker assert(tx_size == TX_4X4);
413*fb1b10abSAndroid Build Coastguard Worker x->fwd_txfm4x4(src_diff, coeff, diff_stride);
414*fb1b10abSAndroid Build Coastguard Worker vp9_quantize_fp(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob,
415*fb1b10abSAndroid Build Coastguard Worker scan_order);
416*fb1b10abSAndroid Build Coastguard Worker break;
417*fb1b10abSAndroid Build Coastguard Worker }
418*fb1b10abSAndroid Build Coastguard Worker }
419*fb1b10abSAndroid Build Coastguard Worker
vp9_xform_quant_dc(MACROBLOCK * x,int plane,int block,int row,int col,BLOCK_SIZE plane_bsize,TX_SIZE tx_size)420*fb1b10abSAndroid Build Coastguard Worker void vp9_xform_quant_dc(MACROBLOCK *x, int plane, int block, int row, int col,
421*fb1b10abSAndroid Build Coastguard Worker BLOCK_SIZE plane_bsize, TX_SIZE tx_size) {
422*fb1b10abSAndroid Build Coastguard Worker MACROBLOCKD *const xd = &x->e_mbd;
423*fb1b10abSAndroid Build Coastguard Worker const struct macroblock_plane *const p = &x->plane[plane];
424*fb1b10abSAndroid Build Coastguard Worker const struct macroblockd_plane *const pd = &xd->plane[plane];
425*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
426*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
427*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
428*fb1b10abSAndroid Build Coastguard Worker uint16_t *const eob = &p->eobs[block];
429*fb1b10abSAndroid Build Coastguard Worker const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
430*fb1b10abSAndroid Build Coastguard Worker const int16_t *src_diff;
431*fb1b10abSAndroid Build Coastguard Worker src_diff = &p->src_diff[4 * (row * diff_stride + col)];
432*fb1b10abSAndroid Build Coastguard Worker // skip block condition should be handled before this is called.
433*fb1b10abSAndroid Build Coastguard Worker assert(!x->skip_block);
434*fb1b10abSAndroid Build Coastguard Worker
435*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
436*fb1b10abSAndroid Build Coastguard Worker if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
437*fb1b10abSAndroid Build Coastguard Worker switch (tx_size) {
438*fb1b10abSAndroid Build Coastguard Worker case TX_32X32:
439*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_fdct32x32_1(src_diff, coeff, diff_stride);
440*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_dc_32x32(coeff, p->round, p->quant_fp[0], qcoeff,
441*fb1b10abSAndroid Build Coastguard Worker dqcoeff, pd->dequant[0], eob);
442*fb1b10abSAndroid Build Coastguard Worker break;
443*fb1b10abSAndroid Build Coastguard Worker case TX_16X16:
444*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_fdct16x16_1(src_diff, coeff, diff_stride);
445*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_dc(coeff, 256, p->round, p->quant_fp[0], qcoeff,
446*fb1b10abSAndroid Build Coastguard Worker dqcoeff, pd->dequant[0], eob);
447*fb1b10abSAndroid Build Coastguard Worker break;
448*fb1b10abSAndroid Build Coastguard Worker case TX_8X8:
449*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_fdct8x8_1(src_diff, coeff, diff_stride);
450*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_dc(coeff, 64, p->round, p->quant_fp[0], qcoeff,
451*fb1b10abSAndroid Build Coastguard Worker dqcoeff, pd->dequant[0], eob);
452*fb1b10abSAndroid Build Coastguard Worker break;
453*fb1b10abSAndroid Build Coastguard Worker default:
454*fb1b10abSAndroid Build Coastguard Worker assert(tx_size == TX_4X4);
455*fb1b10abSAndroid Build Coastguard Worker x->fwd_txfm4x4(src_diff, coeff, diff_stride);
456*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_dc(coeff, 16, p->round, p->quant_fp[0], qcoeff,
457*fb1b10abSAndroid Build Coastguard Worker dqcoeff, pd->dequant[0], eob);
458*fb1b10abSAndroid Build Coastguard Worker break;
459*fb1b10abSAndroid Build Coastguard Worker }
460*fb1b10abSAndroid Build Coastguard Worker return;
461*fb1b10abSAndroid Build Coastguard Worker }
462*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
463*fb1b10abSAndroid Build Coastguard Worker
464*fb1b10abSAndroid Build Coastguard Worker switch (tx_size) {
465*fb1b10abSAndroid Build Coastguard Worker case TX_32X32:
466*fb1b10abSAndroid Build Coastguard Worker vpx_fdct32x32_1(src_diff, coeff, diff_stride);
467*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_dc_32x32(coeff, p->round, p->quant_fp[0], qcoeff, dqcoeff,
468*fb1b10abSAndroid Build Coastguard Worker pd->dequant[0], eob);
469*fb1b10abSAndroid Build Coastguard Worker break;
470*fb1b10abSAndroid Build Coastguard Worker case TX_16X16:
471*fb1b10abSAndroid Build Coastguard Worker vpx_fdct16x16_1(src_diff, coeff, diff_stride);
472*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_dc(coeff, 256, p->round, p->quant_fp[0], qcoeff, dqcoeff,
473*fb1b10abSAndroid Build Coastguard Worker pd->dequant[0], eob);
474*fb1b10abSAndroid Build Coastguard Worker break;
475*fb1b10abSAndroid Build Coastguard Worker case TX_8X8:
476*fb1b10abSAndroid Build Coastguard Worker vpx_fdct8x8_1(src_diff, coeff, diff_stride);
477*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_dc(coeff, 64, p->round, p->quant_fp[0], qcoeff, dqcoeff,
478*fb1b10abSAndroid Build Coastguard Worker pd->dequant[0], eob);
479*fb1b10abSAndroid Build Coastguard Worker break;
480*fb1b10abSAndroid Build Coastguard Worker default:
481*fb1b10abSAndroid Build Coastguard Worker assert(tx_size == TX_4X4);
482*fb1b10abSAndroid Build Coastguard Worker x->fwd_txfm4x4(src_diff, coeff, diff_stride);
483*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_dc(coeff, 16, p->round, p->quant_fp[0], qcoeff, dqcoeff,
484*fb1b10abSAndroid Build Coastguard Worker pd->dequant[0], eob);
485*fb1b10abSAndroid Build Coastguard Worker break;
486*fb1b10abSAndroid Build Coastguard Worker }
487*fb1b10abSAndroid Build Coastguard Worker }
488*fb1b10abSAndroid Build Coastguard Worker
vp9_xform_quant(MACROBLOCK * x,int plane,int block,int row,int col,BLOCK_SIZE plane_bsize,TX_SIZE tx_size)489*fb1b10abSAndroid Build Coastguard Worker void vp9_xform_quant(MACROBLOCK *x, int plane, int block, int row, int col,
490*fb1b10abSAndroid Build Coastguard Worker BLOCK_SIZE plane_bsize, TX_SIZE tx_size) {
491*fb1b10abSAndroid Build Coastguard Worker MACROBLOCKD *const xd = &x->e_mbd;
492*fb1b10abSAndroid Build Coastguard Worker const struct macroblock_plane *const p = &x->plane[plane];
493*fb1b10abSAndroid Build Coastguard Worker const struct macroblockd_plane *const pd = &xd->plane[plane];
494*fb1b10abSAndroid Build Coastguard Worker const ScanOrder *const scan_order = &vp9_default_scan_orders[tx_size];
495*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
496*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
497*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
498*fb1b10abSAndroid Build Coastguard Worker uint16_t *const eob = &p->eobs[block];
499*fb1b10abSAndroid Build Coastguard Worker const int diff_stride = 4 * num_4x4_blocks_wide_lookup[plane_bsize];
500*fb1b10abSAndroid Build Coastguard Worker const int16_t *src_diff;
501*fb1b10abSAndroid Build Coastguard Worker src_diff = &p->src_diff[4 * (row * diff_stride + col)];
502*fb1b10abSAndroid Build Coastguard Worker // skip block condition should be handled before this is called.
503*fb1b10abSAndroid Build Coastguard Worker assert(!x->skip_block);
504*fb1b10abSAndroid Build Coastguard Worker
505*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
506*fb1b10abSAndroid Build Coastguard Worker if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
507*fb1b10abSAndroid Build Coastguard Worker switch (tx_size) {
508*fb1b10abSAndroid Build Coastguard Worker case TX_32X32:
509*fb1b10abSAndroid Build Coastguard Worker highbd_fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride);
510*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_b_32x32(coeff, p, qcoeff, dqcoeff, pd->dequant, eob,
511*fb1b10abSAndroid Build Coastguard Worker scan_order);
512*fb1b10abSAndroid Build Coastguard Worker break;
513*fb1b10abSAndroid Build Coastguard Worker case TX_16X16:
514*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_fdct16x16(src_diff, coeff, diff_stride);
515*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_b(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, eob,
516*fb1b10abSAndroid Build Coastguard Worker scan_order);
517*fb1b10abSAndroid Build Coastguard Worker break;
518*fb1b10abSAndroid Build Coastguard Worker case TX_8X8:
519*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_fdct8x8(src_diff, coeff, diff_stride);
520*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_b(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob,
521*fb1b10abSAndroid Build Coastguard Worker scan_order);
522*fb1b10abSAndroid Build Coastguard Worker break;
523*fb1b10abSAndroid Build Coastguard Worker default:
524*fb1b10abSAndroid Build Coastguard Worker assert(tx_size == TX_4X4);
525*fb1b10abSAndroid Build Coastguard Worker x->fwd_txfm4x4(src_diff, coeff, diff_stride);
526*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_b(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob,
527*fb1b10abSAndroid Build Coastguard Worker scan_order);
528*fb1b10abSAndroid Build Coastguard Worker break;
529*fb1b10abSAndroid Build Coastguard Worker }
530*fb1b10abSAndroid Build Coastguard Worker return;
531*fb1b10abSAndroid Build Coastguard Worker }
532*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
533*fb1b10abSAndroid Build Coastguard Worker
534*fb1b10abSAndroid Build Coastguard Worker switch (tx_size) {
535*fb1b10abSAndroid Build Coastguard Worker case TX_32X32:
536*fb1b10abSAndroid Build Coastguard Worker fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride);
537*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_b_32x32(coeff, p, qcoeff, dqcoeff, pd->dequant, eob,
538*fb1b10abSAndroid Build Coastguard Worker scan_order);
539*fb1b10abSAndroid Build Coastguard Worker break;
540*fb1b10abSAndroid Build Coastguard Worker case TX_16X16:
541*fb1b10abSAndroid Build Coastguard Worker vpx_fdct16x16(src_diff, coeff, diff_stride);
542*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_b(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, eob,
543*fb1b10abSAndroid Build Coastguard Worker scan_order);
544*fb1b10abSAndroid Build Coastguard Worker break;
545*fb1b10abSAndroid Build Coastguard Worker case TX_8X8:
546*fb1b10abSAndroid Build Coastguard Worker vpx_fdct8x8(src_diff, coeff, diff_stride);
547*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_b(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob,
548*fb1b10abSAndroid Build Coastguard Worker scan_order);
549*fb1b10abSAndroid Build Coastguard Worker break;
550*fb1b10abSAndroid Build Coastguard Worker default:
551*fb1b10abSAndroid Build Coastguard Worker assert(tx_size == TX_4X4);
552*fb1b10abSAndroid Build Coastguard Worker x->fwd_txfm4x4(src_diff, coeff, diff_stride);
553*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_b(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob,
554*fb1b10abSAndroid Build Coastguard Worker scan_order);
555*fb1b10abSAndroid Build Coastguard Worker break;
556*fb1b10abSAndroid Build Coastguard Worker }
557*fb1b10abSAndroid Build Coastguard Worker }
558*fb1b10abSAndroid Build Coastguard Worker
encode_block(int plane,int block,int row,int col,BLOCK_SIZE plane_bsize,TX_SIZE tx_size,void * arg)559*fb1b10abSAndroid Build Coastguard Worker static void encode_block(int plane, int block, int row, int col,
560*fb1b10abSAndroid Build Coastguard Worker BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
561*fb1b10abSAndroid Build Coastguard Worker struct encode_b_args *const args = arg;
562*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MISMATCH_DEBUG
563*fb1b10abSAndroid Build Coastguard Worker int mi_row = args->mi_row;
564*fb1b10abSAndroid Build Coastguard Worker int mi_col = args->mi_col;
565*fb1b10abSAndroid Build Coastguard Worker int output_enabled = args->output_enabled;
566*fb1b10abSAndroid Build Coastguard Worker #endif
567*fb1b10abSAndroid Build Coastguard Worker MACROBLOCK *const x = args->x;
568*fb1b10abSAndroid Build Coastguard Worker MACROBLOCKD *const xd = &x->e_mbd;
569*fb1b10abSAndroid Build Coastguard Worker struct macroblock_plane *const p = &x->plane[plane];
570*fb1b10abSAndroid Build Coastguard Worker struct macroblockd_plane *const pd = &xd->plane[plane];
571*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
572*fb1b10abSAndroid Build Coastguard Worker uint8_t *dst;
573*fb1b10abSAndroid Build Coastguard Worker ENTROPY_CONTEXT *a, *l;
574*fb1b10abSAndroid Build Coastguard Worker dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col];
575*fb1b10abSAndroid Build Coastguard Worker a = &args->ta[col];
576*fb1b10abSAndroid Build Coastguard Worker l = &args->tl[row];
577*fb1b10abSAndroid Build Coastguard Worker
578*fb1b10abSAndroid Build Coastguard Worker // TODO(jingning): per transformed block zero forcing only enabled for
579*fb1b10abSAndroid Build Coastguard Worker // luma component. will integrate chroma components as well.
580*fb1b10abSAndroid Build Coastguard Worker if (x->zcoeff_blk[tx_size][block] && plane == 0) {
581*fb1b10abSAndroid Build Coastguard Worker p->eobs[block] = 0;
582*fb1b10abSAndroid Build Coastguard Worker *a = *l = 0;
583*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MISMATCH_DEBUG
584*fb1b10abSAndroid Build Coastguard Worker goto encode_block_end;
585*fb1b10abSAndroid Build Coastguard Worker #else
586*fb1b10abSAndroid Build Coastguard Worker return;
587*fb1b10abSAndroid Build Coastguard Worker #endif
588*fb1b10abSAndroid Build Coastguard Worker }
589*fb1b10abSAndroid Build Coastguard Worker
590*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_recode) {
591*fb1b10abSAndroid Build Coastguard Worker if (x->quant_fp) {
592*fb1b10abSAndroid Build Coastguard Worker // Encoding process for rtc mode
593*fb1b10abSAndroid Build Coastguard Worker if (x->skip_txfm[0] == SKIP_TXFM_AC_DC && plane == 0) {
594*fb1b10abSAndroid Build Coastguard Worker // skip forward transform
595*fb1b10abSAndroid Build Coastguard Worker p->eobs[block] = 0;
596*fb1b10abSAndroid Build Coastguard Worker *a = *l = 0;
597*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MISMATCH_DEBUG
598*fb1b10abSAndroid Build Coastguard Worker goto encode_block_end;
599*fb1b10abSAndroid Build Coastguard Worker #else
600*fb1b10abSAndroid Build Coastguard Worker return;
601*fb1b10abSAndroid Build Coastguard Worker #endif
602*fb1b10abSAndroid Build Coastguard Worker } else {
603*fb1b10abSAndroid Build Coastguard Worker vp9_xform_quant_fp(x, plane, block, row, col, plane_bsize, tx_size);
604*fb1b10abSAndroid Build Coastguard Worker }
605*fb1b10abSAndroid Build Coastguard Worker } else {
606*fb1b10abSAndroid Build Coastguard Worker if (max_txsize_lookup[plane_bsize] == tx_size) {
607*fb1b10abSAndroid Build Coastguard Worker int txfm_blk_index = (plane << 2) + (block >> (tx_size << 1));
608*fb1b10abSAndroid Build Coastguard Worker if (x->skip_txfm[txfm_blk_index] == SKIP_TXFM_NONE) {
609*fb1b10abSAndroid Build Coastguard Worker // full forward transform and quantization
610*fb1b10abSAndroid Build Coastguard Worker vp9_xform_quant(x, plane, block, row, col, plane_bsize, tx_size);
611*fb1b10abSAndroid Build Coastguard Worker } else if (x->skip_txfm[txfm_blk_index] == SKIP_TXFM_AC_ONLY) {
612*fb1b10abSAndroid Build Coastguard Worker // fast path forward transform and quantization
613*fb1b10abSAndroid Build Coastguard Worker vp9_xform_quant_dc(x, plane, block, row, col, plane_bsize, tx_size);
614*fb1b10abSAndroid Build Coastguard Worker } else {
615*fb1b10abSAndroid Build Coastguard Worker // skip forward transform
616*fb1b10abSAndroid Build Coastguard Worker p->eobs[block] = 0;
617*fb1b10abSAndroid Build Coastguard Worker *a = *l = 0;
618*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MISMATCH_DEBUG
619*fb1b10abSAndroid Build Coastguard Worker goto encode_block_end;
620*fb1b10abSAndroid Build Coastguard Worker #else
621*fb1b10abSAndroid Build Coastguard Worker return;
622*fb1b10abSAndroid Build Coastguard Worker #endif
623*fb1b10abSAndroid Build Coastguard Worker }
624*fb1b10abSAndroid Build Coastguard Worker } else {
625*fb1b10abSAndroid Build Coastguard Worker vp9_xform_quant(x, plane, block, row, col, plane_bsize, tx_size);
626*fb1b10abSAndroid Build Coastguard Worker }
627*fb1b10abSAndroid Build Coastguard Worker }
628*fb1b10abSAndroid Build Coastguard Worker }
629*fb1b10abSAndroid Build Coastguard Worker
630*fb1b10abSAndroid Build Coastguard Worker if (x->optimize && (!x->skip_recode || !x->skip_optimize)) {
631*fb1b10abSAndroid Build Coastguard Worker const int ctx = combine_entropy_contexts(*a, *l);
632*fb1b10abSAndroid Build Coastguard Worker *a = *l = vp9_optimize_b(x, plane, block, tx_size, ctx) > 0;
633*fb1b10abSAndroid Build Coastguard Worker } else {
634*fb1b10abSAndroid Build Coastguard Worker *a = *l = p->eobs[block] > 0;
635*fb1b10abSAndroid Build Coastguard Worker }
636*fb1b10abSAndroid Build Coastguard Worker
637*fb1b10abSAndroid Build Coastguard Worker if (p->eobs[block]) *(args->skip) = 0;
638*fb1b10abSAndroid Build Coastguard Worker
639*fb1b10abSAndroid Build Coastguard Worker if (x->skip_encode || p->eobs[block] == 0) {
640*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MISMATCH_DEBUG
641*fb1b10abSAndroid Build Coastguard Worker goto encode_block_end;
642*fb1b10abSAndroid Build Coastguard Worker #else
643*fb1b10abSAndroid Build Coastguard Worker return;
644*fb1b10abSAndroid Build Coastguard Worker #endif
645*fb1b10abSAndroid Build Coastguard Worker }
646*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
647*fb1b10abSAndroid Build Coastguard Worker if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
648*fb1b10abSAndroid Build Coastguard Worker uint16_t *const dst16 = CONVERT_TO_SHORTPTR(dst);
649*fb1b10abSAndroid Build Coastguard Worker switch (tx_size) {
650*fb1b10abSAndroid Build Coastguard Worker case TX_32X32:
651*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_idct32x32_add(dqcoeff, dst16, pd->dst.stride, p->eobs[block],
652*fb1b10abSAndroid Build Coastguard Worker xd->bd);
653*fb1b10abSAndroid Build Coastguard Worker break;
654*fb1b10abSAndroid Build Coastguard Worker case TX_16X16:
655*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_idct16x16_add(dqcoeff, dst16, pd->dst.stride, p->eobs[block],
656*fb1b10abSAndroid Build Coastguard Worker xd->bd);
657*fb1b10abSAndroid Build Coastguard Worker break;
658*fb1b10abSAndroid Build Coastguard Worker case TX_8X8:
659*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_idct8x8_add(dqcoeff, dst16, pd->dst.stride, p->eobs[block],
660*fb1b10abSAndroid Build Coastguard Worker xd->bd);
661*fb1b10abSAndroid Build Coastguard Worker break;
662*fb1b10abSAndroid Build Coastguard Worker default:
663*fb1b10abSAndroid Build Coastguard Worker assert(tx_size == TX_4X4);
664*fb1b10abSAndroid Build Coastguard Worker // this is like vp9_short_idct4x4 but has a special case around eob<=1
665*fb1b10abSAndroid Build Coastguard Worker // which is significant (not just an optimization) for the lossless
666*fb1b10abSAndroid Build Coastguard Worker // case.
667*fb1b10abSAndroid Build Coastguard Worker x->highbd_inv_txfm_add(dqcoeff, dst16, pd->dst.stride, p->eobs[block],
668*fb1b10abSAndroid Build Coastguard Worker xd->bd);
669*fb1b10abSAndroid Build Coastguard Worker break;
670*fb1b10abSAndroid Build Coastguard Worker }
671*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MISMATCH_DEBUG
672*fb1b10abSAndroid Build Coastguard Worker goto encode_block_end;
673*fb1b10abSAndroid Build Coastguard Worker #else
674*fb1b10abSAndroid Build Coastguard Worker return;
675*fb1b10abSAndroid Build Coastguard Worker #endif
676*fb1b10abSAndroid Build Coastguard Worker }
677*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
678*fb1b10abSAndroid Build Coastguard Worker
679*fb1b10abSAndroid Build Coastguard Worker switch (tx_size) {
680*fb1b10abSAndroid Build Coastguard Worker case TX_32X32:
681*fb1b10abSAndroid Build Coastguard Worker vp9_idct32x32_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
682*fb1b10abSAndroid Build Coastguard Worker break;
683*fb1b10abSAndroid Build Coastguard Worker case TX_16X16:
684*fb1b10abSAndroid Build Coastguard Worker vp9_idct16x16_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
685*fb1b10abSAndroid Build Coastguard Worker break;
686*fb1b10abSAndroid Build Coastguard Worker case TX_8X8:
687*fb1b10abSAndroid Build Coastguard Worker vp9_idct8x8_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
688*fb1b10abSAndroid Build Coastguard Worker break;
689*fb1b10abSAndroid Build Coastguard Worker default:
690*fb1b10abSAndroid Build Coastguard Worker assert(tx_size == TX_4X4);
691*fb1b10abSAndroid Build Coastguard Worker // this is like vp9_short_idct4x4 but has a special case around eob<=1
692*fb1b10abSAndroid Build Coastguard Worker // which is significant (not just an optimization) for the lossless
693*fb1b10abSAndroid Build Coastguard Worker // case.
694*fb1b10abSAndroid Build Coastguard Worker x->inv_txfm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
695*fb1b10abSAndroid Build Coastguard Worker break;
696*fb1b10abSAndroid Build Coastguard Worker }
697*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MISMATCH_DEBUG
698*fb1b10abSAndroid Build Coastguard Worker encode_block_end:
699*fb1b10abSAndroid Build Coastguard Worker if (output_enabled) {
700*fb1b10abSAndroid Build Coastguard Worker int pixel_c, pixel_r;
701*fb1b10abSAndroid Build Coastguard Worker int blk_w = 1 << (tx_size + TX_UNIT_SIZE_LOG2);
702*fb1b10abSAndroid Build Coastguard Worker int blk_h = 1 << (tx_size + TX_UNIT_SIZE_LOG2);
703*fb1b10abSAndroid Build Coastguard Worker mi_to_pixel_loc(&pixel_c, &pixel_r, mi_col, mi_row, col, row,
704*fb1b10abSAndroid Build Coastguard Worker pd->subsampling_x, pd->subsampling_y);
705*fb1b10abSAndroid Build Coastguard Worker mismatch_record_block_tx(dst, pd->dst.stride, plane, pixel_c, pixel_r,
706*fb1b10abSAndroid Build Coastguard Worker blk_w, blk_h,
707*fb1b10abSAndroid Build Coastguard Worker xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH);
708*fb1b10abSAndroid Build Coastguard Worker }
709*fb1b10abSAndroid Build Coastguard Worker #endif
710*fb1b10abSAndroid Build Coastguard Worker }
711*fb1b10abSAndroid Build Coastguard Worker
encode_block_pass1(int plane,int block,int row,int col,BLOCK_SIZE plane_bsize,TX_SIZE tx_size,void * arg)712*fb1b10abSAndroid Build Coastguard Worker static void encode_block_pass1(int plane, int block, int row, int col,
713*fb1b10abSAndroid Build Coastguard Worker BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
714*fb1b10abSAndroid Build Coastguard Worker void *arg) {
715*fb1b10abSAndroid Build Coastguard Worker MACROBLOCK *const x = (MACROBLOCK *)arg;
716*fb1b10abSAndroid Build Coastguard Worker MACROBLOCKD *const xd = &x->e_mbd;
717*fb1b10abSAndroid Build Coastguard Worker struct macroblock_plane *const p = &x->plane[plane];
718*fb1b10abSAndroid Build Coastguard Worker struct macroblockd_plane *const pd = &xd->plane[plane];
719*fb1b10abSAndroid Build Coastguard Worker tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
720*fb1b10abSAndroid Build Coastguard Worker uint8_t *dst;
721*fb1b10abSAndroid Build Coastguard Worker dst = &pd->dst.buf[4 * row * pd->dst.stride + 4 * col];
722*fb1b10abSAndroid Build Coastguard Worker
723*fb1b10abSAndroid Build Coastguard Worker vp9_xform_quant(x, plane, block, row, col, plane_bsize, tx_size);
724*fb1b10abSAndroid Build Coastguard Worker
725*fb1b10abSAndroid Build Coastguard Worker if (p->eobs[block] > 0) {
726*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
727*fb1b10abSAndroid Build Coastguard Worker if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
728*fb1b10abSAndroid Build Coastguard Worker x->highbd_inv_txfm_add(dqcoeff, CONVERT_TO_SHORTPTR(dst), pd->dst.stride,
729*fb1b10abSAndroid Build Coastguard Worker p->eobs[block], xd->bd);
730*fb1b10abSAndroid Build Coastguard Worker return;
731*fb1b10abSAndroid Build Coastguard Worker }
732*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
733*fb1b10abSAndroid Build Coastguard Worker x->inv_txfm_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
734*fb1b10abSAndroid Build Coastguard Worker }
735*fb1b10abSAndroid Build Coastguard Worker }
736*fb1b10abSAndroid Build Coastguard Worker
vp9_encode_sby_pass1(MACROBLOCK * x,BLOCK_SIZE bsize)737*fb1b10abSAndroid Build Coastguard Worker void vp9_encode_sby_pass1(MACROBLOCK *x, BLOCK_SIZE bsize) {
738*fb1b10abSAndroid Build Coastguard Worker vp9_subtract_plane(x, bsize, 0);
739*fb1b10abSAndroid Build Coastguard Worker vp9_foreach_transformed_block_in_plane(&x->e_mbd, bsize, 0,
740*fb1b10abSAndroid Build Coastguard Worker encode_block_pass1, x);
741*fb1b10abSAndroid Build Coastguard Worker }
742*fb1b10abSAndroid Build Coastguard Worker
vp9_encode_sb(MACROBLOCK * x,BLOCK_SIZE bsize,int mi_row,int mi_col,int output_enabled)743*fb1b10abSAndroid Build Coastguard Worker void vp9_encode_sb(MACROBLOCK *x, BLOCK_SIZE bsize, int mi_row, int mi_col,
744*fb1b10abSAndroid Build Coastguard Worker int output_enabled) {
745*fb1b10abSAndroid Build Coastguard Worker MACROBLOCKD *const xd = &x->e_mbd;
746*fb1b10abSAndroid Build Coastguard Worker struct optimize_ctx ctx;
747*fb1b10abSAndroid Build Coastguard Worker MODE_INFO *mi = xd->mi[0];
748*fb1b10abSAndroid Build Coastguard Worker int plane;
749*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MISMATCH_DEBUG
750*fb1b10abSAndroid Build Coastguard Worker struct encode_b_args arg = { x,
751*fb1b10abSAndroid Build Coastguard Worker 1, // enable_trellis_opt
752*fb1b10abSAndroid Build Coastguard Worker 0.0, // trellis_opt_thresh
753*fb1b10abSAndroid Build Coastguard Worker NULL, // &sse_calc_done
754*fb1b10abSAndroid Build Coastguard Worker NULL, // &sse
755*fb1b10abSAndroid Build Coastguard Worker NULL, // above entropy context
756*fb1b10abSAndroid Build Coastguard Worker NULL, // left entropy context
757*fb1b10abSAndroid Build Coastguard Worker &mi->skip, mi_row, mi_col, output_enabled };
758*fb1b10abSAndroid Build Coastguard Worker #else
759*fb1b10abSAndroid Build Coastguard Worker struct encode_b_args arg = { x,
760*fb1b10abSAndroid Build Coastguard Worker 1, // enable_trellis_opt
761*fb1b10abSAndroid Build Coastguard Worker 0.0, // trellis_opt_thresh
762*fb1b10abSAndroid Build Coastguard Worker NULL, // &sse_calc_done
763*fb1b10abSAndroid Build Coastguard Worker NULL, // &sse
764*fb1b10abSAndroid Build Coastguard Worker NULL, // above entropy context
765*fb1b10abSAndroid Build Coastguard Worker NULL, // left entropy context
766*fb1b10abSAndroid Build Coastguard Worker &mi->skip };
767*fb1b10abSAndroid Build Coastguard Worker (void)mi_row;
768*fb1b10abSAndroid Build Coastguard Worker (void)mi_col;
769*fb1b10abSAndroid Build Coastguard Worker (void)output_enabled;
770*fb1b10abSAndroid Build Coastguard Worker #endif
771*fb1b10abSAndroid Build Coastguard Worker
772*fb1b10abSAndroid Build Coastguard Worker mi->skip = 1;
773*fb1b10abSAndroid Build Coastguard Worker
774*fb1b10abSAndroid Build Coastguard Worker if (x->skip) return;
775*fb1b10abSAndroid Build Coastguard Worker
776*fb1b10abSAndroid Build Coastguard Worker for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
777*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_recode) vp9_subtract_plane(x, bsize, plane);
778*fb1b10abSAndroid Build Coastguard Worker
779*fb1b10abSAndroid Build Coastguard Worker if (x->optimize && (!x->skip_recode || !x->skip_optimize)) {
780*fb1b10abSAndroid Build Coastguard Worker const struct macroblockd_plane *const pd = &xd->plane[plane];
781*fb1b10abSAndroid Build Coastguard Worker const TX_SIZE tx_size = plane ? get_uv_tx_size(mi, pd) : mi->tx_size;
782*fb1b10abSAndroid Build Coastguard Worker vp9_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane],
783*fb1b10abSAndroid Build Coastguard Worker ctx.tl[plane]);
784*fb1b10abSAndroid Build Coastguard Worker arg.enable_trellis_opt = 1;
785*fb1b10abSAndroid Build Coastguard Worker } else {
786*fb1b10abSAndroid Build Coastguard Worker arg.enable_trellis_opt = 0;
787*fb1b10abSAndroid Build Coastguard Worker }
788*fb1b10abSAndroid Build Coastguard Worker arg.ta = ctx.ta[plane];
789*fb1b10abSAndroid Build Coastguard Worker arg.tl = ctx.tl[plane];
790*fb1b10abSAndroid Build Coastguard Worker
791*fb1b10abSAndroid Build Coastguard Worker vp9_foreach_transformed_block_in_plane(xd, bsize, plane, encode_block,
792*fb1b10abSAndroid Build Coastguard Worker &arg);
793*fb1b10abSAndroid Build Coastguard Worker }
794*fb1b10abSAndroid Build Coastguard Worker }
795*fb1b10abSAndroid Build Coastguard Worker
vp9_encode_block_intra(int plane,int block,int row,int col,BLOCK_SIZE plane_bsize,TX_SIZE tx_size,void * arg)796*fb1b10abSAndroid Build Coastguard Worker void vp9_encode_block_intra(int plane, int block, int row, int col,
797*fb1b10abSAndroid Build Coastguard Worker BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
798*fb1b10abSAndroid Build Coastguard Worker void *arg) {
799*fb1b10abSAndroid Build Coastguard Worker struct encode_b_args *const args = arg;
800*fb1b10abSAndroid Build Coastguard Worker MACROBLOCK *const x = args->x;
801*fb1b10abSAndroid Build Coastguard Worker MACROBLOCKD *const xd = &x->e_mbd;
802*fb1b10abSAndroid Build Coastguard Worker MODE_INFO *mi = xd->mi[0];
803*fb1b10abSAndroid Build Coastguard Worker struct macroblock_plane *const p = &x->plane[plane];
804*fb1b10abSAndroid Build Coastguard Worker struct macroblockd_plane *const pd = &xd->plane[plane];
805*fb1b10abSAndroid Build Coastguard Worker tran_low_t *coeff = BLOCK_OFFSET(p->coeff, block);
806*fb1b10abSAndroid Build Coastguard Worker tran_low_t *qcoeff = BLOCK_OFFSET(p->qcoeff, block);
807*fb1b10abSAndroid Build Coastguard Worker tran_low_t *dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
808*fb1b10abSAndroid Build Coastguard Worker const ScanOrder *scan_order;
809*fb1b10abSAndroid Build Coastguard Worker TX_TYPE tx_type = DCT_DCT;
810*fb1b10abSAndroid Build Coastguard Worker PREDICTION_MODE mode;
811*fb1b10abSAndroid Build Coastguard Worker const int bwl = b_width_log2_lookup[plane_bsize];
812*fb1b10abSAndroid Build Coastguard Worker const int diff_stride = 4 * (1 << bwl);
813*fb1b10abSAndroid Build Coastguard Worker uint8_t *src, *dst;
814*fb1b10abSAndroid Build Coastguard Worker int16_t *src_diff;
815*fb1b10abSAndroid Build Coastguard Worker uint16_t *eob = &p->eobs[block];
816*fb1b10abSAndroid Build Coastguard Worker const int src_stride = p->src.stride;
817*fb1b10abSAndroid Build Coastguard Worker const int dst_stride = pd->dst.stride;
818*fb1b10abSAndroid Build Coastguard Worker int enable_trellis_opt = !x->skip_recode;
819*fb1b10abSAndroid Build Coastguard Worker ENTROPY_CONTEXT *a = NULL;
820*fb1b10abSAndroid Build Coastguard Worker ENTROPY_CONTEXT *l = NULL;
821*fb1b10abSAndroid Build Coastguard Worker int entropy_ctx = 0;
822*fb1b10abSAndroid Build Coastguard Worker dst = &pd->dst.buf[4 * (row * dst_stride + col)];
823*fb1b10abSAndroid Build Coastguard Worker src = &p->src.buf[4 * (row * src_stride + col)];
824*fb1b10abSAndroid Build Coastguard Worker src_diff = &p->src_diff[4 * (row * diff_stride + col)];
825*fb1b10abSAndroid Build Coastguard Worker
826*fb1b10abSAndroid Build Coastguard Worker if (tx_size == TX_4X4) {
827*fb1b10abSAndroid Build Coastguard Worker tx_type = get_tx_type_4x4(get_plane_type(plane), xd, block);
828*fb1b10abSAndroid Build Coastguard Worker scan_order = &vp9_scan_orders[TX_4X4][tx_type];
829*fb1b10abSAndroid Build Coastguard Worker mode = plane == 0 ? get_y_mode(xd->mi[0], block) : mi->uv_mode;
830*fb1b10abSAndroid Build Coastguard Worker } else {
831*fb1b10abSAndroid Build Coastguard Worker mode = plane == 0 ? mi->mode : mi->uv_mode;
832*fb1b10abSAndroid Build Coastguard Worker if (tx_size == TX_32X32) {
833*fb1b10abSAndroid Build Coastguard Worker scan_order = &vp9_default_scan_orders[TX_32X32];
834*fb1b10abSAndroid Build Coastguard Worker } else {
835*fb1b10abSAndroid Build Coastguard Worker tx_type = get_tx_type(get_plane_type(plane), xd);
836*fb1b10abSAndroid Build Coastguard Worker scan_order = &vp9_scan_orders[tx_size][tx_type];
837*fb1b10abSAndroid Build Coastguard Worker }
838*fb1b10abSAndroid Build Coastguard Worker }
839*fb1b10abSAndroid Build Coastguard Worker
840*fb1b10abSAndroid Build Coastguard Worker vp9_predict_intra_block(
841*fb1b10abSAndroid Build Coastguard Worker xd, bwl, tx_size, mode, (x->skip_encode || x->fp_src_pred) ? src : dst,
842*fb1b10abSAndroid Build Coastguard Worker (x->skip_encode || x->fp_src_pred) ? src_stride : dst_stride, dst,
843*fb1b10abSAndroid Build Coastguard Worker dst_stride, col, row, plane);
844*fb1b10abSAndroid Build Coastguard Worker
845*fb1b10abSAndroid Build Coastguard Worker // skip block condition should be handled before this is called.
846*fb1b10abSAndroid Build Coastguard Worker assert(!x->skip_block);
847*fb1b10abSAndroid Build Coastguard Worker
848*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_recode) {
849*fb1b10abSAndroid Build Coastguard Worker const int tx_size_in_pixels = (1 << tx_size) << 2;
850*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
851*fb1b10abSAndroid Build Coastguard Worker if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
852*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_subtract_block(tx_size_in_pixels, tx_size_in_pixels, src_diff,
853*fb1b10abSAndroid Build Coastguard Worker diff_stride, src, src_stride, dst, dst_stride,
854*fb1b10abSAndroid Build Coastguard Worker xd->bd);
855*fb1b10abSAndroid Build Coastguard Worker } else {
856*fb1b10abSAndroid Build Coastguard Worker vpx_subtract_block(tx_size_in_pixels, tx_size_in_pixels, src_diff,
857*fb1b10abSAndroid Build Coastguard Worker diff_stride, src, src_stride, dst, dst_stride);
858*fb1b10abSAndroid Build Coastguard Worker }
859*fb1b10abSAndroid Build Coastguard Worker #else
860*fb1b10abSAndroid Build Coastguard Worker vpx_subtract_block(tx_size_in_pixels, tx_size_in_pixels, src_diff,
861*fb1b10abSAndroid Build Coastguard Worker diff_stride, src, src_stride, dst, dst_stride);
862*fb1b10abSAndroid Build Coastguard Worker #endif
863*fb1b10abSAndroid Build Coastguard Worker enable_trellis_opt = do_trellis_opt(pd, src_diff, diff_stride, row, col,
864*fb1b10abSAndroid Build Coastguard Worker plane_bsize, tx_size, args);
865*fb1b10abSAndroid Build Coastguard Worker }
866*fb1b10abSAndroid Build Coastguard Worker
867*fb1b10abSAndroid Build Coastguard Worker if (enable_trellis_opt) {
868*fb1b10abSAndroid Build Coastguard Worker a = &args->ta[col];
869*fb1b10abSAndroid Build Coastguard Worker l = &args->tl[row];
870*fb1b10abSAndroid Build Coastguard Worker entropy_ctx = combine_entropy_contexts(*a, *l);
871*fb1b10abSAndroid Build Coastguard Worker }
872*fb1b10abSAndroid Build Coastguard Worker
873*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_VP9_HIGHBITDEPTH
874*fb1b10abSAndroid Build Coastguard Worker if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
875*fb1b10abSAndroid Build Coastguard Worker uint16_t *const dst16 = CONVERT_TO_SHORTPTR(dst);
876*fb1b10abSAndroid Build Coastguard Worker switch (tx_size) {
877*fb1b10abSAndroid Build Coastguard Worker case TX_32X32:
878*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_recode) {
879*fb1b10abSAndroid Build Coastguard Worker highbd_fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride);
880*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_b_32x32(coeff, p, qcoeff, dqcoeff, pd->dequant,
881*fb1b10abSAndroid Build Coastguard Worker eob, scan_order);
882*fb1b10abSAndroid Build Coastguard Worker }
883*fb1b10abSAndroid Build Coastguard Worker if (enable_trellis_opt) {
884*fb1b10abSAndroid Build Coastguard Worker *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
885*fb1b10abSAndroid Build Coastguard Worker }
886*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_encode && *eob) {
887*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_idct32x32_add(dqcoeff, dst16, dst_stride, *eob, xd->bd);
888*fb1b10abSAndroid Build Coastguard Worker }
889*fb1b10abSAndroid Build Coastguard Worker break;
890*fb1b10abSAndroid Build Coastguard Worker case TX_16X16:
891*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_recode) {
892*fb1b10abSAndroid Build Coastguard Worker if (tx_type == DCT_DCT)
893*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_fdct16x16(src_diff, coeff, diff_stride);
894*fb1b10abSAndroid Build Coastguard Worker else
895*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_fht16x16(src_diff, coeff, diff_stride, tx_type);
896*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_b(coeff, 256, p, qcoeff, dqcoeff, pd->dequant,
897*fb1b10abSAndroid Build Coastguard Worker eob, scan_order);
898*fb1b10abSAndroid Build Coastguard Worker }
899*fb1b10abSAndroid Build Coastguard Worker if (enable_trellis_opt) {
900*fb1b10abSAndroid Build Coastguard Worker *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
901*fb1b10abSAndroid Build Coastguard Worker }
902*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_encode && *eob) {
903*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_iht16x16_add(tx_type, dqcoeff, dst16, dst_stride, *eob,
904*fb1b10abSAndroid Build Coastguard Worker xd->bd);
905*fb1b10abSAndroid Build Coastguard Worker }
906*fb1b10abSAndroid Build Coastguard Worker break;
907*fb1b10abSAndroid Build Coastguard Worker case TX_8X8:
908*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_recode) {
909*fb1b10abSAndroid Build Coastguard Worker if (tx_type == DCT_DCT)
910*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_fdct8x8(src_diff, coeff, diff_stride);
911*fb1b10abSAndroid Build Coastguard Worker else
912*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_fht8x8(src_diff, coeff, diff_stride, tx_type);
913*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_b(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob,
914*fb1b10abSAndroid Build Coastguard Worker scan_order);
915*fb1b10abSAndroid Build Coastguard Worker }
916*fb1b10abSAndroid Build Coastguard Worker if (enable_trellis_opt) {
917*fb1b10abSAndroid Build Coastguard Worker *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
918*fb1b10abSAndroid Build Coastguard Worker }
919*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_encode && *eob) {
920*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_iht8x8_add(tx_type, dqcoeff, dst16, dst_stride, *eob,
921*fb1b10abSAndroid Build Coastguard Worker xd->bd);
922*fb1b10abSAndroid Build Coastguard Worker }
923*fb1b10abSAndroid Build Coastguard Worker break;
924*fb1b10abSAndroid Build Coastguard Worker default:
925*fb1b10abSAndroid Build Coastguard Worker assert(tx_size == TX_4X4);
926*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_recode) {
927*fb1b10abSAndroid Build Coastguard Worker if (tx_type != DCT_DCT)
928*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_fht4x4(src_diff, coeff, diff_stride, tx_type);
929*fb1b10abSAndroid Build Coastguard Worker else
930*fb1b10abSAndroid Build Coastguard Worker x->fwd_txfm4x4(src_diff, coeff, diff_stride);
931*fb1b10abSAndroid Build Coastguard Worker vpx_highbd_quantize_b(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob,
932*fb1b10abSAndroid Build Coastguard Worker scan_order);
933*fb1b10abSAndroid Build Coastguard Worker }
934*fb1b10abSAndroid Build Coastguard Worker if (enable_trellis_opt) {
935*fb1b10abSAndroid Build Coastguard Worker *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
936*fb1b10abSAndroid Build Coastguard Worker }
937*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_encode && *eob) {
938*fb1b10abSAndroid Build Coastguard Worker if (tx_type == DCT_DCT) {
939*fb1b10abSAndroid Build Coastguard Worker // this is like vp9_short_idct4x4 but has a special case around
940*fb1b10abSAndroid Build Coastguard Worker // eob<=1 which is significant (not just an optimization) for the
941*fb1b10abSAndroid Build Coastguard Worker // lossless case.
942*fb1b10abSAndroid Build Coastguard Worker x->highbd_inv_txfm_add(dqcoeff, dst16, dst_stride, *eob, xd->bd);
943*fb1b10abSAndroid Build Coastguard Worker } else {
944*fb1b10abSAndroid Build Coastguard Worker vp9_highbd_iht4x4_16_add(dqcoeff, dst16, dst_stride, tx_type,
945*fb1b10abSAndroid Build Coastguard Worker xd->bd);
946*fb1b10abSAndroid Build Coastguard Worker }
947*fb1b10abSAndroid Build Coastguard Worker }
948*fb1b10abSAndroid Build Coastguard Worker break;
949*fb1b10abSAndroid Build Coastguard Worker }
950*fb1b10abSAndroid Build Coastguard Worker if (*eob) *(args->skip) = 0;
951*fb1b10abSAndroid Build Coastguard Worker return;
952*fb1b10abSAndroid Build Coastguard Worker }
953*fb1b10abSAndroid Build Coastguard Worker #endif // CONFIG_VP9_HIGHBITDEPTH
954*fb1b10abSAndroid Build Coastguard Worker
955*fb1b10abSAndroid Build Coastguard Worker switch (tx_size) {
956*fb1b10abSAndroid Build Coastguard Worker case TX_32X32:
957*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_recode) {
958*fb1b10abSAndroid Build Coastguard Worker fdct32x32(x->use_lp32x32fdct, src_diff, coeff, diff_stride);
959*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_b_32x32(coeff, p, qcoeff, dqcoeff, pd->dequant, eob,
960*fb1b10abSAndroid Build Coastguard Worker scan_order);
961*fb1b10abSAndroid Build Coastguard Worker }
962*fb1b10abSAndroid Build Coastguard Worker if (enable_trellis_opt) {
963*fb1b10abSAndroid Build Coastguard Worker *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
964*fb1b10abSAndroid Build Coastguard Worker }
965*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_encode && *eob)
966*fb1b10abSAndroid Build Coastguard Worker vp9_idct32x32_add(dqcoeff, dst, dst_stride, *eob);
967*fb1b10abSAndroid Build Coastguard Worker break;
968*fb1b10abSAndroid Build Coastguard Worker case TX_16X16:
969*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_recode) {
970*fb1b10abSAndroid Build Coastguard Worker vp9_fht16x16(src_diff, coeff, diff_stride, tx_type);
971*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_b(coeff, 256, p, qcoeff, dqcoeff, pd->dequant, eob,
972*fb1b10abSAndroid Build Coastguard Worker scan_order);
973*fb1b10abSAndroid Build Coastguard Worker }
974*fb1b10abSAndroid Build Coastguard Worker if (enable_trellis_opt) {
975*fb1b10abSAndroid Build Coastguard Worker *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
976*fb1b10abSAndroid Build Coastguard Worker }
977*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_encode && *eob)
978*fb1b10abSAndroid Build Coastguard Worker vp9_iht16x16_add(tx_type, dqcoeff, dst, dst_stride, *eob);
979*fb1b10abSAndroid Build Coastguard Worker break;
980*fb1b10abSAndroid Build Coastguard Worker case TX_8X8:
981*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_recode) {
982*fb1b10abSAndroid Build Coastguard Worker vp9_fht8x8(src_diff, coeff, diff_stride, tx_type);
983*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_b(coeff, 64, p, qcoeff, dqcoeff, pd->dequant, eob,
984*fb1b10abSAndroid Build Coastguard Worker scan_order);
985*fb1b10abSAndroid Build Coastguard Worker }
986*fb1b10abSAndroid Build Coastguard Worker if (enable_trellis_opt) {
987*fb1b10abSAndroid Build Coastguard Worker *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
988*fb1b10abSAndroid Build Coastguard Worker }
989*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_encode && *eob)
990*fb1b10abSAndroid Build Coastguard Worker vp9_iht8x8_add(tx_type, dqcoeff, dst, dst_stride, *eob);
991*fb1b10abSAndroid Build Coastguard Worker break;
992*fb1b10abSAndroid Build Coastguard Worker default:
993*fb1b10abSAndroid Build Coastguard Worker assert(tx_size == TX_4X4);
994*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_recode) {
995*fb1b10abSAndroid Build Coastguard Worker if (tx_type != DCT_DCT)
996*fb1b10abSAndroid Build Coastguard Worker vp9_fht4x4(src_diff, coeff, diff_stride, tx_type);
997*fb1b10abSAndroid Build Coastguard Worker else
998*fb1b10abSAndroid Build Coastguard Worker x->fwd_txfm4x4(src_diff, coeff, diff_stride);
999*fb1b10abSAndroid Build Coastguard Worker vpx_quantize_b(coeff, 16, p, qcoeff, dqcoeff, pd->dequant, eob,
1000*fb1b10abSAndroid Build Coastguard Worker scan_order);
1001*fb1b10abSAndroid Build Coastguard Worker }
1002*fb1b10abSAndroid Build Coastguard Worker if (enable_trellis_opt) {
1003*fb1b10abSAndroid Build Coastguard Worker *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
1004*fb1b10abSAndroid Build Coastguard Worker }
1005*fb1b10abSAndroid Build Coastguard Worker if (!x->skip_encode && *eob) {
1006*fb1b10abSAndroid Build Coastguard Worker if (tx_type == DCT_DCT)
1007*fb1b10abSAndroid Build Coastguard Worker // this is like vp9_short_idct4x4 but has a special case around eob<=1
1008*fb1b10abSAndroid Build Coastguard Worker // which is significant (not just an optimization) for the lossless
1009*fb1b10abSAndroid Build Coastguard Worker // case.
1010*fb1b10abSAndroid Build Coastguard Worker x->inv_txfm_add(dqcoeff, dst, dst_stride, *eob);
1011*fb1b10abSAndroid Build Coastguard Worker else
1012*fb1b10abSAndroid Build Coastguard Worker vp9_iht4x4_16_add(dqcoeff, dst, dst_stride, tx_type);
1013*fb1b10abSAndroid Build Coastguard Worker }
1014*fb1b10abSAndroid Build Coastguard Worker break;
1015*fb1b10abSAndroid Build Coastguard Worker }
1016*fb1b10abSAndroid Build Coastguard Worker if (*eob) *(args->skip) = 0;
1017*fb1b10abSAndroid Build Coastguard Worker }
1018*fb1b10abSAndroid Build Coastguard Worker
vp9_encode_intra_block_plane(MACROBLOCK * x,BLOCK_SIZE bsize,int plane,int enable_trellis_opt)1019*fb1b10abSAndroid Build Coastguard Worker void vp9_encode_intra_block_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane,
1020*fb1b10abSAndroid Build Coastguard Worker int enable_trellis_opt) {
1021*fb1b10abSAndroid Build Coastguard Worker const MACROBLOCKD *const xd = &x->e_mbd;
1022*fb1b10abSAndroid Build Coastguard Worker struct optimize_ctx ctx;
1023*fb1b10abSAndroid Build Coastguard Worker #if CONFIG_MISMATCH_DEBUG
1024*fb1b10abSAndroid Build Coastguard Worker // TODO(angiebird): make mismatch_debug support intra mode
1025*fb1b10abSAndroid Build Coastguard Worker struct encode_b_args arg = {
1026*fb1b10abSAndroid Build Coastguard Worker x,
1027*fb1b10abSAndroid Build Coastguard Worker enable_trellis_opt,
1028*fb1b10abSAndroid Build Coastguard Worker 0.0, // trellis_opt_thresh
1029*fb1b10abSAndroid Build Coastguard Worker NULL, // &sse_calc_done
1030*fb1b10abSAndroid Build Coastguard Worker NULL, // &sse
1031*fb1b10abSAndroid Build Coastguard Worker ctx.ta[plane],
1032*fb1b10abSAndroid Build Coastguard Worker ctx.tl[plane],
1033*fb1b10abSAndroid Build Coastguard Worker &xd->mi[0]->skip,
1034*fb1b10abSAndroid Build Coastguard Worker 0, // mi_row
1035*fb1b10abSAndroid Build Coastguard Worker 0, // mi_col
1036*fb1b10abSAndroid Build Coastguard Worker 0 // output_enabled
1037*fb1b10abSAndroid Build Coastguard Worker };
1038*fb1b10abSAndroid Build Coastguard Worker #else
1039*fb1b10abSAndroid Build Coastguard Worker struct encode_b_args arg = { x,
1040*fb1b10abSAndroid Build Coastguard Worker enable_trellis_opt,
1041*fb1b10abSAndroid Build Coastguard Worker 0.0, // trellis_opt_thresh
1042*fb1b10abSAndroid Build Coastguard Worker NULL, // &sse_calc_done
1043*fb1b10abSAndroid Build Coastguard Worker NULL, // &sse
1044*fb1b10abSAndroid Build Coastguard Worker ctx.ta[plane],
1045*fb1b10abSAndroid Build Coastguard Worker ctx.tl[plane],
1046*fb1b10abSAndroid Build Coastguard Worker &xd->mi[0]->skip };
1047*fb1b10abSAndroid Build Coastguard Worker #endif
1048*fb1b10abSAndroid Build Coastguard Worker
1049*fb1b10abSAndroid Build Coastguard Worker if (enable_trellis_opt && x->optimize &&
1050*fb1b10abSAndroid Build Coastguard Worker (!x->skip_recode || !x->skip_optimize)) {
1051*fb1b10abSAndroid Build Coastguard Worker const struct macroblockd_plane *const pd = &xd->plane[plane];
1052*fb1b10abSAndroid Build Coastguard Worker const TX_SIZE tx_size =
1053*fb1b10abSAndroid Build Coastguard Worker plane ? get_uv_tx_size(xd->mi[0], pd) : xd->mi[0]->tx_size;
1054*fb1b10abSAndroid Build Coastguard Worker vp9_get_entropy_contexts(bsize, tx_size, pd, ctx.ta[plane], ctx.tl[plane]);
1055*fb1b10abSAndroid Build Coastguard Worker } else {
1056*fb1b10abSAndroid Build Coastguard Worker arg.enable_trellis_opt = 0;
1057*fb1b10abSAndroid Build Coastguard Worker }
1058*fb1b10abSAndroid Build Coastguard Worker
1059*fb1b10abSAndroid Build Coastguard Worker vp9_foreach_transformed_block_in_plane(xd, bsize, plane,
1060*fb1b10abSAndroid Build Coastguard Worker vp9_encode_block_intra, &arg);
1061*fb1b10abSAndroid Build Coastguard Worker }
1062