Coverage Report

Created: 2026-03-12 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libvpx/vp8/encoder/encodemb.c
Line
Count
Source
1
/*
2
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5
 *  that can be found in the LICENSE file in the root of the source
6
 *  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.
9
 */
10
11
#include "./vpx_dsp_rtcd.h"
12
13
#include "vpx_config.h"
14
#include "vp8_rtcd.h"
15
#include "encodemb.h"
16
#include "vp8/common/reconinter.h"
17
#include "vp8/encoder/quantize.h"
18
#include "tokenize.h"
19
#include "vp8/common/invtrans.h"
20
#include "vpx_mem/vpx_mem.h"
21
#include "rdopt.h"
22
23
248M
void vp8_subtract_b(BLOCK *be, BLOCKD *bd, int pitch) {
24
248M
  unsigned char *src_ptr = (*(be->base_src) + be->src);
25
248M
  short *diff_ptr = be->src_diff;
26
248M
  unsigned char *pred_ptr = bd->predictor;
27
248M
  int src_stride = be->src_stride;
28
29
248M
  vpx_subtract_block(4, 4, diff_ptr, pitch, src_ptr, src_stride, pred_ptr,
30
248M
                     pitch);
31
248M
}
32
33
void vp8_subtract_mbuv(short *diff, unsigned char *usrc, unsigned char *vsrc,
34
                       int src_stride, unsigned char *upred,
35
9.20M
                       unsigned char *vpred, int pred_stride) {
36
9.20M
  short *udiff = diff + 256;
37
9.20M
  short *vdiff = diff + 320;
38
39
9.20M
  vpx_subtract_block(8, 8, udiff, 8, usrc, src_stride, upred, pred_stride);
40
9.20M
  vpx_subtract_block(8, 8, vdiff, 8, vsrc, src_stride, vpred, pred_stride);
41
9.20M
}
42
43
void vp8_subtract_mby(short *diff, unsigned char *src, int src_stride,
44
7.91M
                      unsigned char *pred, int pred_stride) {
45
7.91M
  vpx_subtract_block(16, 16, diff, 16, src, src_stride, pred, pred_stride);
46
7.91M
}
47
48
857k
static void vp8_subtract_mb(MACROBLOCK *x) {
49
857k
  BLOCK *b = &x->block[0];
50
51
857k
  vp8_subtract_mby(x->src_diff, *(b->base_src), b->src_stride,
52
857k
                   x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride);
53
857k
  vp8_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
54
857k
                    x->src.uv_stride, x->e_mbd.dst.u_buffer,
55
857k
                    x->e_mbd.dst.v_buffer, x->e_mbd.dst.uv_stride);
56
857k
}
57
58
969k
static void build_dcblock(MACROBLOCK *x) {
59
969k
  short *src_diff_ptr = &x->src_diff[384];
60
969k
  int i;
61
62
16.4M
  for (i = 0; i < 16; ++i) {
63
15.5M
    src_diff_ptr[i] = x->coeff[i * 16];
64
15.5M
  }
65
969k
}
66
67
8.34M
void vp8_transform_mbuv(MACROBLOCK *x) {
68
8.34M
  int i;
69
70
41.7M
  for (i = 16; i < 24; i += 2) {
71
33.3M
    x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16);
72
33.3M
  }
73
8.34M
}
74
75
311k
void vp8_transform_intra_mby(MACROBLOCK *x) {
76
311k
  int i;
77
78
2.80M
  for (i = 0; i < 16; i += 2) {
79
2.49M
    x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
80
2.49M
  }
81
82
  /* build dc block from 16 y dc values */
83
311k
  build_dcblock(x);
84
85
  /* do 2nd order transform on the dc block */
86
311k
  x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
87
311k
}
88
89
857k
static void transform_mb(MACROBLOCK *x) {
90
857k
  int i;
91
92
7.71M
  for (i = 0; i < 16; i += 2) {
93
6.86M
    x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
94
6.86M
  }
95
96
  /* build dc block from 16 y dc values */
97
857k
  if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) build_dcblock(x);
