encodemb.c 16.7 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
13
 */


#include "vpx_ports/config.h"
#include "encodemb.h"
John Koleszar's avatar
John Koleszar committed
14
#include "vp8/common/reconinter.h"
John Koleszar's avatar
John Koleszar committed
15
#include "quantize.h"
16
#include "tokenize.h"
John Koleszar's avatar
John Koleszar committed
17
18
19
#include "vp8/common/invtrans.h"
#include "vp8/common/recon.h"
#include "vp8/common/reconintra.h"
John Koleszar's avatar
John Koleszar committed
20
21
#include "dct.h"
#include "vpx_mem/vpx_mem.h"
Yunqing Wang's avatar
Yunqing Wang committed
22
#include "rdopt.h"
John Koleszar's avatar
John Koleszar committed
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

#if CONFIG_RUNTIME_CPU_DETECT
#define IF_RTCD(x) (x)
#else
#define IF_RTCD(x) NULL
#endif
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;

    for (r = 0; r < 4; r++)
    {
        for (c = 0; c < 4; c++)
        {
            diff_ptr[c] = src_ptr[c] - pred_ptr[c];
        }

        diff_ptr += pitch;
        pred_ptr += pitch;
        src_ptr  += src_stride;
    }
}

void vp8_subtract_mbuv_c(short *diff, unsigned char *usrc, unsigned char *vsrc, unsigned char *pred, int stride)
{
    short *udiff = diff + 256;
    short *vdiff = diff + 320;
    unsigned char *upred = pred + 256;
    unsigned char *vpred = pred + 320;

    int r, c;

    for (r = 0; r < 8; r++)
    {
        for (c = 0; c < 8; c++)
        {
            udiff[c] = usrc[c] - upred[c];
        }

        udiff += 8;
        upred += 8;
        usrc  += stride;
    }

    for (r = 0; r < 8; r++)
    {
        for (c = 0; c < 8; c++)
        {
            vdiff[c] = vsrc[c] - vpred[c];
        }

        vdiff += 8;
        vpred += 8;
        vsrc  += stride;
    }
}

void vp8_subtract_mby_c(short *diff, unsigned char *src, unsigned char *pred, int stride)
{
    int r, c;

    for (r = 0; r < 16; r++)
    {
        for (c = 0; c < 16; c++)
        {
            diff[c] = src[c] - pred[c];
        }

        diff += 16;
        pred += 16;
        src  += stride;
    }
}

static void vp8_subtract_mb(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, x->src.y_buffer, x->e_mbd.predictor, x->src.y_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);
}

108
static void build_dcblock(MACROBLOCK *x)
John Koleszar's avatar
John Koleszar committed
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
{
    short *src_diff_ptr = &x->src_diff[384];
    int i;

    for (i = 0; i < 16; i++)
    {
        src_diff_ptr[i] = x->coeff[i * 16];
    }
}

void vp8_transform_mbuv(MACROBLOCK *x)
{
    int i;

    for (i = 16; i < 24; i += 2)
    {
125
        x->vp8_short_fdct8x4(&x->block[i].src_diff[0],
Yaowu Xu's avatar
Yaowu Xu committed
126
            &x->block[i].coeff[0], 16);
John Koleszar's avatar
John Koleszar committed
127
128
129
    }
}

Yaowu Xu's avatar
Yaowu Xu committed
130

John Koleszar's avatar
John Koleszar committed
131
132
133
134
135
136
void vp8_transform_intra_mby(MACROBLOCK *x)
{
    int i;

    for (i = 0; i < 16; i += 2)
    {
Yaowu Xu's avatar
Yaowu Xu committed
137
138
        x->vp8_short_fdct8x4(&x->block[i].src_diff[0],
            &x->block[i].coeff[0], 32);
John Koleszar's avatar
John Koleszar committed
139
140
141
    }

    // build dc block from 16 y dc values
142
    build_dcblock(x);
John Koleszar's avatar
John Koleszar committed
143
144

    // do 2nd order transform on the dc block
Yaowu Xu's avatar
Yaowu Xu committed
145
146
    x->short_walsh4x4(&x->block[24].src_diff[0],
        &x->block[24].coeff[0], 8);
John Koleszar's avatar
John Koleszar committed
147
148
149
150

}


151
static void transform_mb(MACROBLOCK *x)
John Koleszar's avatar
John Koleszar committed
152
153
154
155
156
{
    int i;

    for (i = 0; i < 16; i += 2)
    {
Yaowu Xu's avatar
Yaowu Xu committed
157
158
        x->vp8_short_fdct8x4(&x->block[i].src_diff[0],
            &x->block[i].coeff[0], 32);
John Koleszar's avatar
John Koleszar committed
159
160
161
    }

    // build dc block from 16 y dc values
162
    if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
163
        build_dcblock(x);
John Koleszar's avatar
John Koleszar committed
164
165
166

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

    // do 2nd order transform on the dc block
172
    if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
Yaowu Xu's avatar
Yaowu Xu committed
173
174
        x->short_walsh4x4(&x->block[24].src_diff[0],
        &x->block[24].coeff[0], 8);
John Koleszar's avatar
John Koleszar committed
175
176
177

}

