vp9_encodemb.c 28.4 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
6
 *  that can be found in the LICENSE file in the root of the source
 *  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.
John Koleszar's avatar
John Koleszar committed
9
10
11
 */

#include "vpx_ports/config.h"
12
#include "vp9/encoder/vp9_encodemb.h"
13
#include "vp9/common/vp9_reconinter.h"
14
15
#include "vp9/encoder/vp9_quantize.h"
#include "vp9/encoder/vp9_tokenize.h"
16
17
#include "vp9/common/vp9_invtrans.h"
#include "vp9/common/vp9_reconintra.h"
John Koleszar's avatar
John Koleszar committed
18
#include "vpx_mem/vpx_mem.h"
19
#include "vp9/encoder/vp9_rdopt.h"
20
#include "vp9/common/vp9_systemdependent.h"
21
#include "vp9_rtcd.h"
John Koleszar's avatar
John Koleszar committed
22

23
void vp9_subtract_b_c(BLOCK *be, BLOCKD *bd, int pitch) {
John Koleszar's avatar
John Koleszar committed
24
25
26
27
28
29
  unsigned char *src_ptr = (*(be->base_src) + be->src);
  short *diff_ptr = be->src_diff;
  unsigned char *pred_ptr = bd->predictor;
  int src_stride = be->src_stride;

  int r, c;
John Koleszar's avatar
John Koleszar committed
30

John Koleszar's avatar
John Koleszar committed
31
32
33
  for (r = 0; r < 4; r++) {
    for (c = 0; c < 4; c++) {
      diff_ptr[c] = src_ptr[c] - pred_ptr[c];
John Koleszar's avatar
John Koleszar committed
34
    }
John Koleszar's avatar
John Koleszar committed
35
36
37
38
39

    diff_ptr += pitch;
    pred_ptr += pitch;
    src_ptr  += src_stride;
  }
John Koleszar's avatar
John Koleszar committed
40
41
}

42
void vp9_subtract_4b_c(BLOCK *be, BLOCKD *bd, int pitch) {
John Koleszar's avatar
John Koleszar committed
43
44
45
46
47
  unsigned char *src_ptr = (*(be->base_src) + be->src);
  short *diff_ptr = be->src_diff;
  unsigned char *pred_ptr = bd->predictor;
  int src_stride = be->src_stride;
  int r, c;
48

John Koleszar's avatar
John Koleszar committed
49
50
51
  for (r = 0; r < 8; r++) {
    for (c = 0; c < 8; c++) {
      diff_ptr[c] = src_ptr[c] - pred_ptr[c];
Yaowu Xu's avatar
Yaowu Xu committed
52
    }
John Koleszar's avatar
John Koleszar committed
53
54
55
56
    diff_ptr += pitch;
    pred_ptr += pitch;
    src_ptr  += src_stride;
  }
Yaowu Xu's avatar
Yaowu Xu committed
57
58
}

59
void vp9_subtract_mbuv_s_c(short *diff, const unsigned char *usrc,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
60
61
62
                           const unsigned char *vsrc, int src_stride,
                           const unsigned char *upred,
                           const unsigned char *vpred, int dst_stride) {
John Koleszar's avatar
John Koleszar committed
63
64
65
  short *udiff = diff + 256;
  short *vdiff = diff + 320;
  int r, c;
John Koleszar's avatar
John Koleszar committed
66

John Koleszar's avatar
John Koleszar committed
67
68
69
  for (r = 0; r < 8; r++) {
    for (c = 0; c < 8; c++) {
      udiff[c] = usrc[c] - upred[c];
John Koleszar's avatar
John Koleszar committed
70
71
    }

John Koleszar's avatar
John Koleszar committed
72
    udiff += 8;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
73
74
    upred += dst_stride;
    usrc  += src_stride;
John Koleszar's avatar
John Koleszar committed
75
  }
John Koleszar's avatar
John Koleszar committed
76

John Koleszar's avatar
John Koleszar committed
77
78
79
  for (r = 0; r < 8; r++) {
    for (c = 0; c < 8; c++) {
      vdiff[c] = vsrc[c] - vpred[c];
John Koleszar's avatar
John Koleszar committed
80
81
    }

John Koleszar's avatar
John Koleszar committed
82
    vdiff += 8;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
83
84
    vpred += dst_stride;
    vsrc  += src_stride;
John Koleszar's avatar
John Koleszar committed
85
86
  }
}
John Koleszar's avatar
John Koleszar committed
87

88
void vp9_subtract_mbuv_c(short *diff, unsigned char *usrc,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
89
                         unsigned char *vsrc, unsigned char *pred, int stride) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
90
91
92
  unsigned char *upred = pred + 256;
  unsigned char *vpred = pred + 320;

93
  vp9_subtract_mbuv_s_c(diff, usrc, vsrc, stride, upred, vpred, 8);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
94
95
}

96
void vp9_subtract_mby_s_c(short *diff, const unsigned char *src, int src_stride,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
97
                          const unsigned char *pred, int dst_stride) {
John Koleszar's avatar
John Koleszar committed
98
  int r, c;
John Koleszar's avatar
John Koleszar committed
99

John Koleszar's avatar
John Koleszar committed
100
101
102
  for (r = 0; r < 16; r++) {
    for (c = 0; c < 16; c++) {
      diff[c] = src[c] - pred[c];
John Koleszar's avatar
John Koleszar committed
103
    }
John Koleszar's avatar
John Koleszar committed
104
105

    diff += 16;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
106
107
    pred += dst_stride;
    src  += src_stride;
John Koleszar's avatar
John Koleszar committed
108
  }
John Koleszar's avatar
John Koleszar committed
109
110
}

111
void vp9_subtract_mby_c(short *diff, unsigned char *src,
Ronald S. Bultje's avatar
Ronald S. Bultje committed
112
                        unsigned char *pred, int stride) {
113
  vp9_subtract_mby_s_c(diff, src, stride, pred, 16);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
114
115
}

