encodemb.c 27.8 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
12
 */

#include "vpx_ports/config.h"
#include "encodemb.h"
John Koleszar's avatar
John Koleszar committed
13
#include "vp8/common/reconinter.h"
John Koleszar's avatar
John Koleszar committed
14
#include "quantize.h"
15
#include "tokenize.h"
John Koleszar's avatar
John Koleszar committed
16
17
#include "vp8/common/invtrans.h"
#include "vp8/common/reconintra.h"
John Koleszar's avatar
John Koleszar committed
18
19
#include "dct.h"
#include "vpx_mem/vpx_mem.h"
Yunqing Wang's avatar
Yunqing Wang committed
20
#include "rdopt.h"
21
#include "vp8/common/systemdependent.h"
Jim Bankoski's avatar
Jim Bankoski committed
22
#include "vpx_rtcd.h"
John Koleszar's avatar
John Koleszar committed
23
24
25
26
27
28

#if CONFIG_RUNTIME_CPU_DETECT
#define IF_RTCD(x) (x)
#else
#define IF_RTCD(x) NULL
#endif
29
30
31
32
33

#ifdef ENC_DEBUG
extern int enc_debug;
#endif

John Koleszar's avatar
John Koleszar committed
34
35
36
37
38
39
40
void vp8_subtract_b_c(BLOCK *be, BLOCKD *bd, int pitch) {
  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
41

John Koleszar's avatar
John Koleszar committed
42
43
44
  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
45
    }
John Koleszar's avatar
John Koleszar committed
46
47
48
49
50

    diff_ptr += pitch;
    pred_ptr += pitch;
    src_ptr  += src_stride;
  }
John Koleszar's avatar
John Koleszar committed
51
52
}

John Koleszar's avatar
John Koleszar committed
53
54
55
56
57
58
void vp8_subtract_4b_c(BLOCK *be, BLOCKD *bd, int pitch) {
  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;
59

John Koleszar's avatar
John Koleszar committed
60
61
62
  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
63
    }
John Koleszar's avatar
John Koleszar committed
64
65
66
67
    diff_ptr += pitch;
    pred_ptr += pitch;
    src_ptr  += src_stride;
  }
Yaowu Xu's avatar
Yaowu Xu committed
68
69
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
70
71
72
73
void vp8_subtract_mbuv_s_c(short *diff, const unsigned char *usrc,
                           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
74
75
76
  short *udiff = diff + 256;
  short *vdiff = diff + 320;
  int r, c;
John Koleszar's avatar
John Koleszar committed
77

John Koleszar's avatar
John Koleszar committed
78
79
80
  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
81
82
    }

John Koleszar's avatar
John Koleszar committed
83
    udiff += 8;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
84
85
    upred += dst_stride;
    usrc  += src_stride;
John Koleszar's avatar
John Koleszar committed
86
  }
John Koleszar's avatar
John Koleszar committed
87

John Koleszar's avatar
John Koleszar committed
88
89
90
  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
91
92
    }

John Koleszar's avatar
John Koleszar committed
93
    vdiff += 8;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
94
95
    vpred += dst_stride;
    vsrc  += src_stride;
John Koleszar's avatar
John Koleszar committed
96
97
  }
}
John Koleszar's avatar
John Koleszar committed
98

Ronald S. Bultje's avatar
Ronald S. Bultje committed
99
100
void vp8_subtract_mbuv_c(short *diff, unsigned char *usrc,
                         unsigned char *vsrc, unsigned char *pred, int stride) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
101
102
103
104
105
106
  unsigned char *upred = pred + 256;
  unsigned char *vpred = pred + 320;

  vp8_subtract_mbuv_s_c(diff, usrc, vsrc, stride, upred, vpred, 8);
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
107
108
void vp8_subtract_mby_s_c(short *diff, const unsigned char *src, int src_stride,
                          const unsigned char *pred, int dst_stride) {
John Koleszar's avatar
John Koleszar committed
109
  int r, c;
John Koleszar's avatar
John Koleszar committed
110

John Koleszar's avatar
John Koleszar committed
111
112
113
  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
114
    }