178
179

static void transform_mby(MACROBLOCK *x)
John Koleszar's avatar
John Koleszar committed
180
181
182
183
184
{
    int i;

    for (i = 0; i < 16; i += 2)
    {
Yaowu Xu's avatar
Yaowu Xu committed
185
186
        x->vp8_short_fdct8x4(&x->block[i].src_diff[0],
            &x->block[i].coeff[0], 32);
John Koleszar's avatar
John Koleszar committed
187
188
189
    }

    // build dc block from 16 y dc values
190
    if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
John Koleszar's avatar
John Koleszar committed
191
    {
192
        build_dcblock(x);
Yaowu Xu's avatar
Yaowu Xu committed
193
194
        x->short_walsh4x4(&x->block[24].src_diff[0],
            &x->block[24].coeff[0], 8);
John Koleszar's avatar
John Koleszar committed
195
196
197
198
199
    }
}



200
201
202
203
204
205
206
207
208
209
210
211
#define RDTRUNC(RM,DM,R,D) ( (128+(R)*(RM)) & 0xFF )

typedef struct vp8_token_state vp8_token_state;

struct vp8_token_state{
  int           rate;
  int           error;
  signed char   next;
  signed char   token;
  short         qc;
};

212
// TODO: experiments to find optimal multiple numbers
213
214
215
#define Y1_RD_MULT 4
#define UV_RD_MULT 2
#define Y2_RD_MULT 16
216
217
218
219
220
221
222
223
224

static const int plane_rd_mult[4]=
{
    Y1_RD_MULT,
    Y2_RD_MULT,
    UV_RD_MULT,
    Y1_RD_MULT
};

225
226
227
static void optimize_b(MACROBLOCK *mb, int ib, int type,
                       ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
                       const VP8_ENCODER_RTCD *rtcd)
John Koleszar's avatar
John Koleszar committed
228
{
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
    BLOCK *b;
    BLOCKD *d;
    vp8_token_state tokens[17][2];
    unsigned best_mask[2];
    const short *dequant_ptr;
    const short *coeff_ptr;
    short *qcoeff_ptr;
    short *dqcoeff_ptr;
    int eob;
    int i0;
    int rc;
    int x;
    int sz;
    int next;
    int rdmult;
    int rddiv;
    int final_eob;
    int rd_cost0;
    int rd_cost1;
    int rate0;
    int rate1;
    int error0;
    int error1;
    int t0;
    int t1;
    int best;
    int band;
    int pt;
257
258
    int i;
    int err_mult = plane_rd_mult[type];
259

260
261
    b = &mb->block[ib];
    d = &mb->e_mbd.block[ib];
262
263
264
265
266
267
268

    /* Enable this to test the effect of RDO as a replacement for the dynamic
     *  zero bin instead of an augmentation of it.
     */
#if 0
    vp8_strict_quantize_b(b, d);
#endif
John Koleszar's avatar
John Koleszar committed
269

270
271
    dequant_ptr = d->dequant;
    coeff_ptr = b->coeff;
272
273
274
275
276
277
    qcoeff_ptr = d->qcoeff;
    dqcoeff_ptr = d->dqcoeff;
    i0 = !type;
    eob = d->eob;

    /* Now set up a Viterbi trellis to evaluate alternative roundings. */
278
    rdmult = mb->rdmult * err_mult;
279
280
281
    if(mb->e_mbd.mode_info_context->mbmi.ref_frame==INTRA_FRAME)
        rdmult = (rdmult * 9)>>4;

282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
    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;
    tokens[eob][0].next = 16;
    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;

        rc = vp8_default_zig_zag1d[i];
        x = qcoeff_ptr[rc];
        /* Only add a trellis state for non-zero coefficients. */
        if (x)
John Koleszar's avatar
John Koleszar committed
302
        {
303
304
305
306
307
308
309
310
311
            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 < 16)
John Koleszar's avatar
John Koleszar committed
312
            {
313
314
315
316
317
318
                band = vp8_coef_bands[i + 1];
                pt = vp8_prev_token_class[t0];
                rate0 +=
                    mb->token_costs[type][band][pt][tokens[next][0].token];
                rate1 +=
                    mb->token_costs[type][band][pt][tokens[next][1].token];
John Koleszar's avatar
John Koleszar committed
319
            }
320
321
322
            rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
            rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
            if (rd_cost0 == rd_cost1)
John Koleszar's avatar
John Koleszar committed
323
            {
324
325
                rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
                rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
John Koleszar's avatar
John Koleszar committed
326
            }
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
            /* 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;

            if((abs(x)*dequant_ptr[rc]>abs(coeff_ptr[rc])) &&
               (abs(x)*dequant_ptr[rc]<abs(coeff_ptr[rc])+dequant_ptr[rc]))
                shortcut = 1;
            else
                shortcut = 0;

            if(shortcut)
John Koleszar's avatar
John Koleszar committed
349
            {
350
351
352
                sz = -(x < 0);
                x -= 2*sz + 1;
            }
John Koleszar's avatar
John Koleszar committed
353

354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
            /* 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 < 16)
            {
                band = vp8_coef_bands[i + 1];
                if(t0!=DCT_EOB_TOKEN)
John Koleszar's avatar
John Koleszar committed
373
                {
374
375
376
                    pt = vp8_prev_token_class[t0];
                    rate0 += mb->token_costs[type][band][pt][
                        tokens[next][0].token];
John Koleszar's avatar
John Koleszar committed
377
                }
378
                if(t1!=DCT_EOB_TOKEN)
John Koleszar's avatar
John Koleszar committed
379
                {
380
381
382
                    pt = vp8_prev_token_class[t1];
                    rate1 += mb->token_costs[type][band][pt][
                        tokens[next][1].token];
John Koleszar's avatar
John Koleszar committed
383
384
385
                }
            }

386
387
388
            rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
            rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
            if (rd_cost0 == rd_cost1)
John Koleszar's avatar
John Koleszar committed
389
            {
390
391
                rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
                rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
John Koleszar's avatar
John Koleszar committed
392
            }
393
394
395
            /* And pick the best. */
            best = rd_cost1 < rd_cost0;
            base_bits = *(vp8_dct_value_cost_ptr + x);
John Koleszar's avatar
John Koleszar committed
396

397
            if(shortcut)
John Koleszar's avatar
John Koleszar committed
398
            {
399
400
                dx -= (dequant_ptr[rc] + sz) ^ sz;
                d2 = dx*dx;
John Koleszar's avatar
John Koleszar committed
401
            }
402
403
404
405
406
407
408
409
            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;
John Koleszar's avatar
John Koleszar committed
410
        }