98
99
4.28M
  for (i = 16; i < 24; i += 2) {
100
3.43M
    x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16);
101
3.43M
  }
102
103
  /* do 2nd order transform on the dc block */
104
857k
  if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) {
105
657k
    x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
106
657k
  }
107
857k
}
108
109
0
static void transform_mby(MACROBLOCK *x) {
110
0
  int i;
111
112
0
  for (i = 0; i < 16; i += 2) {
113
0
    x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
114
0
  }
115
116
  /* build dc block from 16 y dc values */
117
0
  if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) {
118
0
    build_dcblock(x);
119
0
    x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
120
0
  }
121
0
}
122
123
141M
#define RDTRUNC(RM, DM, R, D) ((128 + (R) * (RM)) & 0xFF)
124
125
typedef struct vp8_token_state vp8_token_state;
126
127
struct vp8_token_state {
128
  int rate;
129
  int error;
130
  signed char next;
131
  signed char token;
132
  short qc;
133
};
134
135
/* TODO: experiments to find optimal multiple numbers */
136
#define Y1_RD_MULT 4
137
#define UV_RD_MULT 2
138
#define Y2_RD_MULT 16
139
140
static const int plane_rd_mult[4] = { Y1_RD_MULT, Y2_RD_MULT, UV_RD_MULT,
141
                                      Y1_RD_MULT };
