encodemb.c 27.3 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"
John Koleszar's avatar
John Koleszar committed
22
23
24
25
26
27

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

#ifdef ENC_DEBUG
extern int enc_debug;
#endif

John Koleszar's avatar
John Koleszar committed
33
34
35
36
37
38
39
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
40

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

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

John Koleszar's avatar
John Koleszar committed
52
53
54
55
56
57
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;
58

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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
69
70
71
72
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
73
74
75
  short *udiff = diff + 256;
  short *vdiff = diff + 320;
  int r, c;
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++) {
      udiff[c] = usrc[c] - upred[c];
John Koleszar's avatar
John Koleszar committed
80
81
    }

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

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

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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
98
99
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
100
101
102
103
104
105
  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
106
107
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
108
  int r, c;
John Koleszar's avatar
John Koleszar committed
109

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

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

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

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

John Koleszar's avatar
John Koleszar committed
129
130
  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
131
132
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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
  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
340
341
342
343
344

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
637
638
void vp8_optimize_mby_8x8(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd) {
  int b;
639
  PLANE_TYPE type;
John Koleszar's avatar
John Koleszar committed
640
641
642
  ENTROPY_CONTEXT_PLANES t_above, t_left;
  ENTROPY_CONTEXT *ta;
  ENTROPY_CONTEXT *tl;
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 = PLANE_TYPE_Y_NO_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);
John Koleszar's avatar
John Koleszar committed
657
658
659
    *(ta + vp8_block2above_8x8[b] + 1) = *(ta + vp8_block2above_8x8[b]);
    *(tl + vp8_block2left_8x8[b] + 1)  = *(tl + vp8_block2left_8x8[b]);
  }
660

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

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

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

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

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

John Koleszar's avatar
John Koleszar committed
681
  for (b = 16; b < 24; b += 4) {
682
683
684
    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
685
686
687
    *(ta + vp8_block2above_8x8[b] + 1) = *(ta + vp8_block2above_8x8[b]);
    *(tl + vp8_block2left_8x8[b] + 1) = *(tl + vp8_block2left_8x8[b]);
  }
688
689
}

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

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

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

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

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

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

916
  vp8_recon_mb(xd);
John Koleszar's avatar
John Koleszar committed
917
918
}

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

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

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

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

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

938
  vp8_recon_mby(xd);
John Koleszar's avatar
John Koleszar committed
939
}