John Koleszar's avatar
John Koleszar committed
115
116

    diff += 16;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
117
118
    pred += dst_stride;
    src  += src_stride;
John Koleszar's avatar
John Koleszar committed
119
  }
John Koleszar's avatar
John Koleszar committed
120
121
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
122
123
void vp8_subtract_mby_c(short *diff, unsigned char *src,
                        unsigned char *pred, int stride) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
124
125
126
  vp8_subtract_mby_s_c(diff, src, stride, pred, 16);
}

John Koleszar's avatar
John Koleszar committed
127
128
static void vp8_subtract_mb(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) {
  BLOCK *b = &x->block[0];
129

Jim Bankoski's avatar
Jim Bankoski committed
130
131
132
133
  vp8_subtract_mby(x->src_diff, *(b->base_src), x->e_mbd.predictor,
                   b->src_stride);
  vp8_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
                    x->e_mbd.predictor, x->src.uv_stride);
John Koleszar's avatar
John Koleszar committed
134
135
}

136
static void build_dcblock_4x4(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
137
138
  short *src_diff_ptr = &x->src_diff[384];
  int i;
John Koleszar's avatar
John Koleszar committed
139

John Koleszar's avatar
John Koleszar committed
140
141
142
  for (i = 0; i < 16; i++) {
    src_diff_ptr[i] = x->coeff[i * 16];
  }
John Koleszar's avatar
John Koleszar committed
143
}
144

145
void vp8_transform_mby_4x4(MACROBLOCK *x) {
John Koleszar's avatar
John Koleszar committed
146
  int i;
John Koleszar's avatar
John Koleszar committed
147

John Koleszar's avatar
John Koleszar committed
148
149
150
151
  for (i = 0; i < 16; i += 2) {
    x->vp8_short_fdct8x4(&x->block[i].src_diff[0],
                         &x->block[i].coeff[0], 32);
  }
John Koleszar's avatar
John Koleszar committed
152

John Koleszar's avatar
John Koleszar committed
153
  if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) {
154
    // build dc block from 16 y dc values
155
    build_dcblock_4x4(x);
156
157

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

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

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

172
173
174
static void transform_mb_4x4(MACROBLOCK *x) {
  vp8_transform_mby_4x4(x);
  vp8_transform_mbuv_4x4(x);
175
176
}

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

181
182
  for (i = 0; i < 16; i++) {
    src_diff_ptr[i] = 0;
John Koleszar's avatar
John Koleszar committed
183
  }
184
185
186
187
  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];
188
189
}

John Koleszar's avatar
John Koleszar committed
190
191
void vp8_transform_mby_8x8(MACROBLOCK *x) {
  int i;
192

John Koleszar's avatar
John Koleszar committed
193
194
195
196
197
198
199
200
  for (i = 0; i < 9; i += 8) {
    x->vp8_short_fdct8x8(&x->block[i].src_diff[0],
                         &x->block[i].coeff[0], 32);
  }
  for (i = 2; i < 11; i += 8) {
    x->vp8_short_fdct8x8(&x->block[i].src_diff[0],
                         &x->block[i + 2].coeff[0], 32);
  }
201

John Koleszar's avatar
John Koleszar committed
202
  if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) {
203
    // build dc block from 2x2 y dc values
John Koleszar's avatar
John Koleszar committed
204
    vp8_build_dcblock_8x8(x);
205
206

    // do 2nd order transform on the dc block
John Koleszar's avatar
John Koleszar committed
207
208
209
    x->short_fhaar2x2(&x->block[24].src_diff[0],
                      &x->block[24].coeff[0], 8);
  }
210
211
}

212
void vp8_transform_mbuv_8x8(MACROBLOCK *x) {
Daniel Kang's avatar
Daniel Kang committed
213
214
  int i;

215
  for (i = 16; i < 24; i += 4) {
Daniel Kang's avatar
Daniel Kang committed
216
    x->vp8_short_fdct8x8(&x->block[i].src_diff[0],
217
218
                         &x->block[i].coeff[0], 16);
  }
Daniel Kang's avatar
Daniel Kang committed
219
220
}

