encodemb.c 42.6 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4 5 6 7 8 9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10 11
 */

Yaowu Xu's avatar
Yaowu Xu committed
12 13 14
#include "./av1_rtcd.h"
#include "./aom_config.h"
#include "./aom_dsp_rtcd.h"
Jingning Han's avatar
Jingning Han committed
15

16
#include "aom_dsp/quantize.h"
Yaowu Xu's avatar
Yaowu Xu committed
17
#include "aom_mem/aom_mem.h"
18
#include "aom_ports/mem.h"
Jingning Han's avatar
Jingning Han committed
19

20 21 22 23
#include "av1/common/idct.h"
#include "av1/common/reconinter.h"
#include "av1/common/reconintra.h"
#include "av1/common/scan.h"
Jingning Han's avatar
Jingning Han committed
24

25 26 27 28 29
#include "av1/encoder/encodemb.h"
#include "av1/encoder/hybrid_fwd_txfm.h"
#include "av1/encoder/quantize.h"
#include "av1/encoder/rd.h"
#include "av1/encoder/tokenize.h"
Jingning Han's avatar
Jingning Han committed
30

31 32 33 34 35 36
#if CONFIG_PVQ
#include "av1/encoder/encint.h"
#include "av1/common/partition.h"
#include "av1/encoder/pvq_encoder.h"
#endif

37 38 39
// Check if one needs to use c version subtraction.
static int check_subtract_block_size(int w, int h) { return w < 4 || h < 4; }

Yaowu Xu's avatar
Yaowu Xu committed
40
void av1_subtract_plane(MACROBLOCK *x, BLOCK_SIZE bsize, int plane) {
Jingning Han's avatar
Jingning Han committed
41 42 43
  struct macroblock_plane *const p = &x->plane[plane];
  const struct macroblockd_plane *const pd = &x->e_mbd.plane[plane];
  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
44 45
  const int bw = block_size_wide[plane_bsize];
  const int bh = block_size_high[plane_bsize];
Jingning Han's avatar
Jingning Han committed
46

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
  if (check_subtract_block_size(bw, bh)) {
#if CONFIG_AOM_HIGHBITDEPTH
    if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
      aom_highbd_subtract_block_c(bh, bw, p->src_diff, bw, p->src.buf,
                                  p->src.stride, pd->dst.buf, pd->dst.stride,
                                  x->e_mbd.bd);
      return;
    }
#endif  // CONFIG_AOM_HIGHBITDEPTH
    aom_subtract_block_c(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride,
                         pd->dst.buf, pd->dst.stride);

    return;
  }

Yaowu Xu's avatar
Yaowu Xu committed
62
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
63
  if (x->e_mbd.cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xu's avatar
Yaowu Xu committed
64
    aom_highbd_subtract_block(bh, bw, p->src_diff, bw, p->src.buf,
Jingning Han's avatar
Jingning Han committed
65 66 67 68
                              p->src.stride, pd->dst.buf, pd->dst.stride,
                              x->e_mbd.bd);
    return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
69 70
#endif  // CONFIG_AOM_HIGHBITDEPTH
  aom_subtract_block(bh, bw, p->src_diff, bw, p->src.buf, p->src.stride,
Jingning Han's avatar
Jingning Han committed
71 72 73
                     pd->dst.buf, pd->dst.stride);
}

Yaowu Xu's avatar
Yaowu Xu committed
74
typedef struct av1_token_state {
75 76 77 78 79 80
  int rate;
  int64_t error;
  int next;
  int16_t token;
  tran_low_t qc;
  tran_low_t dqc;
Yaowu Xu's avatar
Yaowu Xu committed
81
} av1_token_state;
Jingning Han's avatar
Jingning Han committed
82

83 84
// These numbers are empirically obtained.
static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] = {
85
  { 10, 6 }, { 8, 5 },
86
};
Jingning Han's avatar
Jingning Han committed
87

88 89 90 91 92
#define UPDATE_RD_COST()                             \
  {                                                  \
    rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0); \
    rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1); \
  }
Jingning Han's avatar
Jingning Han committed
93

Angie Chiang's avatar
Angie Chiang committed
94 95
int av1_optimize_b(const AV1_COMMON *cm, MACROBLOCK *mb, int plane, int block,
                   TX_SIZE tx_size, int ctx) {
Jingning Han's avatar
Jingning Han committed
96 97 98 99
  MACROBLOCKD *const xd = &mb->e_mbd;
  struct macroblock_plane *const p = &mb->plane[plane];
  struct macroblockd_plane *const pd = &xd->plane[plane];
  const int ref = is_inter_block(&xd->mi[0]->mbmi);
Yaowu Xu's avatar
Yaowu Xu committed
100
  av1_token_state tokens[MAX_TX_SQUARE + 1][2];
101
  unsigned best_index[MAX_TX_SQUARE + 1][2];
102
  uint8_t token_cache[MAX_TX_SQUARE];
Jingning Han's avatar
Jingning Han committed
103 104 105 106
  const tran_low_t *const coeff = BLOCK_OFFSET(mb->plane[plane].coeff, block);
  tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
  tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
  const int eob = p->eobs[block];
107
  const PLANE_TYPE plane_type = pd->plane_type;
108
  const int default_eob = tx_size_2d[tx_size];
109 110
  const int16_t *const dequant_ptr = pd->dequant;
  const uint8_t *const band_translate = get_band_translate(tx_size);
111
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
112
  const SCAN_ORDER *const scan_order =
Angie Chiang's avatar
Angie Chiang committed
113
      get_scan(cm, tx_size, tx_type, is_inter_block(&xd->mi[0]->mbmi));
114 115
  const int16_t *const scan = scan_order->scan;
  const int16_t *const nb = scan_order->neighbors;
Thomas Davies's avatar
Thomas Davies committed
116
  int dqv;
117
  const int shift = get_tx_scale(tx_size);
118 119
#if CONFIG_AOM_QM
  int seg_id = xd->mi[0]->mbmi.segment_id;
120
  const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!ref][tx_size];
