encodemb.c 17.4 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_config.h"
John Koleszar's avatar
John Koleszar committed
13
#include "vpx_rtcd.h"
John Koleszar's avatar
John Koleszar committed
14
#include "encodemb.h"
John Koleszar's avatar
John Koleszar committed
15
#include "vp8/common/reconinter.h"
John Koleszar's avatar
John Koleszar committed
16
#include "quantize.h"
17
#include "tokenize.h"
John Koleszar's avatar
John Koleszar committed
18
#include "vp8/common/invtrans.h"
John Koleszar's avatar
John Koleszar committed
19
#include "vpx_mem/vpx_mem.h"
Yunqing Wang's avatar
Yunqing Wang committed
20
#include "rdopt.h"
John Koleszar's avatar
John Koleszar committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

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;
    }
}

44 45 46
void vp8_subtract_mbuv_c(short *diff, unsigned char *usrc, unsigned char *vsrc,
                         int src_stride, unsigned char *upred,
                         unsigned char *vpred, int pred_stride)
John Koleszar's avatar
John Koleszar committed
47 48 49 50 51 52 53 54 55 56 57 58 59 60
{
    short *udiff = diff + 256;
    short *vdiff = diff + 320;

    int r, c;

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

        udiff += 8;
61 62
        upred += pred_stride;
        usrc  += src_stride;
John Koleszar's avatar
John Koleszar committed
63 64 65 66 67 68 69 70 71 72
    }

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

        vdiff += 8;
73 74
        vpred += pred_stride;
        vsrc  += src_stride;
John Koleszar's avatar
John Koleszar committed
75 76 77
    }
}

78 79
void vp8_subtract_mby_c(short *diff, unsigned char *src, int src_stride,
                        unsigned char *pred, int pred_stride)
John Koleszar's avatar
John Koleszar committed
80 81 82 83 84 85 86 87 88 89 90
{
    int r, c;

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

        diff += 16;
91 92
        pred += pred_stride;
        src  += src_stride;
John Koleszar's avatar
John Koleszar committed
93 94 95
    }
}

John Koleszar's avatar
John Koleszar committed
96
static void vp8_subtract_mb(MACROBLOCK *x)
John Koleszar's avatar
John Koleszar committed
97
{
98 99
    BLOCK *b = &x->block[0];

100
    vp8_subtract_mby(x->src_diff, *(b->base_src),
101
        b->src_stride, x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride);
102
    vp8_subtract_mbuv(x->src_diff, x->src.u_buffer,
103 104
        x->src.v_buffer, x->src.uv_stride, x->e_mbd.dst.u_buffer,
        x->e_mbd.dst.v_buffer, x->e_mbd.dst.uv_stride);
John Koleszar's avatar
John Koleszar committed
105 106
}

107
static void build_dcblock(MACROBLOCK *x)
John Koleszar's avatar
John Koleszar committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
{
    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)
    {
John Koleszar's avatar
John Koleszar committed
124
        x->short_fdct8x4(&x->block[i].src_diff[0],
Yaowu Xu's avatar
Yaowu Xu committed
125
            &x->block[i].coeff[0], 16);
John Koleszar's avatar
John Koleszar committed
126 127 128
    }
}

Yaowu Xu's avatar
Yaowu Xu committed
129

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

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

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

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

}


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

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

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

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

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

}

177 178

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

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

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



199 200 201 202 203 204 205 206 207 208 209 210
#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;
};

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

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