221
222
223
void vp8_transform_mb_8x8(MACROBLOCK *x) {
  vp8_transform_mby_8x8(x);
  vp8_transform_mbuv_8x8(x);
Daniel Kang's avatar
Daniel Kang committed
224
225
}

226
void vp8_transform_mby_16x16(MACROBLOCK *x) {
Daniel Kang's avatar
Daniel Kang committed
227
228
  vp8_clear_system_state();
  x->vp8_short_fdct16x16(&x->block[0].src_diff[0],
229
                         &x->block[0].coeff[0], 32);
Daniel Kang's avatar
Daniel Kang committed
230
231
}

232
233
234
void vp8_transform_mb_16x16(MACROBLOCK *x) {
  vp8_transform_mby_16x16(x);
  vp8_transform_mbuv_8x8(x);
Daniel Kang's avatar
Daniel Kang committed
235
}
236
237
238

#define RDTRUNC(RM,DM,R,D) ( (128+(R)*(RM)) & 0xFF )
#define RDTRUNC_8x8(RM,DM,R,D) ( (128+(R)*(RM)) & 0xFF )
239
240
typedef struct vp8_token_state vp8_token_state;

John Koleszar's avatar
John Koleszar committed
241
struct vp8_token_state {
242
243
  int           rate;
  int           error;
Daniel Kang's avatar
Daniel Kang committed
244
  int           next;
245
246
247
248
  signed char   token;
  short         qc;
};

249
// TODO: experiments to find optimal multiple numbers
250
251
#define Y1_RD_MULT 4
#define UV_RD_MULT 2
252
#define Y2_RD_MULT 4
253

John Koleszar's avatar
John Koleszar committed
254
255
256
257
258
static const int plane_rd_mult[4] = {
  Y1_RD_MULT,
  Y2_RD_MULT,
  UV_RD_MULT,
  Y1_RD_MULT
259
260
};

261
262
263
264
265
266
267
268
269
270
#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);\
  }\
}