121
#endif
122
#if CONFIG_NEW_QUANT
123
  int dq = get_dq_profile_from_ctx(mb->qindex, ctx, ref, plane_type);
124
  const dequant_val_type_nuq *dequant_val = pd->dequant_val_nuq[dq];
125
#elif !CONFIG_AOM_QM
126
  const int dq_step[2] = { dequant_ptr[0] >> shift, dequant_ptr[1] >> shift };
127
#endif  // CONFIG_NEW_QUANT
Jingning Han's avatar
Jingning Han committed
128
  int next = eob, sz = 0;
129
  const int64_t rdmult = (mb->rdmult * plane_rd_mult[ref][plane_type]) >> 1;
hui su's avatar
hui su committed
130
  const int64_t rddiv = mb->rddiv;
Jingning Han's avatar
Jingning Han committed
131
  int64_t rd_cost0, rd_cost1;
132 133
  int rate0, rate1;
  int64_t error0, error1;
Jingning Han's avatar
Jingning Han committed
134
  int16_t t0, t1;
135 136
  int best, band = (eob < default_eob) ? band_translate[eob]
                                       : band_translate[eob - 1];
137
  int pt, i, final_eob;
Yaowu Xu's avatar
Yaowu Xu committed
138 139
#if CONFIG_AOM_HIGHBITDEPTH
  const int *cat6_high_cost = av1_get_high_cost_table(xd->bd);
Jingning Han's avatar
Jingning Han committed
140
#else
Yaowu Xu's avatar
Yaowu Xu committed
141
  const int *cat6_high_cost = av1_get_high_cost_table(8);
Jingning Han's avatar
Jingning Han committed
142
#endif
143
  unsigned int(*token_costs)[2][COEFF_CONTEXTS][ENTROPY_TOKENS] =
144
      mb->token_costs[txsize_sqr_map[tx_size]][plane_type][ref];
145 146
  const uint16_t *band_counts = &band_count_table[tx_size][band];
  uint16_t band_left = eob - band_cum_count_table[tx_size][band] + 1;
147 148
  int shortcut = 0;
  int next_shortcut = 0;
149

150
  assert((mb->qindex == 0) ^ (xd->lossless[xd->mi[0]->mbmi.segment_id] == 0));
151

152
  token_costs += band;
Jingning Han's avatar
Jingning Han committed
153

154
  assert((!plane_type && !plane) || (plane_type && plane));
Jingning Han's avatar
Jingning Han committed
155
  assert(eob <= default_eob);
156

Jingning Han's avatar
Jingning Han committed
157 158 159 160 161 162 163 164 165
  /* Now set up a Viterbi trellis to evaluate alternative roundings. */
  /* Initialize the sentinel node of the trellis. */
  tokens[eob][0].rate = 0;
  tokens[eob][0].error = 0;
  tokens[eob][0].next = default_eob;
  tokens[eob][0].token = EOB_TOKEN;
  tokens[eob][0].qc = 0;
  tokens[eob][1] = tokens[eob][0];

166 167
  for (i = 0; i < eob; i++) {
    const int rc = scan[i];
Yaowu Xu's avatar
Yaowu Xu committed
168
    tokens[i][0].rate = av1_get_token_cost(qcoeff[rc], &t0, cat6_high_cost);
169
    tokens[i][0].token = t0;
Yaowu Xu's avatar
Yaowu Xu committed
170
    token_cache[rc] = av1_pt_energy_class[t0];
171
  }
