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