142
143
static void optimize_b(MACROBLOCK *mb, int ib, int type, ENTROPY_CONTEXT *a,
144
19.2M
                       ENTROPY_CONTEXT *l) {
145
19.2M
  BLOCK *b;
146
19.2M
  BLOCKD *d;
147
19.2M
  vp8_token_state tokens[17][2];
148
19.2M
  unsigned best_mask[2];
149
19.2M
  const short *dequant_ptr;
150
19.2M
  const short *coeff_ptr;
151
19.2M
  short *qcoeff_ptr;
152
19.2M
  short *dqcoeff_ptr;
153
19.2M
  int eob;
154
19.2M
  int i0;
155
19.2M
  int rc;
156
19.2M
  int x;
157
19.2M
  int sz = 0;
158
19.2M
  int next;
159
19.2M
  int rdmult;
160
19.2M
  int rddiv;
161
19.2M
  int final_eob;
162
19.2M
  int rd_cost0;
163
19.2M
  int rd_cost1;
164
19.2M
  int rate0;
165
19.2M
  int rate1;
166
19.2M
  int error0;
167
19.2M
  int error1;
168
19.2M
  int t0;
169
19.2M
  int t1;
170
19.2M
  int best;
171
19.2M
  int band;
172
19.2M
  int pt;
173
19.2M
  int i;
174
19.2M
  int err_mult = plane_rd_mult[type];
175
176
19.2M
  b = &mb->block[ib];
177
19.2M
  d = &mb->e_mbd.block[ib];
178
179
19.2M
  dequant_ptr = d->dequant;
180
19.2M
  coeff_ptr = b->coeff;
181
19.2M
  qcoeff_ptr = d->qcoeff;
182
19.2M
  dqcoeff_ptr = d->dqcoeff;
183
19.2M
  i0 = !type;
184
19.2M
  eob = *d->eob;
185
186
  /* Now set up a Viterbi trellis to evaluate alternative roundings. */
187
19.2M
  rdmult = mb->rdmult * err_mult;
188
19.2M
  if (mb->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
189
7.18M
    rdmult = (rdmult * 9) >> 4;
190
7.18M
  }
191
192
19.2M
  rddiv = mb->rddiv;
193
19.2M
  best_mask[0] = best_mask[1] = 0;
194
  /* Initialize the sentinel node of the trellis. */
195
19.2M
  tokens[eob][0].rate = 0;
196
19.2M
  tokens[eob][0].error = 0;
197
19.2M
  tokens[eob][0].next = 16;
198
19.2M
  tokens[eob][0].token = DCT_EOB_TOKEN;
199
19.2M
  tokens[eob][0].qc = 0;
200
19.2M
  *(tokens[eob] + 1) = *(tokens[eob] + 0);
201
19.2M
  next = eob;
202
84.7M
  for (i = eob; i-- > i0;) {
203
65.4M
    int base_bits;
204
65.4M
    int d2;
205
65.4M
    int dx;
206
207
65.4M
    rc = vp8_default_zig_zag1d[i];
208
65.4M
    x = qcoeff_ptr[rc];
209
    /* Only add a trellis state for non-zero coefficients. */
210
65.4M
    if (x) {
211
42.0M
      int shortcut = 0;
212
42.0M
      error0 = tokens[next][0].error;
213
42.0M
      error1 = tokens[next][1].error;
214
      /* Evaluate the first possibility for this state. */
215
42.0M
      rate0 = tokens[next][0].rate;
216
42.0M
      rate1 = tokens[next][1].rate;
217
42.0M
      t0 = (vp8_dct_value_tokens_ptr + x)->Token;
218
      /* Consider both possible successor states. */
219
42.0M
      if (next < 16) {
220
40.1M
        band = vp8_coef_bands[i + 1];
221
40.1M
        pt = vp8_prev_token_class[t0];
222
40.1M
        rate0 += mb->token_costs[type][band][pt][tokens[next][0].token];
223
40.1M
        rate1 += mb->token_costs[type][band][pt][tokens[next][1].token];
224
40.1M
      }
225
42.0M
      rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
226
42.0M
      rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
227
42.0M
      if (rd_cost0 == rd_cost1) {
228
27.2M
        rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
229
27.2M
        rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
230
27.2M
      }
231
      /* And pick the best. */
232
42.0M
      best = rd_cost1 < rd_cost0;
233
42.0M
      base_bits = *(vp8_dct_value_cost_ptr + x);
234
42.0M
      dx = dqcoeff_ptr[rc] - coeff_ptr[rc];
235
42.0M
      d2 = dx * dx;
236
42.0M
      tokens[i][0].rate = base_bits + (best ? rate1 : rate0);
237
42.0M
      tokens[i][0].error = d2 + (best ? error1 : error0);
238
42.0M
      tokens[i][0].next = next;
239
42.0M
      tokens[i][0].token = t0;
240
42.0M
      tokens[i][0].qc = x;
241
42.0M
      best_mask[0] |= best << i;
242
      /* Evaluate the second possibility for this state. */
243
42.0M
      rate0 = tokens[next][0].rate;
244
42.0M
      rate1 = tokens[next][1].rate;
245
246
42.0M
      if ((abs(x) * dequant_ptr[rc] > abs(coeff_ptr[rc])) &&
247
17.6M
          (abs(x) * dequant_ptr[rc] < abs(coeff_ptr[rc]) + dequant_ptr[rc])) {
248
17.6M
        shortcut = 1;
249
24.3M
      } else {
250
24.3M
        shortcut = 0;
251
24.3M
      }
252
253
42.0M
      if (shortcut) {
254
17.6M
        sz = -(x < 0);
255
17.6M
        x -= 2 * sz + 1;
256
17.6M
      }
257
258
      /* Consider both possible successor states. */
259
42.0M
      if (!x) {
260
        /* If we reduced this coefficient to zero, check to see if
261
         *  we need to move the EOB back here.
262
         */
263
6.70M
        t0 =
264
6.70M
            tokens[next][0].token == DCT_EOB_TOKEN ? DCT_EOB_TOKEN : ZERO_TOKEN;
265
6.70M
        t1 =
266
6.70M
            tokens[next][1].token == DCT_EOB_TOKEN ? DCT_EOB_TOKEN : ZERO_TOKEN;
267
35.3M
      } else {
268
35.3M
        t0 = t1 = (vp8_dct_value_tokens_ptr + x)->Token;
269
35.3M
      }
270
42.0M
      if (next < 16) {
271
40.1M
        band = vp8_coef_bands[i + 1];
272
40.1M
        if (t0 != DCT_EOB_TOKEN) {
273
38.8M
          pt = vp8_prev_token_class[t0];
274
38.8M
          rate0 += mb->token_costs[type][band][pt][tokens[next][0].token];
275
38.8M
        }
276
40.1M
        if (t1 != DCT_EOB_TOKEN) {
277
38.2M
          pt = vp8_prev_token_class[t1];
278
38.2M
          rate1 += mb->token_costs[type][band][pt][tokens[next][1].token];
279
38.2M
        }
280
40.1M
      }
281
282
42.0M
      rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
283
42.0M
      rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
284
42.0M
      if (rd_cost0 == rd_cost1) {
285
27.2M
        rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
286
27.2M
        rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
287
27.2M
      }
288
      /* And pick the best. */
289
42.0M
      best = rd_cost1 < rd_cost0;
290
42.0M
      base_bits = *(vp8_dct_value_cost_ptr + x);
291
292
42.0M
      if (shortcut) {
293
17.6M
        dx -= (dequant_ptr[rc] + sz) ^ sz;
294
17.6M
        d2 = dx * dx;
295
17.6M
      }
296
42.0M
      tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
297
42.0M
      tokens[i][1].error = d2 + (best ? error1 : error0);
298
42.0M
      tokens[i][1].next = next;
299
42.0M
      tokens[i][1].token = best ? t1 : t0;
300
42.0M
      tokens[i][1].qc = x;
301
42.0M
      best_mask[1] |= best << i;
302
      /* Finally, make this the new head of the trellis. */
303
42.0M
      next = i;
304
42.0M
    }
305
    /* There's no choice to make for a zero coefficient, so we don't
306
     *  add a new trellis node, but we do need to update the costs.
307
     */
308
23.4M
    else {
309
23.4M
      band = vp8_coef_bands[i + 1];
310
23.4M
      t0 = tokens[next][0].token;
311
23.4M
      t1 = tokens[next][1].token;
312
      /* Update the cost of each path if we're past the EOB token. */
313
23.4M
      if (t0 != DCT_EOB_TOKEN) {
314
23.4M
        tokens[next][0].rate += mb->token_costs[type][band][0][t0];
315
23.4M
        tokens[next][0].token = ZERO_TOKEN;
316
23.4M
      }
317
23.4M
      if (t1 != DCT_EOB_TOKEN) {
318
20.7M
        tokens[next][1].rate += mb->token_costs[type][band][0][t1];
319
20.7M
        tokens[next][1].token = ZERO_TOKEN;
320
20.7M
      }
321
      /* Don't update next, because we didn't add a new node. */
322
23.4M
    }
323
65.4M
  }
324
325
  /* Now pick the best path through the whole trellis. */
326
19.2M
  band = vp8_coef_bands[i + 1];
327
19.2M
  VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
328
19.2M
  rate0 = tokens[next][0].rate;
329
19.2M
  rate1 = tokens[next][1].rate;
330
19.2M
  error0 = tokens[next][0].error;
331
19.2M
  error1 = tokens[next][1].error;
332
19.2M
  t0 = tokens[next][0].token;
333
19.2M
  t1 = tokens[next][1].token;
334
19.2M
  rate0 += mb->token_costs[type][band][pt][t0];
335
19.2M
  rate1 += mb->token_costs[type][band][pt][t1];
336
19.2M
  rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
337
19.2M
  rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
338
19.2M
  if (rd_cost0 == rd_cost1) {
339
16.3M
    rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
340
16.3M
    rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
341
16.3M
  }
342
19.2M
  best = rd_cost1 < rd_cost0;
343
19.2M
  final_eob = i0 - 1;
344
61.2M
  for (i = next; i < eob; i = next) {
345
42.0M
    x = tokens[i][best].qc;
346
42.0M
    if (x) final_eob = i;
347
42.0M
    rc = vp8_default_zig_zag1d[i];
348
42.0M
    qcoeff_ptr[rc] = x;
349
42.0M
    dqcoeff_ptr[rc] = x * dequant_ptr[rc];
350
42.0M
    next = tokens[i][best].next;
351
42.0M
    best = (best_mask[best] >> i) & 1;
352
42.0M
  }
353
19.2M
  final_eob++;
354
355
19.2M
  *a = *l = (final_eob != !type);
356
19.2M
  *d->eob = (char)final_eob;
357
19.2M
}
358
static void check_reset_2nd_coeffs(MACROBLOCKD *x, int type, ENTROPY_CONTEXT *a,
359
465k
                                   ENTROPY_CONTEXT *l) {
360
465k
  int sum = 0;
361
465k
  int i;
362
465k
  BLOCKD *bd = &x->block[24];
363
364
465k
  if (bd->dequant[0] >= 35 && bd->dequant[1] >= 35) return;
365
366
464k
  for (i = 0; i < (*bd->eob); ++i) {
367
241k
    int coef = bd->dqcoeff[vp8_default_zig_zag1d[i]];
368
241k
    sum += (coef >= 0) ? coef : -coef;
369
241k
    if (sum >= 35) return;
370
241k
  }
371
  /**************************************************************************
372
  our inverse hadamard transform effectively is weighted sum of all 16 inputs
373
  with weight either 1 or -1. It has a last stage scaling of (sum+3)>>3. And
374
  dc only idct is (dc+4)>>3. So if all the sums are between -35 and 29, the
375
  output after inverse wht and idct will be all zero. A sum of absolute value
376
  smaller than 35 guarantees all 16 different (+1/-1) weighted sums in wht
377
  fall between -35 and +35.
378
  **************************************************************************/
379
223k
  if (sum < 35) {
380
358k
    for (i = 0; i < (*bd->eob); ++i) {
381
134k
      int rc = vp8_default_zig_zag1d[i];
382
134k
      bd->qcoeff[rc] = 0;
383
134k
      bd->dqcoeff[rc] = 0;
384
134k
    }
385
223k
    *bd->eob = 0;
386
223k
    *a = *l = (*bd->eob != !type);
387
223k
  }
388
223k
}
389
390
489k
static void optimize_mb(MACROBLOCK *x) {
391
489k
  int b;
392
489k
  int type;
393
489k
  int has_2nd_order;
394
395
489k
  ENTROPY_CONTEXT_PLANES t_above, t_left;
396
489k
  ENTROPY_CONTEXT *ta;
397
489k
  ENTROPY_CONTEXT *tl;
398
399
489k
  t_above = *x->e_mbd.above_context;
400
489k
  t_left = *x->e_mbd.left_context;
401
402
489k
  ta = (ENTROPY_CONTEXT *)&t_above;
403
489k
  tl = (ENTROPY_CONTEXT *)&t_left;
404
405
489k
  has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&
406
489k
                   x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
407
489k
  type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
408
409
8.31M
  for (b = 0; b < 16; ++b) {
410
7.82M
    optimize_b(x, b, type, ta + vp8_block2above[b], tl + vp8_block2left[b]);
411
7.82M
  }
412
413
4.40M
  for (b = 16; b < 24; ++b) {
414
3.91M
    optimize_b(x, b, PLANE_TYPE_UV, ta + vp8_block2above[b],
415
3.91M
               tl + vp8_block2left[b]);
416
3.91M
  }
417
418
489k
  if (has_2nd_order) {
419
289k
    b = 24;
420
289k
    optimize_b(x, b, PLANE_TYPE_Y2, ta + vp8_block2above[b],
421
289k
               tl + vp8_block2left[b]);
422
289k
    check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2, ta + vp8_block2above[b],
423
289k
                           tl + vp8_block2left[b]);
424
289k
  }