Jingning Han's avatar
Jingning Han committed
172 173

  for (i = eob; i-- > 0;) {
174 175
    int base_bits, dx;
    int64_t d2;
Jingning Han's avatar
Jingning Han committed
176
    const int rc = scan[i];
Thomas Davies's avatar
Thomas Davies committed
177
    int x = qcoeff[rc];
178 179
#if CONFIG_AOM_QM
    int iwt = iqmatrix[rc];
Thomas Davies's avatar
Thomas Davies committed
180 181 182 183
    dqv = dequant_ptr[rc != 0];
    dqv = ((iwt * (int)dqv) + (1 << (AOM_QM_BITS - 1))) >> AOM_QM_BITS;
#else
    dqv = dequant_ptr[rc != 0];
184
#endif
185
    next_shortcut = shortcut;
186

Jingning Han's avatar
Jingning Han committed
187
    /* Only add a trellis state for non-zero coefficients. */
188
    if (UNLIKELY(x)) {
Jingning Han's avatar
Jingning Han committed
189 190 191 192 193
      error0 = tokens[next][0].error;
      error1 = tokens[next][1].error;
      /* Evaluate the first possibility for this state. */
      rate0 = tokens[next][0].rate;
      rate1 = tokens[next][1].rate;
194

195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
      if (next_shortcut) {
        /* Consider both possible successor states. */
        if (next < default_eob) {
          pt = get_coef_context(nb, token_cache, i + 1);
          rate0 += (*token_costs)[0][pt][tokens[next][0].token];
          rate1 += (*token_costs)[0][pt][tokens[next][1].token];
        }
        UPDATE_RD_COST();
        /* And pick the best. */
        best = rd_cost1 < rd_cost0;
      } else {
        if (next < default_eob) {
          pt = get_coef_context(nb, token_cache, i + 1);
          rate0 += (*token_costs)[0][pt][tokens[next][0].token];
        }
        best = 0;
Jingning Han's avatar
Jingning Han committed
211
      }
212 213

      dx = (dqcoeff[rc] - coeff[rc]) * (1 << shift);
Yaowu Xu's avatar
Yaowu Xu committed
214
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
215 216 217
      if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
        dx >>= xd->bd - 8;
      }
Yaowu Xu's avatar
Yaowu Xu committed
218
#endif  // CONFIG_AOM_HIGHBITDEPTH
219
      d2 = (int64_t)dx * dx;
220
      tokens[i][0].rate += (best ? rate1 : rate0);
Jingning Han's avatar
Jingning Han committed
221 222 223
      tokens[i][0].error = d2 + (best ? error1 : error0);
      tokens[i][0].next = next;
      tokens[i][0].qc = x;
224
      tokens[i][0].dqc = dqcoeff[rc];
Jingning Han's avatar
Jingning Han committed
225 226 227 228 229 230
      best_index[i][0] = best;

      /* Evaluate the second possibility for this state. */
      rate0 = tokens[next][0].rate;
      rate1 = tokens[next][1].rate;

231
      // The threshold of 3 is empirically obtained.
232
      if (UNLIKELY(abs(x) > 3)) {
233 234
        shortcut = 0;
      } else {
235
#if CONFIG_NEW_QUANT
Thomas Davies's avatar
Thomas Davies committed
236
        shortcut = ((av1_dequant_abscoeff_nuq(abs(x), dqv,
Yaowu Xu's avatar
Yaowu Xu committed
237
                                              dequant_val[band_translate[i]]) >
238
                     (abs(coeff[rc]) << shift)) &&
Thomas Davies's avatar
Thomas Davies committed
239
                    (av1_dequant_abscoeff_nuq(abs(x) - 1, dqv,
Yaowu Xu's avatar
Yaowu Xu committed
240
                                              dequant_val[band_translate[i]]) <
241
                     (abs(coeff[rc]) << shift)));
242 243 244 245 246 247 248 249
#else  // CONFIG_NEW_QUANT
#if CONFIG_AOM_QM
        if ((abs(x) * dequant_ptr[rc != 0] * iwt >
             ((abs(coeff[rc]) << shift) << AOM_QM_BITS)) &&
            (abs(x) * dequant_ptr[rc != 0] * iwt <
             (((abs(coeff[rc]) << shift) + dequant_ptr[rc != 0])
              << AOM_QM_BITS)))
#else
250
        if ((abs(x) * dequant_ptr[rc != 0] > (abs(coeff[rc]) << shift)) &&
251 252
            (abs(x) * dequant_ptr[rc != 0] <
             (abs(coeff[rc]) << shift) + dequant_ptr[rc != 0]))
253
#endif  // CONFIG_AOM_QM
254 255 256
          shortcut = 1;
        else
          shortcut = 0;
257
#endif  // CONFIG_NEW_QUANT
258
      }
Jingning Han's avatar
Jingning Han committed
259 260 261 262

      if (shortcut) {
        sz = -(x < 0);
        x -= 2 * sz + 1;
263 264 265 266
      } else {
        tokens[i][1] = tokens[i][0];
        best_index[i][1] = best_index[i][0];
        next = i;
267

268
        if (UNLIKELY(!(--band_left))) {
269 270 271 272
          --band_counts;
          band_left = *band_counts;
          --token_costs;
        }
273
        continue;
Jingning Han's avatar
Jingning Han committed
274 275 276 277 278 279 280 281 282
      }

      /* Consider both possible successor states. */
      if (!x) {
        /* If we reduced this coefficient to zero, check to see if
         *  we need to move the EOB back here.
         */
        t0 = tokens[next][0].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
        t1 = tokens[next][1].token == EOB_TOKEN ? EOB_TOKEN : ZERO_TOKEN;
283
        base_bits = 0;
Jingning Han's avatar
Jingning Han committed
284
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
285
        base_bits = av1_get_token_cost(x, &t0, cat6_high_cost);
Jingning Han's avatar
Jingning Han committed
286 287
        t1 = t0;
      }
288 289

      if (next_shortcut) {
290
        if (LIKELY(next < default_eob)) {
291
          if (t0 != EOB_TOKEN) {
Yaowu Xu's avatar
Yaowu Xu committed
292
            token_cache[rc] = av1_pt_energy_class[t0];
293 294 295 296
            pt = get_coef_context(nb, token_cache, i + 1);
            rate0 += (*token_costs)[!x][pt][tokens[next][0].token];
          }
          if (t1 != EOB_TOKEN) {
Yaowu Xu's avatar
Yaowu Xu committed
297
            token_cache[rc] = av1_pt_energy_class[t1];
298 299 300 301 302 303 304 305 306 307 308
            pt = get_coef_context(nb, token_cache, i + 1);
            rate1 += (*token_costs)[!x][pt][tokens[next][1].token];
          }
        }

        UPDATE_RD_COST();
        /* And pick the best. */
        best = rd_cost1 < rd_cost0;
      } else {
        // The two states in next stage are identical.
        if (next < default_eob && t0 != EOB_TOKEN) {
Yaowu Xu's avatar
Yaowu Xu committed
309
          token_cache[rc] = av1_pt_energy_class[t0];
Jingning Han's avatar
Jingning Han committed
310
          pt = get_coef_context(nb, token_cache, i + 1);
311
          rate0 += (*token_costs)[!x][pt][tokens[next][0].token];
Jingning Han's avatar
Jingning Han committed
312
        }
313
        best = 0;
Jingning Han's avatar
Jingning Han committed
314 315
      }

316
#if CONFIG_NEW_QUANT
Thomas Davies's avatar
Thomas Davies committed
317
      dx = av1_dequant_coeff_nuq(x, dqv, dequant_val[band_translate[i]]) -
318
           (coeff[rc] << shift);
Yaowu Xu's avatar
Yaowu Xu committed
319
#if CONFIG_AOM_HIGHBITDEPTH
hui su's avatar
hui su committed
320 321 322
      if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
        dx >>= xd->bd - 8;
      }
