encodemb.c 27.6 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
#include "vp8/common/invtrans.h"
17
#include "vp8/common/recon.h"
John Koleszar's avatar
John Koleszar committed
18
#include "vp8/common/reconintra.h"
John Koleszar's avatar
John Koleszar committed
19
20
#include "dct.h"
#include "vpx_mem/vpx_mem.h"
Yunqing Wang's avatar
Yunqing Wang committed
21
#include "rdopt.h"
22
#include "vp8/common/systemdependent.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

John Koleszar's avatar
John Koleszar committed
130
131
  ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src), x->e_mbd.predictor, b->src_stride);
  ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(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
132
133
}

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

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

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

John Koleszar's avatar
John Koleszar committed
146
147
148
149
  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
150

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

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

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

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
191
192
193
194
195
196
197
198
  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);
  }
199

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

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

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

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

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

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

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

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

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

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

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

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

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

300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
  b = &mb->block[i];
  d = &mb->e_mbd.block[i];
  switch (tx_type) {
    default:
    case TX_4X4:
      scan = vp8_default_zig_zag1d;
      bands = vp8_coef_bands;
      default_eob = 16;
#if CONFIG_HYBRIDTRANSFORM
      // TODO: this isn't called (for intra4x4 modes), but will be left in
      // since it could be used later
      {
        int active_ht = (mb->q_index < ACTIVE_HT) &&
                        (mb->e_mbd.mode_info_context->mbmi.mode == B_PRED);

        if((type == PLANE_TYPE_Y_WITH_DC) && active_ht) {
          switch (d->bmi.as_mode.tx_type) {
            case ADST_DCT:
              scan = vp8_row_scan;
              break;

            case DCT_ADST:
              scan = vp8_col_scan;
              break;

            default:
              scan = vp8_default_zig_zag1d;
              break;
          }

        } else
          scan = vp8_default_zig_zag1d;
      }
#endif
      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
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357

  dequant_ptr = d->dequant;
  coeff_ptr = b->coeff;
  qcoeff_ptr = d->qcoeff;
  dqcoeff_ptr = d->dqcoeff;
  i0 = !type;
  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;
358
  tokens[eob][0].next = default_eob;
John Koleszar's avatar
John Koleszar committed
359
360
361
362
363
364
365
366
367
  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;

368
    rc = scan[i];
John Koleszar's avatar
John Koleszar committed
369
370
371
372
373
374
375
376
377
378
379
    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. */
380
381
      if (next < default_eob) {
        band = bands[i + 1];
John Koleszar's avatar
John Koleszar committed
382
383
        pt = vp8_prev_token_class[t0];
        rate0 +=
384
          mb->token_costs[tx_type][type][band][pt][tokens[next][0].token];
John Koleszar's avatar
John Koleszar committed
385
        rate1 +=
386
          mb->token_costs[tx_type][type][band][pt][tokens[next][1].token];
John Koleszar's avatar
John Koleszar committed
387
      }
388
      UPDATE_RD_COST();
John Koleszar's avatar
John Koleszar committed
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
      /* 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;

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

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

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

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

John Koleszar's avatar
John Koleszar committed
501
502
503
504
505
506
507
    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
508
509
}

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

Paul Wilkins's avatar
Paul Wilkins committed
520
static void check_reset_2nd_coeffs(MACROBLOCKD *xd, int type,
John Koleszar's avatar
John Koleszar committed
521
522
523
                                   ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l) {
  int sum = 0;
  int i;
Paul Wilkins's avatar
Paul Wilkins committed
524
  BLOCKD *bd = &xd->block[24];
John Koleszar's avatar
John Koleszar committed
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
  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;
541
    }
John Koleszar's avatar
John Koleszar committed
542
543
544
    bd->eob = 0;
    *a = *l = (bd->eob != !type);
  }
545
}
546

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

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

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

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

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

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
621
622
  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
623

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

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

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

John Koleszar's avatar
John Koleszar committed
638
639
640
641
642
643
void vp8_optimize_mby_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) {
  int b;
  int type;
  ENTROPY_CONTEXT_PLANES t_above, t_left;
  ENTROPY_CONTEXT *ta;
  ENTROPY_CONTEXT *tl;
644

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

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

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

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

John Koleszar's avatar
John Koleszar committed
667
668
669
670
671
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;
672

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

John Koleszar's avatar
John Koleszar committed
676
677
  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));
678

John Koleszar's avatar
John Koleszar committed
679
680
  ta = (ENTROPY_CONTEXT *)&t_above;
  tl = (ENTROPY_CONTEXT *)&t_left;
681

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

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

Daniel Kang's avatar
Daniel Kang committed
696
697
698
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
void optimize_b_16x16(MACROBLOCK *mb, int i, int type,
                      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];
745
746
        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
747
748
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
      }
      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];
791
            rate0 += mb->token_costs[TX_16X16][type][band][pt]
Daniel Kang's avatar
Daniel Kang committed
792
793
794
795
                [tokens[next][0].token];
        }
        if (t1!=DCT_EOB_TOKEN) {
            pt = vp8_prev_token_class[t1];
796
            rate1 += mb->token_costs[TX_16X16][type][band][pt]
Daniel Kang's avatar
Daniel Kang committed
797
798
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
                [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) {
827
        tokens[next][0].rate += mb->token_costs[TX_16X16][type][band][0][t0];
Daniel Kang's avatar
Daniel Kang committed
828
829
830
        tokens[next][0].token = ZERO_TOKEN;
      }
      if (t1 != DCT_EOB_TOKEN) {
831
        tokens[next][1].rate += mb->token_costs[TX_16X16][type][band][0][t1];
Daniel Kang's avatar
Daniel Kang committed
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
        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;
847
848
  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
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
  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) {
871
872
873
874
875
876
877
878
879
880
881
882
  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
883
884
}

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

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

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

897
  if (tx_size == TX_16X16) {
Daniel Kang's avatar
Daniel Kang committed
898
899
    vp8_transform_mb_16x16(x);
    vp8_quantize_mb_16x16(x);
900
    if (x->optimize)
Daniel Kang's avatar
Daniel Kang committed
901
      optimize_mb_16x16(x, rtcd);
902
903
904
905
906
    vp8_inverse_transform_mb_16x16(IF_RTCD(&rtcd->common->idct), xd);
  } else if (tx_size == TX_8X8) {
    vp8_transform_mb_8x8(x);
    vp8_quantize_mb_8x8(x);
    if (x->optimize)
John Koleszar's avatar
John Koleszar committed
907
      optimize_mb_8x8(x, rtcd);
908
909
910
911
912
    vp8_inverse_transform_mb_8x8(IF_RTCD(&rtcd->common->idct), xd);
  } else {
    transform_mb_4x4(x);
    vp8_quantize_mb_4x4(x);
    if (x->optimize)
913
      optimize_mb_4x4(x, rtcd);
914
    vp8_inverse_transform_mb_4x4(IF_RTCD(&rtcd->common->idct), xd);
John Koleszar's avatar
John Koleszar committed
915
916
  }

917
918
  RECON_INVOKE(&rtcd->common->recon, recon_mb)(IF_RTCD(&rtcd->common->recon),
                                               xd);
John Koleszar's avatar
John Koleszar committed
919
920
}

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

926
#if CONFIG_PRED_FILTER
John Koleszar's avatar
John Koleszar committed
927
  // Disable the prediction filter for firstpass
928
  xd->mode_info_context->mbmi.pred_filter_enabled = 0;
929
930
#endif

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

933
934
  ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, *(b->base_src),
                                           xd->predictor, b->src_stride);
John Koleszar's avatar
John Koleszar committed
935

936
  vp8_transform_mby_4x4(x);
937
  vp8_quantize_mby_4x4(x);
938
  vp8_inverse_transform_mby_4x4(IF_RTCD(&rtcd->common->idct), xd);
Yaowu Xu's avatar
Yaowu Xu committed
939

940
941
  RECON_INVOKE(&rtcd->common->recon, recon_mby)(IF_RTCD(&rtcd->common->recon),
                                                xd);
John Koleszar's avatar
John Koleszar committed
942
}