Coverage Report

Created: 2026-04-12 06:11

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
235M
void vp8_subtract_b(BLOCK *be, BLOCKD *bd, int pitch) {
24
235M
  unsigned char *src_ptr = (*(be->base_src) + be->src);
25
235M
  short *diff_ptr = be->src_diff;
26
235M
  unsigned char *pred_ptr = bd->predictor;
27
235M
  int src_stride = be->src_stride;
28
29
235M
  vpx_subtract_block(4, 4, diff_ptr, pitch, src_ptr, src_stride, pred_ptr,
30
235M
                     pitch);
31
235M
}
32
33
void vp8_subtract_mbuv(short *diff, unsigned char *usrc, unsigned char *vsrc,
34
                       int src_stride, unsigned char *upred,
35
8.94M
                       unsigned char *vpred, int pred_stride) {
36
8.94M
  short *udiff = diff + 256;
37
8.94M
  short *vdiff = diff + 320;
38
39
8.94M
  vpx_subtract_block(8, 8, udiff, 8, usrc, src_stride, upred, pred_stride);
40
8.94M
  vpx_subtract_block(8, 8, vdiff, 8, vsrc, src_stride, vpred, pred_stride);
41
8.94M
}
42
43
void vp8_subtract_mby(short *diff, unsigned char *src, int src_stride,
44
7.68M
                      unsigned char *pred, int pred_stride) {
45
7.68M
  vpx_subtract_block(16, 16, diff, 16, src, src_stride, pred, pred_stride);
46
7.68M
}
47
48
828k
static void vp8_subtract_mb(MACROBLOCK *x) {
49
828k
  BLOCK *b = &x->block[0];
50
51
828k
  vp8_subtract_mby(x->src_diff, *(b->base_src), b->src_stride,
52
828k
                   x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride);
53
828k
  vp8_subtract_mbuv(x->src_diff, x->src.u_buffer, x->src.v_buffer,
54
828k
                    x->src.uv_stride, x->e_mbd.dst.u_buffer,
55
828k
                    x->e_mbd.dst.v_buffer, x->e_mbd.dst.uv_stride);
56
828k
}
57
58
943k
static void build_dcblock(MACROBLOCK *x) {
59
943k
  short *src_diff_ptr = &x->src_diff[384];
60
943k
  int i;
61
62
16.0M
  for (i = 0; i < 16; ++i) {
63
15.0M
    src_diff_ptr[i] = x->coeff[i * 16];
64
15.0M
  }
65
943k
}
66
67
8.11M
void vp8_transform_mbuv(MACROBLOCK *x) {
68
8.11M
  int i;
69
70
40.5M
  for (i = 16; i < 24; i += 2) {
71
32.4M
    x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16);
72
32.4M
  }
73
8.11M
}
74
75
307k
void vp8_transform_intra_mby(MACROBLOCK *x) {
76
307k
  int i;
77
78
2.76M
  for (i = 0; i < 16; i += 2) {
79
2.46M
    x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
80
2.46M
  }
81
82
  /* build dc block from 16 y dc values */
83
307k
  build_dcblock(x);
84
85
  /* do 2nd order transform on the dc block */
86
307k
  x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
87
307k
}
88
89
828k
static void transform_mb(MACROBLOCK *x) {
90
828k
  int i;
91
92
7.45M
  for (i = 0; i < 16; i += 2) {
93
6.62M
    x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 32);
94
6.62M
  }
95
96
  /* build dc block from 16 y dc values */
97
828k
  if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) build_dcblock(x);
98
99
4.14M
  for (i = 16; i < 24; i += 2) {
100
3.31M
    x->short_fdct8x4(&x->block[i].src_diff[0], &x->block[i].coeff[0], 16);
101
3.31M
  }
102
103
  /* do 2nd order transform on the dc block */
104
828k
  if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV) {
105
635k
    x->short_walsh4x4(&x->block[24].src_diff[0], &x->block[24].coeff[0], 8);
106
635k
  }