425
489k
}
426
427
176k
void vp8_optimize_mby(MACROBLOCK *x) {
428
176k
  int b;
429
176k
  int type;
430
176k
  int has_2nd_order;
431
432
176k
  ENTROPY_CONTEXT_PLANES t_above, t_left;
433
176k
  ENTROPY_CONTEXT *ta;
434
176k
  ENTROPY_CONTEXT *tl;
435
436
176k
  if (!x->e_mbd.above_context) return;
437
438
176k
  if (!x->e_mbd.left_context) return;
439
440
176k
  t_above = *x->e_mbd.above_context;
441
176k
  t_left = *x->e_mbd.left_context;
442
443
176k
  ta = (ENTROPY_CONTEXT *)&t_above;
444
176k
  tl = (ENTROPY_CONTEXT *)&t_left;
445
446
176k
  has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&
447
176k
                   x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
448
176k
  type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
449
450
2.99M
  for (b = 0; b < 16; ++b) {
451
2.81M
    optimize_b(x, b, type, ta + vp8_block2above[b], tl + vp8_block2left[b]);
452
2.81M
  }
453
454
176k
  if (has_2nd_order) {
455
176k
    b = 24;
456
176k
    optimize_b(x, b, PLANE_TYPE_Y2, ta + vp8_block2above[b],
457
176k
               tl + vp8_block2left[b]);
458
176k
    check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2, ta + vp8_block2above[b],
459
176k
                           tl + vp8_block2left[b]);
460
176k
  }
