Coverage Report

Created: 2026-09-14 08:00

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