107
828k
}
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
135M
#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
18.9M
                       ENTROPY_CONTEXT *l) {
145
18.9M
  BLOCK *b;
146
18.9M
  BLOCKD *d;
147
18.9M
  vp8_token_state tokens[17][2];
148
18.9M
  unsigned best_mask[2];
149
18.9M
  const short *dequant_ptr;
150
18.9M
  const short *coeff_ptr;
151
18.9M
  short *qcoeff_ptr;
152
18.9M
  short *dqcoeff_ptr;
153
18.9M
  int eob;
154
18.9M
  int i0;
155
18.9M
  int rc;
156
18.9M
  int x;
157
18.9M
  int sz = 0;
158
18.9M
  int next;
159
18.9M
  int rdmult;
160
18.9M
  int rddiv;
161
18.9M
  int final_eob;
162
18.9M
  int rd_cost0;
163
18.9M
  int rd_cost1;
164
18.9M
  int rate0;
165
18.9M
  int rate1;
166
18.9M
  int error0;
167
18.9M
  int error1;
168
18.9M
  int t0;
169
18.9M
  int t1;
170
18.9M
  int best;
171
18.9M
  int band;
172
18.9M
  int pt;
173
18.9M
  int i;
174
18.9M
  int err_mult = plane_rd_mult[type];
175
176
18.9M
  b = &mb->block[ib];
177
18.9M
  d = &mb->e_mbd.block[ib];
178
179
18.9M
  dequant_ptr = d->dequant;
180
18.9M
  coeff_ptr = b->coeff;
181
18.9M
  qcoeff_ptr = d->qcoeff;
182
18.9M
  dqcoeff_ptr = d->dqcoeff;
183
18.9M
  i0 = !type;
184
18.9M
  eob = *d->eob;
185
186
  /* Now set up a Viterbi trellis to evaluate alternative roundings. */
187
18.9M
  rdmult = mb->rdmult * err_mult;
188
18.9M
  if (mb->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME) {
189
6.92M
    rdmult = (rdmult * 9) >> 4;
190
6.92M
  }
191
192
18.9M
  rddiv = mb->rddiv;
193
18.9M
  best_mask[0] = best_mask[1] = 0;
194
  /* Initialize the sentinel node of the trellis. */
195
18.9M
  tokens[eob][0].rate = 0;
196
18.9M
  tokens[eob][0].error = 0;
197
18.9M
  tokens[eob][0].next = 16;
198
18.9M
  tokens[eob][0].token = DCT_EOB_TOKEN;
199
18.9M
  tokens[eob][0].qc = 0;
200
18.9M
  *(tokens[eob] + 1) = *(tokens[eob] + 0);
201
18.9M
  next = eob;
202
80.6M
  for (i = eob; i-- > i0;) {
203
61.7M
    int base_bits;
204
61.7M
    int d2;
205
61.7M
    int dx;
206
207
61.7M
    rc = vp8_default_zig_zag1d[i];
208
61.7M
    x = qcoeff_ptr[rc];
209
    /* Only add a trellis state for non-zero coefficients. */
210
61.7M
    if (x) {
211
39.8M
      int shortcut = 0;
212
39.8M
      error0 = tokens[next][0].error;
213
39.8M
      error1 = tokens[next][1].error;
214
      /* Evaluate the first possibility for this state. */
215
39.8M
      rate0 = tokens[next][0].rate;
216
39.8M
      rate1 = tokens[next][1].rate;
217
39.8M
      t0 = (vp8_dct_value_tokens_ptr + x)->Token;
218
      /* Consider both possible successor states. */
219
39.8M
      if (next < 16) {
220
38.0M
        band = vp8_coef_bands[i + 1];
221
38.0M
        pt = vp8_prev_token_class[t0];
222
38.0M
        rate0 += mb->token_costs[type][band][pt][tokens[next][0].token];
223
38.0M
        rate1 += mb->token_costs[type][band][pt][tokens[next][1].token];
224
38.0M
      }
225
39.8M
      rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
226
39.8M
      rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
227
39.8M
      if (rd_cost0 == rd_cost1) {
228
25.8M
        rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
229
25.8M
        rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
230
25.8M
      }
231
      /* And pick the best. */
232
39.8M
      best = rd_cost1 < rd_cost0;
233
39.8M
      base_bits = *(vp8_dct_value_cost_ptr + x);
234
39.8M
      dx = dqcoeff_ptr[rc] - coeff_ptr[rc];
235
39.8M
      d2 = dx * dx;
236
39.8M
      tokens[i][0].rate = base_bits + (best ? rate1 : rate0);
237
39.8M
      tokens[i][0].error = d2 + (best ? error1 : error0);
238
39.8M
      tokens[i][0].next = next;
239
39.8M
      tokens[i][0].token = t0;
240
39.8M
      tokens[i][0].qc = x;
241
39.8M
      best_mask[0] |= best << i;
242
      /* Evaluate the second possibility for this state. */
243
39.8M
      rate0 = tokens[next][0].rate;
244
39.8M
      rate1 = tokens[next][1].rate;
245
246
39.8M
      if ((abs(x) * dequant_ptr[rc] > abs(coeff_ptr[rc])) &&
247
16.6M
          (abs(x) * dequant_ptr[rc] < abs(coeff_ptr[rc]) + dequant_ptr[rc])) {
248
16.6M
        shortcut = 1;
249
23.1M
      } else {
250
23.1M
        shortcut = 0;
251
23.1M
      }
252
253
39.8M
      if (shortcut) {
254
16.6M
        sz = -(x < 0);
255
16.6M
        x -= 2 * sz + 1;
256
16.6M
      }
257
258
      /* Consider both possible successor states. */
259
39.8M
      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.21M
        t0 =
264
6.21M
            tokens[next][0].token == DCT_EOB_TOKEN ? DCT_EOB_TOKEN : ZERO_TOKEN;
265
6.21M
        t1 =
266
6.21M
            tokens[next][1].token == DCT_EOB_TOKEN ? DCT_EOB_TOKEN : ZERO_TOKEN;
267
33.5M
      } else {
268
33.5M
        t0 = t1 = (vp8_dct_value_tokens_ptr + x)->Token;
269
33.5M
      }
270
39.8M
      if (next < 16) {
271
38.0M
        band = vp8_coef_bands[i + 1];
272
38.0M
        if (t0 != DCT_EOB_TOKEN) {
273
36.8M
          pt = vp8_prev_token_class[t0];
274
36.8M
          rate0 += mb->token_costs[type][band][pt][tokens[next][0].token];
275
36.8M
        }
276
38.0M
        if (t1 != DCT_EOB_TOKEN) {
277
36.2M
          pt = vp8_prev_token_class[t1];
278
36.2M
          rate1 += mb->token_costs[type][band][pt][tokens[next][1].token];
279
36.2M
        }
280
38.0M
      }
281
282
39.8M
      rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
283
39.8M
      rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
284
39.8M
      if (rd_cost0 == rd_cost1) {
285
25.8M
        rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
286
25.8M
        rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
287
25.8M
      }
288
      /* And pick the best. */
289
39.8M
      best = rd_cost1 < rd_cost0;
290
39.8M
      base_bits = *(vp8_dct_value_cost_ptr + x);
291
292
39.8M
      if (shortcut) {
293
16.6M
        dx -= (dequant_ptr[rc] + sz) ^ sz;
294
16.6M
        d2 = dx * dx;
295
16.6M
      }
296
39.8M
      tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
297
39.8M
      tokens[i][1].error = d2 + (best ? error1 : error0);
298
39.8M
      tokens[i][1].next = next;
299
39.8M
      tokens[i][1].token = best ? t1 : t0;
300
39.8M
      tokens[i][1].qc = x;
301
39.8M
      best_mask[1] |= best << i;
302
      /* Finally, make this the new head of the trellis. */
303
39.8M
      next = i;
304
39.8M
    }
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
21.9M
    else {
309
21.9M
      band = vp8_coef_bands[i + 1];
310
21.9M
      t0 = tokens[next][0].token;
311
21.9M
      t1 = tokens[next][1].token;
312
      /* Update the cost of each path if we're past the EOB token. */
313
21.9M
      if (t0 != DCT_EOB_TOKEN) {
314
21.9M
        tokens[next][0].rate += mb->token_costs[type][band][0][t0];
315
21.9M
        tokens[next][0].token = ZERO_TOKEN;
316
21.9M
      }
317
21.9M
      if (t1 != DCT_EOB_TOKEN) {
318
19.3M
        tokens[next][1].rate += mb->token_costs[type][band][0][t1];
319
19.3M
        tokens[next][1].token = ZERO_TOKEN;
320
19.3M
      }
321
      /* Don't update next, because we didn't add a new node. */
322
21.9M
    }
323
61.7M
  }
