159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ------------------------------------------------------------------
259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Copyright (C) 1998-2009 PacketVideo
359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *
459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Licensed under the Apache License, Version 2.0 (the "License");
559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * you may not use this file except in compliance with the License.
659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * You may obtain a copy of the License at
759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *
859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *      http://www.apache.org/licenses/LICENSE-2.0
959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong *
1059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * Unless required by applicable law or agreed to in writing, software
1159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
1359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * express or implied.
1459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * See the License for the specific language governing permissions
1559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * and limitations under the License.
1659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong * -------------------------------------------------------------------
1759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong */
1859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4def.h"
1959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4lib_int.h"
2059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "mp4enc_lib.h"
2159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "dct.h"
2259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#include "m4venc_oscl.h"
2359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
2459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
2559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : CodeMB_H263( )                                               */
2659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 8/15/2001                                                    */
2759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Perform residue calc (only zero MV), DCT, H263 Quant/Dequant,*/
2859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*              IDCT and motion compensation.Modified from FastCodeMB()     */
2959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Input    :                                                              */
3059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      video       Video encoder data structure                            */
3159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      function    Approximate DCT function, scaling and threshold         */
3259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      ncoefblck   Array for last nonzero coeff for speedup in VlcEncode   */
3359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      QP      Combined offset from the origin to the current          */
3459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                  macroblock  and QP  for current MB.                     */
3559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*    Output     :                                                          */
3659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      video->outputMB     Quantized DCT coefficients.                     */
3759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      currVop->yChan,uChan,vChan  Reconstructed pixels                    */
3859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
3959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   :   PV_STATUS                                                  */
4059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
4159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*           2/26/01
4259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            -modified threshold based on correlation coeff 0.75 only for mode H.263
4359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            -ncoefblck[] as input,  to keep position of last non-zero coeff*/
4459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*           8/10/01
4559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            -modified threshold based on correlation coeff 0.5
4659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            -used column threshold to speedup column DCT.
4759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            -used bitmap zigzag to speedup RunLevel().                      */
4859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
4959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
5059f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS CodeMB_H263(VideoEncData *video, approxDCT *function, Int QP, Int ncoefblck[])
5159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
5259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int sad, k, CBP, mbnum = video->mbnum;
5359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Short *output, *dataBlock;
5459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar Mode = video->headerInfo.Mode[mbnum];
5559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *bitmapcol, *bitmaprow = video->bitmaprow;
5659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UInt  *bitmapzz ;
5759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar shortHeader = video->vol[video->currLayer]->shortVideoHeader;
5859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int dc_scaler = 8;
5959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);
6059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    struct QPstruct QuantParam;
6159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int dctMode, DctTh1;
6259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ColTh;
6359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int(*BlockQuantDequantH263)(Short *, Short *, struct QPstruct *,
6459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                UChar[], UChar *, UInt *, Int, Int, Int, UChar);
6559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int(*BlockQuantDequantH263DC)(Short *, Short *, struct QPstruct *,
6659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                  UChar *, UInt *, Int, UChar);
6759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*BlockDCT1x1)(Short *, UChar *, UChar *, Int);
6859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*BlockDCT2x2)(Short *, UChar *, UChar *, Int);
6959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*BlockDCT4x4)(Short *, UChar *, UChar *, Int);
7059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*BlockDCT8x8)(Short *, UChar *, UChar *, Int);
7159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
7259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* motion comp. related var. */
7359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vop *currVop = video->currVop;
7459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncFrameIO *inputFrame = video->input;
7559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ind_x = video->outputMB->mb_x;
7659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ind_y = video->outputMB->mb_y;
7759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = currVop->pitch;
7859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = currVop->width;
7959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *rec, *input, *pred;
8059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int offset = QP >> 5;  /* QP is combined offset and QP */
8159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int offsetc = (offset >> 2) + (ind_x << 2); /* offset for chrom */
8259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*****************************/
8359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
8459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    OSCL_UNUSED_ARG(function);
8559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
8659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    output = video->outputMB->block[0];
8759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    CBP = 0;
8859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    QP = QP & 0x1F;
8959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//  M4VENC_MEMSET(output,0,(sizeof(Short)<<6)*6); /* reset quantized coeff. to zero , 7/24/01*/
9059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    QuantParam.QPx2 = QP << 1;
9259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    QuantParam.QP = QP;
9359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    QuantParam.QPdiv2 = QP >> 1;
9459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    QuantParam.QPx2plus = QuantParam.QPx2 + QuantParam.QPdiv2;
9559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    QuantParam.Addition = QP - 1 + (QP & 0x1);
9659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
9759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (intra)
9859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
9959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT1x1 = &Block1x1DCTIntra;
10059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT2x2 = &Block2x2DCT_AANIntra;
10159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT4x4 = &Block4x4DCT_AANIntra;
10259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT8x8 = &BlockDCT_AANIntra;
10359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockQuantDequantH263 = &BlockQuantDequantH263Intra;
10459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockQuantDequantH263DC = &BlockQuantDequantH263DCIntra;
10559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (shortHeader)
10659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
10759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dc_scaler = 8;
10859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
10959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
11059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
11159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dc_scaler = cal_dc_scalerENC(QP, 1); /* luminance blocks */
11259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
11359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        DctTh1 = (Int)(dc_scaler * 3);//*1.829
11459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ColTh = ColThIntra[QP];
11559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
11659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
11759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
11859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT1x1 = &Block1x1DCTwSub;
11959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT2x2 = &Block2x2DCT_AANwSub;
12059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT4x4 = &Block4x4DCT_AANwSub;
12159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT8x8 = &BlockDCT_AANwSub;
12259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockQuantDequantH263 = &BlockQuantDequantH263Inter;
12459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockQuantDequantH263DC = &BlockQuantDequantH263DCInter;
12559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ColTh = ColThInter[QP];
12659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        DctTh1 = (Int)(16 * QP);  //9*QP;
12759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
12859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
12959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    rec = currVop->yChan + offset;
13059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    input = inputFrame->yChan + offset;
13159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (lx != width) input -= (ind_y << 9);  /* non-padded offset */
13259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    dataBlock = video->dataBlock;
13459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    pred = video->predictedMB;
13559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
13659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (k = 0; k < 6; k++)
13759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
13859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        CBP <<= 1;
13959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        bitmapcol = video->bitmapcol[k];
14059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        bitmapzz = video->bitmapzz[k];  /*  7/30/01 */
14159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (k < 4)
14259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
14359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            sad = video->mot[mbnum][k+1].sad;
14459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (k&1)
14559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
14659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                rec += 8;
14759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                input += 8;
14859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
14959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (k == 2)
15059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
15159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dctMode = ((width << 3) - 8);
15259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                input += dctMode;
15359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dctMode = ((lx << 3) - 8);
15459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                rec += dctMode;
15559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
15659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
15759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
15859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
15959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (k == 4)
16059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
16159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                rec = currVop->uChan + offsetc;
16259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                input = inputFrame->uChan + offsetc;
16359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (lx != width) input -= (ind_y << 7);
16459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                lx >>= 1;
16559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                width >>= 1;
16659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (intra)
16759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
16859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    sad = getBlockSum(input, width);
16959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    if (shortHeader)
17059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        dc_scaler = 8;
17159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    else
17259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    {
17359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                        dc_scaler = cal_dc_scalerENC(QP, 2); /* chrominance blocks */
17459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    }
17559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    DctTh1 = (Int)(dc_scaler * 3);//*1.829
17659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
17759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else
17859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    sad = Sad8x8(input, pred, width);
17959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
18059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else
18159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
18259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                rec = currVop->vChan + offsetc;
18359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                input = inputFrame->vChan + offsetc;
18459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (lx != width) input -= (ind_y << 7);
18559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (intra)
18659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
18759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    sad = getBlockSum(input, width);
18859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
18959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else
19059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    sad = Sad8x8(input, pred, width);
19159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
19259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
19359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
19459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (sad < DctTh1 && !(shortHeader && intra)) /* all-zero */
19559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {                       /* For shortHeader intra block, DC value cannot be zero */
19659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dctMode = 0;
19759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            CBP |= 0;
19859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ncoefblck[k] = 0;
19959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
20059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else if (sad < 18*QP/*(QP<<4)*/) /* DC-only */
20159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
20259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dctMode = 1;
20359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            BlockDCT1x1(dataBlock, input, pred, width);
20459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
20559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            CBP |= (*BlockQuantDequantH263DC)(dataBlock, output, &QuantParam,
20659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                              bitmaprow + k, bitmapzz, dc_scaler, shortHeader);
20759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ncoefblck[k] = 1;
20859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
20959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
21059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
21159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
21259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dataBlock[64] = ColTh;
21359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
21459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (sad < 22*QP/*(QP<<4)+(QP<<1)*/)  /* 2x2 DCT */
21559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
21659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dctMode = 2;
21759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BlockDCT2x2(dataBlock, input, pred, width);
21859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ncoefblck[k] = 6;
21959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
22059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (sad < (QP << 5)) /* 4x4 DCT */
22159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
22259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dctMode = 4;
22359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BlockDCT4x4(dataBlock, input, pred, width);
22459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ncoefblck[k] = 26;
22559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
22659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else /* Full-DCT */
22759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
22859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dctMode = 8;
22959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BlockDCT8x8(dataBlock, input, pred, width);
23059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ncoefblck[k] = 64;
23159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
23259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
23359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            CBP |= (*BlockQuantDequantH263)(dataBlock, output, &QuantParam,
23459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                            bitmapcol, bitmaprow + k, bitmapzz, dctMode, k, dc_scaler, shortHeader);
23559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
23659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockIDCTMotionComp(dataBlock, bitmapcol, bitmaprow[k], dctMode, rec, pred, (lx << 1) | intra);
23759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        output += 64;
23859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (!(k&1))
23959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
24059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pred += 8;
24159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
24259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
24359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
24459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pred += 120;
24559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
24659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
24759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
24859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->headerInfo.CBP[mbnum] = CBP; /*  5/18/2001 */
24959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_SUCCESS;
25059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
25159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
25259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#ifndef NO_MPEG_QUANT
25359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
25459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : CodeMB_MPEG( )                                               */
25559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 8/15/2001                                                    */
25659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Perform residue calc (only zero MV), DCT, MPEG Quant/Dequant,*/
25759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*              IDCT and motion compensation.Modified from FastCodeMB()     */
25859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Input    :                                                              */
25959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      video       Video encoder data structure                            */
26059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      function    Approximate DCT function, scaling and threshold         */
26159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      ncoefblck   Array for last nonzero coeff for speedup in VlcEncode   */
26259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      QP      Combined offset from the origin to the current          */
26359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                  macroblock  and QP  for current MB.                     */
26459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*    Output     :                                                          */
26559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      video->outputMB     Quantized DCT coefficients.                     */
26659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      currVop->yChan,uChan,vChan  Reconstructed pixels                    */
26759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*                                                                          */
26859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   :   PV_STATUS                                                  */
26959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
27059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*           2/26/01
27159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            -modified threshold based on correlation coeff 0.75 only for mode H.263
27259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            -ncoefblck[] as input, keep position of last non-zero coeff*/
27359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*           8/10/01
27459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            -modified threshold based on correlation coeff 0.5
27559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            -used column threshold to speedup column DCT.
27659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            -used bitmap zigzag to speedup RunLevel().                      */
27759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
27859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
27959f566c4ec3dfc097ad8163523e522280b27e5c3James DongPV_STATUS CodeMB_MPEG(VideoEncData *video, approxDCT *function, Int QP, Int ncoefblck[])
28059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
28159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int sad, k, CBP, mbnum = video->mbnum;
28259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Short *output, *dataBlock;
28359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar Mode = video->headerInfo.Mode[mbnum];
28459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *bitmapcol, *bitmaprow = video->bitmaprow;
28559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UInt  *bitmapzz ;
28659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int dc_scaler = 8;
28759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vol *currVol = video->vol[video->currLayer];
28859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);
28959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int *qmat;
29059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int dctMode, DctTh1, DctTh2, DctTh3, DctTh4;
29159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ColTh;
29259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
29359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int(*BlockQuantDequantMPEG)(Short *, Short *, Int, Int *,
29459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                UChar [], UChar *, UInt *, Int,  Int, Int);
29559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int(*BlockQuantDequantMPEGDC)(Short *, Short *, Int, Int *,
29659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                  UChar [], UChar *, UInt *, Int);
29759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
29859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*BlockDCT1x1)(Short *, UChar *, UChar *, Int);
29959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*BlockDCT2x2)(Short *, UChar *, UChar *, Int);
30059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*BlockDCT4x4)(Short *, UChar *, UChar *, Int);
30159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    void (*BlockDCT8x8)(Short *, UChar *, UChar *, Int);
30259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
30359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /* motion comp. related var. */
30459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Vop *currVop = video->currVop;
30559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    VideoEncFrameIO *inputFrame = video->input;
30659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ind_x = video->outputMB->mb_x;
30759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int ind_y = video->outputMB->mb_y;
30859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int lx = currVop->pitch;
30959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int width = currVop->width;
31059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *rec, *input, *pred;
31159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int offset = QP >> 5;
31259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int offsetc = (offset >> 2) + (ind_x << 2); /* offset for chrom */
31359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    /*****************************/
31459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
31559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    OSCL_UNUSED_ARG(function);
31659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
31759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    output = video->outputMB->block[0];
31859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    CBP = 0;
31959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    QP = QP & 0x1F;
32059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong//  M4VENC_MEMSET(output,0,(sizeof(Short)<<6)*6); /* reset quantized coeff. to zero ,  7/24/01*/
32159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
32259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (intra)
32359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
32459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT1x1 = &Block1x1DCTIntra;
32559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT2x2 = &Block2x2DCT_AANIntra;
32659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT4x4 = &Block4x4DCT_AANIntra;
32759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT8x8 = &BlockDCT_AANIntra;
32859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
32959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockQuantDequantMPEG = &BlockQuantDequantMPEGIntra;
33059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockQuantDequantMPEGDC = &BlockQuantDequantMPEGDCIntra;
33159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        dc_scaler = cal_dc_scalerENC(QP, 1); /* luminance blocks */
33259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        qmat = currVol->iqmat;
33359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        DctTh1 = (Int)(3 * dc_scaler);//2*dc_scaler);
33459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        DctTh2 = (Int)((1.25 * QP - 1) * qmat[1] * 0.45);//0.567);//0.567);
33559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        DctTh3 = (Int)((1.25 * QP - 1) * qmat[2] * 0.55);//1.162); /*  8/2/2001 */
33659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        DctTh4 = (Int)((1.25 * QP - 1) * qmat[32] * 0.8);//1.7583);//0.7942);
33759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ColTh = ColThIntra[QP];
33859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
33959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    else
34059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
34159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT1x1 = &Block1x1DCTwSub;
34259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT2x2 = &Block2x2DCT_AANwSub;
34359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT4x4 = &Block4x4DCT_AANwSub;
34459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockDCT8x8 = &BlockDCT_AANwSub;
34559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
34659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockQuantDequantMPEG = &BlockQuantDequantMPEGInter;
34759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockQuantDequantMPEGDC = &BlockQuantDequantMPEGDCInter;
34859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        qmat = currVol->niqmat;
34959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        DctTh1 = (Int)(((QP << 1) - 0.5) * qmat[0] * 0.4);//0.2286);//0.3062);
35059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        DctTh2 = (Int)(((QP << 1) - 0.5) * qmat[1] * 0.45);//0.567);//0.4);
35159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        DctTh3 = (Int)(((QP << 1) - 0.5) * qmat[2] * 0.55);//1.162); /*  8/2/2001 */
35259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        DctTh4 = (Int)(((QP << 1) - 0.5) * qmat[32] * 0.8);//1.7583);//0.7942);
35359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        ColTh = ColThInter[QP];
35459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }// get qmat, DctTh1, DctTh2, DctTh3
35559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
35659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    rec = currVop->yChan + offset;
35759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    input = inputFrame->yChan + offset;
35859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    if (lx != width) input -= (ind_y << 9);  /* non-padded offset */
35959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
36059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    dataBlock = video->dataBlock;
36159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    pred = video->predictedMB;
36259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
36359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    for (k = 0; k < 6; k++)
36459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
36559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        CBP <<= 1;
36659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        bitmapcol = video->bitmapcol[k];
36759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        bitmapzz = video->bitmapzz[k];  /*  8/2/01 */
36859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (k < 4)
36959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {//Y block
37059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            sad = video->mot[mbnum][k+1].sad;
37159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (k&1)
37259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
37359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                rec += 8;
37459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                input += 8;
37559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
37659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (k == 2)
37759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
37859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dctMode = ((width << 3) - 8);
37959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                input += dctMode;
38059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dctMode = ((lx << 3) - 8);
38159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                rec += dctMode;
38259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
38359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
38459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
38559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {// U, V block
38659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (k == 4)
38759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
38859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                rec = currVop->uChan + offsetc;
38959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                input = inputFrame->uChan + offsetc;
39059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (lx != width) input -= (ind_y << 7);
39159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                lx >>= 1;
39259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                width >>= 1;
39359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (intra)
39459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                {
39559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    dc_scaler = cal_dc_scalerENC(QP, 2); /* luminance blocks */
39659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    DctTh1 = dc_scaler * 3;
39759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    sad = getBlockSum(input, width);
39859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                }
39959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else
40059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    sad = Sad8x8(input, pred, width);
40159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
40259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else
40359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
40459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                rec = currVop->vChan + offsetc;
40559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                input = inputFrame->vChan + offsetc;
40659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (lx != width) input -= (ind_y << 7);
40759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                if (intra)
40859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    sad = getBlockSum(input, width);
40959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                else
41059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                    sad = Sad8x8(input, pred, width);
41159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
41259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
41359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
41459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (sad < DctTh1) /* all-zero */
41559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
41659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dctMode = 0;
41759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            CBP |= 0;
41859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ncoefblck[k] = 0;
41959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
42059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else if (sad < DctTh2) /* DC-only */
42159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
42259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dctMode = 1;
42359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            BlockDCT1x1(dataBlock, input, pred, width);
42459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
42559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            CBP |= (*BlockQuantDequantMPEGDC)(dataBlock, output, QP, qmat,
42659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                              bitmapcol, bitmaprow + k, bitmapzz, dc_scaler);
42759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            ncoefblck[k] = 1;
42859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
42959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
43059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
43159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            dataBlock[64] = ColTh;
43259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
43359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            if (sad < DctTh3) /* 2x2-DCT */
43459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
43559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dctMode = 2;
43659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BlockDCT2x2(dataBlock, input, pred, width);
43759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ncoefblck[k] = 6;
43859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
43959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else if (sad < DctTh4) /* 4x4 DCT */
44059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
44159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dctMode = 4;
44259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BlockDCT4x4(dataBlock, input, pred, width);
44359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ncoefblck[k] = 26;
44459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
44559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            else /* full-DCT */
44659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            {
44759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                dctMode = 8;
44859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                BlockDCT8x8(dataBlock, input, pred, width);
44959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                ncoefblck[k] = 64;
45059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            }
45159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
45259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            CBP |= (*BlockQuantDequantMPEG)(dataBlock, output, QP, qmat,
45359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong                                            bitmapcol, bitmaprow + k, bitmapzz, dctMode, k, dc_scaler); //
45459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
45559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        dctMode = 8; /* for mismatch handle */
45659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        BlockIDCTMotionComp(dataBlock, bitmapcol, bitmaprow[k], dctMode, rec, pred, (lx << 1) | (intra));
45759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
45859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        output += 64;
45959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (!(k&1))
46059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
46159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pred += 8;
46259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
46359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else
46459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        {
46559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong            pred += 120;
46659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        }
46759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
46859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
46959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    video->headerInfo.CBP[mbnum] = CBP; /*  5/18/2001 */
47059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return PV_SUCCESS;
47159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
47259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
47359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong#endif
47459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
47559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
47659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : getBlockSAV( )                                               */
47759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 8/10/2000                                                    */
47859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Get SAV for one block                                        */
47959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   : block[64] contain one block data                             */
48059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   :                                                              */
48159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
48259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
48359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* can be written in MMX or SSE,  2/22/2001 */
48459f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt getBlockSAV(Short block[])
48559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
48659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int i, val, sav = 0;
48759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
48859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    i = 8;
48959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    while (i--)
49059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
49159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        val = *block++;
49259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (val > 0)    sav += val;
49359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else        sav -= val;
49459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        val = *block++;
49559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (val > 0)    sav += val;
49659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else        sav -= val;
49759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        val = *block++;
49859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (val > 0)    sav += val;
49959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else        sav -= val;
50059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        val = *block++;
50159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (val > 0)    sav += val;
50259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else        sav -= val;
50359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        val = *block++;
50459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (val > 0)    sav += val;
50559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else        sav -= val;
50659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        val = *block++;
50759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (val > 0)    sav += val;
50859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else        sav -= val;
50959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        val = *block++;
51059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (val > 0)    sav += val;
51159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else        sav -= val;
51259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        val = *block++;
51359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (val > 0)    sav += val;
51459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        else        sav -= val;
51559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
51659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
51759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return sav;
51859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
51959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
52059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
52159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
52259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : Sad8x8( )                                                    */
52359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 8/10/2000                                                    */
52459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Find SAD between prev block and current block                */
52559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   : Previous and current frame block pointers, and frame width   */
52659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   :                                                              */
52759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
52859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*      8/15/01,  - do 4 pixel at a time    assuming 32 bit register        */
52959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
530488d3706adb6d4c16fb14712412bc4945f13ff83Dan Austin#ifdef __clang__
531488d3706adb6d4c16fb14712412bc4945f13ff83Dan Austin__attribute((no_sanitize("integer")))
532488d3706adb6d4c16fb14712412bc4945f13ff83Dan Austin#endif
53359f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt Sad8x8(UChar *cur, UChar *prev, Int width)
53459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
53559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *end = cur + (width << 3);
53659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int sad = 0;
53759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int *curInt = (Int*) cur;
53859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int *prevInt = (Int*) prev;
53959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int cur1, cur2, prev1, prev2;
54059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UInt mask, sgn_msk = 0x80808080;
54159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int  sum2 = 0, sum4 = 0;
54259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int  tmp;
54359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    do
54459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
54559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        mask    = ~(0xFF00);
54659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur1    = curInt[1];        /* load cur[4..7] */
54759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur2    = curInt[0];
54859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        curInt += (width >> 2);     /* load cur[0..3] and +=lx */
54959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        prev1   = prevInt[1];
55059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        prev2   = prevInt[0];
55159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        prevInt += 4;
55259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
55359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        tmp     = prev2 ^ cur2;
55459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur2    = prev2 - cur2;
55559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        tmp     = tmp ^ cur2;       /* (^)^(-) last bit is one if carry */
55659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        tmp     = sgn_msk & ((UInt)tmp >> 1); /* check the sign of each byte */
55759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (cur2 < 0)   tmp = tmp | 0x80000000; /* corcurt sign of first byte */
55859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        tmp     = (tmp << 8) - tmp;     /* carry borrowed bytes are marked with 0x1FE */
55959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur2    = cur2 + (tmp >> 7);     /* negative bytes is added with 0xFF, -1 */
56059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur2    = cur2 ^(tmp >> 7); /* take absolute by inverting bits (EOR) */
56159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
56259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        tmp     = prev1 ^ cur1;
56359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur1    = prev1 - cur1;
56459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        tmp     = tmp ^ cur1;       /* (^)^(-) last bit is one if carry */
56559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        tmp     = sgn_msk & ((UInt)tmp >> 1); /* check the sign of each byte */
56659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        if (cur1 < 0)   tmp = tmp | 0x80000000; /* corcurt sign of first byte */
56759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        tmp     = (tmp << 8) - tmp;     /* carry borrowed bytes are marked with 0x1FE */
56859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur1    = cur1 + (tmp >> 7);     /* negative bytes is added with 0xFF, -1 */
56959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur1    = cur1 ^(tmp >> 7); /* take absolute by inverting bits (EOR) */
57059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
57159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        sum4    = sum4 + cur1;
57259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur1    = cur1 & (mask << 8);   /* mask first and third bytes */
57359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        sum2    = sum2 + ((UInt)cur1 >> 8);
57459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        sum4    = sum4 + cur2;
57559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        cur2    = cur2 & (mask << 8);   /* mask first and third bytes */
57659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        sum2    = sum2 + ((UInt)cur2 >> 8);
57759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
578377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT    while ((uintptr_t)curInt < (uintptr_t)end);
57959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
58059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    cur1 = sum4 - (sum2 << 8);  /* get even-sum */
58159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    cur1 = cur1 + sum2;         /* add 16 bit even-sum and odd-sum*/
58259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    cur1 = cur1 + (cur1 << 16); /* add upper and lower 16 bit sum */
58359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    sad  = ((UInt)cur1 >> 16);  /* take upper 16 bit */
58459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return sad;
58559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
58659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
58759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
58859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Function : getBlockSum( )                                               */
58959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Date     : 8/10/2000                                                    */
59059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Purpose  : Find summation of value within a block.                      */
59159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  In/out   : Pointer to current block in a frame and frame width          */
59259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Return   :                                                              */
59359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*  Modified :                                                              */
59459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/*          8/15/01,  - SIMD 4 pixels at a time                         */
59559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong/* ======================================================================== */
596488d3706adb6d4c16fb14712412bc4945f13ff83Dan Austin#ifdef __clang__
597488d3706adb6d4c16fb14712412bc4945f13ff83Dan Austin__attribute((no_sanitize("integer")))
598488d3706adb6d4c16fb14712412bc4945f13ff83Dan Austin#endif
59959f566c4ec3dfc097ad8163523e522280b27e5c3James DongInt getBlockSum(UChar *cur, Int width)
60059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong{
60159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int sad = 0, sum4 = 0, sum2 = 0;
60259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UChar *end = cur + (width << 3);
60359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int *curInt = (Int*)cur;
60459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    UInt mask   = ~(0xFF00);
60559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    Int load1, load2;
60659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
60759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    do
60859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    {
60959f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        load1 = curInt[1];
61059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        load2 = curInt[0];
61159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        curInt += (width >> 2);
61259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        sum4 += load1;
61359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        load1 = load1 & (mask << 8); /* even bytes */
61459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        sum2 += ((UInt)load1 >> 8); /* sum even bytes, 16 bit */
61559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        sum4 += load2;
61659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        load2 = load2 & (mask << 8); /* even bytes */
61759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong        sum2 += ((UInt)load2 >> 8); /* sum even bytes, 16 bit */
61859f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    }
619377b2ec9a2885f9b6405b07ba900a9e3f4349c38Kévin PETIT    while ((uintptr_t)curInt < (uintptr_t)end);
62059f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    load1 = sum4 - (sum2 << 8);     /* get even-sum */
62159f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    load1 = load1 + sum2;           /* add 16 bit even-sum and odd-sum*/
62259f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    load1 = load1 + (load1 << 16);  /* add upper and lower 16 bit sum */
62359f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    sad  = ((UInt)load1 >> 16); /* take upper 16 bit */
62459f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
62559f566c4ec3dfc097ad8163523e522280b27e5c3James Dong    return sad;
62659f566c4ec3dfc097ad8163523e522280b27e5c3James Dong}
62759f566c4ec3dfc097ad8163523e522280b27e5c3James Dong
628