271
void optimize_b(MACROBLOCK *mb, int i, PLANE_TYPE type,
272
                ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
Deb Mukherjee's avatar
Deb Mukherjee committed
273
                const VP8_ENCODER_RTCD *rtcd, int tx_size) {
John Koleszar's avatar
John Koleszar committed
274
275
  BLOCK *b;
  BLOCKD *d;
276
277
  vp8_token_state tokens[65][2];
  uint64_t best_mask[2];
John Koleszar's avatar
John Koleszar committed
278
279
280
281
282
283
284
285
286
287
288
289
290
  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;
291
292
293
294
  int64_t rd_cost0, rd_cost1;
  int rate0, rate1;
  int error0, error1;
  int t0, t1;
John Koleszar's avatar
John Koleszar committed
295
296
297
298
  int best;
  int band;
  int pt;
  int err_mult = plane_rd_mult[type];
299
300
  int default_eob;
  int const *scan, *bands;
John Koleszar's avatar
John Koleszar committed
301

302
303
  b = &mb->block[i];
  d = &mb->e_mbd.block[i];
Deb Mukherjee's avatar
Deb Mukherjee committed
304
  switch (tx_size) {
305
306
307
308
309
310
311
312
    default:
    case TX_4X4:
      scan = vp8_default_zig_zag1d;
      bands = vp8_coef_bands;
      default_eob = 16;
      // TODO: this isn't called (for intra4x4 modes), but will be left in
      // since it could be used later
      {
Deb Mukherjee's avatar
Deb Mukherjee committed
313
314
315
        TX_TYPE tx_type = get_tx_type(&mb->e_mbd, d);
        if (tx_type != DCT_DCT) {
          switch (tx_type) {
316
317
318
319
320
321
322
323
324
325
326
327
            case ADST_DCT:
              scan = vp8_row_scan;
              break;

            case DCT_ADST:
              scan = vp8_col_scan;
              break;

            default:
              scan = vp8_default_zig_zag1d;
              break;
          }
Deb Mukherjee's avatar
Deb Mukherjee committed
328
        } else {
329
          scan = vp8_default_zig_zag1d;
Deb Mukherjee's avatar
Deb Mukherjee committed
330
        }
331
332
333
334
335
336
337
338
      }
      break;
    case TX_8X8:
      scan = vp8_default_zig_zag1d_8x8;
      bands = vp8_coef_bands_8x8;
      default_eob = 64;
      break;
  }
John Koleszar's avatar
John Koleszar committed
339
340
341
342
343

  dequant_ptr = d->dequant;
  coeff_ptr = b->coeff;
  qcoeff_ptr = d->qcoeff;
  dqcoeff_ptr = d->dqcoeff;
344
  i0 = (type == PLANE_TYPE_Y_NO_DC);
John Koleszar's avatar
John Koleszar committed
345
346
347
348
349
350
351
352
353
354
355
  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;
356
  tokens[eob][0].next = default_eob;
John Koleszar's avatar
John Koleszar committed
357
358
359
360
361
362
363
364
365
  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;

366
    rc = scan[i];
John Koleszar's avatar
John Koleszar committed
367
368
369
370
371
372
373
374
375
376
377
    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;
      t0 = (vp8_dct_value_tokens_ptr + x)->Token;
      /* Consider both possible successor states. */
378
379
      if (next < default_eob) {
        band = bands[i + 1];
John Koleszar's avatar
John Koleszar committed
380
381
        pt = vp8_prev_token_class[t0];
        rate0 +=
Deb Mukherjee's avatar
Deb Mukherjee committed
382
          mb->token_costs[tx_size][type][band][pt][tokens[next][0].token];
John Koleszar's avatar
John Koleszar committed
383
        rate1 +=
Deb Mukherjee's avatar
Deb Mukherjee committed
384
          mb->token_costs[tx_size][type][band][pt][tokens[next][1].token];
John Koleszar's avatar
John Koleszar committed
385
      }
386
      UPDATE_RD_COST();
John Koleszar's avatar
John Koleszar committed
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
      /* And pick the best. */
      best = rd_cost1 < rd_cost0;
      base_bits = *(vp8_dct_value_cost_ptr + x);
      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;

402
403
      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
404
405
406
407
408
409
410
411
412
413
414
415
416
        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.
417
         */
John Koleszar's avatar
John Koleszar committed
418
419
420
421
422
423
424
        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 {
        t0 = t1 = (vp8_dct_value_tokens_ptr + x)->Token;
      }
425
426
      if (next < default_eob) {
        band = bands[i + 1];
John Koleszar's avatar
John Koleszar committed
427
428
        if (t0 != DCT_EOB_TOKEN) {
          pt = vp8_prev_token_class[t0];
Deb Mukherjee's avatar
Deb Mukherjee committed
429
          rate0 += mb->token_costs[tx_size][type][band][pt][
430
              tokens[next][0].token];
John Koleszar's avatar
John Koleszar committed
431
        }
John Koleszar's avatar
John Koleszar committed
432
433
        if (t1 != DCT_EOB_TOKEN) {
          pt = vp8_prev_token_class[t1];
Deb Mukherjee's avatar
Deb Mukherjee committed
434
          rate1 += mb->token_costs[tx_size][type][band][pt][
435
              tokens[next][1].token];
John Koleszar's avatar
John Koleszar committed
436
437
        }
      }
John Koleszar's avatar
John Koleszar committed
438

439
      UPDATE_RD_COST();
John Koleszar's avatar
John Koleszar committed
440
441
442
443
444
      /* And pick the best. */
      best = rd_cost1 < rd_cost0;
      base_bits = *(vp8_dct_value_cost_ptr + x);

      if (shortcut) {
445
        dx -= (dequant_ptr[rc != 0] + sz) ^ sz;
John Koleszar's avatar
John Koleszar committed
446
447
448
449
450
451
452
453
454
455
        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;
456
    }
John Koleszar's avatar
John Koleszar committed
457
458
459
460
    /* 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 {
461
      band = bands[i + 1];
John Koleszar's avatar
John Koleszar committed
462
463
464
465
      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
466
        tokens[next][0].rate += mb->token_costs[tx_size][type][band][0][t0];
John Koleszar's avatar
John Koleszar committed
467
468
469
        tokens[next][0].token = ZERO_TOKEN;
      }
      if (t1 != DCT_EOB_TOKEN) {
Deb Mukherjee's avatar
Deb Mukherjee committed
470
        tokens[next][1].rate += mb->token_costs[tx_size][type][band][0][t1];
John Koleszar's avatar
John Koleszar committed
471
472
473
        tokens[next][1].token = ZERO_TOKEN;
      }
      /* Don't update next, because we didn't add a new node. */
474
    }