324
325
  /* Now pick the best path through the whole trellis. */
326
18.9M
  band = vp8_coef_bands[i + 1];
327
18.9M
  VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
328
18.9M
  rate0 = tokens[next][0].rate;
329
18.9M
  rate1 = tokens[next][1].rate;
330
18.9M
  error0 = tokens[next][0].error;
331
18.9M
  error1 = tokens[next][1].error;
332
18.9M
  t0 = tokens[next][0].token;
333
18.9M
  t1 = tokens[next][1].token;
334
18.9M
  rate0 += mb->token_costs[type][band][pt][t0];
335
18.9M
  rate1 += mb->token_costs[type][band][pt][t1];
336
18.9M
  rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
337
18.9M
  rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
338
18.9M
  if (rd_cost0 == rd_cost1) {
339
16.2M
    rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
340
16.2M
    rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
341
16.2M
  }
342
18.9M
  best = rd_cost1 < rd_cost0;
343
18.9M
  final_eob = i0 - 1;
344
58.7M
  for (i = next; i < eob; i = next) {
345
39.8M
    x = tokens[i][best].qc;
346
39.8M
    if (x) final_eob = i;
347
39.8M
    rc = vp8_default_zig_zag1d[i];
348
39.8M
    qcoeff_ptr[rc] = x;
349
39.8M
    dqcoeff_ptr[rc] = x * dequant_ptr[rc];
350
39.8M
    next = tokens[i][best].next;
351
39.8M
    best = (best_mask[best] >> i) & 1;
352
39.8M
  }
353
18.9M
  final_eob++;