116
static void subtract_mb(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
117
  BLOCK *b = &x->block[0];
118

119
  vp9_subtract_mby(x->src_diff, *(b->base_src), x->e_mbd.predictor,
Jim Bankoski's avatar
Jim Bankoski committed
120
                   b->src_stride);
121
  vp9_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
Jim Bankoski's avatar
Jim Bankoski committed
122
                    x->e_mbd.predictor, x->src.uv_stride);
John Koleszar's avatar
John Koleszar committed
123
124
}

125
static void build_dcblock_4x4(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
126
127
  short *src_diff_ptr = &x->src_diff[384];
  int i;
John Koleszar's avatar
John Koleszar committed
128

John Koleszar's avatar
John Koleszar committed
129
130
  for (i = 0; i < 16; i++) {
    src_diff_ptr[i] = x->coeff[i * 16];
131
    x->coeff[i * 16] = 0;
John Koleszar's avatar
John Koleszar committed
132
  }
John Koleszar's avatar
John Koleszar committed
133
}
134

135
void vp9_transform_mby_4x4(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
136
  int i;
137
138
  MACROBLOCKD *xd = &x->e_mbd;
  int has_2nd_order = get_2nd_order_usage(xd);
John Koleszar's avatar
John Koleszar committed
139

140
141
142
143
144
145
146
147
148
149
  for (i = 0; i < 16; i++) {
    BLOCK *b = &x->block[i];
    TX_TYPE tx_type = get_tx_type_4x4(xd, &xd->block[i]);
    if (tx_type != DCT_DCT) {
      assert(has_2nd_order == 0);
      vp9_fht_c(b->src_diff, 32, b->coeff, tx_type, 4);
    } else {
      x->vp9_short_fdct4x4(&x->block[i].src_diff[0],
                           &x->block[i].coeff[0], 32);
    }
John Koleszar's avatar
John Koleszar committed
150
  }
John Koleszar's avatar
John Koleszar committed
151

152
  if (has_2nd_order) {
153
    // build dc block from 16 y dc values
154
    build_dcblock_4x4(x);
155
156

    // do 2nd order transform on the dc block
John Koleszar's avatar
John Koleszar committed
157
158
    x->short_walsh4x4(&x->block[24].src_diff[0],
                      &x->block[24].coeff[0], 8);
159
160
  } else {
    vpx_memset(x->block[24].coeff, 0, 16 * sizeof(x->block[24].coeff[0]));
John Koleszar's avatar
John Koleszar committed
161
  }
John Koleszar's avatar
John Koleszar committed
162
163
}

164
void vp9_transform_mbuv_4x4(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
165
  int i;
John Koleszar's avatar
John Koleszar committed
166

167
  for (i = 16; i < 24; i += 2) {
168
    x->vp9_short_fdct8x4(&x->block[i].src_diff[0],
John Koleszar's avatar
John Koleszar committed
169
170
                         &x->block[i].coeff[0], 16);
  }
171
172
}

173
static void transform_mb_4x4(MACROBLOCK *x) {
174
175
  vp9_transform_mby_4x4(x);
  vp9_transform_mbuv_4x4(x);
176
177
}

178
static void build_dcblock_8x8(MACROBLOCK *x) {
179
  int16_t *src_diff_ptr = x->block[24].src_diff;
John Koleszar's avatar
John Koleszar committed
180
  int i;
Paul Wilkins's avatar
Paul Wilkins committed
181

182
183
  for (i = 0; i < 16; i++) {
    src_diff_ptr[i] = 0;
John Koleszar's avatar
John Koleszar committed
184
  }
185
186
187
188
  src_diff_ptr[0] = x->coeff[0 * 16];
  src_diff_ptr[1] = x->coeff[4 * 16];
  src_diff_ptr[4] = x->coeff[8 * 16];
  src_diff_ptr[8] = x->coeff[12 * 16];
189
190
191
192
  x->coeff[0 * 16] = 0;
  x->coeff[4 * 16] = 0;
  x->coeff[8 * 16] = 0;
  x->coeff[12 * 16] = 0;
193
194
}

195
void vp9_transform_mby_8x8(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
196
  int i;
197
198
199
  MACROBLOCKD *xd = &x->e_mbd;
  TX_TYPE tx_type;
  int has_2nd_order = get_2nd_order_usage(xd);
200

John Koleszar's avatar
John Koleszar committed
201
  for (i = 0; i < 9; i += 8) {
202
203
204
205
206
207
208
209
210
    BLOCK *b = &x->block[i];
    tx_type = get_tx_type_8x8(xd, &xd->block[i]);
    if (tx_type != DCT_DCT) {
      assert(has_2nd_order == 0);
      vp9_fht_c(b->src_diff, 32, b->coeff, tx_type, 8);
    } else {
      x->vp9_short_fdct8x8(&x->block[i].src_diff[0],
                           &x->block[i].coeff[0], 32);
    }
John Koleszar's avatar
John Koleszar committed
211
212
  }
  for (i = 2; i < 11; i += 8) {
213
214
215
216
217
218
219
220
221
    BLOCK *b = &x->block[i];
    tx_type = get_tx_type_8x8(xd, &xd->block[i]);
    if (tx_type != DCT_DCT) {
      assert(has_2nd_order == 0);
      vp9_fht_c(b->src_diff, 32, (b + 2)->coeff, tx_type, 8);
    } else {
      x->vp9_short_fdct8x8(&x->block[i].src_diff[0],
                           &x->block[i + 2].coeff[0], 32);
    }
John Koleszar's avatar
John Koleszar committed
222
  }
223

224
  if (has_2nd_order) {
225
    // build dc block from 2x2 y dc values
226
    build_dcblock_8x8(x);
227
228

    // do 2nd order transform on the dc block
John Koleszar's avatar
John Koleszar committed
229
230
    x->short_fhaar2x2(&x->block[24].src_diff[0],
                      &x->block[24].coeff[0], 8);
231
232
  } else {
    vpx_memset(x->block[24].coeff, 0, 16 * sizeof(x->block[24].coeff[0]));
John Koleszar's avatar
John Koleszar committed
233
  }
234
235
}

