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