354
355
18.9M
  *a = *l = (final_eob != !type);
356
18.9M
  *d->eob = (char)final_eob;
357
18.9M
}
358
static void check_reset_2nd_coeffs(MACROBLOCKD *x, int type, ENTROPY_CONTEXT *a,
359
470k
                                   ENTROPY_CONTEXT *l) {
360
470k
  int sum = 0;
361
470k
  int i;
362
470k
  BLOCKD *bd = &x->block[24];
363
364
470k
  if (bd->dequant[0] >= 35 && bd->dequant[1] >= 35) return;
365
366
464k
  for (i = 0; i < (*bd->eob); ++i) {
367
234k
    int coef = bd->dqcoeff[vp8_default_zig_zag1d[i]];
368
234k
    sum += (coef >= 0) ? coef : -coef;
369
234k
    if (sum >= 35) return;
370
234k
  }
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
229k
  if (sum < 35) {
380
362k
    for (i = 0; i < (*bd->eob); ++i) {
381
133k
      int rc = vp8_default_zig_zag1d[i];
382
133k
      bd->qcoeff[rc] = 0;
383
133k
      bd->dqcoeff[rc] = 0;
384
133k
    }
385
229k
    *bd->eob = 0;
386
229k
    *a = *l = (*bd->eob != !type);
387
229k
  }
388
229k
}
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.32M
  for (b = 0; b < 16; ++b) {
410
7.83M
    optimize_b(x, b, type, ta + vp8_block2above[b], tl + vp8_block2left[b]);
411
7.83M
  }
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
296k
    b = 24;
420
296k
    optimize_b(x, b, PLANE_TYPE_Y2, ta + vp8_block2above[b],
421
296k
               tl + vp8_block2left[b]);
422
296k
    check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2, ta + vp8_block2above[b],
423
296k
                           tl + vp8_block2left[b]);
424
296k
  }
425
489k
}
426
427
173k
void vp8_optimize_mby(MACROBLOCK *x) {
428
173k
  int b;
429
173k
  int type;
430
173k
  int has_2nd_order;
431
432
173k
  ENTROPY_CONTEXT_PLANES t_above, t_left;
433
173k
  ENTROPY_CONTEXT *ta;
434
173k
  ENTROPY_CONTEXT *tl;
435
436
173k
  if (!x->e_mbd.above_context) return;
437
438
173k
  if (!x->e_mbd.left_context) return;
439
440
173k
  t_above = *x->e_mbd.above_context;
441
173k
  t_left = *x->e_mbd.left_context;
442
443
173k
  ta = (ENTROPY_CONTEXT *)&t_above;
444
173k
  tl = (ENTROPY_CONTEXT *)&t_left;
445
446
173k
  has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED &&
447
173k
                   x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
448
173k
  type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
449
450
2.95M
  for (b = 0; b < 16; ++b) {
451
2.77M
    optimize_b(x, b, type, ta + vp8_block2above[b], tl + vp8_block2left[b]);
452
2.77M
  }
453
454
173k
  if (has_2nd_order) {
455
173k
    b = 24;
456
173k
    optimize_b(x, b, PLANE_TYPE_Y2, ta + vp8_block2above[b],
457
173k
               tl + vp8_block2left[b]);
458
173k
    check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2, ta + vp8_block2above[b],
459
173k
                           tl + vp8_block2left[b]);
460
173k
  }
461
173k
}
462
463
497k
void vp8_optimize_mbuv(MACROBLOCK *x) {
464
497k
  int b;
465
497k
  ENTROPY_CONTEXT_PLANES t_above, t_left;
466
497k
  ENTROPY_CONTEXT *ta;
467
497k
  ENTROPY_CONTEXT *tl;
468
469
497k
  if (!x->e_mbd.above_context) return;
470
471
497k
  if (!x->e_mbd.left_context) return;
472
473
497k
  t_above = *x->e_mbd.above_context;
474
497k
  t_left = *x->e_mbd.left_context;
475
476
497k
  ta = (ENTROPY_CONTEXT *)&t_above;
477
497k
  tl = (ENTROPY_CONTEXT *)&t_left;
478
479
4.47M
  for (b = 16; b < 24; ++b) {
480
3.97M
    optimize_b(x, b, PLANE_TYPE_UV, ta + vp8_block2above[b],
481
3.97M
               tl + vp8_block2left[b]);
482
3.97M
  }
483
497k
}
484
485
828k
void vp8_encode_inter16x16(MACROBLOCK *x) {
486
828k
  vp8_build_inter_predictors_mb(&x->e_mbd);
487
488
828k
  vp8_subtract_mb(x);
489
490
828k
  transform_mb(x);
491
492
828k
  vp8_quantize_mb(x);
493
494
828k
  if (x->optimize) optimize_mb(x);
495
828k
}
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
}