John Koleszar's avatar
John Koleszar committed
475
476
477
  }

  /* Now pick the best path through the whole trellis. */
478
  band = bands[i + 1];
John Koleszar's avatar
John Koleszar committed
479
480
481
482
483
484
485
  VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
  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
486
487
  rate0 += mb->token_costs[tx_size][type][band][pt][t0];
  rate1 += mb->token_costs[tx_size][type][band][pt][t1];
488
  UPDATE_RD_COST();
John Koleszar's avatar
John Koleszar committed
489
490
491
492
493
494
  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;
495
    rc = scan[i];
John Koleszar's avatar
John Koleszar committed
496
    qcoeff_ptr[rc] = x;
497
498
    dqcoeff_ptr[rc] = (x * dequant_ptr[rc != 0]);

John Koleszar's avatar
John Koleszar committed
499
500
501
502
503
504
505
    next = tokens[i][best].next;
    best = (best_mask[best] >> i) & 1;
  }
  final_eob++;

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

John Koleszar's avatar
John Koleszar committed
508
509
510
511
512
513
514
515
/**************************************************************************
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.
**************************************************************************/
516
517
#define SUM_2ND_COEFF_THRESH 65

518
static void check_reset_2nd_coeffs(MACROBLOCKD *xd,
John Koleszar's avatar
John Koleszar committed
519
520
521
                                   ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
  int sum = 0;
  int i;
Paul Wilkins's avatar
Paul Wilkins committed
522
  BLOCKD *bd = &xd->block[24];
John Koleszar's avatar
John Koleszar committed
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
  if (bd->dequant[0] >= SUM_2ND_COEFF_THRESH
      && bd->dequant[1] >= SUM_2ND_COEFF_THRESH)
    return;

  for (i = 0; i < bd->eob; i++) {
    int coef = bd->dqcoeff[vp8_default_zig_zag1d[i]];
    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++) {
      int rc = vp8_default_zig_zag1d[i];
      bd->qcoeff[rc] = 0;
      bd->dqcoeff[rc] = 0;
539
    }
John Koleszar's avatar
John Koleszar committed
540
    bd->eob = 0;
541
    *a = *l = (bd->eob != 0);
John Koleszar's avatar
John Koleszar committed
542
  }
543
}
544

545
#define SUM_2ND_COEFF_THRESH_8X8 32
546
static void check_reset_8x8_2nd_coeffs(MACROBLOCKD *xd,
John Koleszar's avatar
John Koleszar committed
547
548
                                       ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
  int sum = 0;
Paul Wilkins's avatar
Paul Wilkins committed
549
  BLOCKD *bd = &xd->block[24];
John Koleszar's avatar
John Koleszar committed
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
  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;
571
    *a = *l = (bd->eob != 0);
John Koleszar's avatar
John Koleszar committed
572
  }
573
574
}

575
void vp8_optimize_mby_4x4(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) {
John Koleszar's avatar
John Koleszar committed
576
  int b;
577
  PLANE_TYPE type;
John Koleszar's avatar
John Koleszar committed
578
579
580
581
  int has_2nd_order;
  ENTROPY_CONTEXT_PLANES t_above, t_left;
  ENTROPY_CONTEXT *ta;
  ENTROPY_CONTEXT *tl;
Paul Wilkins's avatar
Paul Wilkins committed
582
  MB_PREDICTION_MODE mode = x->e_mbd.mode_info_context->mbmi.mode;
583

584
  if (!x->e_mbd.above_context || !x->e_mbd.left_context)
John Koleszar's avatar
John Koleszar committed
585
    return;
586

John Koleszar's avatar
John Koleszar committed
587
588
  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));