236
void vp9_transform_mbuv_8x8(MACROBLOCK *x) {
Daniel Kang's avatar
Daniel Kang committed
237
238
  int i;

239
  for (i = 16; i < 24; i += 4) {
240
    x->vp9_short_fdct8x8(&x->block[i].src_diff[0],
241
242
                         &x->block[i].coeff[0], 16);
  }
Daniel Kang's avatar
Daniel Kang committed
243
244
}

245
246
247
void vp9_transform_mb_8x8(MACROBLOCK *x) {
  vp9_transform_mby_8x8(x);
  vp9_transform_mbuv_8x8(x);
Daniel Kang's avatar
Daniel Kang committed
248
249
}

250
void vp9_transform_mby_16x16(MACROBLOCK *x) {
251
252
253
  MACROBLOCKD *xd = &x->e_mbd;
  BLOCK *b = &x->block[0];
  TX_TYPE tx_type = get_tx_type_16x16(xd, &xd->block[0]);
254
  vp9_clear_system_state();
255
256
257
258
259
260
  if (tx_type != DCT_DCT) {
    vp9_fht_c(b->src_diff, 32, b->coeff, tx_type, 16);
  } else {
    x->vp9_short_fdct16x16(&x->block[0].src_diff[0],
                           &x->block[0].coeff[0], 32);
  }
Daniel Kang's avatar
Daniel Kang committed
261
262
}

263
264
265
void vp9_transform_mb_16x16(MACROBLOCK *x) {
  vp9_transform_mby_16x16(x);
  vp9_transform_mbuv_8x8(x);
Daniel Kang's avatar
Daniel Kang committed
266
}
267
268
269

#define RDTRUNC(RM,DM,R,D) ( (128+(R)*(RM)) & 0xFF )
#define RDTRUNC_8x8(RM,DM,R,D) ( (128+(R)*(RM)) & 0xFF )
270
typedef struct vp9_token_state vp9_token_state;
271

272
struct vp9_token_state {
273
274
  int           rate;
  int           error;
Daniel Kang's avatar
Daniel Kang committed
275
  int           next;
276
277
278
279
  signed char   token;
  short         qc;
};

280
// TODO: experiments to find optimal multiple numbers
281
282
#define Y1_RD_MULT 4
#define UV_RD_MULT 2
283
#define Y2_RD_MULT 4
284

John Koleszar's avatar
John Koleszar committed
285
286
287
288
289
static const int plane_rd_mult[4] = {
  Y1_RD_MULT,
  Y2_RD_MULT,
  UV_RD_MULT,
  Y1_RD_MULT
290
291
};

292
293
294
295
296
297
298
299
300
301
#define UPDATE_RD_COST()\
{\
  rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);\
  rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);\
  if (rd_cost0 == rd_cost1) {\
    rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);\
    rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);\
  }\
}