Yaowu Xu's avatar
Yaowu Xu committed
323
#endif  // CONFIG_AOM_HIGHBITDEPTH
324
#else   // CONFIG_NEW_QUANT
Yaowu Xu's avatar
Yaowu Xu committed
325
#if CONFIG_AOM_HIGHBITDEPTH
hui su's avatar
hui su committed
326
      if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Thomas Davies's avatar
Thomas Davies committed
327
        dx -= ((dqv >> (xd->bd - 8)) + sz) ^ sz;
hui su's avatar
hui su committed
328
      } else {
Thomas Davies's avatar
Thomas Davies committed
329
        dx -= (dqv + sz) ^ sz;
hui su's avatar
hui su committed
330 331
      }
#else
Thomas Davies's avatar
Thomas Davies committed
332
      dx -= (dqv + sz) ^ sz;
Yaowu Xu's avatar
Yaowu Xu committed
333
#endif  // CONFIG_AOM_HIGHBITDEPTH
334
#endif  // CONFIG_NEW_QUANT
335
      d2 = (int64_t)dx * dx;
hui su's avatar
hui su committed
336

Jingning Han's avatar
Jingning Han committed
337 338 339 340 341
      tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
      tokens[i][1].error = d2 + (best ? error1 : error0);
      tokens[i][1].next = next;
      tokens[i][1].token = best ? t1 : t0;
      tokens[i][1].qc = x;
342 343

      if (x) {
344
#if CONFIG_NEW_QUANT
Yaowu Xu's avatar
Yaowu Xu committed
345
        tokens[i][1].dqc = av1_dequant_abscoeff_nuq(
Thomas Davies's avatar
Thomas Davies committed
346
            abs(x), dqv, dequant_val[band_translate[i]]);
347 348 349
        tokens[i][1].dqc = shift ? ROUND_POWER_OF_TWO(tokens[i][1].dqc, shift)
                                 : tokens[i][1].dqc;
        if (sz) tokens[i][1].dqc = -tokens[i][1].dqc;
350
#else
351 352 353 354
// The 32x32 transform coefficient uses half quantization step size.
// Account for the rounding difference in the dequantized coefficeint
// value when the quantization index is dropped from an even number
// to an odd number.
Thomas Davies's avatar
Thomas Davies committed
355 356 357 358 359 360 361

#if CONFIG_AOM_QM
        tran_low_t offset = dqv >> shift;
#else
        tran_low_t offset = dq_step[rc != 0];
#endif
        if (shift & x) offset += (dqv & 0x01);
362 363 364 365 366

        if (sz == 0)
          tokens[i][1].dqc = dqcoeff[rc] - offset;
        else
          tokens[i][1].dqc = dqcoeff[rc] + offset;
367
#endif  // CONFIG_NEW_QUANT
368 369 370 371
      } else {
        tokens[i][1].dqc = 0;
      }

Jingning Han's avatar
Jingning Han committed
372 373 374 375 376 377 378 379 380
      best_index[i][1] = best;
      /* Finally, make this the new head of the trellis. */
      next = i;
    } else {
      /* There's no choice to make for a zero coefficient, so we don't
       *  add a new trellis node, but we do need to update the costs.
       */
      t0 = tokens[next][0].token;
      t1 = tokens[next][1].token;
381
      pt = get_coef_context(nb, token_cache, i + 1);
Jingning Han's avatar
Jingning Han committed
382 383
      /* Update the cost of each path if we're past the EOB token. */
      if (t0 != EOB_TOKEN) {
384
        tokens[next][0].rate += (*token_costs)[1][pt][t0];
Jingning Han's avatar
Jingning Han committed
385 386 387
        tokens[next][0].token = ZERO_TOKEN;
      }
      if (t1 != EOB_TOKEN) {
388
        tokens[next][1].rate += (*token_costs)[1][pt][t1];
Jingning Han's avatar
Jingning Han committed
389 390 391
        tokens[next][1].token = ZERO_TOKEN;
      }
      best_index[i][0] = best_index[i][1] = 0;
392
      shortcut = (tokens[next][0].rate != tokens[next][1].rate);
Jingning Han's avatar
Jingning Han committed
393 394
      /* Don't update next, because we didn't add a new node. */
    }
395

396
    if (UNLIKELY(!(--band_left))) {
397 398 399 400
      --band_counts;
      band_left = *band_counts;
      --token_costs;
    }
Jingning Han's avatar
Jingning Han committed
401 402 403 404 405 406 407 408 409
  }

  /* Now pick the best path through the whole trellis. */
  rate0 = tokens[next][0].rate;
  rate1 = tokens[next][1].rate;
  error0 = tokens[next][0].error;
  error1 = tokens[next][1].error;
  t0 = tokens[next][0].token;
  t1 = tokens[next][1].token;
410 411
  rate0 += (*token_costs)[0][ctx][t0];
  rate1 += (*token_costs)[0][ctx][t1];
Jingning Han's avatar
Jingning Han committed
412 413
  UPDATE_RD_COST();
  best = rd_cost1 < rd_cost0;
414

Jingning Han's avatar
Jingning Han committed
415
  final_eob = -1;
416

Jingning Han's avatar
Jingning Han committed
417 418 419
  for (i = next; i < eob; i = next) {
    const int x = tokens[i][best].qc;
    const int rc = scan[i];
420
    if (x) final_eob = i;
Jingning Han's avatar
Jingning Han committed
421
    qcoeff[rc] = x;
422 423
    dqcoeff[rc] = tokens[i][best].dqc;

Jingning Han's avatar
Jingning Han committed
424 425 426 427 428 429
    next = tokens[i][best].next;
    best = best_index[i][best];
  }
  final_eob++;

  mb->plane[plane].eobs[block] = final_eob;
430
  assert(final_eob <= default_eob);