589

John Koleszar's avatar
John Koleszar committed
590
591
  ta = (ENTROPY_CONTEXT *)&t_above;
  tl = (ENTROPY_CONTEXT *)&t_left;
592

Paul Wilkins's avatar
Paul Wilkins committed
593
  has_2nd_order = (mode != B_PRED && mode != I8X8_PRED && mode != SPLITMV);
John Koleszar's avatar
John Koleszar committed
594
  type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
John Koleszar's avatar
John Koleszar committed
595

John Koleszar's avatar
John Koleszar committed
596
597
  for (b = 0; b < 16; b++) {
    optimize_b(x, b, type,
598
               ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd, TX_4X4);
John Koleszar's avatar
John Koleszar committed
599
  }
John Koleszar's avatar
John Koleszar committed
600

John Koleszar's avatar
John Koleszar committed
601
602
603
  if (has_2nd_order) {
    b = 24;
    optimize_b(x, b, PLANE_TYPE_Y2,
604
               ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd, TX_4X4);
605
    check_reset_2nd_coeffs(&x->e_mbd,
John Koleszar's avatar
John Koleszar committed
606
607
                           ta + vp8_block2above[b], tl + vp8_block2left[b]);
  }
John Koleszar's avatar
John Koleszar committed
608
609
}

610
void vp8_optimize_mbuv_4x4(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) {
John Koleszar's avatar
John Koleszar committed
611
612
613
614
  int b;
  ENTROPY_CONTEXT_PLANES t_above, t_left;
  ENTROPY_CONTEXT *ta;
  ENTROPY_CONTEXT *tl;
John Koleszar's avatar
John Koleszar committed
615

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

John Koleszar's avatar
John Koleszar committed
619
620
  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
621

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

John Koleszar's avatar
John Koleszar committed
625
626
  for (b = 16; b < 24; b++) {
    optimize_b(x, b, PLANE_TYPE_UV,
627
               ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd, TX_4X4);
John Koleszar's avatar
John Koleszar committed
628
  }
629
630
}

631
632
633
static void optimize_mb_4x4(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) {
  vp8_optimize_mby_4x4(x, rtcd);
  vp8_optimize_mbuv_4x4(x, rtcd);
634
635
}

John Koleszar's avatar
John Koleszar committed
636
637
void vp8_optimize_mby_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) {
  int b;
638
  PLANE_TYPE type;
John Koleszar's avatar
John Koleszar committed
639
640
641
  ENTROPY_CONTEXT_PLANES t_above, t_left;
  ENTROPY_CONTEXT *ta;
  ENTROPY_CONTEXT *tl;
642
  int has_2nd_order = x->e_mbd.mode_info_context->mbmi.mode != SPLITMV;
643

644
  if (!x->e_mbd.above_context || !x->e_mbd.left_context)
John Koleszar's avatar
John Koleszar committed
645
    return;
646

John Koleszar's avatar
John Koleszar committed
647
648
  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));
649

John Koleszar's avatar
John Koleszar committed
650
651
  ta = (ENTROPY_CONTEXT *)&t_above;
  tl = (ENTROPY_CONTEXT *)&t_left;
652
  type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
John Koleszar's avatar
John Koleszar committed
653
  for (b = 0; b < 16; b += 4) {
654
    optimize_b(x, b, type,
655
               ta + vp8_block2above_8x8[b], tl + vp8_block2left_8x8[b],
656
               rtcd, TX_8X8);
657
658
    ta[vp8_block2above_8x8[b] + 1] = ta[vp8_block2above_8x8[b]];
    tl[vp8_block2left_8x8[b] + 1]  = tl[vp8_block2left_8x8[b]];
John Koleszar's avatar
John Koleszar committed
659
  }
660

John Koleszar's avatar
John Koleszar committed
661
  // 8x8 always have 2nd roder haar block
662
663
664
665
666
  if (has_2nd_order) {
    check_reset_8x8_2nd_coeffs(&x->e_mbd,
                               ta + vp8_block2above_8x8[24],
                               tl + vp8_block2left_8x8[24]);
  }
667
668
}