302
303
static void optimize_b(MACROBLOCK *mb, int i, PLANE_TYPE type,
                       ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
304
                       int tx_size) {
John Koleszar's avatar
John Koleszar committed
305
306
  BLOCK *b;
  BLOCKD *d;
307
  vp9_token_state tokens[65][2];
308
  uint64_t best_mask[2];
John Koleszar's avatar
John Koleszar committed
309
310
311
312
313
314
315
316
317
318
319
320
321
  const short *dequant_ptr;
  const short *coeff_ptr;
  short *qcoeff_ptr;
  short *dqcoeff_ptr;
  int eob;
  int i0;
  int rc;
  int x;
  int sz = 0;
  int next;
  int rdmult;
  int rddiv;
  int final_eob;
322
323
324
325
  int64_t rd_cost0, rd_cost1;
  int rate0, rate1;
  int error0, error1;
  int t0, t1;
John Koleszar's avatar
John Koleszar committed
326
327
328
329
  int best;
  int band;
  int pt;
  int err_mult = plane_rd_mult[type];
330
331
  int default_eob;
  int const *scan, *bands;
John Koleszar's avatar
John Koleszar committed
332

333
334
  b = &mb->block[i];
  d = &mb->e_mbd.block[i];
Deb Mukherjee's avatar
Deb Mukherjee committed
335
  switch (tx_size) {
336
337
    default:
    case TX_4X4:
338
339
      scan = vp9_default_zig_zag1d;
      bands = vp9_coef_bands;
340
341
342
343
      default_eob = 16;
      // TODO: this isn't called (for intra4x4 modes), but will be left in
      // since it could be used later
      {
344
        TX_TYPE tx_type = get_tx_type_4x4(&mb->e_mbd, d);
Deb Mukherjee's avatar
Deb Mukherjee committed
345
346
        if (tx_type != DCT_DCT) {
          switch (tx_type) {
347
            case ADST_DCT:
348
              scan = vp9_row_scan;
349
350
351
              break;

            case DCT_ADST:
352
              scan = vp9_col_scan;
353
354
355
              break;

            default:
356
              scan = vp9_default_zig_zag1d;
357
358
              break;
          }
Deb Mukherjee's avatar
Deb Mukherjee committed
359
        } else {
360
          scan = vp9_default_zig_zag1d;
Deb Mukherjee's avatar
Deb Mukherjee committed
361
        }
362
363
364
      }
      break;
    case TX_8X8:
365
366
      scan = vp9_default_zig_zag1d_8x8;
      bands = vp9_coef_bands_8x8;
367
368
369
      default_eob = 64;
      break;
  }
John Koleszar's avatar
John Koleszar committed
370
371
372
373
374

  dequant_ptr = d->dequant;
  coeff_ptr = b->coeff;
  qcoeff_ptr = d->qcoeff;
  dqcoeff_ptr = d->dqcoeff;
375
  i0 = (type == PLANE_TYPE_Y_NO_DC);
John Koleszar's avatar
John Koleszar committed
376
377
378
379
380
381
382
383
384
385
386
  eob = d->eob;

  /* Now set up a Viterbi trellis to evaluate alternative roundings. */
  rdmult = mb->rdmult * err_mult;
  if (mb->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME)
    rdmult = (rdmult * 9) >> 4;
  rddiv = mb->rddiv;
  best_mask[0] = best_mask[1] = 0;
  /* Initialize the sentinel node of the trellis. */
  tokens[eob][0].rate = 0;
  tokens[eob][0].error = 0;
387
  tokens[eob][0].next = default_eob;
John Koleszar's avatar
John Koleszar committed
388
389
390
391
392
393
394
395
396
  tokens[eob][0].token = DCT_EOB_TOKEN;
  tokens[eob][0].qc = 0;
  *(tokens[eob] + 1) = *(tokens[eob] + 0);
  next = eob;
  for (i = eob; i-- > i0;) {
    int base_bits;
    int d2;
    int dx;

397
    rc = scan[i];
John Koleszar's avatar
John Koleszar committed
398
399
400
401
402
403
404
405
406
    x = qcoeff_ptr[rc];
    /* Only add a trellis state for non-zero coefficients. */
    if (x) {
      int shortcut = 0;
      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;
407
      t0 = (vp9_dct_value_tokens_ptr + x)->Token;
John Koleszar's avatar
John Koleszar committed
408
      /* Consider both possible successor states. */
409
410
      if (next < default_eob) {
        band = bands[i + 1];
411
        pt = vp9_prev_token_class[t0];
John Koleszar's avatar
John Koleszar committed
412
        rate0 +=
Deb Mukherjee's avatar
Deb Mukherjee committed
413
          mb->token_costs[tx_size][type][band][pt][tokens[next][0].token];
John Koleszar's avatar
John Koleszar committed
414
        rate1 +=
Deb Mukherjee's avatar
Deb Mukherjee committed
415
          mb->token_costs[tx_size][type][band][pt][tokens[next][1].token];
John Koleszar's avatar
John Koleszar committed
416
      }
417
      UPDATE_RD_COST();
John Koleszar's avatar
John Koleszar committed
418
419
      /* And pick the best. */
      best = rd_cost1 < rd_cost0;
420
      base_bits = *(vp9_dct_value_cost_ptr + x);
John Koleszar's avatar
John Koleszar committed
421
422
423
424
425
426
427
428
429
430
431
432
      dx = dqcoeff_ptr[rc] - coeff_ptr[rc];
      d2 = dx * dx;
      tokens[i][0].rate = base_bits + (best ? rate1 : rate0);
      tokens[i][0].error = d2 + (best ? error1 : error0);
      tokens[i][0].next = next;
      tokens[i][0].token = t0;
      tokens[i][0].qc = x;
      best_mask[0] |= best << i;
      /* Evaluate the second possibility for this state. */
      rate0 = tokens[next][0].rate;
      rate1 = tokens[next][1].rate;

433
434
      if ((abs(x)*dequant_ptr[rc != 0] > abs(coeff_ptr[rc])) &&
          (abs(x)*dequant_ptr[rc != 0] < abs(coeff_ptr[rc]) + dequant_ptr[rc != 0]))
John Koleszar's avatar
John Koleszar committed
435
436
437
438
439
440
441
442
443
444
445
446
447
        shortcut = 1;
      else
        shortcut = 0;

      if (shortcut) {
        sz = -(x < 0);
        x -= 2 * sz + 1;
      }

      /* 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.
448
         */
John Koleszar's avatar
John Koleszar committed
449
450
451
452
453
        t0 = tokens[next][0].token == DCT_EOB_TOKEN ?
             DCT_EOB_TOKEN : ZERO_TOKEN;
        t1 = tokens[next][1].token == DCT_EOB_TOKEN ?
             DCT_EOB_TOKEN : ZERO_TOKEN;
      } else {
454
        t0 = t1 = (vp9_dct_value_tokens_ptr + x)->Token;
John Koleszar's avatar
John Koleszar committed
455
      }
456
457
      if (next < default_eob) {
        band = bands[i + 1];
John Koleszar's avatar
John Koleszar committed
458
        if (t0 != DCT_EOB_TOKEN) {
459
          pt = vp9_prev_token_class[t0];
Deb Mukherjee's avatar
Deb Mukherjee committed
460
          rate0 += mb->token_costs[tx_size][type][band][pt][
461
              tokens[next][0].token];
John Koleszar's avatar
John Koleszar committed
462
        }
John Koleszar's avatar
John Koleszar committed
463
        if (t1 != DCT_EOB_TOKEN) {
464
          pt = vp9_prev_token_class[t1];
Deb Mukherjee's avatar
Deb Mukherjee committed
465
          rate1 += mb->token_costs[tx_size][type][band][pt][
466
              tokens[next][1].token];
John Koleszar's avatar
John Koleszar committed
467
468
        }
      }
John Koleszar's avatar
John Koleszar committed
469

470
      UPDATE_RD_COST();
John Koleszar's avatar
John Koleszar committed
471
472
      /* And pick the best. */
      best = rd_cost1 < rd_cost0;
473
      base_bits = *(vp9_dct_value_cost_ptr + x);
John Koleszar's avatar
John Koleszar committed
474
475

      if (shortcut) {
476
        dx -= (dequant_ptr[rc != 0] + sz) ^ sz;
John Koleszar's avatar
John Koleszar committed
477
478
479
480
481
482
483
484
485
486
        d2 = dx * dx;
      }
      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;
      best_mask[1] |= best << i;
      /* Finally, make this the new head of the trellis. */
      next = i;
487
    }
John Koleszar's avatar
John Koleszar committed
488
489
490
491
    /* 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.
     */
    else {
492
      band = bands[i + 1];
John Koleszar's avatar
John Koleszar committed
493
494
495
496
      t0 = tokens[next][0].token;
      t1 = tokens[next][1].token;
      /* Update the cost of each path if we're past the EOB token. */
      if (t0 != DCT_EOB_TOKEN) {
Deb Mukherjee's avatar
Deb Mukherjee committed
497
        tokens[next][0].rate += mb->token_costs[tx_size][type][band][0][t0];
John Koleszar's avatar
John Koleszar committed
498
499
500
        tokens[next][0].token = ZERO_TOKEN;
      }
      if (t1 != DCT_EOB_TOKEN) {
Deb Mukherjee's avatar
Deb Mukherjee committed
501
        tokens[next][1].rate += mb->token_costs[tx_size][type][band][0][t1];
John Koleszar's avatar
John Koleszar committed
502
503
504
        tokens[next][1].token = ZERO_TOKEN;
      }
      /* Don't update next, because we didn't add a new node. */
505
    }
John Koleszar's avatar
John Koleszar committed
506
507
508
  }

  /* Now pick the best path through the whole trellis. */