411
412
413
        /* 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.
         */
John Koleszar's avatar
John Koleszar committed
414
415
        else
        {
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
            band = vp8_coef_bands[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)
            {
                tokens[next][0].rate += mb->token_costs[type][band][0][t0];
                tokens[next][0].token = ZERO_TOKEN;
            }
            if (t1 != DCT_EOB_TOKEN)
            {
                tokens[next][1].rate += mb->token_costs[type][band][0][t1];
                tokens[next][1].token = ZERO_TOKEN;
            }
            /* Don't update next, because we didn't add a new node. */
John Koleszar's avatar
John Koleszar committed
431
432
433
        }
    }

434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
    /* Now pick the best path through the whole trellis. */
    band = vp8_coef_bands[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;
    rate0 += mb->token_costs[type][band][pt][t0];
    rate1 += mb->token_costs[type][band][pt][t1];
    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);
    }
    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;
        rc = vp8_default_zig_zag1d[i];
        qcoeff_ptr[rc] = x;
        dqcoeff_ptr[rc] = x * dequant_ptr[rc];
        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
469
470
}

471
static void optimize_mb(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
John Koleszar's avatar
John Koleszar committed
472
473
{
    int b;
474
475
    int type;
    int has_2nd_order;
476
477
478
479
480
481
482
483
484
    ENTROPY_CONTEXT_PLANES t_above, t_left;
    ENTROPY_CONTEXT *ta;
    ENTROPY_CONTEXT *tl;

    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;
John Koleszar's avatar
John Koleszar committed
485

486
487
    has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
        && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
Scott LaVarnway's avatar
Scott LaVarnway committed
488
    type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
John Koleszar's avatar
John Koleszar committed
489
490
491

    for (b = 0; b < 16; b++)
    {
492
        optimize_b(x, b, type,
493
            ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd);
John Koleszar's avatar
John Koleszar committed
494
495
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
496
    for (b = 16; b < 24; b++)
John Koleszar's avatar
John Koleszar committed
497
    {
498
        optimize_b(x, b, PLANE_TYPE_UV,
499
            ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd);
John Koleszar's avatar
John Koleszar committed
500
501
    }

502
503
    if (has_2nd_order)
    {
504
        b=24;
505
        optimize_b(x, b, PLANE_TYPE_Y2,
506
            ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd);
John Koleszar's avatar
John Koleszar committed
507
508
509
510
511
512
513
    }
}


void vp8_optimize_mby(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
{
    int b;
514
515
    int type;
    int has_2nd_order;
John Koleszar's avatar
John Koleszar committed
516

517
518
519
520
521
    ENTROPY_CONTEXT_PLANES t_above, t_left;
    ENTROPY_CONTEXT *ta;
    ENTROPY_CONTEXT *tl;

    if (!x->e_mbd.above_context)
John Koleszar's avatar
John Koleszar committed
522
523
        return;

524
    if (!x->e_mbd.left_context)
John Koleszar's avatar
John Koleszar committed
525
        return;
526
527
528
529
530
531
532

    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;

533
534
    has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
        && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
Scott LaVarnway's avatar
Scott LaVarnway committed
535
    type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
John Koleszar's avatar
John Koleszar committed
536
537
538

    for (b = 0; b < 16; b++)
    {
539
        optimize_b(x, b, type,
540
        ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd);
John Koleszar's avatar
John Koleszar committed
541
542
    }

543

544
545
    if (has_2nd_order)
    {
546
        b=24;
547
        optimize_b(x, b, PLANE_TYPE_Y2,
548
            ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd);
549
    }
John Koleszar's avatar
John Koleszar committed
550
551
552
553
554
}

void vp8_optimize_mbuv(MACROBLOCK *x, const VP8_ENCODER_RTCD *rtcd)
{
    int b;
555
556
557
    ENTROPY_CONTEXT_PLANES t_above, t_left;
    ENTROPY_CONTEXT *ta;
    ENTROPY_CONTEXT *tl;
John Koleszar's avatar
John Koleszar committed
558

559
    if (!x->e_mbd.above_context)
John Koleszar's avatar
John Koleszar committed
560
561
        return;

562
    if (!x->e_mbd.left_context)
John Koleszar's avatar
John Koleszar committed
563
564
        return;

565
566
    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
567

568
569
    ta = (ENTROPY_CONTEXT *)&t_above;
    tl = (ENTROPY_CONTEXT *)&t_left;
John Koleszar's avatar
John Koleszar committed
570

Scott LaVarnway's avatar
Scott LaVarnway committed
571
    for (b = 16; b < 24; b++)
John Koleszar's avatar
John Koleszar committed
572
    {
573
        optimize_b(x, b, PLANE_TYPE_UV,
574
            ta + vp8_block2above[b], tl + vp8_block2left[b], rtcd);
John Koleszar's avatar
John Koleszar committed
575
576
577
578
579
580
581
582
583
    }
}

void vp8_encode_inter16x16(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    vp8_build_inter_predictors_mb(&x->e_mbd);

    vp8_subtract_mb(rtcd, x);

584
    transform_mb(x);
John Koleszar's avatar
John Koleszar committed
585
586
587

    vp8_quantize_mb(x);

588
    if (x->optimize)
589
        optimize_mb(x, rtcd);
John Koleszar's avatar
John Koleszar committed
590
591
592

    vp8_inverse_transform_mb(IF_RTCD(&rtcd->common->idct), &x->e_mbd);

593
594
    RECON_INVOKE(&rtcd->common->recon, recon_mb)
        (IF_RTCD(&rtcd->common->recon), &x->e_mbd);
John Koleszar's avatar
John Koleszar committed
595
596
597
598
599
600
}


/* this funciton is used by first pass only */
void vp8_encode_inter16x16y(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
601
    vp8_build_inter16x16_predictors_mby(&x->e_mbd);
John Koleszar's avatar
John Koleszar committed
602
603
604

    ENCODEMB_INVOKE(&rtcd->encodemb, submby)(x->src_diff, x->src.y_buffer, x->e_mbd.predictor, x->src.y_stride);

605
    transform_mby(x);
John Koleszar's avatar
John Koleszar committed
606
607
608
609
610

    vp8_quantize_mby(x);

    vp8_inverse_transform_mby(IF_RTCD(&rtcd->common->idct), &x->e_mbd);

611
612
    RECON_INVOKE(&rtcd->common->recon, recon_mby)
        (IF_RTCD(&rtcd->common->recon), &x->e_mbd);
John Koleszar's avatar
John Koleszar committed
613
614
615
616
617
618
619
620
}


void vp8_encode_inter16x16uvrd(const VP8_ENCODER_RTCD *rtcd, MACROBLOCK *x)
{
    vp8_build_inter_predictors_mbuv(&x->e_mbd);
    ENCODEMB_INVOKE(&rtcd->encodemb, submbuv)(x->src_diff, x->src.u_buffer, x->src.v_buffer, x->e_mbd.predictor, x->src.uv_stride);

Yaowu Xu's avatar
Yaowu Xu committed
621
    vp8_transform_mbuv(x);
John Koleszar's avatar
John Koleszar committed
622

623
    vp8_quantize_mbuv(x);
John Koleszar's avatar
John Koleszar committed
624
625

}