John Koleszar's avatar
John Koleszar committed
669
670
671
672
673
void vp8_optimize_mbuv_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) {
  int b;
  ENTROPY_CONTEXT_PLANES t_above, t_left;
  ENTROPY_CONTEXT *ta;
  ENTROPY_CONTEXT *tl;
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

John Koleszar's avatar
John Koleszar committed
684
  for (b = 16; b < 24; b += 4) {
685
686
687
    optimize_b(x, b, PLANE_TYPE_UV,
               ta + vp8_block2above_8x8[b], tl + vp8_block2left_8x8[b],
               rtcd, TX_8X8);
688
689
    ta[vp8_block2above_8x8[b] + 1] = ta[vp8_block2above_8x8[b]];
    tl[vp8_block2left_8x8[b] + 1]  = tl[vp8_block2left_8x8[b]];
John Koleszar's avatar
John Koleszar committed
690
  }
691
692
}

693
694
695
696
697
void optimize_mb_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) {
  vp8_optimize_mby_8x8(x, rtcd);
  vp8_optimize_mbuv_8x8(x, rtcd);
}

698
void optimize_b_16x16(MACROBLOCK *mb, int i, PLANE_TYPE type,
Daniel Kang's avatar
Daniel Kang committed
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
                      ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
                      const VP8_ENCODER_RTCD *rtcd) {
  BLOCK *b = &mb->block[i];
  BLOCKD *d = &mb->e_mbd.block[i];
  vp8_token_state tokens[257][2];
  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;

    rc = vp8_default_zig_zag1d_16x16[i];
    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;
      t0 = (vp8_dct_value_tokens_ptr + x)->Token;
      /* Consider both possible successor states. */
      if (next < 256) {
        band = vp8_coef_bands_16x16[i + 1];
        pt = vp8_prev_token_class[t0];
747
748
        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
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
      }
      UPDATE_RD_COST();
      /* And pick the best. */
      best = rd_cost1 < rd_cost0;
      base_bits = *(vp8_dct_value_cost_ptr + x);
      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
        t0=t1 = (vp8_dct_value_tokens_ptr + x)->Token;
      if (next < 256) {
        band = vp8_coef_bands_16x16[i + 1];
        if (t0 != DCT_EOB_TOKEN) {
            pt = vp8_prev_token_class[t0];
793
            rate0 += mb->token_costs[TX_16X16][type][band][pt]
Daniel Kang's avatar
Daniel Kang committed
794
795
796
797
                [tokens[next][0].token];
        }
        if (t1!=DCT_EOB_TOKEN) {
            pt = vp8_prev_token_class[t1];
798
            rate1 += mb->token_costs[TX_16X16][type][band][pt]
Daniel Kang's avatar
Daniel Kang committed
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
                [tokens[next][1].token];
        }
      }
      UPDATE_RD_COST();
      /* And pick the best. */
      best = rd_cost1 < rd_cost0;
      base_bits = *(vp8_dct_value_cost_ptr + x);

      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 {
      band = vp8_coef_bands_16x16[i + 1];
      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) {
829
        tokens[next][0].rate += mb->token_costs[TX_16X16][type][band][0][t0];
Daniel Kang's avatar
Daniel Kang committed
830
831
832
        tokens[next][0].token = ZERO_TOKEN;
      }
      if (t1 != DCT_EOB_TOKEN) {
833
        tokens[next][1].rate += mb->token_costs[TX_16X16][type][band][0][t1];
Daniel Kang's avatar
Daniel Kang committed
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
        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. */
  band = vp8_coef_bands_16x16[i + 1];
  VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
  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;
849
850
  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
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
  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;
    rc = vp8_default_zig_zag1d_16x16[i];
    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;
  *a = *l = (d->eob != !type);
}

void vp8_optimize_mby_16x16(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) {
873
874
875
876
877
878
879
880
881
882
883
884
  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;
  optimize_b_16x16(x, 0, PLANE_TYPE_Y_WITH_DC, ta, tl, rtcd);
Daniel Kang's avatar
Daniel Kang committed
885
886
}

887
static void optimize_mb_16x16(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) {
888
889
  vp8_optimize_mby_16x16(x, rtcd);
  vp8_optimize_mbuv_8x8(x, rtcd);
Daniel Kang's avatar
Daniel Kang committed
890
891
}

John Koleszar's avatar
John Koleszar committed
892
void vp8_encode_inter16x16(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) {
893
894
  MACROBLOCKD *xd = &x->e_mbd;
  TX_SIZE tx_size = xd->mode_info_context->mbmi.txfm_size;
John Koleszar's avatar
John Koleszar committed
895

896
  vp8_build_inter_predictors_mb(xd);
John Koleszar's avatar
John Koleszar committed
897
  vp8_subtract_mb(rtcd, x);
John Koleszar's avatar
John Koleszar committed
898

899
  if (tx_size == TX_16X16) {
Daniel Kang's avatar
Daniel Kang committed
900
901
    vp8_transform_mb_16x16(x);
    vp8_quantize_mb_16x16(x);
902
    if (x->optimize)
Daniel Kang's avatar
Daniel Kang committed
903
      optimize_mb_16x16(x, rtcd);
904
905
    vp8_inverse_transform_mb_16x16(IF_RTCD(&rtcd->common->idct), xd);
  } else if (tx_size == TX_8X8) {
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
    if (xd->mode_info_context->mbmi.mode == SPLITMV) {
      assert(xd->mode_info_context->mbmi.partitioning != PARTITIONING_4X4);
      vp8_transform_mby_8x8(x);
      vp8_transform_mbuv_4x4(x);
      vp8_quantize_mby_8x8(x);
      vp8_quantize_mbuv_4x4(x);
      if (x->optimize) {
        vp8_optimize_mby_8x8(x, rtcd);
        vp8_optimize_mbuv_4x4(x, rtcd);
      }
      vp8_inverse_transform_mby_8x8(IF_RTCD(&rtcd->common->idct), xd);
      vp8_inverse_transform_mbuv_4x4(IF_RTCD(&rtcd->common->idct), xd);
    } else {
      vp8_transform_mb_8x8(x);
      vp8_quantize_mb_8x8(x);
      if (x->optimize)
        optimize_mb_8x8(x, rtcd);
      vp8_inverse_transform_mb_8x8(IF_RTCD(&rtcd->common->idct), xd);
    }
925
926
927
928
  } else {
    transform_mb_4x4(x);
    vp8_quantize_mb_4x4(x);
    if (x->optimize)
929
      optimize_mb_4x4(x, rtcd);
930
    vp8_inverse_transform_mb_4x4(IF_RTCD(&rtcd->common->idct), xd);
John Koleszar's avatar
John Koleszar committed
931
932
  }

933
  vp8_recon_mb(xd);
John Koleszar's avatar
John Koleszar committed
934
935
}

936
/* this function is used by first pass only */
John Koleszar's avatar
John Koleszar committed
937
void vp8_encode_inter16x16y(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x) {
938
  MACROBLOCKD *xd = &x->e_mbd;
John Koleszar's avatar
John Koleszar committed
939
  BLOCK *b = &x->block[0];
940

941
#if CONFIG_PRED_FILTER
John Koleszar's avatar
John Koleszar committed
942
  // Disable the prediction filter for firstpass
943
  xd->mode_info_context->mbmi.pred_filter_enabled = 0;
944
945
#endif

946
  vp8_build_1st_inter16x16_predictors_mby(xd, xd->predictor, 16, 0);
John Koleszar's avatar
John Koleszar committed
947

Jim Bankoski's avatar
Jim Bankoski committed
948
  vp8_subtract_mby(x->src_diff, *(b->base_src), xd->predictor, b->src_stride);
John Koleszar's avatar
John Koleszar committed
949

950
  vp8_transform_mby_4x4(x);
951
  vp8_quantize_mby_4x4(x);
952
  vp8_inverse_transform_mby_4x4(IF_RTCD(&rtcd->common->idct), xd);
Yaowu Xu's avatar
Yaowu Xu committed
953

954
  vp8_recon_mby(xd);
John Koleszar's avatar
John Koleszar committed
955
}