509
  band = bands[i + 1];
510
  VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
John Koleszar's avatar
John Koleszar committed
511
512
513
514
515
516
  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;
Deb Mukherjee's avatar
Deb Mukherjee committed
517
518
  rate0 += mb->token_costs[tx_size][type][band][pt][t0];
  rate1 += mb->token_costs[tx_size][type][band][pt][t1];
519
  UPDATE_RD_COST();
John Koleszar's avatar
John Koleszar committed
520
521
522
523
524
525
  best = rd_cost1 < rd_cost0;
  final_eob = i0 - 1;
  for (i = next; i < eob; i = next) {
    x = tokens[i][best].qc;
    if (x)
      final_eob = i;
526
    rc = scan[i];
John Koleszar's avatar
John Koleszar committed
527
    qcoeff_ptr[rc] = x;
528
529
    dqcoeff_ptr[rc] = (x * dequant_ptr[rc != 0]);

John Koleszar's avatar
John Koleszar committed
530
531
532
533
534
535
    next = tokens[i][best].next;
    best = (best_mask[best] >> i) & 1;
  }
  final_eob++;

  d->eob = final_eob;
536
  *a = *l = (d->eob > !type);
John Koleszar's avatar
John Koleszar committed
537
538
}

John Koleszar's avatar
John Koleszar committed
539
540
541
542
543
544
545
546
/**************************************************************************
our inverse hadamard transform effectively is weighted sum of all 16 inputs
with weight either 1 or -1. It has a last stage scaling of (sum+1)>>2. And
dc only idct is (dc+16)>>5. So if all the sums are between -65 and 63 the
output after inverse wht and idct will be all zero. A sum of absolute value
smaller than 65 guarantees all 16 different (+1/-1) weighted sums in wht
fall between -65 and +65.
**************************************************************************/
547
548
#define SUM_2ND_COEFF_THRESH 65

549
static void check_reset_2nd_coeffs(MACROBLOCKD *xd,
John Koleszar's avatar
John Koleszar committed
550
551
552
                                   ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
  int sum = 0;
  int i;
Paul Wilkins's avatar
Paul Wilkins committed
553
  BLOCKD *bd = &xd->block[24];
John Koleszar's avatar
John Koleszar committed
554
555
556
557
558
  if (bd->dequant[0] >= SUM_2ND_COEFF_THRESH
      && bd->dequant[1] >= SUM_2ND_COEFF_THRESH)
    return;

  for (i = 0; i < bd->eob; i++) {
559
    int coef = bd->dqcoeff[vp9_default_zig_zag1d[i]];
John Koleszar's avatar
John Koleszar committed
560
561
562
563
564
565
566
    sum += (coef >= 0) ? coef : -coef;
    if (sum >= SUM_2ND_COEFF_THRESH)
      return;
  }

  if (sum < SUM_2ND_COEFF_THRESH) {
    for (i = 0; i < bd->eob; i++) {
567
      int rc = vp9_default_zig_zag1d[i];
John Koleszar's avatar
John Koleszar committed
568
569
      bd->qcoeff[rc] = 0;
      bd->dqcoeff[rc] = 0;
570
    }
John Koleszar's avatar
John Koleszar committed
571
    bd->eob = 0;
572
    *a = *l = (bd->eob != 0);
John Koleszar's avatar
John Koleszar committed
573
  }
574
}
575

576
#define SUM_2ND_COEFF_THRESH_8X8 32
577
static void check_reset_8x8_2nd_coeffs(MACROBLOCKD *xd,
John Koleszar's avatar
John Koleszar committed
578
579
                                       ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
  int sum = 0;
Paul Wilkins's avatar
Paul Wilkins committed
580
  BLOCKD *bd = &xd->block[24];
John Koleszar's avatar
John Koleszar committed
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
  int coef;

  coef = bd->dqcoeff[0];
  sum += (coef >= 0) ? coef : -coef;
  coef = bd->dqcoeff[1];
  sum += (coef >= 0) ? coef : -coef;
  coef = bd->dqcoeff[4];
  sum += (coef >= 0) ? coef : -coef;
  coef = bd->dqcoeff[8];
  sum += (coef >= 0) ? coef : -coef;

  if (sum < SUM_2ND_COEFF_THRESH_8X8) {
    bd->qcoeff[0] = 0;
    bd->dqcoeff[0] = 0;
    bd->qcoeff[1] = 0;
    bd->dqcoeff[1] = 0;
    bd->qcoeff[4] = 0;
    bd->dqcoeff[4] = 0;
    bd->qcoeff[8] = 0;
    bd->dqcoeff[8] = 0;
    bd->eob = 0;
602
    *a = *l = (bd->eob != 0);
John Koleszar's avatar
John Koleszar committed
603
  }
604
605
}