Jingning Han's avatar
Jingning Han committed
431 432 433
  return final_eob;
}

Yaowu Xu's avatar
Yaowu Xu committed
434
#if CONFIG_AOM_HIGHBITDEPTH
Angie Chiang's avatar
Angie Chiang committed
435 436
typedef enum QUANT_FUNC {
  QUANT_FUNC_LOWBD = 0,
437
  QUANT_FUNC_HIGHBD = 1,
438
  QUANT_FUNC_TYPES = 2
Angie Chiang's avatar
Angie Chiang committed
439 440
} QUANT_FUNC;

441 442 443
static AV1_QUANT_FACADE
    quant_func_list[AV1_XFORM_QUANT_TYPES][QUANT_FUNC_TYPES] = {
      { av1_quantize_fp_facade, av1_highbd_quantize_fp_facade },
Yaowu Xu's avatar
Yaowu Xu committed
444 445
      { av1_quantize_b_facade, av1_highbd_quantize_b_facade },
      { av1_quantize_dc_facade, av1_highbd_quantize_dc_facade },
446 447 448 449 450 451 452
#if CONFIG_NEW_QUANT
      { av1_quantize_fp_nuq_facade, av1_highbd_quantize_fp_nuq_facade },
      { av1_quantize_b_nuq_facade, av1_highbd_quantize_b_nuq_facade },
      { av1_quantize_dc_nuq_facade, av1_highbd_quantize_dc_nuq_facade },
#endif  // CONFIG_NEW_QUANT
      { NULL, NULL }
    };
453

454 455
#elif !CONFIG_PVQ

Angie Chiang's avatar
Angie Chiang committed
456 457
typedef enum QUANT_FUNC {
  QUANT_FUNC_LOWBD = 0,
458
  QUANT_FUNC_TYPES = 1
Angie Chiang's avatar
Angie Chiang committed
459
} QUANT_FUNC;
Angie Chiang's avatar
Angie Chiang committed
460

461 462
static AV1_QUANT_FACADE quant_func_list[AV1_XFORM_QUANT_TYPES]
                                       [QUANT_FUNC_TYPES] = {
clang-format's avatar
clang-format committed
463 464 465
                                         { av1_quantize_fp_facade },
                                         { av1_quantize_b_facade },
                                         { av1_quantize_dc_facade },
466 467 468 469 470
#if CONFIG_NEW_QUANT
                                         { av1_quantize_fp_nuq_facade },
                                         { av1_quantize_b_nuq_facade },
                                         { av1_quantize_dc_nuq_facade },
#endif  // CONFIG_NEW_QUANT
clang-format's avatar
clang-format committed
471 472
                                         { NULL }
                                       };
Angie Chiang's avatar
Angie Chiang committed
473
#endif
474

475 476 477 478 479 480
static FWD_TXFM_OPT fwd_txfm_opt_list[AV1_XFORM_QUANT_TYPES] = {
  FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_DC,
#if CONFIG_NEW_QUANT
  FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_NORMAL, FWD_TXFM_OPT_DC,
#endif  // CONFIG_NEW_QUANT
  FWD_TXFM_OPT_NORMAL
481
};
482

Angie Chiang's avatar
Angie Chiang committed
483 484
void av1_xform_quant(const AV1_COMMON *cm, MACROBLOCK *x, int plane, int block,
                     int blk_row, int blk_col, BLOCK_SIZE plane_bsize,
485 486
                     TX_SIZE tx_size, int ctx,
                     AV1_XFORM_QUANT xform_quant_idx) {
Jingning Han's avatar
Jingning Han committed
487
  MACROBLOCKD *const xd = &x->e_mbd;
488
#if !CONFIG_PVQ
Jingning Han's avatar
Jingning Han committed
489 490
  const struct macroblock_plane *const p = &x->plane[plane];
  const struct macroblockd_plane *const pd = &xd->plane[plane];
491 492 493 494
#else
  struct macroblock_plane *const p = &x->plane[plane];
  struct macroblockd_plane *const pd = &xd->plane[plane];
#endif
hui su's avatar
hui su committed
495
  PLANE_TYPE plane_type = (plane == 0) ? PLANE_TYPE_Y : PLANE_TYPE_UV;
hui su's avatar
hui su committed
496
  TX_TYPE tx_type = get_tx_type(plane_type, xd, block, tx_size);
497
  const int is_inter = is_inter_block(&xd->mi[0]->mbmi);
Angie Chiang's avatar
Angie Chiang committed
498
  const SCAN_ORDER *const scan_order = get_scan(cm, tx_size, tx_type, is_inter);
Jingning Han's avatar
Jingning Han committed
499 500 501 502
  tran_low_t *const coeff = BLOCK_OFFSET(p->coeff, block);
  tran_low_t *const qcoeff = BLOCK_OFFSET(p->qcoeff, block);
  tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
  uint16_t *const eob = &p->eobs[block];
503
  const int diff_stride = block_size_wide[plane_bsize];
504 505
#if CONFIG_AOM_QM
  int seg_id = xd->mi[0]->mbmi.segment_id;
506 507
  const qm_val_t *qmatrix = pd->seg_qmatrix[seg_id][!is_inter][tx_size];
  const qm_val_t *iqmatrix = pd->seg_iqmatrix[seg_id][!is_inter][tx_size];
508
#endif
Angie Chiang's avatar
Angie Chiang committed
509 510

  FWD_TXFM_PARAM fwd_txfm_param;
511 512 513

#if !CONFIG_PVQ
  const int tx2d_size = tx_size_2d[tx_size];
514
  QUANT_PARAM qparam;
515 516 517
  const int16_t *src_diff;

  src_diff = &p->src_diff[4 * (blk_row * diff_stride + blk_col)];
518
  qparam.log_scale = get_tx_scale(tx_size);
519 520 521 522 523 524 525 526
#if CONFIG_NEW_QUANT
  qparam.tx_size = tx_size;
  qparam.dq = get_dq_profile_from_ctx(x->qindex, ctx, is_inter, plane_type);
#endif  // CONFIG_NEW_QUANT
#if CONFIG_AOM_QM
  qparam.qmatrix = qmatrix;
  qparam.iqmatrix = iqmatrix;
#endif  // CONFIG_AOM_QM
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
#else
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
  tran_low_t *ref_coeff = BLOCK_OFFSET(pd->pvq_ref_coeff, block);
  uint8_t *src, *dst;
  int16_t *src_int16, *pred;
  const int src_stride = p->src.stride;
  const int dst_stride = pd->dst.stride;
  int tx_blk_size;
  int i, j;
  int skip = 1;
  PVQ_INFO *pvq_info = NULL;

  (void)scan_order;
  (void)qcoeff;

  if (x->pvq_coded) {
    assert(block < MAX_PVQ_BLOCKS_IN_SB);
    pvq_info = &x->pvq[block][plane];
  }
  dst = &pd->dst.buf[4 * (blk_row * dst_stride + blk_col)];
  src = &p->src.buf[4 * (blk_row * src_stride + blk_col)];
  src_int16 = &p->src_int16[4 * (blk_row * diff_stride + blk_col)];
  pred = &pd->pred[4 * (blk_row * diff_stride + blk_col)];

  // transform block size in pixels
  tx_blk_size = tx_size_wide[tx_size];

  // copy uint8 orig and predicted block to int16 buffer
  // in order to use existing VP10 transform functions
  for (j = 0; j < tx_blk_size; j++)
    for (i = 0; i < tx_blk_size; i++) {
      src_int16[diff_stride * j + i] = src[src_stride * j + i];
      pred[diff_stride * j + i] = dst[dst_stride * j + i];
    }
#endif
562
  (void)ctx;
563 564

  fwd_txfm_param.tx_type = tx_type;
Angie Chiang's avatar
Angie Chiang committed
565
  fwd_txfm_param.tx_size = tx_size;
566
  fwd_txfm_param.fwd_txfm_opt = fwd_txfm_opt_list[xform_quant_idx];
Angie Chiang's avatar
Angie Chiang committed
567 568 569
  fwd_txfm_param.rd_transform = x->use_lp32x32fdct;
  fwd_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];