224
static void optimize_b(MACROBLOCK *mb, int ib, int type,
John Koleszar's avatar
John Koleszar committed
225
                       ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
John Koleszar's avatar
John Koleszar committed
226
{
227 228 229 230 231 232 233 234 235 236 237 238
    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;
Johann's avatar
Johann committed
239
    int sz = 0;
240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
    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;
255 256
    int i;
    int err_mult = plane_rd_mult[type];
257

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

    /* 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
267

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

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

280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299
    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
300
        {
301 302 303 304 305 306 307 308 309
            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
310
            {
311 312 313 314 315 316
                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
317
            }
318 319 320
            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
321
            {
322 323
                rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
                rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
John Koleszar's avatar
John Koleszar committed
324
            }
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
            /* 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
347
            {
348 349 350
                sz = -(x < 0);
                x -= 2*sz + 1;
            }
John Koleszar's avatar
John Koleszar committed
351

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

384 385 386
            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
387
            {
388 389
                rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
                rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
John Koleszar's avatar
John Koleszar committed
390
            }
391 392 393
            /* And pick the best. */
            best = rd_cost1 < rd_cost0;
            base_bits = *(vp8_dct_value_cost_ptr + x);
John Koleszar's avatar
John Koleszar committed
394

395
            if(shortcut)
John Koleszar's avatar
John Koleszar committed
396
            {
397 398
                dx -= (dequant_ptr[rc] + sz) ^ sz;
                d2 = dx*dx;
John Koleszar's avatar
John Koleszar committed
399
            }
400 401 402 403 404 405 406 407
            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
408
        }
409 410 411
        /* 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
412 413
        else
        {
414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
            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
429 430 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
    /* 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++;

465 466
    *a = *l = (final_eob != !type);
    *d->eob = (char)final_eob;
John Koleszar's avatar
John Koleszar committed
467
}
468 469 470 471 472 473 474 475 476 477
static void check_reset_2nd_coeffs(MACROBLOCKD *x, int type,
                                   ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
{
    int sum=0;
    int i;
    BLOCKD *bd = &x->block[24];

    if(bd->dequant[0]>=35 && bd->dequant[1]>=35)
        return;

478
    for(i=0;i<(*bd->eob);i++)
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
    {
        int coef = bd->dqcoeff[vp8_default_zig_zag1d[i]];
        sum+= (coef>=0)?coef:-coef;
        if(sum>=35)
            return;
    }
    /**************************************************************************
    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+3)>>3. And
    dc only idct is (dc+4)>>3. So if all the sums are between -35 and 29, the
    output after inverse wht and idct will be all zero. A sum of absolute value
    smaller than 35 guarantees all 16 different (+1/-1) weighted sums in wht
    fall between -35 and +35.
    **************************************************************************/
    if(sum < 35)
    {
495
        for(i=0;i<(*bd->eob);i++)
496 497 498 499 500
        {
            int rc = vp8_default_zig_zag1d[i];
            bd->qcoeff[rc]=0;
            bd->dqcoeff[rc]=0;
        }
501 502
        *bd->eob = 0;
        *a = *l = (*bd->eob != !type);
503 504
    }
}
John Koleszar's avatar
John Koleszar committed
505

John Koleszar's avatar
John Koleszar committed
506
static void optimize_mb(MACROBLOCK *x)
John Koleszar's avatar
John Koleszar committed
507 508
{
    int b;
509 510
    int type;
    int has_2nd_order;
511

512 513 514 515 516 517 518 519 520
    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
521

522 523
    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
524
    type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
John Koleszar's avatar
John Koleszar committed
525 526 527

    for (b = 0; b < 16; b++)
    {
528
        optimize_b(x, b, type,
John Koleszar's avatar
John Koleszar committed
529
            ta + vp8_block2above[b], tl + vp8_block2left[b]);
John Koleszar's avatar
John Koleszar committed
530 531
    }

Scott LaVarnway's avatar
Scott LaVarnway committed
532
    for (b = 16; b < 24; b++)
John Koleszar's avatar
John Koleszar committed
533
    {
534
        optimize_b(x, b, PLANE_TYPE_UV,
John Koleszar's avatar
John Koleszar committed
535
            ta + vp8_block2above[b], tl + vp8_block2left[b]);
John Koleszar's avatar
John Koleszar committed
536 537
    }

538 539
    if (has_2nd_order)
    {
540
        b=24;
541
        optimize_b(x, b, PLANE_TYPE_Y2,
John Koleszar's avatar
John Koleszar committed
542
            ta + vp8_block2above[b], tl + vp8_block2left[b]);
543 544
        check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2,
            ta + vp8_block2above[b], tl + vp8_block2left[b]);
John Koleszar's avatar
John Koleszar committed
545 546 547 548
    }
}