606
void vp9_optimize_mby_4x4(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
607
  int b;
608
  PLANE_TYPE type;
John Koleszar's avatar
John Koleszar committed
609
610
611
612
  int has_2nd_order;
  ENTROPY_CONTEXT_PLANES t_above, t_left;
  ENTROPY_CONTEXT *ta;
  ENTROPY_CONTEXT *tl;
613

614
  if (!x->e_mbd.above_context || !x->e_mbd.left_context)
John Koleszar's avatar
John Koleszar committed
615
    return;
616

John Koleszar's avatar
John Koleszar committed
617
618
  vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
  vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
619

John Koleszar's avatar
John Koleszar committed
620
621
  ta = (ENTROPY_CONTEXT *)&t_above;
  tl = (ENTROPY_CONTEXT *)&t_left;
622

623
624
  has_2nd_order = get_2nd_order_usage(&x->e_mbd);

John Koleszar's avatar
John Koleszar committed
625
  type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
John Koleszar's avatar
John Koleszar committed
626

John Koleszar's avatar
John Koleszar committed
627
628
  for (b = 0; b < 16; b++) {
    optimize_b(x, b, type,
629
               ta + vp9_block2above[b], tl + vp9_block2left[b], TX_4X4);
John Koleszar's avatar
John Koleszar committed
630
  }
John Koleszar's avatar
John Koleszar committed
631

John Koleszar's avatar
John Koleszar committed
632
633
634
  if (has_2nd_order) {
    b = 24;
    optimize_b(x, b, PLANE_TYPE_Y2,
635
               ta + vp9_block2above[b], tl + vp9_block2left[b], TX_4X4);
636
    check_reset_2nd_coeffs(&x->e_mbd,
637
                           ta + vp9_block2above[b], tl + vp9_block2left[b]);
John Koleszar's avatar
John Koleszar committed
638
  }
John Koleszar's avatar
John Koleszar committed
639
640
}

641
void vp9_optimize_mbuv_4x4(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
642
643
644
645
  int b;
  ENTROPY_CONTEXT_PLANES t_above, t_left;
  ENTROPY_CONTEXT *ta;
  ENTROPY_CONTEXT *tl;
John Koleszar's avatar
John Koleszar committed
646

647
  if (!x->e_mbd.above_context || !x->e_mbd.left_context)
John Koleszar's avatar
John Koleszar committed
648
    return;
John Koleszar's avatar
John Koleszar committed
649

John Koleszar's avatar
John Koleszar committed
650
651
  vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
  vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
John Koleszar's avatar
John Koleszar committed
652

John Koleszar's avatar
John Koleszar committed
653
654
  ta = (ENTROPY_CONTEXT *)&t_above;
  tl = (ENTROPY_CONTEXT *)&t_left;
John Koleszar's avatar
John Koleszar committed
655

John Koleszar's avatar
John Koleszar committed
656
657
  for (b = 16; b < 24; b++) {
    optimize_b(x, b, PLANE_TYPE_UV,
658
               ta + vp9_block2above[b], tl + vp9_block2left[b], TX_4X4);
John Koleszar's avatar
John Koleszar committed
659
  }
660
661
}

662
663
664
static void optimize_mb_4x4(MACROBLOCK *x) {
  vp9_optimize_mby_4x4(x);
  vp9_optimize_mbuv_4x4(x);
665
666
}

667
void vp9_optimize_mby_8x8(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
668
  int b;
669
  PLANE_TYPE type;
John Koleszar's avatar
John Koleszar committed
670
671
672
  ENTROPY_CONTEXT_PLANES t_above, t_left;
  ENTROPY_CONTEXT *ta;
  ENTROPY_CONTEXT *tl;
673
  int has_2nd_order = get_2nd_order_usage(&x->e_mbd);
674

675
  if (!x->e_mbd.above_context || !x->e_mbd.left_context)
John Koleszar's avatar
John Koleszar committed
676
    return;
677

John Koleszar's avatar
John Koleszar committed
678
679
  vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
  vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
680

John Koleszar's avatar
John Koleszar committed
681
682
  ta = (ENTROPY_CONTEXT *)&t_above;
  tl = (ENTROPY_CONTEXT *)&t_left;
683
  type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
John Koleszar's avatar
John Koleszar committed
684
  for (b = 0; b < 16; b += 4) {
685
    optimize_b(x, b, type,
686
               ta + vp9_block2above_8x8[b], tl + vp9_block2left_8x8[b],
687
               TX_8X8);
688
689
    ta[vp9_block2above_8x8[b] + 1] = ta[vp9_block2above_8x8[b]];
    tl[vp9_block2left_8x8[b] + 1]  = tl[vp9_block2left_8x8[b]];
John Koleszar's avatar
John Koleszar committed
690
  }
691

John Koleszar's avatar
John Koleszar committed
692
  // 8x8 always have 2nd roder haar block
693
694
  if (has_2nd_order) {
    check_reset_8x8_2nd_coeffs(&x->e_mbd,
695
696
                               ta + vp9_block2above_8x8[24],
                               tl + vp9_block2left_8x8[24]);
697
  }
698
699
}