Yaowu Xu's avatar
Yaowu Xu committed
570
#if CONFIG_AOM_HIGHBITDEPTH
571
  fwd_txfm_param.bd = xd->bd;
Jingning Han's avatar
Jingning Han committed
572
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Angie Chiang's avatar
Angie Chiang committed
573
    highbd_fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xu's avatar
Yaowu Xu committed
574
    if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
575
      if (LIKELY(!x->skip_block)) {
576
        quant_func_list[xform_quant_idx][QUANT_FUNC_HIGHBD](
577
            coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam);
578
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
579
        av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
580 581 582 583
      }
    }
    return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
584
#endif  // CONFIG_AOM_HIGHBITDEPTH
585

586
#if !CONFIG_PVQ
587
  fwd_txfm(src_diff, coeff, diff_stride, &fwd_txfm_param);
Yaowu Xu's avatar
Yaowu Xu committed
588
  if (xform_quant_idx != AV1_XFORM_QUANT_SKIP_QUANT) {
589
    if (LIKELY(!x->skip_block)) {
590
      quant_func_list[xform_quant_idx][QUANT_FUNC_LOWBD](
591
          coeff, tx2d_size, p, qcoeff, pd, dqcoeff, eob, scan_order, &qparam);
592
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
593
      av1_quantize_skip(tx2d_size, qcoeff, dqcoeff, eob);
Jingning Han's avatar
Jingning Han committed
594 595
    }
  }
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
#else   // #if !CONFIG_PVQ
  fwd_txfm_param.rd_transform = 0;

  fwd_txfm(src_int16, coeff, diff_stride, &fwd_txfm_param);
  fwd_txfm(pred, ref_coeff, diff_stride, &fwd_txfm_param);

  // PVQ for inter mode block
  if (!x->skip_block)
    skip = av1_pvq_encode_helper(&x->daala_enc,
                                 coeff,        // target original vector
                                 ref_coeff,    // reference vector
                                 dqcoeff,      // de-quantized vector
                                 eob,          // End of Block marker
                                 pd->dequant,  // aom's quantizers
                                 plane,        // image plane
                                 tx_size,      // block size in log_2 - 2
                                 tx_type,
                                 &x->rate,  // rate measured
                                 x->pvq_speed,
                                 pvq_info);  // PVQ info for a block

  x->pvq_skip[plane] = skip;

  if (!skip) mbmi->skip = 0;
#endif  // #if !CONFIG_PVQ
Jingning Han's avatar
Jingning Han committed
621 622
}