John Koleszar's avatar
John Koleszar committed
549
void vp8_optimize_mby(MACROBLOCK *x)
John Koleszar's avatar
John Koleszar committed
550 551
{
    int b;
552 553
    int type;
    int has_2nd_order;
John Koleszar's avatar
John Koleszar committed
554

555 556 557 558 559
    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
560 561
        return;

562
    if (!x->e_mbd.left_context)
John Koleszar's avatar
John Koleszar committed
563
        return;
564 565 566 567 568 569 570

    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;

571 572
    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
573
    type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
John Koleszar's avatar
John Koleszar committed
574 575 576

    for (b = 0; b < 16; b++)
    {
577
        optimize_b(x, b, type,
John Koleszar's avatar
John Koleszar committed
578
            ta + vp8_block2above[b], tl + vp8_block2left[b]);
John Koleszar's avatar
John Koleszar committed
579 580
    }

581

582 583
    if (has_2nd_order)
    {
584
        b=24;
585
        optimize_b(x, b, PLANE_TYPE_Y2,
John Koleszar's avatar
John Koleszar committed
586
            ta + vp8_block2above[b], tl + vp8_block2left[b]);
587 588
        check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2,
            ta + vp8_block2above[b], tl + vp8_block2left[b]);
589
    }
John Koleszar's avatar
John Koleszar committed
590 591
}

John Koleszar's avatar
John Koleszar committed
592
void vp8_optimize_mbuv(MACROBLOCK *x)
John Koleszar's avatar
John Koleszar committed
593 594
{
    int b;
595 596 597
    ENTROPY_CONTEXT_PLANES t_above, t_left;
    ENTROPY_CONTEXT *ta;
    ENTROPY_CONTEXT *tl;
John Koleszar's avatar
John Koleszar committed
598

599
    if (!x->e_mbd.above_context)
John Koleszar's avatar
John Koleszar committed
600 601
        return;

602
    if (!x->e_mbd.left_context)
John Koleszar's avatar
John Koleszar committed
603 604
        return;

605 606
    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
607

608 609
    ta = (ENTROPY_CONTEXT *)&t_above;
    tl = (ENTROPY_CONTEXT *)&t_left;
John Koleszar's avatar
John Koleszar committed
610

Scott LaVarnway's avatar
Scott LaVarnway committed
611
    for (b = 16; b < 24; b++)
John Koleszar's avatar
John Koleszar committed
612
    {
613
        optimize_b(x, b, PLANE_TYPE_UV,
John Koleszar's avatar
John Koleszar committed
614
            ta + vp8_block2above[b], tl + vp8_block2left[b]);
John Koleszar's avatar
John Koleszar committed
615 616 617
    }
}

John Koleszar's avatar
John Koleszar committed
618
void vp8_encode_inter16x16(MACROBLOCK *x)
John Koleszar's avatar
John Koleszar committed
619
{
620
    vp8_build_inter_predictors_mb(&x->e_mbd);
John Koleszar's avatar
John Koleszar committed
621

John Koleszar's avatar
John Koleszar committed
622
    vp8_subtract_mb(x);
John Koleszar's avatar
John Koleszar committed
623

624
    transform_mb(x);
John Koleszar's avatar
John Koleszar committed
625 626 627

    vp8_quantize_mb(x);

628
    if (x->optimize)
John Koleszar's avatar
John Koleszar committed
629
        optimize_mb(x);
John Koleszar's avatar
John Koleszar committed
630 631 632
}

/* this funciton is used by first pass only */
John Koleszar's avatar
John Koleszar committed
633
void vp8_encode_inter16x16y(MACROBLOCK *x)
John Koleszar's avatar
John Koleszar committed
634
{
635 636
    BLOCK *b = &x->block[0];

637 638
    vp8_build_inter16x16_predictors_mby(&x->e_mbd, x->e_mbd.dst.y_buffer,
                                        x->e_mbd.dst.y_stride);
John Koleszar's avatar
John Koleszar committed
639

640
    vp8_subtract_mby(x->src_diff, *(b->base_src),
641
        b->src_stride, x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride);
John Koleszar's avatar
John Koleszar committed
642

643
    transform_mby(x);
John Koleszar's avatar
John Koleszar committed
644 645 646

    vp8_quantize_mby(x);

John Koleszar's avatar
John Koleszar committed
647
    vp8_inverse_transform_mby(&x->e_mbd);
John Koleszar's avatar
John Koleszar committed
648
}