700
void vp9_optimize_mbuv_8x8(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
701
702
703
704
  int b;
  ENTROPY_CONTEXT_PLANES t_above, t_left;
  ENTROPY_CONTEXT *ta;
  ENTROPY_CONTEXT *tl;
705

706
  if (!x->e_mbd.above_context || !x->e_mbd.left_context)
John Koleszar's avatar
John Koleszar committed
707
    return;
708

John Koleszar's avatar
John Koleszar committed
709
710
  vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
  vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
711

John Koleszar's avatar
John Koleszar committed
712
713
  ta = (ENTROPY_CONTEXT *)&t_above;
  tl = (ENTROPY_CONTEXT *)&t_left;
714

John Koleszar's avatar
John Koleszar committed
715
  for (b = 16; b < 24; b += 4) {
716
    optimize_b(x, b, PLANE_TYPE_UV,
717
               ta + vp9_block2above_8x8[b], tl + vp9_block2left_8x8[b],
718
               TX_8X8);
719
720
    ta[vp9_block2above_8x8[b] + 1] = ta[vp9_block2above_8x8[b]];
    tl[vp9_block2left_8x8[b] + 1]  = tl[vp9_block2left_8x8[b]];
John Koleszar's avatar
John Koleszar committed
721
  }
722
723
}

724
725
726
static void optimize_mb_8x8(MACROBLOCK *x) {
  vp9_optimize_mby_8x8(x);
  vp9_optimize_mbuv_8x8(x);
727
728
}

729
static void optimize_b_16x16(MACROBLOCK *mb, int i, PLANE_TYPE type,
730
                             ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
Daniel Kang's avatar
Daniel Kang committed
731
732
  BLOCK *b = &mb->block[i];
  BLOCKD *d = &mb->e_mbd.block[i];
733
  vp9_token_state tokens[257][2];
Daniel Kang's avatar
Daniel Kang committed
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
  unsigned best_index[257][2];
  const short *dequant_ptr = d->dequant, *coeff_ptr = b->coeff;
  short *qcoeff_ptr = qcoeff_ptr = d->qcoeff;
  short *dqcoeff_ptr = dqcoeff_ptr = d->dqcoeff;
  int eob = d->eob, final_eob, sz = 0;
  int rc, x, next;
  int64_t rdmult, rddiv, rd_cost0, rd_cost1;
  int rate0, rate1, error0, error1, t0, t1;
  int best, band, pt;
  int err_mult = plane_rd_mult[type];

  /* Now set up a Viterbi trellis to evaluate alternative roundings. */
  rdmult = mb->rdmult * err_mult;
  if (mb->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME)
      rdmult = (rdmult * 9)>>4;
  rddiv = mb->rddiv;
  memset(best_index, 0, sizeof(best_index));
  /* Initialize the sentinel node of the trellis. */
  tokens[eob][0].rate = 0;
  tokens[eob][0].error = 0;
  tokens[eob][0].next = 256;
  tokens[eob][0].token = DCT_EOB_TOKEN;
  tokens[eob][0].qc = 0;
  *(tokens[eob] + 1) = *(tokens[eob] + 0);
  next = eob;
  for (i = eob; i-- > 0;) {
    int base_bits, d2, dx;

762
    rc = vp9_default_zig_zag1d_16x16[i];
Daniel Kang's avatar
Daniel Kang committed
763
764
765
766
767
768
769
770
771
    x = qcoeff_ptr[rc];
    /* Only add a trellis state for non-zero coefficients. */
    if (x) {
      int shortcut = 0;
      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;
772
      t0 = (vp9_dct_value_tokens_ptr + x)->Token;
Daniel Kang's avatar
Daniel Kang committed
773
774
      /* Consider both possible successor states. */
      if (next < 256) {
775
776
        band = vp9_coef_bands_16x16[i + 1];
        pt = vp9_prev_token_class[t0];
777
778
        rate0 += mb->token_costs[TX_16X16][type][band][pt][tokens[next][0].token];
        rate1 += mb->token_costs[TX_16X16][type][band][pt][tokens[next][1].token];
Daniel Kang's avatar
Daniel Kang committed
779
780
781
782
      }
      UPDATE_RD_COST();
      /* And pick the best. */
      best = rd_cost1 < rd_cost0;
783
      base_bits = *(vp9_dct_value_cost_ptr + x);
Daniel Kang's avatar
Daniel Kang committed
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
      dx = dqcoeff_ptr[rc] - coeff_ptr[rc];
      d2 = dx*dx;
      tokens[i][0].rate = base_bits + (best ? rate1 : rate0);
      tokens[i][0].error = d2 + (best ? error1 : error0);
      tokens[i][0].next = next;
      tokens[i][0].token = t0;
      tokens[i][0].qc = x;
      best_index[i][0] = best;
      /* Evaluate the second possibility for this state. */
      rate0 = tokens[next][0].rate;
      rate1 = tokens[next][1].rate;

      if((abs(x)*dequant_ptr[rc!=0]>abs(coeff_ptr[rc])) &&
         (abs(x)*dequant_ptr[rc!=0]<abs(coeff_ptr[rc])+dequant_ptr[rc!=0]))
        shortcut = 1;
      else
        shortcut = 0;

      if (shortcut) {
        sz = -(x < 0);
        x -= 2*sz + 1;
      }

      /* 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 == DCT_EOB_TOKEN ?
             DCT_EOB_TOKEN : ZERO_TOKEN;
        t1 = tokens[next][1].token == DCT_EOB_TOKEN ?
             DCT_EOB_TOKEN : ZERO_TOKEN;
      }
      else
818
        t0=t1 = (vp9_dct_value_tokens_ptr + x)->Token;
Daniel Kang's avatar
Daniel Kang committed
819
      if (next < 256) {
820
        band = vp9_coef_bands_16x16[i + 1];
Daniel Kang's avatar
Daniel Kang committed
821
        if (t0 != DCT_EOB_TOKEN) {
822
            pt = vp9_prev_token_class[t0];
823
            rate0 += mb->token_costs[TX_16X16][type][band][pt]
Daniel Kang's avatar
Daniel Kang committed
824
825
826
                [tokens[next][0].token];
        }
        if (t1!=DCT_EOB_TOKEN) {
827
            pt = vp9_prev_token_class[t1];
828
            rate1 += mb->token_costs[TX_16X16][type][band][pt]
Daniel Kang's avatar
Daniel Kang committed
829
830
831
832
833
834
                [tokens[next][1].token];
        }
      }
      UPDATE_RD_COST();
      /* And pick the best. */
      best = rd_cost1 < rd_cost0;
835
      base_bits = *(vp9_dct_value_cost_ptr + x);
Daniel Kang's avatar
Daniel Kang committed
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853

      if(shortcut) {
        dx -= (dequant_ptr[rc!=0] + sz) ^ sz;
        d2 = dx*dx;
      }
      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;
      best_index[i][1] = best;
      /* Finally, make this the new head of the trellis. */
      next = i;
    }
    /* 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.
     */
    else {
854
      band = vp9_coef_bands_16x16[i + 1];
Daniel Kang's avatar
Daniel Kang committed
855
856
857
858
      t0 = tokens[next][0].token;
      t1 = tokens[next][1].token;
      /* Update the cost of each path if we're past the EOB token. */
      if (t0 != DCT_EOB_TOKEN) {
859
        tokens[next][0].rate += mb->token_costs[TX_16X16][type][band][0][t0];
Daniel Kang's avatar
Daniel Kang committed
860
861
862
        tokens[next][0].token = ZERO_TOKEN;
      }
      if (t1 != DCT_EOB_TOKEN) {
863
        tokens[next][1].rate += mb->token_costs[TX_16X16][type][band][0][t1];
Daniel Kang's avatar
Daniel Kang committed
864
865
866
867
868
869
870
        tokens[next][1].token = ZERO_TOKEN;
      }
      /* Don't update next, because we didn't add a new node. */
    }
  }

  /* Now pick the best path through the whole trellis. */
871
  band = vp9_coef_bands_16x16[i + 1];
872
  VP9_COMBINEENTROPYCONTEXTS(pt, *a, *l);
Daniel Kang's avatar
Daniel Kang committed
873
874
875
876
877
878
  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;
879
880
  rate0 += mb->token_costs[TX_16X16][type][band][pt][t0];
  rate1 += mb->token_costs[TX_16X16][type][band][pt][t1];
Daniel Kang's avatar
Daniel Kang committed
881
882
883
884
885
886
887
888
  UPDATE_RD_COST();
  best = rd_cost1 < rd_cost0;
  final_eob = -1;

  for (i = next; i < eob; i = next) {
    x = tokens[i][best].qc;
    if (x)
      final_eob = i;
889
    rc = vp9_default_zig_zag1d_16x16[i];
Daniel Kang's avatar
Daniel Kang committed
890
891
892
893
894
895
896
897
898
    qcoeff_ptr[rc] = x;
    dqcoeff_ptr[rc] = (x * dequant_ptr[rc!=0]);

    next = tokens[i][best].next;
    best = best_index[i][best];
  }
  final_eob++;

  d->eob = final_eob;
899
  *a = *l = (d->eob > !type);
Daniel Kang's avatar
Daniel Kang committed
900
901
}