623
static void encode_block(int plane, int block, int blk_row, int blk_col,
624
                         BLOCK_SIZE plane_bsize, TX_SIZE tx_size, void *arg) {
Jingning Han's avatar
Jingning Han committed
625
  struct encode_b_args *const args = arg;
Angie Chiang's avatar
Angie Chiang committed
626
  AV1_COMMON *cm = args->cm;
Jingning Han's avatar
Jingning Han committed
627 628
  MACROBLOCK *const x = args->x;
  MACROBLOCKD *const xd = &x->e_mbd;
629
  int ctx;
Jingning Han's avatar
Jingning Han committed
630 631 632 633 634
  struct macroblock_plane *const p = &x->plane[plane];
  struct macroblockd_plane *const pd = &xd->plane[plane];
  tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
  uint8_t *dst;
  ENTROPY_CONTEXT *a, *l;
Angie Chiang's avatar
Angie Chiang committed
635
  INV_TXFM_PARAM inv_txfm_param;
636 637 638 639
#if CONFIG_PVQ
  int tx_blk_size;
  int i, j;
#endif
640 641
#if CONFIG_VAR_TX
  int i;
642
  const int bwl = b_width_log2_lookup[plane_bsize];
643
#endif
644
  dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
645 646
  a = &args->ta[blk_col];
  l = &args->tl[blk_row];
647 648 649 650 651
#if CONFIG_VAR_TX
  ctx = get_entropy_context(tx_size, a, l);
#else
  ctx = combine_entropy_contexts(*a, *l);
#endif
Jingning Han's avatar
Jingning Han committed
652

Alex Converse's avatar
Alex Converse committed
653
#if CONFIG_VAR_TX
654
  // Assert not magic number (uninitialized).
655 656
  assert(x->blk_skip[plane][(blk_row << bwl) + blk_col] != 234);

657
  if (x->blk_skip[plane][(blk_row << bwl) + blk_col] == 0) {
658
#else
659
  {
660
#endif
661
#if CONFIG_NEW_QUANT
662 663
    av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
                    ctx, AV1_XFORM_QUANT_FP_NUQ);
664
#else
Angie Chiang's avatar
Angie Chiang committed
665
    av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
666
                    ctx, AV1_XFORM_QUANT_FP);
667
#endif  // CONFIG_NEW_QUANT
Jingning Han's avatar
Jingning Han committed
668
  }
669 670
#if CONFIG_VAR_TX
  else {
671
    p->eobs[block] = 0;
672 673
  }
#endif
674
#if !CONFIG_PVQ
675
  if (p->eobs[block] && !xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Angie Chiang's avatar
Angie Chiang committed
676
    *a = *l = av1_optimize_b(cm, x, plane, block, tx_size, ctx) > 0;
Jingning Han's avatar
Jingning Han committed
677 678 679 680
  } else {
    *a = *l = p->eobs[block] > 0;
  }

681
#if CONFIG_VAR_TX
682 683 684
  for (i = 0; i < tx_size_wide_unit[tx_size]; ++i) a[i] = a[0];

  for (i = 0; i < tx_size_high_unit[tx_size]; ++i) l[i] = l[0];
685 686
#endif

687
  if (p->eobs[block]) *(args->skip) = 0;
Jingning Han's avatar
Jingning Han committed
688

689
  if (p->eobs[block] == 0) return;
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
#else
  (void)ctx;
  *a = *l = !x->pvq_skip[plane];

  if (!x->pvq_skip[plane]) *(args->skip) = 0;

  if (x->pvq_skip[plane]) return;

  // transform block size in pixels
  tx_blk_size = tx_size_wide[tx_size];

  // Since av1 does not have separate function which does inverse transform
  // but av1_inv_txfm_add_*x*() also does addition of predicted image to
  // inverse transformed image,
  // pass blank dummy image to av1_inv_txfm_add_*x*(), i.e. set dst as zeros
  for (j = 0; j < tx_blk_size; j++)
    for (i = 0; i < tx_blk_size; i++) dst[j * pd->dst.stride + i] = 0;
#endif
Angie Chiang's avatar
Angie Chiang committed
708 709 710 711 712 713 714

  // inverse transform parameters
  inv_txfm_param.tx_type = get_tx_type(pd->plane_type, xd, block, tx_size);
  inv_txfm_param.tx_size = tx_size;
  inv_txfm_param.eob = p->eobs[block];
  inv_txfm_param.lossless = xd->lossless[xd->mi[0]->mbmi.segment_id];

Yaowu Xu's avatar
Yaowu Xu committed
715
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
716
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Angie Chiang's avatar
Angie Chiang committed
717 718
    inv_txfm_param.bd = xd->bd;
    highbd_inv_txfm_add(dqcoeff, dst, pd->dst.stride, &inv_txfm_param);
Jingning Han's avatar
Jingning Han committed
719 720
    return;
  }
Yaowu Xu's avatar
Yaowu Xu committed
721
#endif  // CONFIG_AOM_HIGHBITDEPTH
Angie Chiang's avatar
Angie Chiang committed
722
  inv_txfm_add(dqcoeff, dst, pd->dst.stride, &inv_txfm_param);
Jingning Han's avatar
Jingning Han committed
723 724
}

725 726 727 728 729 730 731 732
#if CONFIG_VAR_TX
static void encode_block_inter(int plane, int block, int blk_row, int blk_col,
                               BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
                               void *arg) {
  struct encode_b_args *const args = arg;
  MACROBLOCK *const x = args->x;
  MACROBLOCKD *const xd = &x->e_mbd;
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
733
  const BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
734
  const struct macroblockd_plane *const pd = &xd->plane[plane];
735 736
  const int tx_row = blk_row >> (1 - pd->subsampling_y);
  const int tx_col = blk_col >> (1 - pd->subsampling_x);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
737
  TX_SIZE plane_tx_size;
738 739
  const int max_blocks_high = max_block_high(xd, plane_bsize, plane);
  const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane);
740

741
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
742

743 744 745
  plane_tx_size =
      plane ? uv_txsize_lookup[bsize][mbmi->inter_tx_size[tx_row][tx_col]][0][0]
            : mbmi->inter_tx_size[tx_row][tx_col];
Debargha Mukherjee's avatar
Debargha Mukherjee committed
746

747
  if (tx_size == plane_tx_size) {
748
    encode_block(plane, block, blk_row, blk_col, plane_bsize, tx_size, arg);
749
  } else {
750 751 752
    const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
    // This is the square transform block partition entry point.
    int bsl = tx_size_wide_unit[sub_txs];
753 754
    int i;
    assert(bsl > 0);
755
    assert(tx_size < TX_SIZES_ALL);
756

757
    for (i = 0; i < 4; ++i) {
758 759 760
      const int offsetr = blk_row + ((i >> 1) * bsl);
      const int offsetc = blk_col + ((i & 0x01) * bsl);
      int step = tx_size_wide_unit[sub_txs] * tx_size_high_unit[sub_txs];
761

762
      if (offsetr >= max_blocks_high || offsetc >= max_blocks_wide) continue;
763

764 765 766
      encode_block_inter(plane, block, offsetr, offsetc, plane_bsize, sub_txs,
                         arg);
      block += step;
767 768 769 770 771
    }
  }
}
#endif

