190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/*
2f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
4f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Use of this source code is governed by a BSD-style license
5f71323e297a928af368937089d3ed71239786f86Andreas Huber *  that can be found in the LICENSE file in the root of the source
6f71323e297a928af368937089d3ed71239786f86Andreas Huber *  tree. An additional intellectual property rights grant can be found
7f71323e297a928af368937089d3ed71239786f86Andreas Huber *  in the file PATENTS.  All contributing project authors may
8f71323e297a928af368937089d3ed71239786f86Andreas Huber *  be found in the AUTHORS file in the root of the source tree.
990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
1090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
121b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_config.h"
131b362b15af34006e6a11974088a46d42b903418eJohann#include "vpx_rtcd.h"
1490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "encodemb.h"
1579f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/reconinter.h"
1690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "quantize.h"
17f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "tokenize.h"
1879f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "vp8/common/invtrans.h"
1990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "vpx_mem/vpx_mem.h"
201b362b15af34006e6a11974088a46d42b903418eJohann#include "rdopt.h"
2190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid vp8_subtract_b_c(BLOCK *be, BLOCKD *bd, int pitch)
2390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
2490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *src_ptr = (*(be->base_src) + be->src);
2590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    short *diff_ptr = be->src_diff;
2690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    unsigned char *pred_ptr = bd->predictor;
2790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int src_stride = be->src_stride;
2890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int r, c;
3090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (r = 0; r < 4; r++)
3290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
3390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (c = 0; c < 4; c++)
3490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
3590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            diff_ptr[c] = src_ptr[c] - pred_ptr[c];
3690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
3790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
3890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        diff_ptr += pitch;
3990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        pred_ptr += pitch;
4090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        src_ptr  += src_stride;
4190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
4290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
4390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
441b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_subtract_mbuv_c(short *diff, unsigned char *usrc, unsigned char *vsrc,
451b362b15af34006e6a11974088a46d42b903418eJohann                         int src_stride, unsigned char *upred,
461b362b15af34006e6a11974088a46d42b903418eJohann                         unsigned char *vpred, int pred_stride)
4790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
4890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    short *udiff = diff + 256;
4990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    short *vdiff = diff + 320;
5090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int r, c;
5290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (r = 0; r < 8; r++)
5490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
5590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (c = 0; c < 8; c++)
5690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
5790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            udiff[c] = usrc[c] - upred[c];
5890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
5990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        udiff += 8;
611b362b15af34006e6a11974088a46d42b903418eJohann        upred += pred_stride;
621b362b15af34006e6a11974088a46d42b903418eJohann        usrc  += src_stride;
6390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
6490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (r = 0; r < 8; r++)
6690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
6790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (c = 0; c < 8; c++)
6890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
6990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            vdiff[c] = vsrc[c] - vpred[c];
7090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
7190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
7290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        vdiff += 8;
731b362b15af34006e6a11974088a46d42b903418eJohann        vpred += pred_stride;
741b362b15af34006e6a11974088a46d42b903418eJohann        vsrc  += src_stride;
7590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
7690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
7790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
781b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_subtract_mby_c(short *diff, unsigned char *src, int src_stride,
791b362b15af34006e6a11974088a46d42b903418eJohann                        unsigned char *pred, int pred_stride)
8090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
8190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int r, c;
8290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
8390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (r = 0; r < 16; r++)
8490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
8590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        for (c = 0; c < 16; c++)
8690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
8790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            diff[c] = src[c] - pred[c];
8890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
8990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
9090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        diff += 16;
911b362b15af34006e6a11974088a46d42b903418eJohann        pred += pred_stride;
921b362b15af34006e6a11974088a46d42b903418eJohann        src  += src_stride;
9390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
9490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
9590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
961b362b15af34006e6a11974088a46d42b903418eJohannstatic void vp8_subtract_mb(MACROBLOCK *x)
9790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
981b362b15af34006e6a11974088a46d42b903418eJohann    BLOCK *b = &x->block[0];
991b362b15af34006e6a11974088a46d42b903418eJohann
1001b362b15af34006e6a11974088a46d42b903418eJohann    vp8_subtract_mby(x->src_diff, *(b->base_src),
1011b362b15af34006e6a11974088a46d42b903418eJohann        b->src_stride, x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride);
1021b362b15af34006e6a11974088a46d42b903418eJohann    vp8_subtract_mbuv(x->src_diff, x->src.u_buffer,
1031b362b15af34006e6a11974088a46d42b903418eJohann        x->src.v_buffer, x->src.uv_stride, x->e_mbd.dst.u_buffer,
1041b362b15af34006e6a11974088a46d42b903418eJohann        x->e_mbd.dst.v_buffer, x->e_mbd.dst.uv_stride);
10590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
10690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
10779f15823c34ae1e423108295e416213200bb280fAndreas Huberstatic void build_dcblock(MACROBLOCK *x)
10890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
10990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    short *src_diff_ptr = &x->src_diff[384];
11090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int i;
11190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < 16; i++)
11390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
11490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        src_diff_ptr[i] = x->coeff[i * 16];
11590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
11690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
11790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
11890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid vp8_transform_mbuv(MACROBLOCK *x)
11990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
12090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int i;
12190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 16; i < 24; i += 2)
12390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
1241b362b15af34006e6a11974088a46d42b903418eJohann        x->short_fdct8x4(&x->block[i].src_diff[0],
125f71323e297a928af368937089d3ed71239786f86Andreas Huber            &x->block[i].coeff[0], 16);
12690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
12790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
12890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
12990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubervoid vp8_transform_intra_mby(MACROBLOCK *x)
13190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
13290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int i;
13390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
13490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < 16; i += 2)
13590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
1361b362b15af34006e6a11974088a46d42b903418eJohann        x->short_fdct8x4(&x->block[i].src_diff[0],
137f71323e297a928af368937089d3ed71239786f86Andreas Huber            &x->block[i].coeff[0], 32);
13890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
13990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1401b362b15af34006e6a11974088a46d42b903418eJohann    /* build dc block from 16 y dc values */
14179f15823c34ae1e423108295e416213200bb280fAndreas Huber    build_dcblock(x);
14290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1431b362b15af34006e6a11974088a46d42b903418eJohann    /* do 2nd order transform on the dc block */
144f71323e297a928af368937089d3ed71239786f86Andreas Huber    x->short_walsh4x4(&x->block[24].src_diff[0],
145f71323e297a928af368937089d3ed71239786f86Andreas Huber        &x->block[24].coeff[0], 8);
14690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
14890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
15079f15823c34ae1e423108295e416213200bb280fAndreas Huberstatic void transform_mb(MACROBLOCK *x)
15190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
15290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int i;
15390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
15490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < 16; i += 2)
15590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
1561b362b15af34006e6a11974088a46d42b903418eJohann        x->short_fdct8x4(&x->block[i].src_diff[0],
157f71323e297a928af368937089d3ed71239786f86Andreas Huber            &x->block[i].coeff[0], 32);
15890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
15990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1601b362b15af34006e6a11974088a46d42b903418eJohann    /* build dc block from 16 y dc values */
161f71323e297a928af368937089d3ed71239786f86Andreas Huber    if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
16279f15823c34ae1e423108295e416213200bb280fAndreas Huber        build_dcblock(x);
16390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
16490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 16; i < 24; i += 2)
16590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
1661b362b15af34006e6a11974088a46d42b903418eJohann        x->short_fdct8x4(&x->block[i].src_diff[0],
167f71323e297a928af368937089d3ed71239786f86Andreas Huber            &x->block[i].coeff[0], 16);
16890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
16990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1701b362b15af34006e6a11974088a46d42b903418eJohann    /* do 2nd order transform on the dc block */
171f71323e297a928af368937089d3ed71239786f86Andreas Huber    if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
172f71323e297a928af368937089d3ed71239786f86Andreas Huber        x->short_walsh4x4(&x->block[24].src_diff[0],
173f71323e297a928af368937089d3ed71239786f86Andreas Huber        &x->block[24].coeff[0], 8);
17490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
17590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
17690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
17779f15823c34ae1e423108295e416213200bb280fAndreas Huber
17879f15823c34ae1e423108295e416213200bb280fAndreas Huberstatic void transform_mby(MACROBLOCK *x)
17990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
18090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int i;
18190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
18290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (i = 0; i < 16; i += 2)
18390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
1841b362b15af34006e6a11974088a46d42b903418eJohann        x->short_fdct8x4(&x->block[i].src_diff[0],
185f71323e297a928af368937089d3ed71239786f86Andreas Huber            &x->block[i].coeff[0], 32);
18690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
18790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1881b362b15af34006e6a11974088a46d42b903418eJohann    /* build dc block from 16 y dc values */
189f71323e297a928af368937089d3ed71239786f86Andreas Huber    if (x->e_mbd.mode_info_context->mbmi.mode != SPLITMV)
19090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
19179f15823c34ae1e423108295e416213200bb280fAndreas Huber        build_dcblock(x);
192f71323e297a928af368937089d3ed71239786f86Andreas Huber        x->short_walsh4x4(&x->block[24].src_diff[0],
193f71323e297a928af368937089d3ed71239786f86Andreas Huber            &x->block[24].coeff[0], 8);
19490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
19590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
19690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
19790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
19890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
199f71323e297a928af368937089d3ed71239786f86Andreas Huber#define RDTRUNC(RM,DM,R,D) ( (128+(R)*(RM)) & 0xFF )
200f71323e297a928af368937089d3ed71239786f86Andreas Huber
201f71323e297a928af368937089d3ed71239786f86Andreas Hubertypedef struct vp8_token_state vp8_token_state;
202f71323e297a928af368937089d3ed71239786f86Andreas Huber
203f71323e297a928af368937089d3ed71239786f86Andreas Huberstruct vp8_token_state{
204f71323e297a928af368937089d3ed71239786f86Andreas Huber  int           rate;
205f71323e297a928af368937089d3ed71239786f86Andreas Huber  int           error;
206f71323e297a928af368937089d3ed71239786f86Andreas Huber  signed char   next;
207f71323e297a928af368937089d3ed71239786f86Andreas Huber  signed char   token;
208f71323e297a928af368937089d3ed71239786f86Andreas Huber  short         qc;
209f71323e297a928af368937089d3ed71239786f86Andreas Huber};
210f71323e297a928af368937089d3ed71239786f86Andreas Huber
2111b362b15af34006e6a11974088a46d42b903418eJohann/* TODO: experiments to find optimal multiple numbers */
21279f15823c34ae1e423108295e416213200bb280fAndreas Huber#define Y1_RD_MULT 4
21379f15823c34ae1e423108295e416213200bb280fAndreas Huber#define UV_RD_MULT 2
21479f15823c34ae1e423108295e416213200bb280fAndreas Huber#define Y2_RD_MULT 16
215538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
216538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberstatic const int plane_rd_mult[4]=
217538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber{
218538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    Y1_RD_MULT,
219538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    Y2_RD_MULT,
220538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    UV_RD_MULT,
221538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    Y1_RD_MULT
222538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber};
223538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
22479f15823c34ae1e423108295e416213200bb280fAndreas Huberstatic void optimize_b(MACROBLOCK *mb, int ib, int type,
2251b362b15af34006e6a11974088a46d42b903418eJohann                       ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
22690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
227f71323e297a928af368937089d3ed71239786f86Andreas Huber    BLOCK *b;
228f71323e297a928af368937089d3ed71239786f86Andreas Huber    BLOCKD *d;
229f71323e297a928af368937089d3ed71239786f86Andreas Huber    vp8_token_state tokens[17][2];
230f71323e297a928af368937089d3ed71239786f86Andreas Huber    unsigned best_mask[2];
231f71323e297a928af368937089d3ed71239786f86Andreas Huber    const short *dequant_ptr;
232f71323e297a928af368937089d3ed71239786f86Andreas Huber    const short *coeff_ptr;
233f71323e297a928af368937089d3ed71239786f86Andreas Huber    short *qcoeff_ptr;
234f71323e297a928af368937089d3ed71239786f86Andreas Huber    short *dqcoeff_ptr;
235f71323e297a928af368937089d3ed71239786f86Andreas Huber    int eob;
236f71323e297a928af368937089d3ed71239786f86Andreas Huber    int i0;
237f71323e297a928af368937089d3ed71239786f86Andreas Huber    int rc;
238f71323e297a928af368937089d3ed71239786f86Andreas Huber    int x;
2391b362b15af34006e6a11974088a46d42b903418eJohann    int sz = 0;
240f71323e297a928af368937089d3ed71239786f86Andreas Huber    int next;
241f71323e297a928af368937089d3ed71239786f86Andreas Huber    int rdmult;
242f71323e297a928af368937089d3ed71239786f86Andreas Huber    int rddiv;
243f71323e297a928af368937089d3ed71239786f86Andreas Huber    int final_eob;
244f71323e297a928af368937089d3ed71239786f86Andreas Huber    int rd_cost0;
245f71323e297a928af368937089d3ed71239786f86Andreas Huber    int rd_cost1;
246f71323e297a928af368937089d3ed71239786f86Andreas Huber    int rate0;
247f71323e297a928af368937089d3ed71239786f86Andreas Huber    int rate1;
248f71323e297a928af368937089d3ed71239786f86Andreas Huber    int error0;
249f71323e297a928af368937089d3ed71239786f86Andreas Huber    int error1;
250f71323e297a928af368937089d3ed71239786f86Andreas Huber    int t0;
251f71323e297a928af368937089d3ed71239786f86Andreas Huber    int t1;
252f71323e297a928af368937089d3ed71239786f86Andreas Huber    int best;
253f71323e297a928af368937089d3ed71239786f86Andreas Huber    int band;
254f71323e297a928af368937089d3ed71239786f86Andreas Huber    int pt;
255538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int i;
256538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int err_mult = plane_rd_mult[type];
257f71323e297a928af368937089d3ed71239786f86Andreas Huber
258538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    b = &mb->block[ib];
259538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    d = &mb->e_mbd.block[ib];
260f71323e297a928af368937089d3ed71239786f86Andreas Huber
261f71323e297a928af368937089d3ed71239786f86Andreas Huber    /* Enable this to test the effect of RDO as a replacement for the dynamic
262f71323e297a928af368937089d3ed71239786f86Andreas Huber     *  zero bin instead of an augmentation of it.
263f71323e297a928af368937089d3ed71239786f86Andreas Huber     */
264f71323e297a928af368937089d3ed71239786f86Andreas Huber#if 0
265f71323e297a928af368937089d3ed71239786f86Andreas Huber    vp8_strict_quantize_b(b, d);
266f71323e297a928af368937089d3ed71239786f86Andreas Huber#endif
26790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
268538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    dequant_ptr = d->dequant;
269538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    coeff_ptr = b->coeff;
270f71323e297a928af368937089d3ed71239786f86Andreas Huber    qcoeff_ptr = d->qcoeff;
271f71323e297a928af368937089d3ed71239786f86Andreas Huber    dqcoeff_ptr = d->dqcoeff;
272f71323e297a928af368937089d3ed71239786f86Andreas Huber    i0 = !type;
2731b362b15af34006e6a11974088a46d42b903418eJohann    eob = *d->eob;
274f71323e297a928af368937089d3ed71239786f86Andreas Huber
275f71323e297a928af368937089d3ed71239786f86Andreas Huber    /* Now set up a Viterbi trellis to evaluate alternative roundings. */
27679f15823c34ae1e423108295e416213200bb280fAndreas Huber    rdmult = mb->rdmult * err_mult;
27779f15823c34ae1e423108295e416213200bb280fAndreas Huber    if(mb->e_mbd.mode_info_context->mbmi.ref_frame==INTRA_FRAME)
27879f15823c34ae1e423108295e416213200bb280fAndreas Huber        rdmult = (rdmult * 9)>>4;
27979f15823c34ae1e423108295e416213200bb280fAndreas Huber
280f71323e297a928af368937089d3ed71239786f86Andreas Huber    rddiv = mb->rddiv;
281f71323e297a928af368937089d3ed71239786f86Andreas Huber    best_mask[0] = best_mask[1] = 0;
282f71323e297a928af368937089d3ed71239786f86Andreas Huber    /* Initialize the sentinel node of the trellis. */
283f71323e297a928af368937089d3ed71239786f86Andreas Huber    tokens[eob][0].rate = 0;
284f71323e297a928af368937089d3ed71239786f86Andreas Huber    tokens[eob][0].error = 0;
285f71323e297a928af368937089d3ed71239786f86Andreas Huber    tokens[eob][0].next = 16;
286f71323e297a928af368937089d3ed71239786f86Andreas Huber    tokens[eob][0].token = DCT_EOB_TOKEN;
287f71323e297a928af368937089d3ed71239786f86Andreas Huber    tokens[eob][0].qc = 0;
288f71323e297a928af368937089d3ed71239786f86Andreas Huber    *(tokens[eob] + 1) = *(tokens[eob] + 0);
289f71323e297a928af368937089d3ed71239786f86Andreas Huber    next = eob;
290f71323e297a928af368937089d3ed71239786f86Andreas Huber    for (i = eob; i-- > i0;)
291f71323e297a928af368937089d3ed71239786f86Andreas Huber    {
292f71323e297a928af368937089d3ed71239786f86Andreas Huber        int base_bits;
293f71323e297a928af368937089d3ed71239786f86Andreas Huber        int d2;
294f71323e297a928af368937089d3ed71239786f86Andreas Huber        int dx;
295f71323e297a928af368937089d3ed71239786f86Andreas Huber
296f71323e297a928af368937089d3ed71239786f86Andreas Huber        rc = vp8_default_zig_zag1d[i];
297f71323e297a928af368937089d3ed71239786f86Andreas Huber        x = qcoeff_ptr[rc];
298f71323e297a928af368937089d3ed71239786f86Andreas Huber        /* Only add a trellis state for non-zero coefficients. */
299f71323e297a928af368937089d3ed71239786f86Andreas Huber        if (x)
300f71323e297a928af368937089d3ed71239786f86Andreas Huber        {
301f71323e297a928af368937089d3ed71239786f86Andreas Huber            int shortcut=0;
302f71323e297a928af368937089d3ed71239786f86Andreas Huber            error0 = tokens[next][0].error;
303f71323e297a928af368937089d3ed71239786f86Andreas Huber            error1 = tokens[next][1].error;
304f71323e297a928af368937089d3ed71239786f86Andreas Huber            /* Evaluate the first possibility for this state. */
305f71323e297a928af368937089d3ed71239786f86Andreas Huber            rate0 = tokens[next][0].rate;
306f71323e297a928af368937089d3ed71239786f86Andreas Huber            rate1 = tokens[next][1].rate;
307f71323e297a928af368937089d3ed71239786f86Andreas Huber            t0 = (vp8_dct_value_tokens_ptr + x)->Token;
308f71323e297a928af368937089d3ed71239786f86Andreas Huber            /* Consider both possible successor states. */
309f71323e297a928af368937089d3ed71239786f86Andreas Huber            if (next < 16)
31090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
311f71323e297a928af368937089d3ed71239786f86Andreas Huber                band = vp8_coef_bands[i + 1];
312f71323e297a928af368937089d3ed71239786f86Andreas Huber                pt = vp8_prev_token_class[t0];
313f71323e297a928af368937089d3ed71239786f86Andreas Huber                rate0 +=
314f71323e297a928af368937089d3ed71239786f86Andreas Huber                    mb->token_costs[type][band][pt][tokens[next][0].token];
315f71323e297a928af368937089d3ed71239786f86Andreas Huber                rate1 +=
316f71323e297a928af368937089d3ed71239786f86Andreas Huber                    mb->token_costs[type][band][pt][tokens[next][1].token];
31790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
318f71323e297a928af368937089d3ed71239786f86Andreas Huber            rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
319f71323e297a928af368937089d3ed71239786f86Andreas Huber            rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
320f71323e297a928af368937089d3ed71239786f86Andreas Huber            if (rd_cost0 == rd_cost1)
32190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
322f71323e297a928af368937089d3ed71239786f86Andreas Huber                rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
323f71323e297a928af368937089d3ed71239786f86Andreas Huber                rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
32490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
325f71323e297a928af368937089d3ed71239786f86Andreas Huber            /* And pick the best. */
326f71323e297a928af368937089d3ed71239786f86Andreas Huber            best = rd_cost1 < rd_cost0;
327f71323e297a928af368937089d3ed71239786f86Andreas Huber            base_bits = *(vp8_dct_value_cost_ptr + x);
328f71323e297a928af368937089d3ed71239786f86Andreas Huber            dx = dqcoeff_ptr[rc] - coeff_ptr[rc];
329f71323e297a928af368937089d3ed71239786f86Andreas Huber            d2 = dx*dx;
330f71323e297a928af368937089d3ed71239786f86Andreas Huber            tokens[i][0].rate = base_bits + (best ? rate1 : rate0);
331f71323e297a928af368937089d3ed71239786f86Andreas Huber            tokens[i][0].error = d2 + (best ? error1 : error0);
332f71323e297a928af368937089d3ed71239786f86Andreas Huber            tokens[i][0].next = next;
333f71323e297a928af368937089d3ed71239786f86Andreas Huber            tokens[i][0].token = t0;
334f71323e297a928af368937089d3ed71239786f86Andreas Huber            tokens[i][0].qc = x;
335f71323e297a928af368937089d3ed71239786f86Andreas Huber            best_mask[0] |= best << i;
336f71323e297a928af368937089d3ed71239786f86Andreas Huber            /* Evaluate the second possibility for this state. */
337f71323e297a928af368937089d3ed71239786f86Andreas Huber            rate0 = tokens[next][0].rate;
338f71323e297a928af368937089d3ed71239786f86Andreas Huber            rate1 = tokens[next][1].rate;
339f71323e297a928af368937089d3ed71239786f86Andreas Huber
340f71323e297a928af368937089d3ed71239786f86Andreas Huber            if((abs(x)*dequant_ptr[rc]>abs(coeff_ptr[rc])) &&
341f71323e297a928af368937089d3ed71239786f86Andreas Huber               (abs(x)*dequant_ptr[rc]<abs(coeff_ptr[rc])+dequant_ptr[rc]))
342f71323e297a928af368937089d3ed71239786f86Andreas Huber                shortcut = 1;
343f71323e297a928af368937089d3ed71239786f86Andreas Huber            else
344f71323e297a928af368937089d3ed71239786f86Andreas Huber                shortcut = 0;
345f71323e297a928af368937089d3ed71239786f86Andreas Huber
346f71323e297a928af368937089d3ed71239786f86Andreas Huber            if(shortcut)
34790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
348f71323e297a928af368937089d3ed71239786f86Andreas Huber                sz = -(x < 0);
349f71323e297a928af368937089d3ed71239786f86Andreas Huber                x -= 2*sz + 1;
35090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
35190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
352f71323e297a928af368937089d3ed71239786f86Andreas Huber            /* Consider both possible successor states. */
353f71323e297a928af368937089d3ed71239786f86Andreas Huber            if (!x)
35490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
355f71323e297a928af368937089d3ed71239786f86Andreas Huber                /* If we reduced this coefficient to zero, check to see if
356f71323e297a928af368937089d3ed71239786f86Andreas Huber                 *  we need to move the EOB back here.
357f71323e297a928af368937089d3ed71239786f86Andreas Huber                 */
358f71323e297a928af368937089d3ed71239786f86Andreas Huber                t0 = tokens[next][0].token == DCT_EOB_TOKEN ?
359f71323e297a928af368937089d3ed71239786f86Andreas Huber                    DCT_EOB_TOKEN : ZERO_TOKEN;
360f71323e297a928af368937089d3ed71239786f86Andreas Huber                t1 = tokens[next][1].token == DCT_EOB_TOKEN ?
361f71323e297a928af368937089d3ed71239786f86Andreas Huber                    DCT_EOB_TOKEN : ZERO_TOKEN;
36290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
363f71323e297a928af368937089d3ed71239786f86Andreas Huber            else
36490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
365f71323e297a928af368937089d3ed71239786f86Andreas Huber                t0=t1 = (vp8_dct_value_tokens_ptr + x)->Token;
366f71323e297a928af368937089d3ed71239786f86Andreas Huber            }
367f71323e297a928af368937089d3ed71239786f86Andreas Huber            if (next < 16)
368f71323e297a928af368937089d3ed71239786f86Andreas Huber            {
369f71323e297a928af368937089d3ed71239786f86Andreas Huber                band = vp8_coef_bands[i + 1];
370f71323e297a928af368937089d3ed71239786f86Andreas Huber                if(t0!=DCT_EOB_TOKEN)
37190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                {
372f71323e297a928af368937089d3ed71239786f86Andreas Huber                    pt = vp8_prev_token_class[t0];
373f71323e297a928af368937089d3ed71239786f86Andreas Huber                    rate0 += mb->token_costs[type][band][pt][
374f71323e297a928af368937089d3ed71239786f86Andreas Huber                        tokens[next][0].token];
37590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
376f71323e297a928af368937089d3ed71239786f86Andreas Huber                if(t1!=DCT_EOB_TOKEN)
37790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                {
378f71323e297a928af368937089d3ed71239786f86Andreas Huber                    pt = vp8_prev_token_class[t1];
379f71323e297a928af368937089d3ed71239786f86Andreas Huber                    rate1 += mb->token_costs[type][band][pt][
380f71323e297a928af368937089d3ed71239786f86Andreas Huber                        tokens[next][1].token];
38190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber                }
38290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
38390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
384f71323e297a928af368937089d3ed71239786f86Andreas Huber            rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
385f71323e297a928af368937089d3ed71239786f86Andreas Huber            rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
386f71323e297a928af368937089d3ed71239786f86Andreas Huber            if (rd_cost0 == rd_cost1)
38790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
388f71323e297a928af368937089d3ed71239786f86Andreas Huber                rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
389f71323e297a928af368937089d3ed71239786f86Andreas Huber                rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
39090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
391f71323e297a928af368937089d3ed71239786f86Andreas Huber            /* And pick the best. */
392f71323e297a928af368937089d3ed71239786f86Andreas Huber            best = rd_cost1 < rd_cost0;
393f71323e297a928af368937089d3ed71239786f86Andreas Huber            base_bits = *(vp8_dct_value_cost_ptr + x);
39490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
395f71323e297a928af368937089d3ed71239786f86Andreas Huber            if(shortcut)
39690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
397f71323e297a928af368937089d3ed71239786f86Andreas Huber                dx -= (dequant_ptr[rc] + sz) ^ sz;
398f71323e297a928af368937089d3ed71239786f86Andreas Huber                d2 = dx*dx;
39990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
400f71323e297a928af368937089d3ed71239786f86Andreas Huber            tokens[i][1].rate = base_bits + (best ? rate1 : rate0);
401f71323e297a928af368937089d3ed71239786f86Andreas Huber            tokens[i][1].error = d2 + (best ? error1 : error0);
402f71323e297a928af368937089d3ed71239786f86Andreas Huber            tokens[i][1].next = next;
403f71323e297a928af368937089d3ed71239786f86Andreas Huber            tokens[i][1].token =best?t1:t0;
404f71323e297a928af368937089d3ed71239786f86Andreas Huber            tokens[i][1].qc = x;
405f71323e297a928af368937089d3ed71239786f86Andreas Huber            best_mask[1] |= best << i;
406f71323e297a928af368937089d3ed71239786f86Andreas Huber            /* Finally, make this the new head of the trellis. */
407f71323e297a928af368937089d3ed71239786f86Andreas Huber            next = i;
408f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
409f71323e297a928af368937089d3ed71239786f86Andreas Huber        /* There's no choice to make for a zero coefficient, so we don't
410f71323e297a928af368937089d3ed71239786f86Andreas Huber         *  add a new trellis node, but we do need to update the costs.
411f71323e297a928af368937089d3ed71239786f86Andreas Huber         */
41290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        else
41390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        {
414f71323e297a928af368937089d3ed71239786f86Andreas Huber            band = vp8_coef_bands[i + 1];
415f71323e297a928af368937089d3ed71239786f86Andreas Huber            t0 = tokens[next][0].token;
416f71323e297a928af368937089d3ed71239786f86Andreas Huber            t1 = tokens[next][1].token;
417f71323e297a928af368937089d3ed71239786f86Andreas Huber            /* Update the cost of each path if we're past the EOB token. */
418f71323e297a928af368937089d3ed71239786f86Andreas Huber            if (t0 != DCT_EOB_TOKEN)
41990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            {
420f71323e297a928af368937089d3ed71239786f86Andreas Huber                tokens[next][0].rate += mb->token_costs[type][band][0][t0];
421f71323e297a928af368937089d3ed71239786f86Andreas Huber                tokens[next][0].token = ZERO_TOKEN;
42290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber            }
423f71323e297a928af368937089d3ed71239786f86Andreas Huber            if (t1 != DCT_EOB_TOKEN)
424f71323e297a928af368937089d3ed71239786f86Andreas Huber            {
425f71323e297a928af368937089d3ed71239786f86Andreas Huber                tokens[next][1].rate += mb->token_costs[type][band][0][t1];
426f71323e297a928af368937089d3ed71239786f86Andreas Huber                tokens[next][1].token = ZERO_TOKEN;
427f71323e297a928af368937089d3ed71239786f86Andreas Huber            }
428f71323e297a928af368937089d3ed71239786f86Andreas Huber            /* Don't update next, because we didn't add a new node. */
42990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        }
43090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
43190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
432f71323e297a928af368937089d3ed71239786f86Andreas Huber    /* Now pick the best path through the whole trellis. */
433f71323e297a928af368937089d3ed71239786f86Andreas Huber    band = vp8_coef_bands[i + 1];
434f71323e297a928af368937089d3ed71239786f86Andreas Huber    VP8_COMBINEENTROPYCONTEXTS(pt, *a, *l);
435f71323e297a928af368937089d3ed71239786f86Andreas Huber    rate0 = tokens[next][0].rate;
436f71323e297a928af368937089d3ed71239786f86Andreas Huber    rate1 = tokens[next][1].rate;
437f71323e297a928af368937089d3ed71239786f86Andreas Huber    error0 = tokens[next][0].error;
438f71323e297a928af368937089d3ed71239786f86Andreas Huber    error1 = tokens[next][1].error;
439f71323e297a928af368937089d3ed71239786f86Andreas Huber    t0 = tokens[next][0].token;
440f71323e297a928af368937089d3ed71239786f86Andreas Huber    t1 = tokens[next][1].token;
441f71323e297a928af368937089d3ed71239786f86Andreas Huber    rate0 += mb->token_costs[type][band][pt][t0];
442f71323e297a928af368937089d3ed71239786f86Andreas Huber    rate1 += mb->token_costs[type][band][pt][t1];
443f71323e297a928af368937089d3ed71239786f86Andreas Huber    rd_cost0 = RDCOST(rdmult, rddiv, rate0, error0);
444f71323e297a928af368937089d3ed71239786f86Andreas Huber    rd_cost1 = RDCOST(rdmult, rddiv, rate1, error1);
445f71323e297a928af368937089d3ed71239786f86Andreas Huber    if (rd_cost0 == rd_cost1)
446f71323e297a928af368937089d3ed71239786f86Andreas Huber    {
447f71323e297a928af368937089d3ed71239786f86Andreas Huber        rd_cost0 = RDTRUNC(rdmult, rddiv, rate0, error0);
448f71323e297a928af368937089d3ed71239786f86Andreas Huber        rd_cost1 = RDTRUNC(rdmult, rddiv, rate1, error1);
449f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
450f71323e297a928af368937089d3ed71239786f86Andreas Huber    best = rd_cost1 < rd_cost0;
451f71323e297a928af368937089d3ed71239786f86Andreas Huber    final_eob = i0 - 1;
452f71323e297a928af368937089d3ed71239786f86Andreas Huber    for (i = next; i < eob; i = next)
453f71323e297a928af368937089d3ed71239786f86Andreas Huber    {
454f71323e297a928af368937089d3ed71239786f86Andreas Huber        x = tokens[i][best].qc;
455f71323e297a928af368937089d3ed71239786f86Andreas Huber        if (x)
456f71323e297a928af368937089d3ed71239786f86Andreas Huber            final_eob = i;
457f71323e297a928af368937089d3ed71239786f86Andreas Huber        rc = vp8_default_zig_zag1d[i];
458f71323e297a928af368937089d3ed71239786f86Andreas Huber        qcoeff_ptr[rc] = x;
459f71323e297a928af368937089d3ed71239786f86Andreas Huber        dqcoeff_ptr[rc] = x * dequant_ptr[rc];
460f71323e297a928af368937089d3ed71239786f86Andreas Huber        next = tokens[i][best].next;
461f71323e297a928af368937089d3ed71239786f86Andreas Huber        best = (best_mask[best] >> i) & 1;
462f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
463f71323e297a928af368937089d3ed71239786f86Andreas Huber    final_eob++;
464f71323e297a928af368937089d3ed71239786f86Andreas Huber
4651b362b15af34006e6a11974088a46d42b903418eJohann    *a = *l = (final_eob != !type);
4661b362b15af34006e6a11974088a46d42b903418eJohann    *d->eob = (char)final_eob;
46790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
4681b362b15af34006e6a11974088a46d42b903418eJohannstatic void check_reset_2nd_coeffs(MACROBLOCKD *x, int type,
4691b362b15af34006e6a11974088a46d42b903418eJohann                                   ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l)
4701b362b15af34006e6a11974088a46d42b903418eJohann{
4711b362b15af34006e6a11974088a46d42b903418eJohann    int sum=0;
4721b362b15af34006e6a11974088a46d42b903418eJohann    int i;
4731b362b15af34006e6a11974088a46d42b903418eJohann    BLOCKD *bd = &x->block[24];
47490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
4751b362b15af34006e6a11974088a46d42b903418eJohann    if(bd->dequant[0]>=35 && bd->dequant[1]>=35)
4761b362b15af34006e6a11974088a46d42b903418eJohann        return;
4771b362b15af34006e6a11974088a46d42b903418eJohann
4781b362b15af34006e6a11974088a46d42b903418eJohann    for(i=0;i<(*bd->eob);i++)
4791b362b15af34006e6a11974088a46d42b903418eJohann    {
4801b362b15af34006e6a11974088a46d42b903418eJohann        int coef = bd->dqcoeff[vp8_default_zig_zag1d[i]];
4811b362b15af34006e6a11974088a46d42b903418eJohann        sum+= (coef>=0)?coef:-coef;
4821b362b15af34006e6a11974088a46d42b903418eJohann        if(sum>=35)
4831b362b15af34006e6a11974088a46d42b903418eJohann            return;
4841b362b15af34006e6a11974088a46d42b903418eJohann    }
4851b362b15af34006e6a11974088a46d42b903418eJohann    /**************************************************************************
4861b362b15af34006e6a11974088a46d42b903418eJohann    our inverse hadamard transform effectively is weighted sum of all 16 inputs
4871b362b15af34006e6a11974088a46d42b903418eJohann    with weight either 1 or -1. It has a last stage scaling of (sum+3)>>3. And
4881b362b15af34006e6a11974088a46d42b903418eJohann    dc only idct is (dc+4)>>3. So if all the sums are between -35 and 29, the
4891b362b15af34006e6a11974088a46d42b903418eJohann    output after inverse wht and idct will be all zero. A sum of absolute value
4901b362b15af34006e6a11974088a46d42b903418eJohann    smaller than 35 guarantees all 16 different (+1/-1) weighted sums in wht
4911b362b15af34006e6a11974088a46d42b903418eJohann    fall between -35 and +35.
4921b362b15af34006e6a11974088a46d42b903418eJohann    **************************************************************************/
4931b362b15af34006e6a11974088a46d42b903418eJohann    if(sum < 35)
4941b362b15af34006e6a11974088a46d42b903418eJohann    {
4951b362b15af34006e6a11974088a46d42b903418eJohann        for(i=0;i<(*bd->eob);i++)
4961b362b15af34006e6a11974088a46d42b903418eJohann        {
4971b362b15af34006e6a11974088a46d42b903418eJohann            int rc = vp8_default_zig_zag1d[i];
4981b362b15af34006e6a11974088a46d42b903418eJohann            bd->qcoeff[rc]=0;
4991b362b15af34006e6a11974088a46d42b903418eJohann            bd->dqcoeff[rc]=0;
5001b362b15af34006e6a11974088a46d42b903418eJohann        }
5011b362b15af34006e6a11974088a46d42b903418eJohann        *bd->eob = 0;
5021b362b15af34006e6a11974088a46d42b903418eJohann        *a = *l = (*bd->eob != !type);
5031b362b15af34006e6a11974088a46d42b903418eJohann    }
5041b362b15af34006e6a11974088a46d42b903418eJohann}
5051b362b15af34006e6a11974088a46d42b903418eJohann
5061b362b15af34006e6a11974088a46d42b903418eJohannstatic void optimize_mb(MACROBLOCK *x)
50790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
50890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int b;
509f71323e297a928af368937089d3ed71239786f86Andreas Huber    int type;
510f71323e297a928af368937089d3ed71239786f86Andreas Huber    int has_2nd_order;
5111b362b15af34006e6a11974088a46d42b903418eJohann
512f71323e297a928af368937089d3ed71239786f86Andreas Huber    ENTROPY_CONTEXT_PLANES t_above, t_left;
513f71323e297a928af368937089d3ed71239786f86Andreas Huber    ENTROPY_CONTEXT *ta;
514f71323e297a928af368937089d3ed71239786f86Andreas Huber    ENTROPY_CONTEXT *tl;
51590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
516f71323e297a928af368937089d3ed71239786f86Andreas Huber    vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
517f71323e297a928af368937089d3ed71239786f86Andreas Huber    vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
51890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
519f71323e297a928af368937089d3ed71239786f86Andreas Huber    ta = (ENTROPY_CONTEXT *)&t_above;
520f71323e297a928af368937089d3ed71239786f86Andreas Huber    tl = (ENTROPY_CONTEXT *)&t_left;
521f71323e297a928af368937089d3ed71239786f86Andreas Huber
522f71323e297a928af368937089d3ed71239786f86Andreas Huber    has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
523f71323e297a928af368937089d3ed71239786f86Andreas Huber        && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
52479f15823c34ae1e423108295e416213200bb280fAndreas Huber    type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
52590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
52690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (b = 0; b < 16; b++)
52790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
52879f15823c34ae1e423108295e416213200bb280fAndreas Huber        optimize_b(x, b, type,
5291b362b15af34006e6a11974088a46d42b903418eJohann            ta + vp8_block2above[b], tl + vp8_block2left[b]);
53090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
53190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
53279f15823c34ae1e423108295e416213200bb280fAndreas Huber    for (b = 16; b < 24; b++)
53390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
53479f15823c34ae1e423108295e416213200bb280fAndreas Huber        optimize_b(x, b, PLANE_TYPE_UV,
5351b362b15af34006e6a11974088a46d42b903418eJohann            ta + vp8_block2above[b], tl + vp8_block2left[b]);
53690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
53790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
538f71323e297a928af368937089d3ed71239786f86Andreas Huber    if (has_2nd_order)
53990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
540538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        b=24;
54179f15823c34ae1e423108295e416213200bb280fAndreas Huber        optimize_b(x, b, PLANE_TYPE_Y2,
5421b362b15af34006e6a11974088a46d42b903418eJohann            ta + vp8_block2above[b], tl + vp8_block2left[b]);
5431b362b15af34006e6a11974088a46d42b903418eJohann        check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2,
5441b362b15af34006e6a11974088a46d42b903418eJohann            ta + vp8_block2above[b], tl + vp8_block2left[b]);
54590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
54690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
54790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
54890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5491b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_optimize_mby(MACROBLOCK *x)
55090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
55190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int b;
552f71323e297a928af368937089d3ed71239786f86Andreas Huber    int type;
553f71323e297a928af368937089d3ed71239786f86Andreas Huber    int has_2nd_order;
554f71323e297a928af368937089d3ed71239786f86Andreas Huber
555f71323e297a928af368937089d3ed71239786f86Andreas Huber    ENTROPY_CONTEXT_PLANES t_above, t_left;
556f71323e297a928af368937089d3ed71239786f86Andreas Huber    ENTROPY_CONTEXT *ta;
557f71323e297a928af368937089d3ed71239786f86Andreas Huber    ENTROPY_CONTEXT *tl;
55890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
559f71323e297a928af368937089d3ed71239786f86Andreas Huber    if (!x->e_mbd.above_context)
56090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return;
56190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
562f71323e297a928af368937089d3ed71239786f86Andreas Huber    if (!x->e_mbd.left_context)
56390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return;
56490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
565f71323e297a928af368937089d3ed71239786f86Andreas Huber    vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
566f71323e297a928af368937089d3ed71239786f86Andreas Huber    vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
56790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
568f71323e297a928af368937089d3ed71239786f86Andreas Huber    ta = (ENTROPY_CONTEXT *)&t_above;
569f71323e297a928af368937089d3ed71239786f86Andreas Huber    tl = (ENTROPY_CONTEXT *)&t_left;
570f71323e297a928af368937089d3ed71239786f86Andreas Huber
571f71323e297a928af368937089d3ed71239786f86Andreas Huber    has_2nd_order = (x->e_mbd.mode_info_context->mbmi.mode != B_PRED
572f71323e297a928af368937089d3ed71239786f86Andreas Huber        && x->e_mbd.mode_info_context->mbmi.mode != SPLITMV);
57379f15823c34ae1e423108295e416213200bb280fAndreas Huber    type = has_2nd_order ? PLANE_TYPE_Y_NO_DC : PLANE_TYPE_Y_WITH_DC;
57490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
57590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    for (b = 0; b < 16; b++)
57690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
57779f15823c34ae1e423108295e416213200bb280fAndreas Huber        optimize_b(x, b, type,
5781b362b15af34006e6a11974088a46d42b903418eJohann            ta + vp8_block2above[b], tl + vp8_block2left[b]);
57990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
58090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
581538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
582f71323e297a928af368937089d3ed71239786f86Andreas Huber    if (has_2nd_order)
583f71323e297a928af368937089d3ed71239786f86Andreas Huber    {
584538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        b=24;
58579f15823c34ae1e423108295e416213200bb280fAndreas Huber        optimize_b(x, b, PLANE_TYPE_Y2,
5861b362b15af34006e6a11974088a46d42b903418eJohann            ta + vp8_block2above[b], tl + vp8_block2left[b]);
5871b362b15af34006e6a11974088a46d42b903418eJohann        check_reset_2nd_coeffs(&x->e_mbd, PLANE_TYPE_Y2,
5881b362b15af34006e6a11974088a46d42b903418eJohann            ta + vp8_block2above[b], tl + vp8_block2left[b]);
589f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
59090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
59190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
5921b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_optimize_mbuv(MACROBLOCK *x)
59390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
59490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    int b;
595f71323e297a928af368937089d3ed71239786f86Andreas Huber    ENTROPY_CONTEXT_PLANES t_above, t_left;
596f71323e297a928af368937089d3ed71239786f86Andreas Huber    ENTROPY_CONTEXT *ta;
597f71323e297a928af368937089d3ed71239786f86Andreas Huber    ENTROPY_CONTEXT *tl;
59890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
599f71323e297a928af368937089d3ed71239786f86Andreas Huber    if (!x->e_mbd.above_context)
60090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return;
60190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
602f71323e297a928af368937089d3ed71239786f86Andreas Huber    if (!x->e_mbd.left_context)
60390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber        return;
60490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
605f71323e297a928af368937089d3ed71239786f86Andreas Huber    vpx_memcpy(&t_above, x->e_mbd.above_context, sizeof(ENTROPY_CONTEXT_PLANES));
606f71323e297a928af368937089d3ed71239786f86Andreas Huber    vpx_memcpy(&t_left, x->e_mbd.left_context, sizeof(ENTROPY_CONTEXT_PLANES));
60790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
608f71323e297a928af368937089d3ed71239786f86Andreas Huber    ta = (ENTROPY_CONTEXT *)&t_above;
609f71323e297a928af368937089d3ed71239786f86Andreas Huber    tl = (ENTROPY_CONTEXT *)&t_left;
61090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
61179f15823c34ae1e423108295e416213200bb280fAndreas Huber    for (b = 16; b < 24; b++)
61290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    {
61379f15823c34ae1e423108295e416213200bb280fAndreas Huber        optimize_b(x, b, PLANE_TYPE_UV,
6141b362b15af34006e6a11974088a46d42b903418eJohann            ta + vp8_block2above[b], tl + vp8_block2left[b]);
61590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
61690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
61790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6181b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_encode_inter16x16(MACROBLOCK *x)
61990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
62090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    vp8_build_inter_predictors_mb(&x->e_mbd);
62190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6221b362b15af34006e6a11974088a46d42b903418eJohann    vp8_subtract_mb(x);
62390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
62479f15823c34ae1e423108295e416213200bb280fAndreas Huber    transform_mb(x);
62590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
62690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    vp8_quantize_mb(x);
62790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
62879f15823c34ae1e423108295e416213200bb280fAndreas Huber    if (x->optimize)
6291b362b15af34006e6a11974088a46d42b903418eJohann        optimize_mb(x);
63090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
63190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
63290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/* this funciton is used by first pass only */
6331b362b15af34006e6a11974088a46d42b903418eJohannvoid vp8_encode_inter16x16y(MACROBLOCK *x)
63490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber{
6351b362b15af34006e6a11974088a46d42b903418eJohann    BLOCK *b = &x->block[0];
6361b362b15af34006e6a11974088a46d42b903418eJohann
6371b362b15af34006e6a11974088a46d42b903418eJohann    vp8_build_inter16x16_predictors_mby(&x->e_mbd, x->e_mbd.dst.y_buffer,
6381b362b15af34006e6a11974088a46d42b903418eJohann                                        x->e_mbd.dst.y_stride);
63990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6401b362b15af34006e6a11974088a46d42b903418eJohann    vp8_subtract_mby(x->src_diff, *(b->base_src),
6411b362b15af34006e6a11974088a46d42b903418eJohann        b->src_stride, x->e_mbd.dst.y_buffer, x->e_mbd.dst.y_stride);
64290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
64379f15823c34ae1e423108295e416213200bb280fAndreas Huber    transform_mby(x);
64490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
64590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    vp8_quantize_mby(x);
64690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
6471b362b15af34006e6a11974088a46d42b903418eJohann    vp8_inverse_transform_mby(&x->e_mbd);
64890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
649