902
void vp9_optimize_mby_16x16(MACROBLOCK *x) {
903
904
905
906
907
908
909
910
911
912
913
  ENTROPY_CONTEXT_PLANES t_above, t_left;
  ENTROPY_CONTEXT *ta, *tl;

  if (!x->e_mbd.above_context || !x->e_mbd.left_context)
    return;

  vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
  vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));

  ta = (ENTROPY_CONTEXT *)&t_above;
  tl = (ENTROPY_CONTEXT *)&t_left;
914
  optimize_b_16x16(x, 0, PLANE_TYPE_Y_WITH_DC, ta, tl);
Daniel Kang's avatar
Daniel Kang committed
915
916
}

917
918
919
static void optimize_mb_16x16(MACROBLOCK *x) {
  vp9_optimize_mby_16x16(x);
  vp9_optimize_mbuv_8x8(x);
Daniel Kang's avatar
Daniel Kang committed
920
921
}

922
void vp9_fidct_mb(MACROBLOCK *x) {
923
  MACROBLOCKD *const xd = &x->e_mbd;
924
  TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
John Koleszar's avatar
John Koleszar committed
925

926
  if (tx_size == TX_16X16) {
927
928
    vp9_transform_mb_16x16(x);
    vp9_quantize_mb_16x16(x);
929
    if (x->optimize)
930
931
      optimize_mb_16x16(x);
    vp9_inverse_transform_mb_16x16(xd);
932
  } else if (tx_size == TX_8X8) {
933
934
    if (xd->mode_info_context->mbmi.mode == SPLITMV) {
      assert(xd->mode_info_context->mbmi.partitioning != PARTITIONING_4X4);
935
936
937
938
      vp9_transform_mby_8x8(x);
      vp9_transform_mbuv_4x4(x);
      vp9_quantize_mby_8x8(x);
      vp9_quantize_mbuv_4x4(x);
939
      if (x->optimize) {
940
941
        vp9_optimize_mby_8x8(x);
        vp9_optimize_mbuv_4x4(x);
942
      }
943
944
      vp9_inverse_transform_mby_8x8(xd);
      vp9_inverse_transform_mbuv_4x4(xd);
945
    } else {
946
947
      vp9_transform_mb_8x8(x);
      vp9_quantize_mb_8x8(x);
948
      if (x->optimize)
949
950
        optimize_mb_8x8(x);
      vp9_inverse_transform_mb_8x8(xd);
951
    }
952
953
  } else {
    transform_mb_4x4(x);
954
    vp9_quantize_mb_4x4(x);
955
    if (x->optimize)
956
957
      optimize_mb_4x4(x);
    vp9_inverse_transform_mb_4x4(xd);
John Koleszar's avatar
John Koleszar committed
958
  }
959
960
}

961
void vp9_encode_inter16x16(MACROBLOCK *x) {
962
  MACROBLOCKD *const xd = &x->e_mbd;
John Koleszar's avatar
John Koleszar committed
963

964
  vp9_build_inter_predictors_mb(xd);