Angie Chiang's avatar
Angie Chiang committed
772 773 774 775 776
typedef struct encode_block_pass1_args {
  AV1_COMMON *cm;
  MACROBLOCK *x;
} encode_block_pass1_args;

777
static void encode_block_pass1(int plane, int block, int blk_row, int blk_col,
778 779
                               BLOCK_SIZE plane_bsize, TX_SIZE tx_size,
                               void *arg) {
Angie Chiang's avatar
Angie Chiang committed
780 781 782
  encode_block_pass1_args *args = (encode_block_pass1_args *)arg;
  AV1_COMMON *cm = args->cm;
  MACROBLOCK *const x = args->x;
Jingning Han's avatar
Jingning Han committed
783 784 785 786 787
  MACROBLOCKD *const xd = &x->e_mbd;
  struct macroblock_plane *const p = &x->plane[plane];
  struct macroblockd_plane *const pd = &xd->plane[plane];
  tran_low_t *const dqcoeff = BLOCK_OFFSET(pd->dqcoeff, block);
  uint8_t *dst;
788
  int ctx = 0;
789
  dst = &pd->dst.buf[4 * blk_row * pd->dst.stride + 4 * blk_col];
Jingning Han's avatar
Jingning Han committed
790

791
#if CONFIG_NEW_QUANT
792 793
  av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
                  ctx, AV1_XFORM_QUANT_B_NUQ);
794
#else
Angie Chiang's avatar
Angie Chiang committed
795
  av1_xform_quant(cm, x, plane, block, blk_row, blk_col, plane_bsize, tx_size,
796
                  ctx, AV1_XFORM_QUANT_B);
797
#endif  // CONFIG_NEW_QUANT
798
#if !CONFIG_PVQ
Jingning Han's avatar
Jingning Han committed
799
  if (p->eobs[block] > 0) {
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
#else
  if (!x->pvq_skip[plane]) {
    {
      int tx_blk_size;
      int i, j;
      // transform block size in pixels
      tx_blk_size = tx_size_wide[tx_size];

      // Since av1 does not have separate function which does inverse transform
      // but av1_inv_txfm_add_*x*() also does addition of predicted image to
      // inverse transformed image,
      // pass blank dummy image to av1_inv_txfm_add_*x*(), i.e. set dst as zeros
      for (j = 0; j < tx_blk_size; j++)
        for (i = 0; i < tx_blk_size; i++) dst[j * pd->dst.stride + i] = 0;
    }
Jingning Han's avatar
Jingning Han committed
815
#endif  // !CONFIG_PVQ
Yaowu Xu's avatar
Yaowu Xu committed
816
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
817
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xu's avatar
Yaowu Xu committed
818
      if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xu's avatar
Yaowu Xu committed
819 820
        av1_highbd_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block],
                               xd->bd);
821
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
822 823
        av1_highbd_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block],
                               xd->bd);
824 825
      }
      return;
Jingning Han's avatar
Jingning Han committed
826
    }
827
#endif  //  CONFIG_AOM_HIGHBITDEPTH
Yaowu Xu's avatar
Yaowu Xu committed
828
    if (xd->lossless[xd->mi[0]->mbmi.segment_id]) {
Yaowu Xu's avatar
Yaowu Xu committed
829
      av1_iwht4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
830
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
831
      av1_idct4x4_add(dqcoeff, dst, pd->dst.stride, p->eobs[block]);
832
    }
Jingning Han's avatar
Jingning Han committed
833 834 835
  }
}

Angie Chiang's avatar
Angie Chiang committed
836 837
void av1_encode_sby_pass1(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
  encode_block_pass1_args args = { cm, x };
Yaowu Xu's avatar
Yaowu Xu committed
838 839
  av1_subtract_plane(x, bsize, 0);
  av1_foreach_transformed_block_in_plane(&x->e_mbd, bsize, 0,
Angie Chiang's avatar
Angie Chiang committed
840
                                         encode_block_pass1, &args);
Jingning Han's avatar
Jingning Han committed
841 842
}

Angie Chiang's avatar
Angie Chiang committed
843
void av1_encode_sb(AV1_COMMON *cm, MACROBLOCK *x, BLOCK_SIZE bsize) {
Jingning Han's avatar
Jingning Han committed
844 845 846
  MACROBLOCKD *const xd = &x->e_mbd;
  struct optimize_ctx ctx;
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Angie Chiang's avatar
Angie Chiang committed
847
  struct encode_b_args arg = { cm, x, &ctx, &mbmi->skip, NULL, NULL, 1 };
Jingning Han's avatar
Jingning Han committed
848 849 850 851
  int plane;

  mbmi->skip = 1;

852
  if (x->skip) return;
Jingning Han's avatar
Jingning Han committed
853 854

  for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
855 856 857 858
#if CONFIG_VAR_TX
    // TODO(jingning): Clean this up.
    const struct macroblockd_plane *const pd = &xd->plane[plane];
    const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, pd);
859 860
    const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
    const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
861
    const TX_SIZE max_tx_size = max_txsize_rect_lookup[plane_bsize];
862
    const BLOCK_SIZE txb_size = txsize_to_bsize[max_tx_size];
863 864
    const int bw = block_size_wide[txb_size] >> tx_size_wide_log2[0];
    const int bh = block_size_high[txb_size] >> tx_size_wide_log2[0];