129a84457aed4c45bc900998b5e11c03023264208James Dong/* ------------------------------------------------------------------
229a84457aed4c45bc900998b5e11c03023264208James Dong * Copyright (C) 1998-2009 PacketVideo
329a84457aed4c45bc900998b5e11c03023264208James Dong *
429a84457aed4c45bc900998b5e11c03023264208James Dong * Licensed under the Apache License, Version 2.0 (the "License");
529a84457aed4c45bc900998b5e11c03023264208James Dong * you may not use this file except in compliance with the License.
629a84457aed4c45bc900998b5e11c03023264208James Dong * You may obtain a copy of the License at
729a84457aed4c45bc900998b5e11c03023264208James Dong *
829a84457aed4c45bc900998b5e11c03023264208James Dong *      http://www.apache.org/licenses/LICENSE-2.0
929a84457aed4c45bc900998b5e11c03023264208James Dong *
1029a84457aed4c45bc900998b5e11c03023264208James Dong * Unless required by applicable law or agreed to in writing, software
1129a84457aed4c45bc900998b5e11c03023264208James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1229a84457aed4c45bc900998b5e11c03023264208James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
1329a84457aed4c45bc900998b5e11c03023264208James Dong * express or implied.
1429a84457aed4c45bc900998b5e11c03023264208James Dong * See the License for the specific language governing permissions
1529a84457aed4c45bc900998b5e11c03023264208James Dong * and limitations under the License.
1629a84457aed4c45bc900998b5e11c03023264208James Dong * -------------------------------------------------------------------
1729a84457aed4c45bc900998b5e11c03023264208James Dong */
1829a84457aed4c45bc900998b5e11c03023264208James Dong#include "avcenc_lib.h"
1929a84457aed4c45bc900998b5e11c03023264208James Dong
2029a84457aed4c45bc900998b5e11c03023264208James Dong/* subtract with the prediction and do transformation */
2129a84457aed4c45bc900998b5e11c03023264208James Dongvoid trans(uint8 *cur, int pitch, uint8 *predBlock, int16 *dataBlock)
2229a84457aed4c45bc900998b5e11c03023264208James Dong{
2329a84457aed4c45bc900998b5e11c03023264208James Dong    int16 *ptr = dataBlock;
2429a84457aed4c45bc900998b5e11c03023264208James Dong    int r0, r1, r2, r3, j;
2529a84457aed4c45bc900998b5e11c03023264208James Dong    int curpitch = (uint)pitch >> 16;
2629a84457aed4c45bc900998b5e11c03023264208James Dong    int predpitch = (pitch & 0xFFFF);
2729a84457aed4c45bc900998b5e11c03023264208James Dong
2829a84457aed4c45bc900998b5e11c03023264208James Dong    /* horizontal */
2929a84457aed4c45bc900998b5e11c03023264208James Dong    j = 4;
3029a84457aed4c45bc900998b5e11c03023264208James Dong    while (j > 0)
3129a84457aed4c45bc900998b5e11c03023264208James Dong    {
3229a84457aed4c45bc900998b5e11c03023264208James Dong        /* calculate the residue first */
3329a84457aed4c45bc900998b5e11c03023264208James Dong        r0 = cur[0] - predBlock[0];
3429a84457aed4c45bc900998b5e11c03023264208James Dong        r1 = cur[1] - predBlock[1];
3529a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = cur[2] - predBlock[2];
3629a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = cur[3] - predBlock[3];
3729a84457aed4c45bc900998b5e11c03023264208James Dong
3829a84457aed4c45bc900998b5e11c03023264208James Dong        r0 += r3;           //ptr[0] + ptr[3];
3929a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = r0 - (r3 << 1);    //ptr[0] - ptr[3];
4029a84457aed4c45bc900998b5e11c03023264208James Dong        r1 += r2;           //ptr[1] + ptr[2];
4129a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = r1 - (r2 << 1);    //ptr[1] - ptr[2];
4229a84457aed4c45bc900998b5e11c03023264208James Dong
4329a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[0] = r0 + r1;
4429a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[2] = r0 - r1;
4529a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[1] = (r3 << 1) + r2;
4629a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[3] = r3 - (r2 << 1);
4729a84457aed4c45bc900998b5e11c03023264208James Dong
4829a84457aed4c45bc900998b5e11c03023264208James Dong        ptr += 16;
4929a84457aed4c45bc900998b5e11c03023264208James Dong        predBlock += predpitch;
5029a84457aed4c45bc900998b5e11c03023264208James Dong        cur += curpitch;
5129a84457aed4c45bc900998b5e11c03023264208James Dong        j--;
5229a84457aed4c45bc900998b5e11c03023264208James Dong    }
5329a84457aed4c45bc900998b5e11c03023264208James Dong    /* vertical */
5429a84457aed4c45bc900998b5e11c03023264208James Dong    ptr = dataBlock;
5529a84457aed4c45bc900998b5e11c03023264208James Dong    j = 4;
5629a84457aed4c45bc900998b5e11c03023264208James Dong    while (j > 0)
5729a84457aed4c45bc900998b5e11c03023264208James Dong    {
5829a84457aed4c45bc900998b5e11c03023264208James Dong        r0 = ptr[0] + ptr[48];
5929a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = ptr[0] - ptr[48];
6029a84457aed4c45bc900998b5e11c03023264208James Dong        r1 = ptr[16] + ptr[32];
6129a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = ptr[16] - ptr[32];
6229a84457aed4c45bc900998b5e11c03023264208James Dong
6329a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[0] = r0 + r1;
6429a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[32] = r0 - r1;
6529a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[16] = (r3 << 1) + r2;
6629a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[48] = r3 - (r2 << 1);
6729a84457aed4c45bc900998b5e11c03023264208James Dong
6829a84457aed4c45bc900998b5e11c03023264208James Dong        ptr++;
6929a84457aed4c45bc900998b5e11c03023264208James Dong        j--;
7029a84457aed4c45bc900998b5e11c03023264208James Dong    }
7129a84457aed4c45bc900998b5e11c03023264208James Dong
7229a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
7329a84457aed4c45bc900998b5e11c03023264208James Dong}
7429a84457aed4c45bc900998b5e11c03023264208James Dong
7529a84457aed4c45bc900998b5e11c03023264208James Dong
7629a84457aed4c45bc900998b5e11c03023264208James Dong/* do residue transform quant invquant, invtrans and write output out */
7729a84457aed4c45bc900998b5e11c03023264208James Dongint dct_luma(AVCEncObject *encvid, int blkidx, uint8 *cur, uint8 *org, int *coef_cost)
7829a84457aed4c45bc900998b5e11c03023264208James Dong{
7929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
8029a84457aed4c45bc900998b5e11c03023264208James Dong    int org_pitch = encvid->currInput->pitch;
8129a84457aed4c45bc900998b5e11c03023264208James Dong    int pitch = video->currPic->pitch;
8229a84457aed4c45bc900998b5e11c03023264208James Dong    int16 *coef = video->block;
8329a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *pred = video->pred_block; // size 16 for a 4x4 block
8429a84457aed4c45bc900998b5e11c03023264208James Dong    int pred_pitch = video->pred_pitch;
8529a84457aed4c45bc900998b5e11c03023264208James Dong    int r0, r1, r2, r3, j, k, idx;
8629a84457aed4c45bc900998b5e11c03023264208James Dong    int *level, *run;
8729a84457aed4c45bc900998b5e11c03023264208James Dong    int Qq, Rq, q_bits, qp_const, quant;
8829a84457aed4c45bc900998b5e11c03023264208James Dong    int data, lev, zero_run;
8929a84457aed4c45bc900998b5e11c03023264208James Dong    int numcoeff;
9029a84457aed4c45bc900998b5e11c03023264208James Dong
9129a84457aed4c45bc900998b5e11c03023264208James Dong    coef += ((blkidx & 0x3) << 2) + ((blkidx >> 2) << 6); /* point to the 4x4 block */
9229a84457aed4c45bc900998b5e11c03023264208James Dong
9329a84457aed4c45bc900998b5e11c03023264208James Dong    /* first take a 4x4 transform */
9429a84457aed4c45bc900998b5e11c03023264208James Dong    /* horizontal */
9529a84457aed4c45bc900998b5e11c03023264208James Dong    j = 4;
9629a84457aed4c45bc900998b5e11c03023264208James Dong    while (j > 0)
9729a84457aed4c45bc900998b5e11c03023264208James Dong    {
9829a84457aed4c45bc900998b5e11c03023264208James Dong        /* calculate the residue first */
9929a84457aed4c45bc900998b5e11c03023264208James Dong        r0 = org[0] - pred[0];   /* OPTIMIZEABLE */
10029a84457aed4c45bc900998b5e11c03023264208James Dong        r1 = org[1] - pred[1];
10129a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = org[2] - pred[2];
10229a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = org[3] - pred[3];
10329a84457aed4c45bc900998b5e11c03023264208James Dong
10429a84457aed4c45bc900998b5e11c03023264208James Dong        r0 += r3;           //ptr[0] + ptr[3];
10529a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = r0 - (r3 << 1);    //ptr[0] - ptr[3];
10629a84457aed4c45bc900998b5e11c03023264208James Dong        r1 += r2;           //ptr[1] + ptr[2];
10729a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = r1 - (r2 << 1);    //ptr[1] - ptr[2];
10829a84457aed4c45bc900998b5e11c03023264208James Dong
10929a84457aed4c45bc900998b5e11c03023264208James Dong        coef[0] = r0 + r1;
11029a84457aed4c45bc900998b5e11c03023264208James Dong        coef[2] = r0 - r1;
11129a84457aed4c45bc900998b5e11c03023264208James Dong        coef[1] = (r3 << 1) + r2;
11229a84457aed4c45bc900998b5e11c03023264208James Dong        coef[3] = r3 - (r2 << 1);
11329a84457aed4c45bc900998b5e11c03023264208James Dong
11429a84457aed4c45bc900998b5e11c03023264208James Dong        coef += 16;
11529a84457aed4c45bc900998b5e11c03023264208James Dong        org += org_pitch;
11629a84457aed4c45bc900998b5e11c03023264208James Dong        pred += pred_pitch;
11729a84457aed4c45bc900998b5e11c03023264208James Dong        j--;
11829a84457aed4c45bc900998b5e11c03023264208James Dong    }
11929a84457aed4c45bc900998b5e11c03023264208James Dong    /* vertical */
12029a84457aed4c45bc900998b5e11c03023264208James Dong    coef -= 64;
12129a84457aed4c45bc900998b5e11c03023264208James Dong    pred -= (pred_pitch << 2);
12229a84457aed4c45bc900998b5e11c03023264208James Dong    j = 4;
12329a84457aed4c45bc900998b5e11c03023264208James Dong    while (j > 0)   /* OPTIMIZABLE */
12429a84457aed4c45bc900998b5e11c03023264208James Dong    {
12529a84457aed4c45bc900998b5e11c03023264208James Dong        r0 = coef[0] + coef[48];
12629a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = coef[0] - coef[48];
12729a84457aed4c45bc900998b5e11c03023264208James Dong        r1 = coef[16] + coef[32];
12829a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = coef[16] - coef[32];
12929a84457aed4c45bc900998b5e11c03023264208James Dong
13029a84457aed4c45bc900998b5e11c03023264208James Dong        coef[0] = r0 + r1;
13129a84457aed4c45bc900998b5e11c03023264208James Dong        coef[32] = r0 - r1;
13229a84457aed4c45bc900998b5e11c03023264208James Dong        coef[16] = (r3 << 1) + r2;
13329a84457aed4c45bc900998b5e11c03023264208James Dong        coef[48] = r3 - (r2 << 1);
13429a84457aed4c45bc900998b5e11c03023264208James Dong
13529a84457aed4c45bc900998b5e11c03023264208James Dong        coef++;
13629a84457aed4c45bc900998b5e11c03023264208James Dong        j--;
13729a84457aed4c45bc900998b5e11c03023264208James Dong    }
13829a84457aed4c45bc900998b5e11c03023264208James Dong
13929a84457aed4c45bc900998b5e11c03023264208James Dong    coef -= 4;
14029a84457aed4c45bc900998b5e11c03023264208James Dong
14129a84457aed4c45bc900998b5e11c03023264208James Dong    /* quant */
14229a84457aed4c45bc900998b5e11c03023264208James Dong    level = encvid->level[ras2dec[blkidx]];
14329a84457aed4c45bc900998b5e11c03023264208James Dong    run = encvid->run[ras2dec[blkidx]];
14429a84457aed4c45bc900998b5e11c03023264208James Dong
14529a84457aed4c45bc900998b5e11c03023264208James Dong    Rq = video->QPy_mod_6;
14629a84457aed4c45bc900998b5e11c03023264208James Dong    Qq = video->QPy_div_6;
14729a84457aed4c45bc900998b5e11c03023264208James Dong    qp_const = encvid->qp_const;
14829a84457aed4c45bc900998b5e11c03023264208James Dong    q_bits = 15 + Qq;
14929a84457aed4c45bc900998b5e11c03023264208James Dong
15029a84457aed4c45bc900998b5e11c03023264208James Dong    zero_run = 0;
15129a84457aed4c45bc900998b5e11c03023264208James Dong    numcoeff = 0;
15229a84457aed4c45bc900998b5e11c03023264208James Dong    for (k = 0; k < 16; k++)
15329a84457aed4c45bc900998b5e11c03023264208James Dong    {
15429a84457aed4c45bc900998b5e11c03023264208James Dong        idx = ZZ_SCAN_BLOCK[k]; /* map back to raster scan order */
15529a84457aed4c45bc900998b5e11c03023264208James Dong        data = coef[idx];
15629a84457aed4c45bc900998b5e11c03023264208James Dong        quant = quant_coef[Rq][k];
15729a84457aed4c45bc900998b5e11c03023264208James Dong        if (data > 0)
15829a84457aed4c45bc900998b5e11c03023264208James Dong        {
15929a84457aed4c45bc900998b5e11c03023264208James Dong            lev = data * quant + qp_const;
16029a84457aed4c45bc900998b5e11c03023264208James Dong        }
16129a84457aed4c45bc900998b5e11c03023264208James Dong        else
16229a84457aed4c45bc900998b5e11c03023264208James Dong        {
16329a84457aed4c45bc900998b5e11c03023264208James Dong            lev = -data * quant + qp_const;
16429a84457aed4c45bc900998b5e11c03023264208James Dong        }
16529a84457aed4c45bc900998b5e11c03023264208James Dong        lev >>= q_bits;
16629a84457aed4c45bc900998b5e11c03023264208James Dong        if (lev)
16729a84457aed4c45bc900998b5e11c03023264208James Dong        {
16829a84457aed4c45bc900998b5e11c03023264208James Dong            *coef_cost += ((lev > 1) ? MAX_VALUE : COEFF_COST[DISABLE_THRESHOLDING][zero_run]);
16929a84457aed4c45bc900998b5e11c03023264208James Dong
17029a84457aed4c45bc900998b5e11c03023264208James Dong            /* dequant */
17129a84457aed4c45bc900998b5e11c03023264208James Dong            quant = dequant_coefres[Rq][k];
17229a84457aed4c45bc900998b5e11c03023264208James Dong            if (data > 0)
17329a84457aed4c45bc900998b5e11c03023264208James Dong            {
17429a84457aed4c45bc900998b5e11c03023264208James Dong                level[numcoeff] = lev;
17529a84457aed4c45bc900998b5e11c03023264208James Dong                coef[idx] = (lev * quant) << Qq;
17629a84457aed4c45bc900998b5e11c03023264208James Dong            }
17729a84457aed4c45bc900998b5e11c03023264208James Dong            else
17829a84457aed4c45bc900998b5e11c03023264208James Dong            {
17929a84457aed4c45bc900998b5e11c03023264208James Dong                level[numcoeff] = -lev;
18029a84457aed4c45bc900998b5e11c03023264208James Dong                coef[idx] = (-lev * quant) << Qq;
18129a84457aed4c45bc900998b5e11c03023264208James Dong            }
18229a84457aed4c45bc900998b5e11c03023264208James Dong            run[numcoeff++] = zero_run;
18329a84457aed4c45bc900998b5e11c03023264208James Dong            zero_run = 0;
18429a84457aed4c45bc900998b5e11c03023264208James Dong        }
18529a84457aed4c45bc900998b5e11c03023264208James Dong        else
18629a84457aed4c45bc900998b5e11c03023264208James Dong        {
18729a84457aed4c45bc900998b5e11c03023264208James Dong            zero_run++;
18829a84457aed4c45bc900998b5e11c03023264208James Dong            coef[idx] = 0;
18929a84457aed4c45bc900998b5e11c03023264208James Dong        }
19029a84457aed4c45bc900998b5e11c03023264208James Dong    }
19129a84457aed4c45bc900998b5e11c03023264208James Dong
19229a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->currMB->mb_intra) // only do inverse transform with intra block
19329a84457aed4c45bc900998b5e11c03023264208James Dong    {
19429a84457aed4c45bc900998b5e11c03023264208James Dong        if (numcoeff) /* then do inverse transform */
19529a84457aed4c45bc900998b5e11c03023264208James Dong        {
19629a84457aed4c45bc900998b5e11c03023264208James Dong            for (j = 4; j > 0; j--) /* horizontal */
19729a84457aed4c45bc900998b5e11c03023264208James Dong            {
19829a84457aed4c45bc900998b5e11c03023264208James Dong                r0 = coef[0] + coef[2];
19929a84457aed4c45bc900998b5e11c03023264208James Dong                r1 = coef[0] - coef[2];
20029a84457aed4c45bc900998b5e11c03023264208James Dong                r2 = (coef[1] >> 1) - coef[3];
20129a84457aed4c45bc900998b5e11c03023264208James Dong                r3 = coef[1] + (coef[3] >> 1);
20229a84457aed4c45bc900998b5e11c03023264208James Dong
20329a84457aed4c45bc900998b5e11c03023264208James Dong                coef[0] = r0 + r3;
20429a84457aed4c45bc900998b5e11c03023264208James Dong                coef[1] = r1 + r2;
20529a84457aed4c45bc900998b5e11c03023264208James Dong                coef[2] = r1 - r2;
20629a84457aed4c45bc900998b5e11c03023264208James Dong                coef[3] = r0 - r3;
20729a84457aed4c45bc900998b5e11c03023264208James Dong
20829a84457aed4c45bc900998b5e11c03023264208James Dong                coef += 16;
20929a84457aed4c45bc900998b5e11c03023264208James Dong            }
21029a84457aed4c45bc900998b5e11c03023264208James Dong
21129a84457aed4c45bc900998b5e11c03023264208James Dong            coef -= 64;
21229a84457aed4c45bc900998b5e11c03023264208James Dong            for (j = 4; j > 0; j--) /* vertical, has to be done after horizontal */
21329a84457aed4c45bc900998b5e11c03023264208James Dong            {
21429a84457aed4c45bc900998b5e11c03023264208James Dong                r0 = coef[0] + coef[32];
21529a84457aed4c45bc900998b5e11c03023264208James Dong                r1 = coef[0] - coef[32];
21629a84457aed4c45bc900998b5e11c03023264208James Dong                r2 = (coef[16] >> 1) - coef[48];
21729a84457aed4c45bc900998b5e11c03023264208James Dong                r3 = coef[16] + (coef[48] >> 1);
21829a84457aed4c45bc900998b5e11c03023264208James Dong                r0 += r3;
21929a84457aed4c45bc900998b5e11c03023264208James Dong                r3 = (r0 - (r3 << 1)); /* r0-r3 */
22029a84457aed4c45bc900998b5e11c03023264208James Dong                r1 += r2;
22129a84457aed4c45bc900998b5e11c03023264208James Dong                r2 = (r1 - (r2 << 1)); /* r1-r2 */
22229a84457aed4c45bc900998b5e11c03023264208James Dong                r0 += 32;
22329a84457aed4c45bc900998b5e11c03023264208James Dong                r1 += 32;
22429a84457aed4c45bc900998b5e11c03023264208James Dong                r2 += 32;
22529a84457aed4c45bc900998b5e11c03023264208James Dong                r3 += 32;
22629a84457aed4c45bc900998b5e11c03023264208James Dong
22729a84457aed4c45bc900998b5e11c03023264208James Dong                r0 = pred[0] + (r0 >> 6);
22829a84457aed4c45bc900998b5e11c03023264208James Dong                if ((uint)r0 > 0xFF)   r0 = 0xFF & (~(r0 >> 31));  /* clip */
22929a84457aed4c45bc900998b5e11c03023264208James Dong                r1 = *(pred += pred_pitch) + (r1 >> 6);
23029a84457aed4c45bc900998b5e11c03023264208James Dong                if ((uint)r1 > 0xFF)   r1 = 0xFF & (~(r1 >> 31));  /* clip */
23129a84457aed4c45bc900998b5e11c03023264208James Dong                r2 = *(pred += pred_pitch) + (r2 >> 6);
23229a84457aed4c45bc900998b5e11c03023264208James Dong                if ((uint)r2 > 0xFF)   r2 = 0xFF & (~(r2 >> 31));  /* clip */
23329a84457aed4c45bc900998b5e11c03023264208James Dong                r3 = pred[pred_pitch] + (r3 >> 6);
23429a84457aed4c45bc900998b5e11c03023264208James Dong                if ((uint)r3 > 0xFF)   r3 = 0xFF & (~(r3 >> 31));  /* clip */
23529a84457aed4c45bc900998b5e11c03023264208James Dong
23629a84457aed4c45bc900998b5e11c03023264208James Dong                *cur = r0;
23729a84457aed4c45bc900998b5e11c03023264208James Dong                *(cur += pitch) = r1;
23829a84457aed4c45bc900998b5e11c03023264208James Dong                *(cur += pitch) = r2;
23929a84457aed4c45bc900998b5e11c03023264208James Dong                cur[pitch] = r3;
24029a84457aed4c45bc900998b5e11c03023264208James Dong                cur -= (pitch << 1);
24129a84457aed4c45bc900998b5e11c03023264208James Dong                cur++;
24229a84457aed4c45bc900998b5e11c03023264208James Dong                pred -= (pred_pitch << 1);
24329a84457aed4c45bc900998b5e11c03023264208James Dong                pred++;
24429a84457aed4c45bc900998b5e11c03023264208James Dong                coef++;
24529a84457aed4c45bc900998b5e11c03023264208James Dong            }
24629a84457aed4c45bc900998b5e11c03023264208James Dong        }
24729a84457aed4c45bc900998b5e11c03023264208James Dong        else  // copy from pred to cur
24829a84457aed4c45bc900998b5e11c03023264208James Dong        {
24929a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)cur) = *((uint32*)pred);
25029a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(cur += pitch)) = *((uint32*)(pred += pred_pitch));
25129a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(cur += pitch)) = *((uint32*)(pred += pred_pitch));
25229a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(cur += pitch)) = *((uint32*)(pred += pred_pitch));
25329a84457aed4c45bc900998b5e11c03023264208James Dong        }
25429a84457aed4c45bc900998b5e11c03023264208James Dong    }
25529a84457aed4c45bc900998b5e11c03023264208James Dong
25629a84457aed4c45bc900998b5e11c03023264208James Dong    return numcoeff;
25729a84457aed4c45bc900998b5e11c03023264208James Dong}
25829a84457aed4c45bc900998b5e11c03023264208James Dong
25929a84457aed4c45bc900998b5e11c03023264208James Dong
26029a84457aed4c45bc900998b5e11c03023264208James Dongvoid MBInterIdct(AVCCommonObj *video, uint8 *curL, AVCMacroblock *currMB, int picPitch)
26129a84457aed4c45bc900998b5e11c03023264208James Dong{
26229a84457aed4c45bc900998b5e11c03023264208James Dong    int16 *coef, *coef8 = video->block;
26329a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *cur;  // the same as curL
26429a84457aed4c45bc900998b5e11c03023264208James Dong    int b8, b4;
26529a84457aed4c45bc900998b5e11c03023264208James Dong    int r0, r1, r2, r3, j, blkidx;
26629a84457aed4c45bc900998b5e11c03023264208James Dong
26729a84457aed4c45bc900998b5e11c03023264208James Dong    for (b8 = 0; b8 < 4; b8++)
26829a84457aed4c45bc900998b5e11c03023264208James Dong    {
26929a84457aed4c45bc900998b5e11c03023264208James Dong        cur = curL;
27029a84457aed4c45bc900998b5e11c03023264208James Dong        coef = coef8;
27129a84457aed4c45bc900998b5e11c03023264208James Dong
27229a84457aed4c45bc900998b5e11c03023264208James Dong        if (currMB->CBP&(1 << b8))
27329a84457aed4c45bc900998b5e11c03023264208James Dong        {
27429a84457aed4c45bc900998b5e11c03023264208James Dong            for (b4 = 0; b4 < 4; b4++)
27529a84457aed4c45bc900998b5e11c03023264208James Dong            {
27629a84457aed4c45bc900998b5e11c03023264208James Dong                blkidx = blkIdx2blkXY[b8][b4];
27729a84457aed4c45bc900998b5e11c03023264208James Dong                /* do IDCT */
27829a84457aed4c45bc900998b5e11c03023264208James Dong                if (currMB->nz_coeff[blkidx])
27929a84457aed4c45bc900998b5e11c03023264208James Dong                {
28029a84457aed4c45bc900998b5e11c03023264208James Dong                    for (j = 4; j > 0; j--) /* horizontal */
28129a84457aed4c45bc900998b5e11c03023264208James Dong                    {
28229a84457aed4c45bc900998b5e11c03023264208James Dong                        r0 = coef[0] + coef[2];
28329a84457aed4c45bc900998b5e11c03023264208James Dong                        r1 = coef[0] - coef[2];
28429a84457aed4c45bc900998b5e11c03023264208James Dong                        r2 = (coef[1] >> 1) - coef[3];
28529a84457aed4c45bc900998b5e11c03023264208James Dong                        r3 = coef[1] + (coef[3] >> 1);
28629a84457aed4c45bc900998b5e11c03023264208James Dong
28729a84457aed4c45bc900998b5e11c03023264208James Dong                        coef[0] = r0 + r3;
28829a84457aed4c45bc900998b5e11c03023264208James Dong                        coef[1] = r1 + r2;
28929a84457aed4c45bc900998b5e11c03023264208James Dong                        coef[2] = r1 - r2;
29029a84457aed4c45bc900998b5e11c03023264208James Dong                        coef[3] = r0 - r3;
29129a84457aed4c45bc900998b5e11c03023264208James Dong
29229a84457aed4c45bc900998b5e11c03023264208James Dong                        coef += 16;
29329a84457aed4c45bc900998b5e11c03023264208James Dong                    }
29429a84457aed4c45bc900998b5e11c03023264208James Dong
29529a84457aed4c45bc900998b5e11c03023264208James Dong                    coef -= 64;
29629a84457aed4c45bc900998b5e11c03023264208James Dong                    for (j = 4; j > 0; j--) /* vertical, has to be done after horizontal */
29729a84457aed4c45bc900998b5e11c03023264208James Dong                    {
29829a84457aed4c45bc900998b5e11c03023264208James Dong                        r0 = coef[0] + coef[32];
29929a84457aed4c45bc900998b5e11c03023264208James Dong                        r1 = coef[0] - coef[32];
30029a84457aed4c45bc900998b5e11c03023264208James Dong                        r2 = (coef[16] >> 1) - coef[48];
30129a84457aed4c45bc900998b5e11c03023264208James Dong                        r3 = coef[16] + (coef[48] >> 1);
30229a84457aed4c45bc900998b5e11c03023264208James Dong                        r0 += r3;
30329a84457aed4c45bc900998b5e11c03023264208James Dong                        r3 = (r0 - (r3 << 1)); /* r0-r3 */
30429a84457aed4c45bc900998b5e11c03023264208James Dong                        r1 += r2;
30529a84457aed4c45bc900998b5e11c03023264208James Dong                        r2 = (r1 - (r2 << 1)); /* r1-r2 */
30629a84457aed4c45bc900998b5e11c03023264208James Dong                        r0 += 32;
30729a84457aed4c45bc900998b5e11c03023264208James Dong                        r1 += 32;
30829a84457aed4c45bc900998b5e11c03023264208James Dong                        r2 += 32;
30929a84457aed4c45bc900998b5e11c03023264208James Dong                        r3 += 32;
31029a84457aed4c45bc900998b5e11c03023264208James Dong
31129a84457aed4c45bc900998b5e11c03023264208James Dong                        r0 = cur[0] + (r0 >> 6);
31229a84457aed4c45bc900998b5e11c03023264208James Dong                        if ((uint)r0 > 0xFF)   r0 = 0xFF & (~(r0 >> 31));  /* clip */
31329a84457aed4c45bc900998b5e11c03023264208James Dong                        *cur = r0;
31429a84457aed4c45bc900998b5e11c03023264208James Dong                        r1 = *(cur += picPitch) + (r1 >> 6);
31529a84457aed4c45bc900998b5e11c03023264208James Dong                        if ((uint)r1 > 0xFF)   r1 = 0xFF & (~(r1 >> 31));  /* clip */
31629a84457aed4c45bc900998b5e11c03023264208James Dong                        *cur = r1;
31729a84457aed4c45bc900998b5e11c03023264208James Dong                        r2 = *(cur += picPitch) + (r2 >> 6);
31829a84457aed4c45bc900998b5e11c03023264208James Dong                        if ((uint)r2 > 0xFF)   r2 = 0xFF & (~(r2 >> 31));  /* clip */
31929a84457aed4c45bc900998b5e11c03023264208James Dong                        *cur = r2;
32029a84457aed4c45bc900998b5e11c03023264208James Dong                        r3 = cur[picPitch] + (r3 >> 6);
32129a84457aed4c45bc900998b5e11c03023264208James Dong                        if ((uint)r3 > 0xFF)   r3 = 0xFF & (~(r3 >> 31));  /* clip */
32229a84457aed4c45bc900998b5e11c03023264208James Dong                        cur[picPitch] = r3;
32329a84457aed4c45bc900998b5e11c03023264208James Dong
32429a84457aed4c45bc900998b5e11c03023264208James Dong                        cur -= (picPitch << 1);
32529a84457aed4c45bc900998b5e11c03023264208James Dong                        cur++;
32629a84457aed4c45bc900998b5e11c03023264208James Dong                        coef++;
32729a84457aed4c45bc900998b5e11c03023264208James Dong                    }
32829a84457aed4c45bc900998b5e11c03023264208James Dong                    cur -= 4;
32929a84457aed4c45bc900998b5e11c03023264208James Dong                    coef -= 4;
33029a84457aed4c45bc900998b5e11c03023264208James Dong                }
33129a84457aed4c45bc900998b5e11c03023264208James Dong                if (b4&1)
33229a84457aed4c45bc900998b5e11c03023264208James Dong                {
33329a84457aed4c45bc900998b5e11c03023264208James Dong                    cur += ((picPitch << 2) - 4);
33429a84457aed4c45bc900998b5e11c03023264208James Dong                    coef += 60;
33529a84457aed4c45bc900998b5e11c03023264208James Dong                }
33629a84457aed4c45bc900998b5e11c03023264208James Dong                else
33729a84457aed4c45bc900998b5e11c03023264208James Dong                {
33829a84457aed4c45bc900998b5e11c03023264208James Dong                    cur += 4;
33929a84457aed4c45bc900998b5e11c03023264208James Dong                    coef += 4;
34029a84457aed4c45bc900998b5e11c03023264208James Dong                }
34129a84457aed4c45bc900998b5e11c03023264208James Dong            }
34229a84457aed4c45bc900998b5e11c03023264208James Dong        }
34329a84457aed4c45bc900998b5e11c03023264208James Dong
34429a84457aed4c45bc900998b5e11c03023264208James Dong        if (b8&1)
34529a84457aed4c45bc900998b5e11c03023264208James Dong        {
34629a84457aed4c45bc900998b5e11c03023264208James Dong            curL += ((picPitch << 3) - 8);
34729a84457aed4c45bc900998b5e11c03023264208James Dong            coef8 += 120;
34829a84457aed4c45bc900998b5e11c03023264208James Dong        }
34929a84457aed4c45bc900998b5e11c03023264208James Dong        else
35029a84457aed4c45bc900998b5e11c03023264208James Dong        {
35129a84457aed4c45bc900998b5e11c03023264208James Dong            curL += 8;
35229a84457aed4c45bc900998b5e11c03023264208James Dong            coef8 += 8;
35329a84457aed4c45bc900998b5e11c03023264208James Dong        }
35429a84457aed4c45bc900998b5e11c03023264208James Dong    }
35529a84457aed4c45bc900998b5e11c03023264208James Dong
35629a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
35729a84457aed4c45bc900998b5e11c03023264208James Dong}
35829a84457aed4c45bc900998b5e11c03023264208James Dong
35929a84457aed4c45bc900998b5e11c03023264208James Dong/* performa dct, quant, iquant, idct for the entire MB */
36029a84457aed4c45bc900998b5e11c03023264208James Dongvoid dct_luma_16x16(AVCEncObject *encvid, uint8 *curL, uint8 *orgL)
36129a84457aed4c45bc900998b5e11c03023264208James Dong{
36229a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
36329a84457aed4c45bc900998b5e11c03023264208James Dong    int pitch = video->currPic->pitch;
36429a84457aed4c45bc900998b5e11c03023264208James Dong    int org_pitch = encvid->currInput->pitch;
36529a84457aed4c45bc900998b5e11c03023264208James Dong    AVCMacroblock *currMB = video->currMB;
36629a84457aed4c45bc900998b5e11c03023264208James Dong    int16 *coef = video->block;
36729a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *pred = encvid->pred_i16[currMB->i16Mode];
36829a84457aed4c45bc900998b5e11c03023264208James Dong    int blk_x, blk_y, j, k, idx, b8, b4;
36929a84457aed4c45bc900998b5e11c03023264208James Dong    int r0, r1, r2, r3, m0, m1, m2 , m3;
37029a84457aed4c45bc900998b5e11c03023264208James Dong    int data, lev;
37129a84457aed4c45bc900998b5e11c03023264208James Dong    int *level, *run, zero_run, ncoeff;
37229a84457aed4c45bc900998b5e11c03023264208James Dong    int Rq, Qq, quant, q_bits, qp_const;
37329a84457aed4c45bc900998b5e11c03023264208James Dong    int offset_cur[4], offset_pred[4], offset;
37429a84457aed4c45bc900998b5e11c03023264208James Dong
37529a84457aed4c45bc900998b5e11c03023264208James Dong    /* horizontal */
37629a84457aed4c45bc900998b5e11c03023264208James Dong    for (j = 16; j > 0; j--)
37729a84457aed4c45bc900998b5e11c03023264208James Dong    {
37829a84457aed4c45bc900998b5e11c03023264208James Dong        for (blk_x = 4; blk_x > 0; blk_x--)
37929a84457aed4c45bc900998b5e11c03023264208James Dong        {
38029a84457aed4c45bc900998b5e11c03023264208James Dong            /* calculate the residue first */
38129a84457aed4c45bc900998b5e11c03023264208James Dong            r0 = *orgL++ - *pred++;
38229a84457aed4c45bc900998b5e11c03023264208James Dong            r1 = *orgL++ - *pred++;
38329a84457aed4c45bc900998b5e11c03023264208James Dong            r2 = *orgL++ - *pred++;
38429a84457aed4c45bc900998b5e11c03023264208James Dong            r3 = *orgL++ - *pred++;
38529a84457aed4c45bc900998b5e11c03023264208James Dong
38629a84457aed4c45bc900998b5e11c03023264208James Dong            r0 += r3;           //ptr[0] + ptr[3];
38729a84457aed4c45bc900998b5e11c03023264208James Dong            r3 = r0 - (r3 << 1);    //ptr[0] - ptr[3];
38829a84457aed4c45bc900998b5e11c03023264208James Dong            r1 += r2;           //ptr[1] + ptr[2];
38929a84457aed4c45bc900998b5e11c03023264208James Dong            r2 = r1 - (r2 << 1);    //ptr[1] - ptr[2];
39029a84457aed4c45bc900998b5e11c03023264208James Dong
39129a84457aed4c45bc900998b5e11c03023264208James Dong            *coef++ = r0 + r1;
39229a84457aed4c45bc900998b5e11c03023264208James Dong            *coef++ = (r3 << 1) + r2;
39329a84457aed4c45bc900998b5e11c03023264208James Dong            *coef++ = r0 - r1;
39429a84457aed4c45bc900998b5e11c03023264208James Dong            *coef++ = r3 - (r2 << 1);
39529a84457aed4c45bc900998b5e11c03023264208James Dong        }
39629a84457aed4c45bc900998b5e11c03023264208James Dong        orgL += (org_pitch - 16);
39729a84457aed4c45bc900998b5e11c03023264208James Dong    }
39829a84457aed4c45bc900998b5e11c03023264208James Dong    pred -= 256;
39929a84457aed4c45bc900998b5e11c03023264208James Dong    coef -= 256;
40029a84457aed4c45bc900998b5e11c03023264208James Dong    /* vertical */
40129a84457aed4c45bc900998b5e11c03023264208James Dong    for (blk_y = 4; blk_y > 0; blk_y--)
40229a84457aed4c45bc900998b5e11c03023264208James Dong    {
40329a84457aed4c45bc900998b5e11c03023264208James Dong        for (j = 16; j > 0; j--)
40429a84457aed4c45bc900998b5e11c03023264208James Dong        {
40529a84457aed4c45bc900998b5e11c03023264208James Dong            r0 = coef[0] + coef[48];
40629a84457aed4c45bc900998b5e11c03023264208James Dong            r3 = coef[0] - coef[48];
40729a84457aed4c45bc900998b5e11c03023264208James Dong            r1 = coef[16] + coef[32];
40829a84457aed4c45bc900998b5e11c03023264208James Dong            r2 = coef[16] - coef[32];
40929a84457aed4c45bc900998b5e11c03023264208James Dong
41029a84457aed4c45bc900998b5e11c03023264208James Dong            coef[0] = r0 + r1;
41129a84457aed4c45bc900998b5e11c03023264208James Dong            coef[32] = r0 - r1;
41229a84457aed4c45bc900998b5e11c03023264208James Dong            coef[16] = (r3 << 1) + r2;
41329a84457aed4c45bc900998b5e11c03023264208James Dong            coef[48] = r3 - (r2 << 1);
41429a84457aed4c45bc900998b5e11c03023264208James Dong
41529a84457aed4c45bc900998b5e11c03023264208James Dong            coef++;
41629a84457aed4c45bc900998b5e11c03023264208James Dong        }
41729a84457aed4c45bc900998b5e11c03023264208James Dong        coef += 48;
41829a84457aed4c45bc900998b5e11c03023264208James Dong    }
41929a84457aed4c45bc900998b5e11c03023264208James Dong
42029a84457aed4c45bc900998b5e11c03023264208James Dong    /* then perform DC transform */
42129a84457aed4c45bc900998b5e11c03023264208James Dong    coef -= 256;
42229a84457aed4c45bc900998b5e11c03023264208James Dong    for (j = 4; j > 0; j--)
42329a84457aed4c45bc900998b5e11c03023264208James Dong    {
42429a84457aed4c45bc900998b5e11c03023264208James Dong        r0 = coef[0] + coef[12];
42529a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = coef[0] - coef[12];
42629a84457aed4c45bc900998b5e11c03023264208James Dong        r1 = coef[4] + coef[8];
42729a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = coef[4] - coef[8];
42829a84457aed4c45bc900998b5e11c03023264208James Dong
42929a84457aed4c45bc900998b5e11c03023264208James Dong        coef[0] = r0 + r1;
43029a84457aed4c45bc900998b5e11c03023264208James Dong        coef[8] = r0 - r1;
43129a84457aed4c45bc900998b5e11c03023264208James Dong        coef[4] = r3 + r2;
43229a84457aed4c45bc900998b5e11c03023264208James Dong        coef[12] = r3 - r2;
43329a84457aed4c45bc900998b5e11c03023264208James Dong        coef += 64;
43429a84457aed4c45bc900998b5e11c03023264208James Dong    }
43529a84457aed4c45bc900998b5e11c03023264208James Dong    coef -= 256;
43629a84457aed4c45bc900998b5e11c03023264208James Dong    for (j = 4; j > 0; j--)
43729a84457aed4c45bc900998b5e11c03023264208James Dong    {
43829a84457aed4c45bc900998b5e11c03023264208James Dong        r0 = coef[0] + coef[192];
43929a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = coef[0] - coef[192];
44029a84457aed4c45bc900998b5e11c03023264208James Dong        r1 = coef[64] + coef[128];
44129a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = coef[64] - coef[128];
44229a84457aed4c45bc900998b5e11c03023264208James Dong
44329a84457aed4c45bc900998b5e11c03023264208James Dong        coef[0] = (r0 + r1) >> 1;
44429a84457aed4c45bc900998b5e11c03023264208James Dong        coef[128] = (r0 - r1) >> 1;
44529a84457aed4c45bc900998b5e11c03023264208James Dong        coef[64] = (r3 + r2) >> 1;
44629a84457aed4c45bc900998b5e11c03023264208James Dong        coef[192] = (r3 - r2) >> 1;
44729a84457aed4c45bc900998b5e11c03023264208James Dong        coef += 4;
44829a84457aed4c45bc900998b5e11c03023264208James Dong    }
44929a84457aed4c45bc900998b5e11c03023264208James Dong
45029a84457aed4c45bc900998b5e11c03023264208James Dong    coef -= 16;
45129a84457aed4c45bc900998b5e11c03023264208James Dong    // then quantize DC
45229a84457aed4c45bc900998b5e11c03023264208James Dong    level = encvid->leveldc;
45329a84457aed4c45bc900998b5e11c03023264208James Dong    run = encvid->rundc;
45429a84457aed4c45bc900998b5e11c03023264208James Dong
45529a84457aed4c45bc900998b5e11c03023264208James Dong    Rq = video->QPy_mod_6;
45629a84457aed4c45bc900998b5e11c03023264208James Dong    Qq = video->QPy_div_6;
45729a84457aed4c45bc900998b5e11c03023264208James Dong    quant = quant_coef[Rq][0];
45829a84457aed4c45bc900998b5e11c03023264208James Dong    q_bits = 15 + Qq;
45929a84457aed4c45bc900998b5e11c03023264208James Dong    qp_const = encvid->qp_const;
46029a84457aed4c45bc900998b5e11c03023264208James Dong
46129a84457aed4c45bc900998b5e11c03023264208James Dong    zero_run = 0;
46229a84457aed4c45bc900998b5e11c03023264208James Dong    ncoeff = 0;
46329a84457aed4c45bc900998b5e11c03023264208James Dong    for (k = 0; k < 16; k++) /* in zigzag scan order */
46429a84457aed4c45bc900998b5e11c03023264208James Dong    {
46529a84457aed4c45bc900998b5e11c03023264208James Dong        idx = ZIGZAG2RASTERDC[k];
46629a84457aed4c45bc900998b5e11c03023264208James Dong        data = coef[idx];
46729a84457aed4c45bc900998b5e11c03023264208James Dong        if (data > 0)   // quant
46829a84457aed4c45bc900998b5e11c03023264208James Dong        {
46929a84457aed4c45bc900998b5e11c03023264208James Dong            lev = data * quant + (qp_const << 1);
47029a84457aed4c45bc900998b5e11c03023264208James Dong        }
47129a84457aed4c45bc900998b5e11c03023264208James Dong        else
47229a84457aed4c45bc900998b5e11c03023264208James Dong        {
47329a84457aed4c45bc900998b5e11c03023264208James Dong            lev = -data * quant + (qp_const << 1);
47429a84457aed4c45bc900998b5e11c03023264208James Dong        }
47529a84457aed4c45bc900998b5e11c03023264208James Dong        lev >>= (q_bits + 1);
47629a84457aed4c45bc900998b5e11c03023264208James Dong        if (lev) // dequant
47729a84457aed4c45bc900998b5e11c03023264208James Dong        {
47829a84457aed4c45bc900998b5e11c03023264208James Dong            if (data > 0)
47929a84457aed4c45bc900998b5e11c03023264208James Dong            {
48029a84457aed4c45bc900998b5e11c03023264208James Dong                level[ncoeff] = lev;
48129a84457aed4c45bc900998b5e11c03023264208James Dong                coef[idx] = lev;
48229a84457aed4c45bc900998b5e11c03023264208James Dong            }
48329a84457aed4c45bc900998b5e11c03023264208James Dong            else
48429a84457aed4c45bc900998b5e11c03023264208James Dong            {
48529a84457aed4c45bc900998b5e11c03023264208James Dong                level[ncoeff] = -lev;
48629a84457aed4c45bc900998b5e11c03023264208James Dong                coef[idx] = -lev;
48729a84457aed4c45bc900998b5e11c03023264208James Dong            }
48829a84457aed4c45bc900998b5e11c03023264208James Dong            run[ncoeff++] = zero_run;
48929a84457aed4c45bc900998b5e11c03023264208James Dong            zero_run = 0;
49029a84457aed4c45bc900998b5e11c03023264208James Dong        }
49129a84457aed4c45bc900998b5e11c03023264208James Dong        else
49229a84457aed4c45bc900998b5e11c03023264208James Dong        {
49329a84457aed4c45bc900998b5e11c03023264208James Dong            zero_run++;
49429a84457aed4c45bc900998b5e11c03023264208James Dong            coef[idx] = 0;
49529a84457aed4c45bc900998b5e11c03023264208James Dong        }
49629a84457aed4c45bc900998b5e11c03023264208James Dong    }
49729a84457aed4c45bc900998b5e11c03023264208James Dong
49829a84457aed4c45bc900998b5e11c03023264208James Dong    /* inverse transform DC */
49929a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->numcoefdc = ncoeff;
50029a84457aed4c45bc900998b5e11c03023264208James Dong    if (ncoeff)
50129a84457aed4c45bc900998b5e11c03023264208James Dong    {
50229a84457aed4c45bc900998b5e11c03023264208James Dong        quant = dequant_coefres[Rq][0];
50329a84457aed4c45bc900998b5e11c03023264208James Dong
50429a84457aed4c45bc900998b5e11c03023264208James Dong        for (j = 0; j < 4; j++)
50529a84457aed4c45bc900998b5e11c03023264208James Dong        {
50629a84457aed4c45bc900998b5e11c03023264208James Dong            m0 = coef[0] + coef[4];
50729a84457aed4c45bc900998b5e11c03023264208James Dong            m1 = coef[0] - coef[4];
50829a84457aed4c45bc900998b5e11c03023264208James Dong            m2 = coef[8] + coef[12];
50929a84457aed4c45bc900998b5e11c03023264208James Dong            m3 = coef[8] - coef[12];
51029a84457aed4c45bc900998b5e11c03023264208James Dong
51129a84457aed4c45bc900998b5e11c03023264208James Dong
51229a84457aed4c45bc900998b5e11c03023264208James Dong            coef[0] = m0 + m2;
51329a84457aed4c45bc900998b5e11c03023264208James Dong            coef[4] = m0 - m2;
51429a84457aed4c45bc900998b5e11c03023264208James Dong            coef[8] = m1 - m3;
51529a84457aed4c45bc900998b5e11c03023264208James Dong            coef[12] = m1 + m3;
51629a84457aed4c45bc900998b5e11c03023264208James Dong            coef += 64;
51729a84457aed4c45bc900998b5e11c03023264208James Dong        }
51829a84457aed4c45bc900998b5e11c03023264208James Dong
51929a84457aed4c45bc900998b5e11c03023264208James Dong        coef -= 256;
52029a84457aed4c45bc900998b5e11c03023264208James Dong
52129a84457aed4c45bc900998b5e11c03023264208James Dong        if (Qq >= 2)  /* this way should be faster than JM */
52229a84457aed4c45bc900998b5e11c03023264208James Dong        {           /* they use (((m4*scale)<<(QPy/6))+2)>>2 for both cases. */
52329a84457aed4c45bc900998b5e11c03023264208James Dong            Qq -= 2;
52429a84457aed4c45bc900998b5e11c03023264208James Dong            for (j = 0; j < 4; j++)
52529a84457aed4c45bc900998b5e11c03023264208James Dong            {
52629a84457aed4c45bc900998b5e11c03023264208James Dong                m0 = coef[0] + coef[64];
52729a84457aed4c45bc900998b5e11c03023264208James Dong                m1 = coef[0] - coef[64];
52829a84457aed4c45bc900998b5e11c03023264208James Dong                m2 = coef[128] + coef[192];
52929a84457aed4c45bc900998b5e11c03023264208James Dong                m3 = coef[128] - coef[192];
53029a84457aed4c45bc900998b5e11c03023264208James Dong
53129a84457aed4c45bc900998b5e11c03023264208James Dong                coef[0] = ((m0 + m2) * quant) << Qq;
53229a84457aed4c45bc900998b5e11c03023264208James Dong                coef[64] = ((m0 - m2) * quant) << Qq;
53329a84457aed4c45bc900998b5e11c03023264208James Dong                coef[128] = ((m1 - m3) * quant) << Qq;
53429a84457aed4c45bc900998b5e11c03023264208James Dong                coef[192] = ((m1 + m3) * quant) << Qq;
53529a84457aed4c45bc900998b5e11c03023264208James Dong                coef += 4;
53629a84457aed4c45bc900998b5e11c03023264208James Dong            }
53729a84457aed4c45bc900998b5e11c03023264208James Dong            Qq += 2; /* restore the value */
53829a84457aed4c45bc900998b5e11c03023264208James Dong        }
53929a84457aed4c45bc900998b5e11c03023264208James Dong        else
54029a84457aed4c45bc900998b5e11c03023264208James Dong        {
54129a84457aed4c45bc900998b5e11c03023264208James Dong            Qq = 2 - Qq;
54229a84457aed4c45bc900998b5e11c03023264208James Dong            offset = 1 << (Qq - 1);
54329a84457aed4c45bc900998b5e11c03023264208James Dong
54429a84457aed4c45bc900998b5e11c03023264208James Dong            for (j = 0; j < 4; j++)
54529a84457aed4c45bc900998b5e11c03023264208James Dong            {
54629a84457aed4c45bc900998b5e11c03023264208James Dong                m0 = coef[0] + coef[64];
54729a84457aed4c45bc900998b5e11c03023264208James Dong                m1 = coef[0] - coef[64];
54829a84457aed4c45bc900998b5e11c03023264208James Dong                m2 = coef[128] + coef[192];
54929a84457aed4c45bc900998b5e11c03023264208James Dong                m3 = coef[128] - coef[192];
55029a84457aed4c45bc900998b5e11c03023264208James Dong
55129a84457aed4c45bc900998b5e11c03023264208James Dong                coef[0] = (((m0 + m2) * quant + offset) >> Qq);
55229a84457aed4c45bc900998b5e11c03023264208James Dong                coef[64] = (((m0 - m2) * quant + offset) >> Qq);
55329a84457aed4c45bc900998b5e11c03023264208James Dong                coef[128] = (((m1 - m3) * quant + offset) >> Qq);
55429a84457aed4c45bc900998b5e11c03023264208James Dong                coef[192] = (((m1 + m3) * quant + offset) >> Qq);
55529a84457aed4c45bc900998b5e11c03023264208James Dong                coef += 4;
55629a84457aed4c45bc900998b5e11c03023264208James Dong            }
55729a84457aed4c45bc900998b5e11c03023264208James Dong            Qq = 2 - Qq; /* restore the value */
55829a84457aed4c45bc900998b5e11c03023264208James Dong        }
55929a84457aed4c45bc900998b5e11c03023264208James Dong        coef -= 16; /* back to the origin */
56029a84457aed4c45bc900998b5e11c03023264208James Dong    }
56129a84457aed4c45bc900998b5e11c03023264208James Dong
56229a84457aed4c45bc900998b5e11c03023264208James Dong    /* now zigzag scan ac coefs, quant, iquant and itrans */
56329a84457aed4c45bc900998b5e11c03023264208James Dong    run = encvid->run[0];
56429a84457aed4c45bc900998b5e11c03023264208James Dong    level = encvid->level[0];
56529a84457aed4c45bc900998b5e11c03023264208James Dong
56629a84457aed4c45bc900998b5e11c03023264208James Dong    /* offset btw 4x4 block */
56729a84457aed4c45bc900998b5e11c03023264208James Dong    offset_cur[0] = 0;
56829a84457aed4c45bc900998b5e11c03023264208James Dong    offset_cur[1] = (pitch << 2) - 8;
56929a84457aed4c45bc900998b5e11c03023264208James Dong
57029a84457aed4c45bc900998b5e11c03023264208James Dong    /* offset btw 8x8 block */
57129a84457aed4c45bc900998b5e11c03023264208James Dong    offset_cur[2] = 8 - (pitch << 3);
57229a84457aed4c45bc900998b5e11c03023264208James Dong    offset_cur[3] = -8;
57329a84457aed4c45bc900998b5e11c03023264208James Dong
57429a84457aed4c45bc900998b5e11c03023264208James Dong    /* similarly for pred */
57529a84457aed4c45bc900998b5e11c03023264208James Dong    offset_pred[0] = 0;
57629a84457aed4c45bc900998b5e11c03023264208James Dong    offset_pred[1] = 56;
57729a84457aed4c45bc900998b5e11c03023264208James Dong    offset_pred[2] = -120;
57829a84457aed4c45bc900998b5e11c03023264208James Dong    offset_pred[3] = -8;
57929a84457aed4c45bc900998b5e11c03023264208James Dong
58029a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->CBP = 0;
58129a84457aed4c45bc900998b5e11c03023264208James Dong
58229a84457aed4c45bc900998b5e11c03023264208James Dong    for (b8 = 0; b8 < 4; b8++)
58329a84457aed4c45bc900998b5e11c03023264208James Dong    {
58429a84457aed4c45bc900998b5e11c03023264208James Dong        for (b4 = 0; b4 < 4; b4++)
58529a84457aed4c45bc900998b5e11c03023264208James Dong        {
58629a84457aed4c45bc900998b5e11c03023264208James Dong
58729a84457aed4c45bc900998b5e11c03023264208James Dong            zero_run = 0;
58829a84457aed4c45bc900998b5e11c03023264208James Dong            ncoeff = 0;
58929a84457aed4c45bc900998b5e11c03023264208James Dong
59029a84457aed4c45bc900998b5e11c03023264208James Dong            for (k = 1; k < 16; k++)
59129a84457aed4c45bc900998b5e11c03023264208James Dong            {
59229a84457aed4c45bc900998b5e11c03023264208James Dong                idx = ZZ_SCAN_BLOCK[k]; /* map back to raster scan order */
59329a84457aed4c45bc900998b5e11c03023264208James Dong                data = coef[idx];
59429a84457aed4c45bc900998b5e11c03023264208James Dong                quant = quant_coef[Rq][k];
59529a84457aed4c45bc900998b5e11c03023264208James Dong                if (data > 0)
59629a84457aed4c45bc900998b5e11c03023264208James Dong                {
59729a84457aed4c45bc900998b5e11c03023264208James Dong                    lev = data * quant + qp_const;
59829a84457aed4c45bc900998b5e11c03023264208James Dong                }
59929a84457aed4c45bc900998b5e11c03023264208James Dong                else
60029a84457aed4c45bc900998b5e11c03023264208James Dong                {
60129a84457aed4c45bc900998b5e11c03023264208James Dong                    lev = -data * quant + qp_const;
60229a84457aed4c45bc900998b5e11c03023264208James Dong                }
60329a84457aed4c45bc900998b5e11c03023264208James Dong                lev >>= q_bits;
60429a84457aed4c45bc900998b5e11c03023264208James Dong                if (lev)
60529a84457aed4c45bc900998b5e11c03023264208James Dong                {   /* dequant */
60629a84457aed4c45bc900998b5e11c03023264208James Dong                    quant = dequant_coefres[Rq][k];
60729a84457aed4c45bc900998b5e11c03023264208James Dong                    if (data > 0)
60829a84457aed4c45bc900998b5e11c03023264208James Dong                    {
60929a84457aed4c45bc900998b5e11c03023264208James Dong                        level[ncoeff] = lev;
61029a84457aed4c45bc900998b5e11c03023264208James Dong                        coef[idx] = (lev * quant) << Qq;
61129a84457aed4c45bc900998b5e11c03023264208James Dong                    }
61229a84457aed4c45bc900998b5e11c03023264208James Dong                    else
61329a84457aed4c45bc900998b5e11c03023264208James Dong                    {
61429a84457aed4c45bc900998b5e11c03023264208James Dong                        level[ncoeff] = -lev;
61529a84457aed4c45bc900998b5e11c03023264208James Dong                        coef[idx] = (-lev * quant) << Qq;
61629a84457aed4c45bc900998b5e11c03023264208James Dong                    }
61729a84457aed4c45bc900998b5e11c03023264208James Dong                    run[ncoeff++] = zero_run;
61829a84457aed4c45bc900998b5e11c03023264208James Dong                    zero_run = 0;
61929a84457aed4c45bc900998b5e11c03023264208James Dong                }
62029a84457aed4c45bc900998b5e11c03023264208James Dong                else
62129a84457aed4c45bc900998b5e11c03023264208James Dong                {
62229a84457aed4c45bc900998b5e11c03023264208James Dong                    zero_run++;
62329a84457aed4c45bc900998b5e11c03023264208James Dong                    coef[idx] = 0;
62429a84457aed4c45bc900998b5e11c03023264208James Dong                }
62529a84457aed4c45bc900998b5e11c03023264208James Dong            }
62629a84457aed4c45bc900998b5e11c03023264208James Dong
62729a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->nz_coeff[blkIdx2blkXY[b8][b4]] = ncoeff; /* in raster scan !!! */
62829a84457aed4c45bc900998b5e11c03023264208James Dong            if (ncoeff)
62929a84457aed4c45bc900998b5e11c03023264208James Dong            {
63029a84457aed4c45bc900998b5e11c03023264208James Dong                currMB->CBP |= (1 << b8);
63129a84457aed4c45bc900998b5e11c03023264208James Dong
63229a84457aed4c45bc900998b5e11c03023264208James Dong                // do inverse transform here
63329a84457aed4c45bc900998b5e11c03023264208James Dong                for (j = 4; j > 0; j--)
63429a84457aed4c45bc900998b5e11c03023264208James Dong                {
63529a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 = coef[0] + coef[2];
63629a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 = coef[0] - coef[2];
63729a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 = (coef[1] >> 1) - coef[3];
63829a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 = coef[1] + (coef[3] >> 1);
63929a84457aed4c45bc900998b5e11c03023264208James Dong
64029a84457aed4c45bc900998b5e11c03023264208James Dong                    coef[0] = r0 + r3;
64129a84457aed4c45bc900998b5e11c03023264208James Dong                    coef[1] = r1 + r2;
64229a84457aed4c45bc900998b5e11c03023264208James Dong                    coef[2] = r1 - r2;
64329a84457aed4c45bc900998b5e11c03023264208James Dong                    coef[3] = r0 - r3;
64429a84457aed4c45bc900998b5e11c03023264208James Dong
64529a84457aed4c45bc900998b5e11c03023264208James Dong                    coef += 16;
64629a84457aed4c45bc900998b5e11c03023264208James Dong                }
64729a84457aed4c45bc900998b5e11c03023264208James Dong                coef -= 64;
64829a84457aed4c45bc900998b5e11c03023264208James Dong                for (j = 4; j > 0; j--)
64929a84457aed4c45bc900998b5e11c03023264208James Dong                {
65029a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 = coef[0] + coef[32];
65129a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 = coef[0] - coef[32];
65229a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 = (coef[16] >> 1) - coef[48];
65329a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 = coef[16] + (coef[48] >> 1);
65429a84457aed4c45bc900998b5e11c03023264208James Dong
65529a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 += r3;
65629a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 = (r0 - (r3 << 1)); /* r0-r3 */
65729a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 += r2;
65829a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 = (r1 - (r2 << 1)); /* r1-r2 */
65929a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 += 32;
66029a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 += 32;
66129a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 += 32;
66229a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 += 32;
66329a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 = pred[0] + (r0 >> 6);
66429a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r0 > 0xFF)   r0 = 0xFF & (~(r0 >> 31));  /* clip */
66529a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 = pred[16] + (r1 >> 6);
66629a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r1 > 0xFF)   r1 = 0xFF & (~(r1 >> 31));  /* clip */
66729a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 = pred[32] + (r2 >> 6);
66829a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r2 > 0xFF)   r2 = 0xFF & (~(r2 >> 31));  /* clip */
66929a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 = pred[48] + (r3 >> 6);
67029a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r3 > 0xFF)   r3 = 0xFF & (~(r3 >> 31));  /* clip */
67129a84457aed4c45bc900998b5e11c03023264208James Dong                    *curL = r0;
67229a84457aed4c45bc900998b5e11c03023264208James Dong                    *(curL += pitch) = r1;
67329a84457aed4c45bc900998b5e11c03023264208James Dong                    *(curL += pitch) = r2;
67429a84457aed4c45bc900998b5e11c03023264208James Dong                    curL[pitch] = r3;
67529a84457aed4c45bc900998b5e11c03023264208James Dong                    curL -= (pitch << 1);
67629a84457aed4c45bc900998b5e11c03023264208James Dong                    curL++;
67729a84457aed4c45bc900998b5e11c03023264208James Dong                    pred++;
67829a84457aed4c45bc900998b5e11c03023264208James Dong                    coef++;
67929a84457aed4c45bc900998b5e11c03023264208James Dong                }
68029a84457aed4c45bc900998b5e11c03023264208James Dong            }
68129a84457aed4c45bc900998b5e11c03023264208James Dong            else  // do DC-only inverse
68229a84457aed4c45bc900998b5e11c03023264208James Dong            {
68329a84457aed4c45bc900998b5e11c03023264208James Dong                m0 = coef[0] + 32;
68429a84457aed4c45bc900998b5e11c03023264208James Dong
68529a84457aed4c45bc900998b5e11c03023264208James Dong                for (j = 4; j > 0; j--)
68629a84457aed4c45bc900998b5e11c03023264208James Dong                {
68729a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 = pred[0] + (m0 >> 6);
68829a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r0 > 0xFF)   r0 = 0xFF & (~(r0 >> 31));  /* clip */
68929a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 = pred[16] + (m0 >> 6);
69029a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r1 > 0xFF)   r1 = 0xFF & (~(r1 >> 31));  /* clip */
69129a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 = pred[32] + (m0 >> 6);
69229a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r2 > 0xFF)   r2 = 0xFF & (~(r2 >> 31));  /* clip */
69329a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 = pred[48] + (m0 >> 6);
69429a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r3 > 0xFF)   r3 = 0xFF & (~(r3 >> 31));  /* clip */
69529a84457aed4c45bc900998b5e11c03023264208James Dong                    *curL = r0;
69629a84457aed4c45bc900998b5e11c03023264208James Dong                    *(curL += pitch) = r1;
69729a84457aed4c45bc900998b5e11c03023264208James Dong                    *(curL += pitch) = r2;
69829a84457aed4c45bc900998b5e11c03023264208James Dong                    curL[pitch] = r3;
69929a84457aed4c45bc900998b5e11c03023264208James Dong                    curL -= (pitch << 1);
70029a84457aed4c45bc900998b5e11c03023264208James Dong                    curL++;
70129a84457aed4c45bc900998b5e11c03023264208James Dong                    pred++;
70229a84457aed4c45bc900998b5e11c03023264208James Dong                }
70329a84457aed4c45bc900998b5e11c03023264208James Dong                coef += 4;
70429a84457aed4c45bc900998b5e11c03023264208James Dong            }
70529a84457aed4c45bc900998b5e11c03023264208James Dong
70629a84457aed4c45bc900998b5e11c03023264208James Dong            run += 16;  // follow coding order
70729a84457aed4c45bc900998b5e11c03023264208James Dong            level += 16;
70829a84457aed4c45bc900998b5e11c03023264208James Dong            curL += offset_cur[b4&1];
70929a84457aed4c45bc900998b5e11c03023264208James Dong            pred += offset_pred[b4&1];
71029a84457aed4c45bc900998b5e11c03023264208James Dong            coef += offset_pred[b4&1];
71129a84457aed4c45bc900998b5e11c03023264208James Dong        }
71229a84457aed4c45bc900998b5e11c03023264208James Dong
71329a84457aed4c45bc900998b5e11c03023264208James Dong        curL += offset_cur[2 + (b8&1)];
71429a84457aed4c45bc900998b5e11c03023264208James Dong        pred += offset_pred[2 + (b8&1)];
71529a84457aed4c45bc900998b5e11c03023264208James Dong        coef += offset_pred[2 + (b8&1)];
71629a84457aed4c45bc900998b5e11c03023264208James Dong    }
71729a84457aed4c45bc900998b5e11c03023264208James Dong
71829a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
71929a84457aed4c45bc900998b5e11c03023264208James Dong}
72029a84457aed4c45bc900998b5e11c03023264208James Dong
72129a84457aed4c45bc900998b5e11c03023264208James Dong
72229a84457aed4c45bc900998b5e11c03023264208James Dongvoid dct_chroma(AVCEncObject *encvid, uint8 *curC, uint8 *orgC, int cr)
72329a84457aed4c45bc900998b5e11c03023264208James Dong{
72429a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
72529a84457aed4c45bc900998b5e11c03023264208James Dong    AVCMacroblock *currMB = video->currMB;
72629a84457aed4c45bc900998b5e11c03023264208James Dong    int org_pitch = (encvid->currInput->pitch) >> 1;
72729a84457aed4c45bc900998b5e11c03023264208James Dong    int pitch = (video->currPic->pitch) >> 1;
72829a84457aed4c45bc900998b5e11c03023264208James Dong    int pred_pitch = 16;
72929a84457aed4c45bc900998b5e11c03023264208James Dong    int16 *coef = video->block + 256;
73029a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *pred = video->pred_block;
73129a84457aed4c45bc900998b5e11c03023264208James Dong    int j, blk_x, blk_y, k, idx, b4;
73229a84457aed4c45bc900998b5e11c03023264208James Dong    int r0, r1, r2, r3, m0;
73329a84457aed4c45bc900998b5e11c03023264208James Dong    int Qq, Rq, qp_const, q_bits, quant;
73429a84457aed4c45bc900998b5e11c03023264208James Dong    int *level, *run, zero_run, ncoeff;
73529a84457aed4c45bc900998b5e11c03023264208James Dong    int data, lev;
73629a84457aed4c45bc900998b5e11c03023264208James Dong    int offset_cur[2], offset_pred[2], offset_coef[2];
73729a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 nz_temp[4];
73829a84457aed4c45bc900998b5e11c03023264208James Dong    int  coeff_cost;
73929a84457aed4c45bc900998b5e11c03023264208James Dong
74029a84457aed4c45bc900998b5e11c03023264208James Dong    if (cr)
74129a84457aed4c45bc900998b5e11c03023264208James Dong    {
74229a84457aed4c45bc900998b5e11c03023264208James Dong        coef += 8;
74329a84457aed4c45bc900998b5e11c03023264208James Dong        pred += 8;
74429a84457aed4c45bc900998b5e11c03023264208James Dong    }
74529a84457aed4c45bc900998b5e11c03023264208James Dong
74629a84457aed4c45bc900998b5e11c03023264208James Dong    if (currMB->mb_intra == 0) // inter mode
74729a84457aed4c45bc900998b5e11c03023264208James Dong    {
74829a84457aed4c45bc900998b5e11c03023264208James Dong        pred = curC;
74929a84457aed4c45bc900998b5e11c03023264208James Dong        pred_pitch = pitch;
75029a84457aed4c45bc900998b5e11c03023264208James Dong    }
75129a84457aed4c45bc900998b5e11c03023264208James Dong
75229a84457aed4c45bc900998b5e11c03023264208James Dong    /* do 4x4 transform */
75329a84457aed4c45bc900998b5e11c03023264208James Dong    /* horizontal */
75429a84457aed4c45bc900998b5e11c03023264208James Dong    for (j = 8; j > 0; j--)
75529a84457aed4c45bc900998b5e11c03023264208James Dong    {
75629a84457aed4c45bc900998b5e11c03023264208James Dong        for (blk_x = 2; blk_x > 0; blk_x--)
75729a84457aed4c45bc900998b5e11c03023264208James Dong        {
75829a84457aed4c45bc900998b5e11c03023264208James Dong            /* calculate the residue first */
75929a84457aed4c45bc900998b5e11c03023264208James Dong            r0 = *orgC++ - *pred++;
76029a84457aed4c45bc900998b5e11c03023264208James Dong            r1 = *orgC++ - *pred++;
76129a84457aed4c45bc900998b5e11c03023264208James Dong            r2 = *orgC++ - *pred++;
76229a84457aed4c45bc900998b5e11c03023264208James Dong            r3 = *orgC++ - *pred++;
76329a84457aed4c45bc900998b5e11c03023264208James Dong
76429a84457aed4c45bc900998b5e11c03023264208James Dong            r0 += r3;           //ptr[0] + ptr[3];
76529a84457aed4c45bc900998b5e11c03023264208James Dong            r3 = r0 - (r3 << 1);    //ptr[0] - ptr[3];
76629a84457aed4c45bc900998b5e11c03023264208James Dong            r1 += r2;           //ptr[1] + ptr[2];
76729a84457aed4c45bc900998b5e11c03023264208James Dong            r2 = r1 - (r2 << 1);    //ptr[1] - ptr[2];
76829a84457aed4c45bc900998b5e11c03023264208James Dong
76929a84457aed4c45bc900998b5e11c03023264208James Dong            *coef++ = r0 + r1;
77029a84457aed4c45bc900998b5e11c03023264208James Dong            *coef++ = (r3 << 1) + r2;
77129a84457aed4c45bc900998b5e11c03023264208James Dong            *coef++ = r0 - r1;
77229a84457aed4c45bc900998b5e11c03023264208James Dong            *coef++ = r3 - (r2 << 1);
77329a84457aed4c45bc900998b5e11c03023264208James Dong
77429a84457aed4c45bc900998b5e11c03023264208James Dong        }
77529a84457aed4c45bc900998b5e11c03023264208James Dong        coef += 8; // coef pitch is 16
77629a84457aed4c45bc900998b5e11c03023264208James Dong        pred += (pred_pitch - 8); // pred_pitch is 16
77729a84457aed4c45bc900998b5e11c03023264208James Dong        orgC += (org_pitch - 8);
77829a84457aed4c45bc900998b5e11c03023264208James Dong    }
77929a84457aed4c45bc900998b5e11c03023264208James Dong    pred -= (pred_pitch << 3);
78029a84457aed4c45bc900998b5e11c03023264208James Dong    coef -= 128;
78129a84457aed4c45bc900998b5e11c03023264208James Dong    /* vertical */
78229a84457aed4c45bc900998b5e11c03023264208James Dong    for (blk_y = 2; blk_y > 0; blk_y--)
78329a84457aed4c45bc900998b5e11c03023264208James Dong    {
78429a84457aed4c45bc900998b5e11c03023264208James Dong        for (j = 8; j > 0; j--)
78529a84457aed4c45bc900998b5e11c03023264208James Dong        {
78629a84457aed4c45bc900998b5e11c03023264208James Dong            r0 = coef[0] + coef[48];
78729a84457aed4c45bc900998b5e11c03023264208James Dong            r3 = coef[0] - coef[48];
78829a84457aed4c45bc900998b5e11c03023264208James Dong            r1 = coef[16] + coef[32];
78929a84457aed4c45bc900998b5e11c03023264208James Dong            r2 = coef[16] - coef[32];
79029a84457aed4c45bc900998b5e11c03023264208James Dong
79129a84457aed4c45bc900998b5e11c03023264208James Dong            coef[0] = r0 + r1;
79229a84457aed4c45bc900998b5e11c03023264208James Dong            coef[32] = r0 - r1;
79329a84457aed4c45bc900998b5e11c03023264208James Dong            coef[16] = (r3 << 1) + r2;
79429a84457aed4c45bc900998b5e11c03023264208James Dong            coef[48] = r3 - (r2 << 1);
79529a84457aed4c45bc900998b5e11c03023264208James Dong
79629a84457aed4c45bc900998b5e11c03023264208James Dong            coef++;
79729a84457aed4c45bc900998b5e11c03023264208James Dong        }
79829a84457aed4c45bc900998b5e11c03023264208James Dong        coef += 56;
79929a84457aed4c45bc900998b5e11c03023264208James Dong    }
80029a84457aed4c45bc900998b5e11c03023264208James Dong    /* then perform DC transform */
80129a84457aed4c45bc900998b5e11c03023264208James Dong    coef -= 128;
80229a84457aed4c45bc900998b5e11c03023264208James Dong
80329a84457aed4c45bc900998b5e11c03023264208James Dong    /* 2x2 transform of DC components*/
80429a84457aed4c45bc900998b5e11c03023264208James Dong    r0 = coef[0];
80529a84457aed4c45bc900998b5e11c03023264208James Dong    r1 = coef[4];
80629a84457aed4c45bc900998b5e11c03023264208James Dong    r2 = coef[64];
80729a84457aed4c45bc900998b5e11c03023264208James Dong    r3 = coef[68];
80829a84457aed4c45bc900998b5e11c03023264208James Dong
80929a84457aed4c45bc900998b5e11c03023264208James Dong    coef[0] = r0 + r1 + r2 + r3;
81029a84457aed4c45bc900998b5e11c03023264208James Dong    coef[4] = r0 - r1 + r2 - r3;
81129a84457aed4c45bc900998b5e11c03023264208James Dong    coef[64] = r0 + r1 - r2 - r3;
81229a84457aed4c45bc900998b5e11c03023264208James Dong    coef[68] = r0 - r1 - r2 + r3;
81329a84457aed4c45bc900998b5e11c03023264208James Dong
81429a84457aed4c45bc900998b5e11c03023264208James Dong    Qq    = video->QPc_div_6;
81529a84457aed4c45bc900998b5e11c03023264208James Dong    Rq    = video->QPc_mod_6;
81629a84457aed4c45bc900998b5e11c03023264208James Dong    quant = quant_coef[Rq][0];
81729a84457aed4c45bc900998b5e11c03023264208James Dong    q_bits    = 15 + Qq;
81829a84457aed4c45bc900998b5e11c03023264208James Dong    qp_const = encvid->qp_const_c;
81929a84457aed4c45bc900998b5e11c03023264208James Dong
82029a84457aed4c45bc900998b5e11c03023264208James Dong    zero_run = 0;
82129a84457aed4c45bc900998b5e11c03023264208James Dong    ncoeff = 0;
82229a84457aed4c45bc900998b5e11c03023264208James Dong    run = encvid->runcdc + (cr << 2);
82329a84457aed4c45bc900998b5e11c03023264208James Dong    level = encvid->levelcdc + (cr << 2);
82429a84457aed4c45bc900998b5e11c03023264208James Dong
82529a84457aed4c45bc900998b5e11c03023264208James Dong    /* in zigzag scan order */
82629a84457aed4c45bc900998b5e11c03023264208James Dong    for (k = 0; k < 4; k++)
82729a84457aed4c45bc900998b5e11c03023264208James Dong    {
82829a84457aed4c45bc900998b5e11c03023264208James Dong        idx = ((k >> 1) << 6) + ((k & 1) << 2);
82929a84457aed4c45bc900998b5e11c03023264208James Dong        data = coef[idx];
83029a84457aed4c45bc900998b5e11c03023264208James Dong        if (data > 0)
83129a84457aed4c45bc900998b5e11c03023264208James Dong        {
83229a84457aed4c45bc900998b5e11c03023264208James Dong            lev = data * quant + (qp_const << 1);
83329a84457aed4c45bc900998b5e11c03023264208James Dong        }
83429a84457aed4c45bc900998b5e11c03023264208James Dong        else
83529a84457aed4c45bc900998b5e11c03023264208James Dong        {
83629a84457aed4c45bc900998b5e11c03023264208James Dong            lev = -data * quant + (qp_const << 1);
83729a84457aed4c45bc900998b5e11c03023264208James Dong        }
83829a84457aed4c45bc900998b5e11c03023264208James Dong        lev >>= (q_bits + 1);
83929a84457aed4c45bc900998b5e11c03023264208James Dong        if (lev)
84029a84457aed4c45bc900998b5e11c03023264208James Dong        {
84129a84457aed4c45bc900998b5e11c03023264208James Dong            if (data > 0)
84229a84457aed4c45bc900998b5e11c03023264208James Dong            {
84329a84457aed4c45bc900998b5e11c03023264208James Dong                level[ncoeff] = lev;
84429a84457aed4c45bc900998b5e11c03023264208James Dong                coef[idx] = lev;
84529a84457aed4c45bc900998b5e11c03023264208James Dong            }
84629a84457aed4c45bc900998b5e11c03023264208James Dong            else
84729a84457aed4c45bc900998b5e11c03023264208James Dong            {
84829a84457aed4c45bc900998b5e11c03023264208James Dong                level[ncoeff] = -lev;
84929a84457aed4c45bc900998b5e11c03023264208James Dong                coef[idx] = -lev;
85029a84457aed4c45bc900998b5e11c03023264208James Dong            }
85129a84457aed4c45bc900998b5e11c03023264208James Dong            run[ncoeff++] = zero_run;
85229a84457aed4c45bc900998b5e11c03023264208James Dong            zero_run = 0;
85329a84457aed4c45bc900998b5e11c03023264208James Dong        }
85429a84457aed4c45bc900998b5e11c03023264208James Dong        else
85529a84457aed4c45bc900998b5e11c03023264208James Dong        {
85629a84457aed4c45bc900998b5e11c03023264208James Dong            zero_run++;
85729a84457aed4c45bc900998b5e11c03023264208James Dong            coef[idx] = 0;
85829a84457aed4c45bc900998b5e11c03023264208James Dong        }
85929a84457aed4c45bc900998b5e11c03023264208James Dong    }
86029a84457aed4c45bc900998b5e11c03023264208James Dong
86129a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->numcoefcdc[cr] = ncoeff;
86229a84457aed4c45bc900998b5e11c03023264208James Dong
86329a84457aed4c45bc900998b5e11c03023264208James Dong    if (ncoeff)
86429a84457aed4c45bc900998b5e11c03023264208James Dong    {
86529a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->CBP |= (1 << 4); // DC present
86629a84457aed4c45bc900998b5e11c03023264208James Dong        // do inverse transform
86729a84457aed4c45bc900998b5e11c03023264208James Dong        quant = dequant_coefres[Rq][0];
86829a84457aed4c45bc900998b5e11c03023264208James Dong
86929a84457aed4c45bc900998b5e11c03023264208James Dong        r0 = coef[0] + coef[4];
87029a84457aed4c45bc900998b5e11c03023264208James Dong        r1 = coef[0] - coef[4];
87129a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = coef[64] + coef[68];
87229a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = coef[64] - coef[68];
87329a84457aed4c45bc900998b5e11c03023264208James Dong
87429a84457aed4c45bc900998b5e11c03023264208James Dong        r0 += r2;
87529a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = r0 - (r2 << 1);
87629a84457aed4c45bc900998b5e11c03023264208James Dong        r1 += r3;
87729a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = r1 - (r3 << 1);
87829a84457aed4c45bc900998b5e11c03023264208James Dong
87929a84457aed4c45bc900998b5e11c03023264208James Dong        if (Qq >= 1)
88029a84457aed4c45bc900998b5e11c03023264208James Dong        {
88129a84457aed4c45bc900998b5e11c03023264208James Dong            Qq -= 1;
88229a84457aed4c45bc900998b5e11c03023264208James Dong            coef[0] = (r0 * quant) << Qq;
88329a84457aed4c45bc900998b5e11c03023264208James Dong            coef[4] = (r1 * quant) << Qq;
88429a84457aed4c45bc900998b5e11c03023264208James Dong            coef[64] = (r2 * quant) << Qq;
88529a84457aed4c45bc900998b5e11c03023264208James Dong            coef[68] = (r3 * quant) << Qq;
88629a84457aed4c45bc900998b5e11c03023264208James Dong            Qq++;
88729a84457aed4c45bc900998b5e11c03023264208James Dong        }
88829a84457aed4c45bc900998b5e11c03023264208James Dong        else
88929a84457aed4c45bc900998b5e11c03023264208James Dong        {
89029a84457aed4c45bc900998b5e11c03023264208James Dong            coef[0] = (r0 * quant) >> 1;
89129a84457aed4c45bc900998b5e11c03023264208James Dong            coef[4] = (r1 * quant) >> 1;
89229a84457aed4c45bc900998b5e11c03023264208James Dong            coef[64] = (r2 * quant) >> 1;
89329a84457aed4c45bc900998b5e11c03023264208James Dong            coef[68] = (r3 * quant) >> 1;
89429a84457aed4c45bc900998b5e11c03023264208James Dong        }
89529a84457aed4c45bc900998b5e11c03023264208James Dong    }
89629a84457aed4c45bc900998b5e11c03023264208James Dong
89729a84457aed4c45bc900998b5e11c03023264208James Dong    /* now do AC zigzag scan, quant, iquant and itrans */
89829a84457aed4c45bc900998b5e11c03023264208James Dong    if (cr)
89929a84457aed4c45bc900998b5e11c03023264208James Dong    {
90029a84457aed4c45bc900998b5e11c03023264208James Dong        run = encvid->run[20];
90129a84457aed4c45bc900998b5e11c03023264208James Dong        level = encvid->level[20];
90229a84457aed4c45bc900998b5e11c03023264208James Dong    }
90329a84457aed4c45bc900998b5e11c03023264208James Dong    else
90429a84457aed4c45bc900998b5e11c03023264208James Dong    {
90529a84457aed4c45bc900998b5e11c03023264208James Dong        run = encvid->run[16];
90629a84457aed4c45bc900998b5e11c03023264208James Dong        level = encvid->level[16];
90729a84457aed4c45bc900998b5e11c03023264208James Dong    }
90829a84457aed4c45bc900998b5e11c03023264208James Dong
90929a84457aed4c45bc900998b5e11c03023264208James Dong    /* offset btw 4x4 block */
91029a84457aed4c45bc900998b5e11c03023264208James Dong    offset_cur[0] = 0;
91129a84457aed4c45bc900998b5e11c03023264208James Dong    offset_cur[1] = (pitch << 2) - 8;
91229a84457aed4c45bc900998b5e11c03023264208James Dong    offset_pred[0] = 0;
91329a84457aed4c45bc900998b5e11c03023264208James Dong    offset_pred[1] = (pred_pitch << 2) - 8;
91429a84457aed4c45bc900998b5e11c03023264208James Dong    offset_coef[0] = 0;
91529a84457aed4c45bc900998b5e11c03023264208James Dong    offset_coef[1] = 56;
91629a84457aed4c45bc900998b5e11c03023264208James Dong
91729a84457aed4c45bc900998b5e11c03023264208James Dong    coeff_cost = 0;
91829a84457aed4c45bc900998b5e11c03023264208James Dong
91929a84457aed4c45bc900998b5e11c03023264208James Dong    for (b4 = 0; b4 < 4; b4++)
92029a84457aed4c45bc900998b5e11c03023264208James Dong    {
92129a84457aed4c45bc900998b5e11c03023264208James Dong        zero_run = 0;
92229a84457aed4c45bc900998b5e11c03023264208James Dong        ncoeff = 0;
92329a84457aed4c45bc900998b5e11c03023264208James Dong        for (k = 1; k < 16; k++) /* in zigzag scan order */
92429a84457aed4c45bc900998b5e11c03023264208James Dong        {
92529a84457aed4c45bc900998b5e11c03023264208James Dong            idx = ZZ_SCAN_BLOCK[k]; /* map back to raster scan order */
92629a84457aed4c45bc900998b5e11c03023264208James Dong            data = coef[idx];
92729a84457aed4c45bc900998b5e11c03023264208James Dong            quant = quant_coef[Rq][k];
92829a84457aed4c45bc900998b5e11c03023264208James Dong            if (data > 0)
92929a84457aed4c45bc900998b5e11c03023264208James Dong            {
93029a84457aed4c45bc900998b5e11c03023264208James Dong                lev = data * quant + qp_const;
93129a84457aed4c45bc900998b5e11c03023264208James Dong            }
93229a84457aed4c45bc900998b5e11c03023264208James Dong            else
93329a84457aed4c45bc900998b5e11c03023264208James Dong            {
93429a84457aed4c45bc900998b5e11c03023264208James Dong                lev = -data * quant + qp_const;
93529a84457aed4c45bc900998b5e11c03023264208James Dong            }
93629a84457aed4c45bc900998b5e11c03023264208James Dong            lev >>= q_bits;
93729a84457aed4c45bc900998b5e11c03023264208James Dong            if (lev)
93829a84457aed4c45bc900998b5e11c03023264208James Dong            {
93929a84457aed4c45bc900998b5e11c03023264208James Dong                /* for RD performance*/
94029a84457aed4c45bc900998b5e11c03023264208James Dong                if (lev > 1)
94129a84457aed4c45bc900998b5e11c03023264208James Dong                    coeff_cost += MAX_VALUE;                // set high cost, shall not be discarded
94229a84457aed4c45bc900998b5e11c03023264208James Dong                else
94329a84457aed4c45bc900998b5e11c03023264208James Dong                    coeff_cost += COEFF_COST[DISABLE_THRESHOLDING][zero_run];
94429a84457aed4c45bc900998b5e11c03023264208James Dong
94529a84457aed4c45bc900998b5e11c03023264208James Dong                /* dequant */
94629a84457aed4c45bc900998b5e11c03023264208James Dong                quant = dequant_coefres[Rq][k];
94729a84457aed4c45bc900998b5e11c03023264208James Dong                if (data > 0)
94829a84457aed4c45bc900998b5e11c03023264208James Dong                {
94929a84457aed4c45bc900998b5e11c03023264208James Dong                    level[ncoeff] = lev;
95029a84457aed4c45bc900998b5e11c03023264208James Dong                    coef[idx] = (lev * quant) << Qq;
95129a84457aed4c45bc900998b5e11c03023264208James Dong                }
95229a84457aed4c45bc900998b5e11c03023264208James Dong                else
95329a84457aed4c45bc900998b5e11c03023264208James Dong                {
95429a84457aed4c45bc900998b5e11c03023264208James Dong                    level[ncoeff] = -lev;
95529a84457aed4c45bc900998b5e11c03023264208James Dong                    coef[idx] = (-lev * quant) << Qq;
95629a84457aed4c45bc900998b5e11c03023264208James Dong                }
95729a84457aed4c45bc900998b5e11c03023264208James Dong                run[ncoeff++] = zero_run;
95829a84457aed4c45bc900998b5e11c03023264208James Dong                zero_run = 0;
95929a84457aed4c45bc900998b5e11c03023264208James Dong            }
96029a84457aed4c45bc900998b5e11c03023264208James Dong            else
96129a84457aed4c45bc900998b5e11c03023264208James Dong            {
96229a84457aed4c45bc900998b5e11c03023264208James Dong                zero_run++;
96329a84457aed4c45bc900998b5e11c03023264208James Dong                coef[idx] = 0;
96429a84457aed4c45bc900998b5e11c03023264208James Dong            }
96529a84457aed4c45bc900998b5e11c03023264208James Dong        }
96629a84457aed4c45bc900998b5e11c03023264208James Dong
96729a84457aed4c45bc900998b5e11c03023264208James Dong        nz_temp[b4] = ncoeff; // raster scan
96829a84457aed4c45bc900998b5e11c03023264208James Dong
96929a84457aed4c45bc900998b5e11c03023264208James Dong        // just advance the pointers for now, do IDCT later
97029a84457aed4c45bc900998b5e11c03023264208James Dong        coef += 4;
97129a84457aed4c45bc900998b5e11c03023264208James Dong        run += 16;
97229a84457aed4c45bc900998b5e11c03023264208James Dong        level += 16;
97329a84457aed4c45bc900998b5e11c03023264208James Dong        coef += offset_coef[b4&1];
97429a84457aed4c45bc900998b5e11c03023264208James Dong    }
97529a84457aed4c45bc900998b5e11c03023264208James Dong
97629a84457aed4c45bc900998b5e11c03023264208James Dong    /* rewind the pointers */
97729a84457aed4c45bc900998b5e11c03023264208James Dong    coef -= 128;
97829a84457aed4c45bc900998b5e11c03023264208James Dong
97929a84457aed4c45bc900998b5e11c03023264208James Dong    if (coeff_cost < _CHROMA_COEFF_COST_)
98029a84457aed4c45bc900998b5e11c03023264208James Dong    {
98129a84457aed4c45bc900998b5e11c03023264208James Dong        /* if it's not efficient to encode any blocks.
98229a84457aed4c45bc900998b5e11c03023264208James Dong        Just do DC only */
98329a84457aed4c45bc900998b5e11c03023264208James Dong        /* We can reset level and run also, but setting nz to zero should be enough. */
98429a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->nz_coeff[16+(cr<<1)] = 0;
98529a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->nz_coeff[17+(cr<<1)] = 0;
98629a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->nz_coeff[20+(cr<<1)] = 0;
98729a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->nz_coeff[21+(cr<<1)] = 0;
98829a84457aed4c45bc900998b5e11c03023264208James Dong
98929a84457aed4c45bc900998b5e11c03023264208James Dong        for (b4 = 0; b4 < 4; b4++)
99029a84457aed4c45bc900998b5e11c03023264208James Dong        {
99129a84457aed4c45bc900998b5e11c03023264208James Dong            // do DC-only inverse
99229a84457aed4c45bc900998b5e11c03023264208James Dong            m0 = coef[0] + 32;
99329a84457aed4c45bc900998b5e11c03023264208James Dong
99429a84457aed4c45bc900998b5e11c03023264208James Dong            for (j = 4; j > 0; j--)
99529a84457aed4c45bc900998b5e11c03023264208James Dong            {
99629a84457aed4c45bc900998b5e11c03023264208James Dong                r0 = pred[0] + (m0 >> 6);
99729a84457aed4c45bc900998b5e11c03023264208James Dong                if ((uint)r0 > 0xFF)   r0 = 0xFF & (~(r0 >> 31));  /* clip */
99829a84457aed4c45bc900998b5e11c03023264208James Dong                r1 = *(pred += pred_pitch) + (m0 >> 6);
99929a84457aed4c45bc900998b5e11c03023264208James Dong                if ((uint)r1 > 0xFF)   r1 = 0xFF & (~(r1 >> 31));  /* clip */
100029a84457aed4c45bc900998b5e11c03023264208James Dong                r2 = pred[pred_pitch] + (m0 >> 6);
100129a84457aed4c45bc900998b5e11c03023264208James Dong                if ((uint)r2 > 0xFF)   r2 = 0xFF & (~(r2 >> 31));  /* clip */
100229a84457aed4c45bc900998b5e11c03023264208James Dong                r3 = pred[pred_pitch<<1] + (m0 >> 6);
100329a84457aed4c45bc900998b5e11c03023264208James Dong                if ((uint)r3 > 0xFF)   r3 = 0xFF & (~(r3 >> 31));  /* clip */
100429a84457aed4c45bc900998b5e11c03023264208James Dong                *curC = r0;
100529a84457aed4c45bc900998b5e11c03023264208James Dong                *(curC += pitch) = r1;
100629a84457aed4c45bc900998b5e11c03023264208James Dong                *(curC += pitch) = r2;
100729a84457aed4c45bc900998b5e11c03023264208James Dong                curC[pitch] = r3;
100829a84457aed4c45bc900998b5e11c03023264208James Dong                curC -= (pitch << 1);
100929a84457aed4c45bc900998b5e11c03023264208James Dong                curC++;
101029a84457aed4c45bc900998b5e11c03023264208James Dong                pred += (1 - pred_pitch);
101129a84457aed4c45bc900998b5e11c03023264208James Dong            }
101229a84457aed4c45bc900998b5e11c03023264208James Dong            coef += 4;
101329a84457aed4c45bc900998b5e11c03023264208James Dong            curC += offset_cur[b4&1];
101429a84457aed4c45bc900998b5e11c03023264208James Dong            pred += offset_pred[b4&1];
101529a84457aed4c45bc900998b5e11c03023264208James Dong            coef += offset_coef[b4&1];
101629a84457aed4c45bc900998b5e11c03023264208James Dong        }
101729a84457aed4c45bc900998b5e11c03023264208James Dong    }
101829a84457aed4c45bc900998b5e11c03023264208James Dong    else // not dropping anything, continue with the IDCT
101929a84457aed4c45bc900998b5e11c03023264208James Dong    {
102029a84457aed4c45bc900998b5e11c03023264208James Dong        for (b4 = 0; b4 < 4; b4++)
102129a84457aed4c45bc900998b5e11c03023264208James Dong        {
102229a84457aed4c45bc900998b5e11c03023264208James Dong            ncoeff = nz_temp[b4] ; // in raster scan
102329a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->nz_coeff[16+(b4&1)+(cr<<1)+((b4>>1)<<2)] = ncoeff; // in raster scan
102429a84457aed4c45bc900998b5e11c03023264208James Dong
102529a84457aed4c45bc900998b5e11c03023264208James Dong            if (ncoeff) // do a check on the nonzero-coeff
102629a84457aed4c45bc900998b5e11c03023264208James Dong            {
102729a84457aed4c45bc900998b5e11c03023264208James Dong                currMB->CBP |= (2 << 4);
102829a84457aed4c45bc900998b5e11c03023264208James Dong
102929a84457aed4c45bc900998b5e11c03023264208James Dong                // do inverse transform here
103029a84457aed4c45bc900998b5e11c03023264208James Dong                for (j = 4; j > 0; j--)
103129a84457aed4c45bc900998b5e11c03023264208James Dong                {
103229a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 = coef[0] + coef[2];
103329a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 = coef[0] - coef[2];
103429a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 = (coef[1] >> 1) - coef[3];
103529a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 = coef[1] + (coef[3] >> 1);
103629a84457aed4c45bc900998b5e11c03023264208James Dong
103729a84457aed4c45bc900998b5e11c03023264208James Dong                    coef[0] = r0 + r3;
103829a84457aed4c45bc900998b5e11c03023264208James Dong                    coef[1] = r1 + r2;
103929a84457aed4c45bc900998b5e11c03023264208James Dong                    coef[2] = r1 - r2;
104029a84457aed4c45bc900998b5e11c03023264208James Dong                    coef[3] = r0 - r3;
104129a84457aed4c45bc900998b5e11c03023264208James Dong
104229a84457aed4c45bc900998b5e11c03023264208James Dong                    coef += 16;
104329a84457aed4c45bc900998b5e11c03023264208James Dong                }
104429a84457aed4c45bc900998b5e11c03023264208James Dong                coef -= 64;
104529a84457aed4c45bc900998b5e11c03023264208James Dong                for (j = 4; j > 0; j--)
104629a84457aed4c45bc900998b5e11c03023264208James Dong                {
104729a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 = coef[0] + coef[32];
104829a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 = coef[0] - coef[32];
104929a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 = (coef[16] >> 1) - coef[48];
105029a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 = coef[16] + (coef[48] >> 1);
105129a84457aed4c45bc900998b5e11c03023264208James Dong
105229a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 += r3;
105329a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 = (r0 - (r3 << 1)); /* r0-r3 */
105429a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 += r2;
105529a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 = (r1 - (r2 << 1)); /* r1-r2 */
105629a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 += 32;
105729a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 += 32;
105829a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 += 32;
105929a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 += 32;
106029a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 = pred[0] + (r0 >> 6);
106129a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r0 > 0xFF)   r0 = 0xFF & (~(r0 >> 31));  /* clip */
106229a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 = *(pred += pred_pitch) + (r1 >> 6);
106329a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r1 > 0xFF)   r1 = 0xFF & (~(r1 >> 31));  /* clip */
106429a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 = pred[pred_pitch] + (r2 >> 6);
106529a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r2 > 0xFF)   r2 = 0xFF & (~(r2 >> 31));  /* clip */
106629a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 = pred[pred_pitch<<1] + (r3 >> 6);
106729a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r3 > 0xFF)   r3 = 0xFF & (~(r3 >> 31));  /* clip */
106829a84457aed4c45bc900998b5e11c03023264208James Dong                    *curC = r0;
106929a84457aed4c45bc900998b5e11c03023264208James Dong                    *(curC += pitch) = r1;
107029a84457aed4c45bc900998b5e11c03023264208James Dong                    *(curC += pitch) = r2;
107129a84457aed4c45bc900998b5e11c03023264208James Dong                    curC[pitch] = r3;
107229a84457aed4c45bc900998b5e11c03023264208James Dong                    curC -= (pitch << 1);
107329a84457aed4c45bc900998b5e11c03023264208James Dong                    curC++;
107429a84457aed4c45bc900998b5e11c03023264208James Dong                    pred += (1 - pred_pitch);
107529a84457aed4c45bc900998b5e11c03023264208James Dong                    coef++;
107629a84457aed4c45bc900998b5e11c03023264208James Dong                }
107729a84457aed4c45bc900998b5e11c03023264208James Dong            }
107829a84457aed4c45bc900998b5e11c03023264208James Dong            else
107929a84457aed4c45bc900998b5e11c03023264208James Dong            {
108029a84457aed4c45bc900998b5e11c03023264208James Dong                // do DC-only inverse
108129a84457aed4c45bc900998b5e11c03023264208James Dong                m0 = coef[0] + 32;
108229a84457aed4c45bc900998b5e11c03023264208James Dong
108329a84457aed4c45bc900998b5e11c03023264208James Dong                for (j = 4; j > 0; j--)
108429a84457aed4c45bc900998b5e11c03023264208James Dong                {
108529a84457aed4c45bc900998b5e11c03023264208James Dong                    r0 = pred[0] + (m0 >> 6);
108629a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r0 > 0xFF)   r0 = 0xFF & (~(r0 >> 31));  /* clip */
108729a84457aed4c45bc900998b5e11c03023264208James Dong                    r1 = *(pred += pred_pitch) + (m0 >> 6);
108829a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r1 > 0xFF)   r1 = 0xFF & (~(r1 >> 31));  /* clip */
108929a84457aed4c45bc900998b5e11c03023264208James Dong                    r2 = pred[pred_pitch] + (m0 >> 6);
109029a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r2 > 0xFF)   r2 = 0xFF & (~(r2 >> 31));  /* clip */
109129a84457aed4c45bc900998b5e11c03023264208James Dong                    r3 = pred[pred_pitch<<1] + (m0 >> 6);
109229a84457aed4c45bc900998b5e11c03023264208James Dong                    if ((uint)r3 > 0xFF)   r3 = 0xFF & (~(r3 >> 31));  /* clip */
109329a84457aed4c45bc900998b5e11c03023264208James Dong                    *curC = r0;
109429a84457aed4c45bc900998b5e11c03023264208James Dong                    *(curC += pitch) = r1;
109529a84457aed4c45bc900998b5e11c03023264208James Dong                    *(curC += pitch) = r2;
109629a84457aed4c45bc900998b5e11c03023264208James Dong                    curC[pitch] = r3;
109729a84457aed4c45bc900998b5e11c03023264208James Dong                    curC -= (pitch << 1);
109829a84457aed4c45bc900998b5e11c03023264208James Dong                    curC++;
109929a84457aed4c45bc900998b5e11c03023264208James Dong                    pred += (1 - pred_pitch);
110029a84457aed4c45bc900998b5e11c03023264208James Dong                }
110129a84457aed4c45bc900998b5e11c03023264208James Dong                coef += 4;
110229a84457aed4c45bc900998b5e11c03023264208James Dong            }
110329a84457aed4c45bc900998b5e11c03023264208James Dong            curC += offset_cur[b4&1];
110429a84457aed4c45bc900998b5e11c03023264208James Dong            pred += offset_pred[b4&1];
110529a84457aed4c45bc900998b5e11c03023264208James Dong            coef += offset_coef[b4&1];
110629a84457aed4c45bc900998b5e11c03023264208James Dong        }
110729a84457aed4c45bc900998b5e11c03023264208James Dong    }
110829a84457aed4c45bc900998b5e11c03023264208James Dong
110929a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
111029a84457aed4c45bc900998b5e11c03023264208James Dong}
111129a84457aed4c45bc900998b5e11c03023264208James Dong
111229a84457aed4c45bc900998b5e11c03023264208James Dong
111329a84457aed4c45bc900998b5e11c03023264208James Dong/* only DC transform */
111429a84457aed4c45bc900998b5e11c03023264208James Dongint TransQuantIntra16DC(AVCEncObject *encvid)
111529a84457aed4c45bc900998b5e11c03023264208James Dong{
111629a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
111729a84457aed4c45bc900998b5e11c03023264208James Dong    int16 *block = video->block;
111829a84457aed4c45bc900998b5e11c03023264208James Dong    int *level = encvid->leveldc;
111929a84457aed4c45bc900998b5e11c03023264208James Dong    int *run = encvid->rundc;
112029a84457aed4c45bc900998b5e11c03023264208James Dong    int16 *ptr = block;
112129a84457aed4c45bc900998b5e11c03023264208James Dong    int r0, r1, r2, r3, j;
112229a84457aed4c45bc900998b5e11c03023264208James Dong    int Qq = video->QPy_div_6;
112329a84457aed4c45bc900998b5e11c03023264208James Dong    int Rq = video->QPy_mod_6;
112429a84457aed4c45bc900998b5e11c03023264208James Dong    int q_bits, qp_const, quant;
112529a84457aed4c45bc900998b5e11c03023264208James Dong    int data, lev, zero_run;
112629a84457aed4c45bc900998b5e11c03023264208James Dong    int k, ncoeff, idx;
112729a84457aed4c45bc900998b5e11c03023264208James Dong
112829a84457aed4c45bc900998b5e11c03023264208James Dong    /* DC transform */
112929a84457aed4c45bc900998b5e11c03023264208James Dong    /* horizontal */
113029a84457aed4c45bc900998b5e11c03023264208James Dong    j = 4;
113129a84457aed4c45bc900998b5e11c03023264208James Dong    while (j)
113229a84457aed4c45bc900998b5e11c03023264208James Dong    {
113329a84457aed4c45bc900998b5e11c03023264208James Dong        r0 = ptr[0] + ptr[12];
113429a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = ptr[0] - ptr[12];
113529a84457aed4c45bc900998b5e11c03023264208James Dong        r1 = ptr[4] + ptr[8];
113629a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = ptr[4] - ptr[8];
113729a84457aed4c45bc900998b5e11c03023264208James Dong
113829a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[0] = r0 + r1;
113929a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[8] = r0 - r1;
114029a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[4] = r3 + r2;
114129a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[12] = r3 - r2;
114229a84457aed4c45bc900998b5e11c03023264208James Dong        ptr += 64;
114329a84457aed4c45bc900998b5e11c03023264208James Dong        j--;
114429a84457aed4c45bc900998b5e11c03023264208James Dong    }
114529a84457aed4c45bc900998b5e11c03023264208James Dong    /* vertical */
114629a84457aed4c45bc900998b5e11c03023264208James Dong    ptr = block;
114729a84457aed4c45bc900998b5e11c03023264208James Dong    j = 4;
114829a84457aed4c45bc900998b5e11c03023264208James Dong    while (j)
114929a84457aed4c45bc900998b5e11c03023264208James Dong    {
115029a84457aed4c45bc900998b5e11c03023264208James Dong        r0 = ptr[0] + ptr[192];
115129a84457aed4c45bc900998b5e11c03023264208James Dong        r3 = ptr[0] - ptr[192];
115229a84457aed4c45bc900998b5e11c03023264208James Dong        r1 = ptr[64] + ptr[128];
115329a84457aed4c45bc900998b5e11c03023264208James Dong        r2 = ptr[64] - ptr[128];
115429a84457aed4c45bc900998b5e11c03023264208James Dong
115529a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[0] = (r0 + r1) >> 1;
115629a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[128] = (r0 - r1) >> 1;
115729a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[64] = (r3 + r2) >> 1;
115829a84457aed4c45bc900998b5e11c03023264208James Dong        ptr[192] = (r3 - r2) >> 1;
115929a84457aed4c45bc900998b5e11c03023264208James Dong        ptr += 4;
116029a84457aed4c45bc900998b5e11c03023264208James Dong        j--;
116129a84457aed4c45bc900998b5e11c03023264208James Dong    }
116229a84457aed4c45bc900998b5e11c03023264208James Dong
116329a84457aed4c45bc900998b5e11c03023264208James Dong    quant = quant_coef[Rq][0];
116429a84457aed4c45bc900998b5e11c03023264208James Dong    q_bits    = 15 + Qq;
116529a84457aed4c45bc900998b5e11c03023264208James Dong    qp_const = (1 << q_bits) / 3;    // intra
116629a84457aed4c45bc900998b5e11c03023264208James Dong
116729a84457aed4c45bc900998b5e11c03023264208James Dong    zero_run = 0;
116829a84457aed4c45bc900998b5e11c03023264208James Dong    ncoeff = 0;
116929a84457aed4c45bc900998b5e11c03023264208James Dong
117029a84457aed4c45bc900998b5e11c03023264208James Dong    for (k = 0; k < 16; k++) /* in zigzag scan order */
117129a84457aed4c45bc900998b5e11c03023264208James Dong    {
117229a84457aed4c45bc900998b5e11c03023264208James Dong        idx = ZIGZAG2RASTERDC[k];
117329a84457aed4c45bc900998b5e11c03023264208James Dong        data = block[idx];
117429a84457aed4c45bc900998b5e11c03023264208James Dong        if (data > 0)
117529a84457aed4c45bc900998b5e11c03023264208James Dong        {
117629a84457aed4c45bc900998b5e11c03023264208James Dong            lev = data * quant + (qp_const << 1);
117729a84457aed4c45bc900998b5e11c03023264208James Dong        }
117829a84457aed4c45bc900998b5e11c03023264208James Dong        else
117929a84457aed4c45bc900998b5e11c03023264208James Dong        {
118029a84457aed4c45bc900998b5e11c03023264208James Dong            lev = -data * quant + (qp_const << 1);
118129a84457aed4c45bc900998b5e11c03023264208James Dong        }
118229a84457aed4c45bc900998b5e11c03023264208James Dong        lev >>= (q_bits + 1);
118329a84457aed4c45bc900998b5e11c03023264208James Dong        if (lev)
118429a84457aed4c45bc900998b5e11c03023264208James Dong        {
118529a84457aed4c45bc900998b5e11c03023264208James Dong            if (data > 0)
118629a84457aed4c45bc900998b5e11c03023264208James Dong            {
118729a84457aed4c45bc900998b5e11c03023264208James Dong                level[ncoeff] = lev;
118829a84457aed4c45bc900998b5e11c03023264208James Dong                block[idx] = lev;
118929a84457aed4c45bc900998b5e11c03023264208James Dong            }
119029a84457aed4c45bc900998b5e11c03023264208James Dong            else
119129a84457aed4c45bc900998b5e11c03023264208James Dong            {
119229a84457aed4c45bc900998b5e11c03023264208James Dong                level[ncoeff] = -lev;
119329a84457aed4c45bc900998b5e11c03023264208James Dong                block[idx] = -lev;
119429a84457aed4c45bc900998b5e11c03023264208James Dong            }
119529a84457aed4c45bc900998b5e11c03023264208James Dong            run[ncoeff++] = zero_run;
119629a84457aed4c45bc900998b5e11c03023264208James Dong            zero_run = 0;
119729a84457aed4c45bc900998b5e11c03023264208James Dong        }
119829a84457aed4c45bc900998b5e11c03023264208James Dong        else
119929a84457aed4c45bc900998b5e11c03023264208James Dong        {
120029a84457aed4c45bc900998b5e11c03023264208James Dong            zero_run++;
120129a84457aed4c45bc900998b5e11c03023264208James Dong            block[idx] = 0;
120229a84457aed4c45bc900998b5e11c03023264208James Dong        }
120329a84457aed4c45bc900998b5e11c03023264208James Dong    }
120429a84457aed4c45bc900998b5e11c03023264208James Dong    return ncoeff;
120529a84457aed4c45bc900998b5e11c03023264208James Dong}
120629a84457aed4c45bc900998b5e11c03023264208James Dong
120729a84457aed4c45bc900998b5e11c03023264208James Dongint TransQuantChromaDC(AVCEncObject *encvid, int16 *block, int slice_type, int cr)
120829a84457aed4c45bc900998b5e11c03023264208James Dong{
120929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
121029a84457aed4c45bc900998b5e11c03023264208James Dong    int *level, *run;
121129a84457aed4c45bc900998b5e11c03023264208James Dong    int r0, r1, r2, r3;
121229a84457aed4c45bc900998b5e11c03023264208James Dong    int Qq, Rq, q_bits, qp_const, quant;
121329a84457aed4c45bc900998b5e11c03023264208James Dong    int data, lev, zero_run;
121429a84457aed4c45bc900998b5e11c03023264208James Dong    int k, ncoeff, idx;
121529a84457aed4c45bc900998b5e11c03023264208James Dong
121629a84457aed4c45bc900998b5e11c03023264208James Dong    level = encvid->levelcdc + (cr << 2); /* cb or cr */
121729a84457aed4c45bc900998b5e11c03023264208James Dong    run = encvid->runcdc + (cr << 2);
121829a84457aed4c45bc900998b5e11c03023264208James Dong
121929a84457aed4c45bc900998b5e11c03023264208James Dong    /* 2x2 transform of DC components*/
122029a84457aed4c45bc900998b5e11c03023264208James Dong    r0 = block[0];
122129a84457aed4c45bc900998b5e11c03023264208James Dong    r1 = block[4];
122229a84457aed4c45bc900998b5e11c03023264208James Dong    r2 = block[64];
122329a84457aed4c45bc900998b5e11c03023264208James Dong    r3 = block[68];
122429a84457aed4c45bc900998b5e11c03023264208James Dong
122529a84457aed4c45bc900998b5e11c03023264208James Dong    block[0] = r0 + r1 + r2 + r3;
122629a84457aed4c45bc900998b5e11c03023264208James Dong    block[4] = r0 - r1 + r2 - r3;
122729a84457aed4c45bc900998b5e11c03023264208James Dong    block[64] = r0 + r1 - r2 - r3;
122829a84457aed4c45bc900998b5e11c03023264208James Dong    block[68] = r0 - r1 - r2 + r3;
122929a84457aed4c45bc900998b5e11c03023264208James Dong
123029a84457aed4c45bc900998b5e11c03023264208James Dong    Qq    = video->QPc_div_6;
123129a84457aed4c45bc900998b5e11c03023264208James Dong    Rq    = video->QPc_mod_6;
123229a84457aed4c45bc900998b5e11c03023264208James Dong    quant = quant_coef[Rq][0];
123329a84457aed4c45bc900998b5e11c03023264208James Dong    q_bits    = 15 + Qq;
123429a84457aed4c45bc900998b5e11c03023264208James Dong    if (slice_type == AVC_I_SLICE)
123529a84457aed4c45bc900998b5e11c03023264208James Dong    {
123629a84457aed4c45bc900998b5e11c03023264208James Dong        qp_const = (1 << q_bits) / 3;
123729a84457aed4c45bc900998b5e11c03023264208James Dong    }
123829a84457aed4c45bc900998b5e11c03023264208James Dong    else
123929a84457aed4c45bc900998b5e11c03023264208James Dong    {
124029a84457aed4c45bc900998b5e11c03023264208James Dong        qp_const = (1 << q_bits) / 6;
124129a84457aed4c45bc900998b5e11c03023264208James Dong    }
124229a84457aed4c45bc900998b5e11c03023264208James Dong
124329a84457aed4c45bc900998b5e11c03023264208James Dong    zero_run = 0;
124429a84457aed4c45bc900998b5e11c03023264208James Dong    ncoeff = 0;
124529a84457aed4c45bc900998b5e11c03023264208James Dong
124629a84457aed4c45bc900998b5e11c03023264208James Dong    for (k = 0; k < 4; k++) /* in zigzag scan order */
124729a84457aed4c45bc900998b5e11c03023264208James Dong    {
124829a84457aed4c45bc900998b5e11c03023264208James Dong        idx = ((k >> 1) << 6) + ((k & 1) << 2);
124929a84457aed4c45bc900998b5e11c03023264208James Dong        data = block[idx];
125029a84457aed4c45bc900998b5e11c03023264208James Dong        if (data > 0)
125129a84457aed4c45bc900998b5e11c03023264208James Dong        {
125229a84457aed4c45bc900998b5e11c03023264208James Dong            lev = data * quant + (qp_const << 1);
125329a84457aed4c45bc900998b5e11c03023264208James Dong        }
125429a84457aed4c45bc900998b5e11c03023264208James Dong        else
125529a84457aed4c45bc900998b5e11c03023264208James Dong        {
125629a84457aed4c45bc900998b5e11c03023264208James Dong            lev = -data * quant + (qp_const << 1);
125729a84457aed4c45bc900998b5e11c03023264208James Dong        }
125829a84457aed4c45bc900998b5e11c03023264208James Dong        lev >>= (q_bits + 1);
125929a84457aed4c45bc900998b5e11c03023264208James Dong        if (lev)
126029a84457aed4c45bc900998b5e11c03023264208James Dong        {
126129a84457aed4c45bc900998b5e11c03023264208James Dong            if (data > 0)
126229a84457aed4c45bc900998b5e11c03023264208James Dong            {
126329a84457aed4c45bc900998b5e11c03023264208James Dong                level[ncoeff] = lev;
126429a84457aed4c45bc900998b5e11c03023264208James Dong                block[idx] = lev;
126529a84457aed4c45bc900998b5e11c03023264208James Dong            }
126629a84457aed4c45bc900998b5e11c03023264208James Dong            else
126729a84457aed4c45bc900998b5e11c03023264208James Dong            {
126829a84457aed4c45bc900998b5e11c03023264208James Dong                level[ncoeff] = -lev;
126929a84457aed4c45bc900998b5e11c03023264208James Dong                block[idx] = -lev;
127029a84457aed4c45bc900998b5e11c03023264208James Dong            }
127129a84457aed4c45bc900998b5e11c03023264208James Dong            run[ncoeff++] = zero_run;
127229a84457aed4c45bc900998b5e11c03023264208James Dong            zero_run = 0;
127329a84457aed4c45bc900998b5e11c03023264208James Dong        }
127429a84457aed4c45bc900998b5e11c03023264208James Dong        else
127529a84457aed4c45bc900998b5e11c03023264208James Dong        {
127629a84457aed4c45bc900998b5e11c03023264208James Dong            zero_run++;
127729a84457aed4c45bc900998b5e11c03023264208James Dong            block[idx] = 0;
127829a84457aed4c45bc900998b5e11c03023264208James Dong        }
127929a84457aed4c45bc900998b5e11c03023264208James Dong    }
128029a84457aed4c45bc900998b5e11c03023264208James Dong    return ncoeff;
128129a84457aed4c45bc900998b5e11c03023264208James Dong}
128229a84457aed4c45bc900998b5e11c03023264208James Dong
128329a84457aed4c45bc900998b5e11c03023264208James Dong
1284