461
176k
}
462
463
523k
void vp8_optimize_mbuv(MACROBLOCK *x) {
464
523k
  int b;
465
523k
  ENTROPY_CONTEXT_PLANES t_above, t_left;
466
523k
  ENTROPY_CONTEXT *ta;
467
523k
  ENTROPY_CONTEXT *tl;
468
469
523k
  if (!x->e_mbd.above_context) return;
470
471
523k
  if (!x->e_mbd.left_context) return;
472
473
523k
  t_above = *x->e_mbd.above_context;
474
523k
  t_left = *x->e_mbd.left_context;
475
476
523k
  ta = (ENTROPY_CONTEXT *)&t_above;
477
523k
  tl = (ENTROPY_CONTEXT *)&t_left;
478
479
4.71M
  for (b = 16; b < 24; ++b) {
480
4.19M
    optimize_b(x, b, PLANE_TYPE_UV, ta + vp8_block2above[b],
481
4.19M
               tl + vp8_block2left[b]);
482
4.19M
  }
483
523k
}
484
485
857k
void vp8_encode_inter16x16(MACROBLOCK *x) {
486
857k
  vp8_build_inter_predictors_mb(&x->e_mbd);
487
488
857k
  vp8_subtract_mb(x);
489
490
857k
  transform_mb(x);
491
492
857k
  vp8_quantize_mb(x);
493
494
857k
  if (x->optimize) optimize_mb(x);
495
857k
}
496
497
/* this funciton is used by first pass only */
498
0
void vp8_encode_inter16x16y(MACROBLOCK *x) {
499
0
  BLOCK *b = &x->block[0];
500
501
0
  vp8_build_inter16x16_predictors_mby(&x->e_mbd, x->e_mbd.dst.y_buffer,
502
0
                                      x->e_mbd.dst.y_stride);
503
504
0
  vp8_subtract_mby(x->src_diff, *(b->base_src), b->src_stride,
505
0
                   x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride);
506
507
0
  transform_mby(x);
508
509
0
  vp8_quantize_mby(x);
510
511
0
  vp8_inverse_transform_mby(&x->e_mbd);
512
0
}