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#define TH_I4  0  /* threshold biasing toward I16 mode instead of I4 mode */
2129a84457aed4c45bc900998b5e11c03023264208James Dong#define TH_Intra  0 /* threshold biasing toward INTER mode instead of intra mode */
2229a84457aed4c45bc900998b5e11c03023264208James Dong
2329a84457aed4c45bc900998b5e11c03023264208James Dong#define FIXED_INTRAPRED_MODE  AVC_I16
2429a84457aed4c45bc900998b5e11c03023264208James Dong#define FIXED_I16_MODE  AVC_I16_DC
2529a84457aed4c45bc900998b5e11c03023264208James Dong#define FIXED_I4_MODE   AVC_I4_Diagonal_Down_Left
2629a84457aed4c45bc900998b5e11c03023264208James Dong#define FIXED_INTRA_CHROMA_MODE AVC_IC_DC
2729a84457aed4c45bc900998b5e11c03023264208James Dong
2829a84457aed4c45bc900998b5e11c03023264208James Dong#define CLIP_RESULT(x)      if((uint)x > 0xFF){ \
2929a84457aed4c45bc900998b5e11c03023264208James Dong                 x = 0xFF & (~(x>>31));}
3029a84457aed4c45bc900998b5e11c03023264208James Dong
3129a84457aed4c45bc900998b5e11c03023264208James Dong
3229a84457aed4c45bc900998b5e11c03023264208James Dongbool IntraDecisionABE(AVCEncObject *encvid, int min_cost, uint8 *curL, int picPitch)
3329a84457aed4c45bc900998b5e11c03023264208James Dong{
3429a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
3529a84457aed4c45bc900998b5e11c03023264208James Dong    AVCFrameIO *currInput = encvid->currInput;
3629a84457aed4c45bc900998b5e11c03023264208James Dong    int orgPitch = currInput->pitch;
3729a84457aed4c45bc900998b5e11c03023264208James Dong    int x_pos = (video->mb_x) << 4;
3829a84457aed4c45bc900998b5e11c03023264208James Dong    int y_pos = (video->mb_y) << 4;
3929a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *orgY = currInput->YCbCr[0] + y_pos * orgPitch + x_pos;
4029a84457aed4c45bc900998b5e11c03023264208James Dong    int j;
4129a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *topL, *leftL, *orgY_2, *orgY_3;
4229a84457aed4c45bc900998b5e11c03023264208James Dong    int temp, SBE, offset;
4329a84457aed4c45bc900998b5e11c03023264208James Dong    OsclFloat ABE;
4429a84457aed4c45bc900998b5e11c03023264208James Dong    bool intra = true;
4529a84457aed4c45bc900998b5e11c03023264208James Dong
4629a84457aed4c45bc900998b5e11c03023264208James Dong    if (((x_pos >> 4) != (int)video->PicWidthInMbs - 1) &&
4729a84457aed4c45bc900998b5e11c03023264208James Dong            ((y_pos >> 4) != (int)video->PicHeightInMbs - 1) &&
4829a84457aed4c45bc900998b5e11c03023264208James Dong            video->intraAvailA &&
4929a84457aed4c45bc900998b5e11c03023264208James Dong            video->intraAvailB)
5029a84457aed4c45bc900998b5e11c03023264208James Dong    {
5129a84457aed4c45bc900998b5e11c03023264208James Dong        SBE = 0;
5229a84457aed4c45bc900998b5e11c03023264208James Dong        /* top neighbor */
5329a84457aed4c45bc900998b5e11c03023264208James Dong        topL = curL - picPitch;
5429a84457aed4c45bc900998b5e11c03023264208James Dong        /* left neighbor */
5529a84457aed4c45bc900998b5e11c03023264208James Dong        leftL = curL - 1;
5629a84457aed4c45bc900998b5e11c03023264208James Dong        orgY_2 = orgY - orgPitch;
5729a84457aed4c45bc900998b5e11c03023264208James Dong
5829a84457aed4c45bc900998b5e11c03023264208James Dong        for (j = 0; j < 16; j++)
5929a84457aed4c45bc900998b5e11c03023264208James Dong        {
6029a84457aed4c45bc900998b5e11c03023264208James Dong            temp = *topL++ - orgY[j];
6129a84457aed4c45bc900998b5e11c03023264208James Dong            SBE += ((temp >= 0) ? temp : -temp);
6229a84457aed4c45bc900998b5e11c03023264208James Dong            temp = *(leftL += picPitch) - *(orgY_2 += orgPitch);
6329a84457aed4c45bc900998b5e11c03023264208James Dong            SBE += ((temp >= 0) ? temp : -temp);
6429a84457aed4c45bc900998b5e11c03023264208James Dong        }
6529a84457aed4c45bc900998b5e11c03023264208James Dong
6629a84457aed4c45bc900998b5e11c03023264208James Dong        /* calculate chroma */
6729a84457aed4c45bc900998b5e11c03023264208James Dong        offset = (y_pos >> 2) * picPitch + (x_pos >> 1);
6829a84457aed4c45bc900998b5e11c03023264208James Dong        topL = video->currPic->Scb + offset;
6929a84457aed4c45bc900998b5e11c03023264208James Dong        orgY_2 = currInput->YCbCr[1] + offset + (y_pos >> 2) * (orgPitch - picPitch);
7029a84457aed4c45bc900998b5e11c03023264208James Dong
7129a84457aed4c45bc900998b5e11c03023264208James Dong        leftL = topL - 1;
7229a84457aed4c45bc900998b5e11c03023264208James Dong        topL -= (picPitch >> 1);
7329a84457aed4c45bc900998b5e11c03023264208James Dong        orgY_3 = orgY_2 - (orgPitch >> 1);
7429a84457aed4c45bc900998b5e11c03023264208James Dong        for (j = 0; j < 8; j++)
7529a84457aed4c45bc900998b5e11c03023264208James Dong        {
7629a84457aed4c45bc900998b5e11c03023264208James Dong            temp = *topL++ - orgY_2[j];
7729a84457aed4c45bc900998b5e11c03023264208James Dong            SBE += ((temp >= 0) ? temp : -temp);
7829a84457aed4c45bc900998b5e11c03023264208James Dong            temp = *(leftL += (picPitch >> 1)) - *(orgY_3 += (orgPitch >> 1));
7929a84457aed4c45bc900998b5e11c03023264208James Dong            SBE += ((temp >= 0) ? temp : -temp);
8029a84457aed4c45bc900998b5e11c03023264208James Dong        }
8129a84457aed4c45bc900998b5e11c03023264208James Dong
8229a84457aed4c45bc900998b5e11c03023264208James Dong        topL = video->currPic->Scr + offset;
8329a84457aed4c45bc900998b5e11c03023264208James Dong        orgY_2 = currInput->YCbCr[2] + offset + (y_pos >> 2) * (orgPitch - picPitch);
8429a84457aed4c45bc900998b5e11c03023264208James Dong
8529a84457aed4c45bc900998b5e11c03023264208James Dong        leftL = topL - 1;
8629a84457aed4c45bc900998b5e11c03023264208James Dong        topL -= (picPitch >> 1);
8729a84457aed4c45bc900998b5e11c03023264208James Dong        orgY_3 = orgY_2 - (orgPitch >> 1);
8829a84457aed4c45bc900998b5e11c03023264208James Dong        for (j = 0; j < 8; j++)
8929a84457aed4c45bc900998b5e11c03023264208James Dong        {
9029a84457aed4c45bc900998b5e11c03023264208James Dong            temp = *topL++ - orgY_2[j];
9129a84457aed4c45bc900998b5e11c03023264208James Dong            SBE += ((temp >= 0) ? temp : -temp);
9229a84457aed4c45bc900998b5e11c03023264208James Dong            temp = *(leftL += (picPitch >> 1)) - *(orgY_3 += (orgPitch >> 1));
9329a84457aed4c45bc900998b5e11c03023264208James Dong            SBE += ((temp >= 0) ? temp : -temp);
9429a84457aed4c45bc900998b5e11c03023264208James Dong        }
9529a84457aed4c45bc900998b5e11c03023264208James Dong
9629a84457aed4c45bc900998b5e11c03023264208James Dong        /* compare mincost/384 and SBE/64 */
9729a84457aed4c45bc900998b5e11c03023264208James Dong        ABE = SBE / 64.0;
9829a84457aed4c45bc900998b5e11c03023264208James Dong        if (ABE*0.8 >= min_cost / 384.0)
9929a84457aed4c45bc900998b5e11c03023264208James Dong        {
10029a84457aed4c45bc900998b5e11c03023264208James Dong            intra = false;
10129a84457aed4c45bc900998b5e11c03023264208James Dong        }
10229a84457aed4c45bc900998b5e11c03023264208James Dong    }
10329a84457aed4c45bc900998b5e11c03023264208James Dong
10429a84457aed4c45bc900998b5e11c03023264208James Dong    return intra;
10529a84457aed4c45bc900998b5e11c03023264208James Dong}
10629a84457aed4c45bc900998b5e11c03023264208James Dong
10729a84457aed4c45bc900998b5e11c03023264208James Dong/* perform searching for MB mode */
10829a84457aed4c45bc900998b5e11c03023264208James Dong/* assuming that this is done inside the encoding loop,
10929a84457aed4c45bc900998b5e11c03023264208James Dongno need to call InitNeighborAvailability */
11029a84457aed4c45bc900998b5e11c03023264208James Dong
11129a84457aed4c45bc900998b5e11c03023264208James Dongvoid MBIntraSearch(AVCEncObject *encvid, int mbnum, uint8 *curL, int picPitch)
11229a84457aed4c45bc900998b5e11c03023264208James Dong{
11329a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
11429a84457aed4c45bc900998b5e11c03023264208James Dong    AVCFrameIO *currInput = encvid->currInput;
11529a84457aed4c45bc900998b5e11c03023264208James Dong    AVCMacroblock *currMB = video->currMB;
11629a84457aed4c45bc900998b5e11c03023264208James Dong    int min_cost;
11729a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *orgY;
11829a84457aed4c45bc900998b5e11c03023264208James Dong    int x_pos = (video->mb_x) << 4;
11929a84457aed4c45bc900998b5e11c03023264208James Dong    int y_pos = (video->mb_y) << 4;
12029a84457aed4c45bc900998b5e11c03023264208James Dong    uint32 *saved_inter;
12129a84457aed4c45bc900998b5e11c03023264208James Dong    int j;
12229a84457aed4c45bc900998b5e11c03023264208James Dong    int orgPitch = currInput->pitch;
12329a84457aed4c45bc900998b5e11c03023264208James Dong    bool intra = true;
12429a84457aed4c45bc900998b5e11c03023264208James Dong
12529a84457aed4c45bc900998b5e11c03023264208James Dong    currMB->CBP = 0;
12629a84457aed4c45bc900998b5e11c03023264208James Dong
12729a84457aed4c45bc900998b5e11c03023264208James Dong    /* first do motion vector and variable block size search */
12829a84457aed4c45bc900998b5e11c03023264208James Dong    min_cost = encvid->min_cost[mbnum];
12929a84457aed4c45bc900998b5e11c03023264208James Dong
13029a84457aed4c45bc900998b5e11c03023264208James Dong    /* now perform intra prediction search */
13129a84457aed4c45bc900998b5e11c03023264208James Dong    /* need to add the check for encvid->intraSearch[video->mbNum] to skip intra
13229a84457aed4c45bc900998b5e11c03023264208James Dong       if it's not worth checking. */
13329a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->slice_type == AVC_P_SLICE)
13429a84457aed4c45bc900998b5e11c03023264208James Dong    {
13529a84457aed4c45bc900998b5e11c03023264208James Dong        /* Decide whether intra search is necessary or not */
13629a84457aed4c45bc900998b5e11c03023264208James Dong        /* This one, we do it in the encoding loop so the neighboring pixel are the
13729a84457aed4c45bc900998b5e11c03023264208James Dong        actual reconstructed pixels. */
13829a84457aed4c45bc900998b5e11c03023264208James Dong        intra = IntraDecisionABE(encvid, min_cost, curL, picPitch);
13929a84457aed4c45bc900998b5e11c03023264208James Dong    }
14029a84457aed4c45bc900998b5e11c03023264208James Dong
14129a84457aed4c45bc900998b5e11c03023264208James Dong    if (intra == true || video->slice_type == AVC_I_SLICE)
14229a84457aed4c45bc900998b5e11c03023264208James Dong    {
14329a84457aed4c45bc900998b5e11c03023264208James Dong        orgY = currInput->YCbCr[0] + y_pos * orgPitch + x_pos;
14429a84457aed4c45bc900998b5e11c03023264208James Dong
14529a84457aed4c45bc900998b5e11c03023264208James Dong        /* i16 mode search */
14629a84457aed4c45bc900998b5e11c03023264208James Dong        /* generate all the predictions */
14729a84457aed4c45bc900998b5e11c03023264208James Dong        intrapred_luma_16x16(encvid);
14829a84457aed4c45bc900998b5e11c03023264208James Dong
14929a84457aed4c45bc900998b5e11c03023264208James Dong        /* evaluate them one by one */
15029a84457aed4c45bc900998b5e11c03023264208James Dong        find_cost_16x16(encvid, orgY, &min_cost);
15129a84457aed4c45bc900998b5e11c03023264208James Dong
15229a84457aed4c45bc900998b5e11c03023264208James Dong        if (video->slice_type == AVC_P_SLICE)
15329a84457aed4c45bc900998b5e11c03023264208James Dong        {
15429a84457aed4c45bc900998b5e11c03023264208James Dong            /* save current inter prediction */
15529a84457aed4c45bc900998b5e11c03023264208James Dong            saved_inter = encvid->subpel_pred; /* reuse existing buffer */
15629a84457aed4c45bc900998b5e11c03023264208James Dong            j = 16;
15729a84457aed4c45bc900998b5e11c03023264208James Dong            curL -= 4;
15829a84457aed4c45bc900998b5e11c03023264208James Dong            picPitch -= 16;
15929a84457aed4c45bc900998b5e11c03023264208James Dong            while (j--)
16029a84457aed4c45bc900998b5e11c03023264208James Dong            {
16129a84457aed4c45bc900998b5e11c03023264208James Dong                *saved_inter++ = *((uint32*)(curL += 4));
16229a84457aed4c45bc900998b5e11c03023264208James Dong                *saved_inter++ = *((uint32*)(curL += 4));
16329a84457aed4c45bc900998b5e11c03023264208James Dong                *saved_inter++ = *((uint32*)(curL += 4));
16429a84457aed4c45bc900998b5e11c03023264208James Dong                *saved_inter++ = *((uint32*)(curL += 4));
16529a84457aed4c45bc900998b5e11c03023264208James Dong                curL += picPitch;
16629a84457aed4c45bc900998b5e11c03023264208James Dong            }
16729a84457aed4c45bc900998b5e11c03023264208James Dong
16829a84457aed4c45bc900998b5e11c03023264208James Dong        }
16929a84457aed4c45bc900998b5e11c03023264208James Dong
17029a84457aed4c45bc900998b5e11c03023264208James Dong        /* i4 mode search */
17129a84457aed4c45bc900998b5e11c03023264208James Dong        mb_intra4x4_search(encvid, &min_cost);
17229a84457aed4c45bc900998b5e11c03023264208James Dong
17329a84457aed4c45bc900998b5e11c03023264208James Dong        encvid->min_cost[mbnum] = min_cost; /* update min_cost */
17429a84457aed4c45bc900998b5e11c03023264208James Dong    }
17529a84457aed4c45bc900998b5e11c03023264208James Dong
17629a84457aed4c45bc900998b5e11c03023264208James Dong
17729a84457aed4c45bc900998b5e11c03023264208James Dong    if (currMB->mb_intra)
17829a84457aed4c45bc900998b5e11c03023264208James Dong    {
17929a84457aed4c45bc900998b5e11c03023264208James Dong        chroma_intra_search(encvid);
18029a84457aed4c45bc900998b5e11c03023264208James Dong
18129a84457aed4c45bc900998b5e11c03023264208James Dong        /* need to set this in order for the MBInterPrediction to work!! */
18229a84457aed4c45bc900998b5e11c03023264208James Dong        memset(currMB->mvL0, 0, sizeof(int32)*16);
18329a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->ref_idx_L0[0] = currMB->ref_idx_L0[1] =
18429a84457aed4c45bc900998b5e11c03023264208James Dong                                    currMB->ref_idx_L0[2] = currMB->ref_idx_L0[3] = -1;
18529a84457aed4c45bc900998b5e11c03023264208James Dong    }
18629a84457aed4c45bc900998b5e11c03023264208James Dong    else if (video->slice_type == AVC_P_SLICE && intra == true)
18729a84457aed4c45bc900998b5e11c03023264208James Dong    {
18829a84457aed4c45bc900998b5e11c03023264208James Dong        /* restore current inter prediction */
18929a84457aed4c45bc900998b5e11c03023264208James Dong        saved_inter = encvid->subpel_pred; /* reuse existing buffer */
19029a84457aed4c45bc900998b5e11c03023264208James Dong        j = 16;
19129a84457aed4c45bc900998b5e11c03023264208James Dong        curL -= ((picPitch + 16) << 4);
19229a84457aed4c45bc900998b5e11c03023264208James Dong        while (j--)
19329a84457aed4c45bc900998b5e11c03023264208James Dong        {
19429a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(curL += 4)) = *saved_inter++;
19529a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(curL += 4)) = *saved_inter++;
19629a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(curL += 4)) = *saved_inter++;
19729a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(curL += 4)) = *saved_inter++;
19829a84457aed4c45bc900998b5e11c03023264208James Dong            curL += picPitch;
19929a84457aed4c45bc900998b5e11c03023264208James Dong        }
20029a84457aed4c45bc900998b5e11c03023264208James Dong    }
20129a84457aed4c45bc900998b5e11c03023264208James Dong
20229a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
20329a84457aed4c45bc900998b5e11c03023264208James Dong}
20429a84457aed4c45bc900998b5e11c03023264208James Dong
20529a84457aed4c45bc900998b5e11c03023264208James Dong/* generate all the prediction values */
20629a84457aed4c45bc900998b5e11c03023264208James Dongvoid intrapred_luma_16x16(AVCEncObject *encvid)
20729a84457aed4c45bc900998b5e11c03023264208James Dong{
20829a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
20929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCPictureData *currPic = video->currPic;
21029a84457aed4c45bc900998b5e11c03023264208James Dong
21129a84457aed4c45bc900998b5e11c03023264208James Dong    int x_pos = (video->mb_x) << 4;
21229a84457aed4c45bc900998b5e11c03023264208James Dong    int y_pos = (video->mb_y) << 4;
21329a84457aed4c45bc900998b5e11c03023264208James Dong    int pitch = currPic->pitch;
21429a84457aed4c45bc900998b5e11c03023264208James Dong
21529a84457aed4c45bc900998b5e11c03023264208James Dong    int offset = y_pos * pitch + x_pos;
21629a84457aed4c45bc900998b5e11c03023264208James Dong
21729a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *pred, *top, *left;
21829a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *curL = currPic->Sl + offset; /* point to reconstructed frame */
21929a84457aed4c45bc900998b5e11c03023264208James Dong    uint32 word1, word2, word3, word4;
22029a84457aed4c45bc900998b5e11c03023264208James Dong    uint32 sum = 0;
22129a84457aed4c45bc900998b5e11c03023264208James Dong
22229a84457aed4c45bc900998b5e11c03023264208James Dong    int a_16, b, c, factor_c;
22329a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *comp_ref_x0, *comp_ref_x1, *comp_ref_y0, *comp_ref_y1;
22429a84457aed4c45bc900998b5e11c03023264208James Dong    int H = 0, V = 0, tmp, value;
22529a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
22629a84457aed4c45bc900998b5e11c03023264208James Dong
22729a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->intraAvailB)
22829a84457aed4c45bc900998b5e11c03023264208James Dong    {
22929a84457aed4c45bc900998b5e11c03023264208James Dong        //get vertical prediction mode
23029a84457aed4c45bc900998b5e11c03023264208James Dong        top = curL - pitch;
23129a84457aed4c45bc900998b5e11c03023264208James Dong
23229a84457aed4c45bc900998b5e11c03023264208James Dong        pred = encvid->pred_i16[AVC_I16_Vertical] - 16;
23329a84457aed4c45bc900998b5e11c03023264208James Dong
23429a84457aed4c45bc900998b5e11c03023264208James Dong        word1 = *((uint32*)(top));  /* read 4 bytes from top */
23529a84457aed4c45bc900998b5e11c03023264208James Dong        word2 = *((uint32*)(top + 4)); /* read 4 bytes from top */
23629a84457aed4c45bc900998b5e11c03023264208James Dong        word3 = *((uint32*)(top + 8)); /* read 4 bytes from top */
23729a84457aed4c45bc900998b5e11c03023264208James Dong        word4 = *((uint32*)(top + 12)); /* read 4 bytes from top */
23829a84457aed4c45bc900998b5e11c03023264208James Dong
23929a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 0; i < 16; i++)
24029a84457aed4c45bc900998b5e11c03023264208James Dong        {
24129a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(pred += 16)) = word1;
24229a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(pred + 4)) = word2;
24329a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(pred + 8)) = word3;
24429a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(pred + 12)) = word4;
24529a84457aed4c45bc900998b5e11c03023264208James Dong
24629a84457aed4c45bc900998b5e11c03023264208James Dong        }
24729a84457aed4c45bc900998b5e11c03023264208James Dong
24829a84457aed4c45bc900998b5e11c03023264208James Dong        sum = word1 & 0xFF00FF;
24929a84457aed4c45bc900998b5e11c03023264208James Dong        word1 = (word1 >> 8) & 0xFF00FF;
25029a84457aed4c45bc900998b5e11c03023264208James Dong        sum += word1;
25129a84457aed4c45bc900998b5e11c03023264208James Dong        word1 = (word2 & 0xFF00FF);
25229a84457aed4c45bc900998b5e11c03023264208James Dong        sum += word1;
25329a84457aed4c45bc900998b5e11c03023264208James Dong        word2 = (word2 >> 8) & 0xFF00FF;
25429a84457aed4c45bc900998b5e11c03023264208James Dong        sum += word2;
25529a84457aed4c45bc900998b5e11c03023264208James Dong        word1 = (word3 & 0xFF00FF);
25629a84457aed4c45bc900998b5e11c03023264208James Dong        sum += word1;
25729a84457aed4c45bc900998b5e11c03023264208James Dong        word3 = (word3 >> 8) & 0xFF00FF;
25829a84457aed4c45bc900998b5e11c03023264208James Dong        sum += word3;
25929a84457aed4c45bc900998b5e11c03023264208James Dong        word1 = (word4 & 0xFF00FF);
26029a84457aed4c45bc900998b5e11c03023264208James Dong        sum += word1;
26129a84457aed4c45bc900998b5e11c03023264208James Dong        word4 = (word4 >> 8) & 0xFF00FF;
26229a84457aed4c45bc900998b5e11c03023264208James Dong        sum += word4;
26329a84457aed4c45bc900998b5e11c03023264208James Dong
26429a84457aed4c45bc900998b5e11c03023264208James Dong        sum += (sum >> 16);
26529a84457aed4c45bc900998b5e11c03023264208James Dong        sum &= 0xFFFF;
26629a84457aed4c45bc900998b5e11c03023264208James Dong
26729a84457aed4c45bc900998b5e11c03023264208James Dong        if (!video->intraAvailA)
26829a84457aed4c45bc900998b5e11c03023264208James Dong        {
26929a84457aed4c45bc900998b5e11c03023264208James Dong            sum = (sum + 8) >> 4;
27029a84457aed4c45bc900998b5e11c03023264208James Dong        }
27129a84457aed4c45bc900998b5e11c03023264208James Dong    }
27229a84457aed4c45bc900998b5e11c03023264208James Dong
27329a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->intraAvailA)
27429a84457aed4c45bc900998b5e11c03023264208James Dong    {
27529a84457aed4c45bc900998b5e11c03023264208James Dong        // get horizontal mode
27629a84457aed4c45bc900998b5e11c03023264208James Dong        left = curL - 1 - pitch;
27729a84457aed4c45bc900998b5e11c03023264208James Dong
27829a84457aed4c45bc900998b5e11c03023264208James Dong        pred = encvid->pred_i16[AVC_I16_Horizontal] - 16;
27929a84457aed4c45bc900998b5e11c03023264208James Dong
28029a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 0; i < 16; i++)
28129a84457aed4c45bc900998b5e11c03023264208James Dong        {
28229a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = *(left += pitch);
28329a84457aed4c45bc900998b5e11c03023264208James Dong            sum += word1;
28429a84457aed4c45bc900998b5e11c03023264208James Dong
28529a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1 << 8) | word1;
28629a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1 << 16) | word1; /* make it 4 */
28729a84457aed4c45bc900998b5e11c03023264208James Dong
28829a84457aed4c45bc900998b5e11c03023264208James Dong            *(uint32*)(pred += 16) = word1;
28929a84457aed4c45bc900998b5e11c03023264208James Dong            *(uint32*)(pred + 4) = word1;
29029a84457aed4c45bc900998b5e11c03023264208James Dong            *(uint32*)(pred + 8) = word1;
29129a84457aed4c45bc900998b5e11c03023264208James Dong            *(uint32*)(pred + 12) = word1;
29229a84457aed4c45bc900998b5e11c03023264208James Dong        }
29329a84457aed4c45bc900998b5e11c03023264208James Dong
29429a84457aed4c45bc900998b5e11c03023264208James Dong        if (!video->intraAvailB)
29529a84457aed4c45bc900998b5e11c03023264208James Dong        {
29629a84457aed4c45bc900998b5e11c03023264208James Dong            sum = (sum + 8) >> 4;
29729a84457aed4c45bc900998b5e11c03023264208James Dong        }
29829a84457aed4c45bc900998b5e11c03023264208James Dong        else
29929a84457aed4c45bc900998b5e11c03023264208James Dong        {
30029a84457aed4c45bc900998b5e11c03023264208James Dong            sum = (sum + 16) >> 5;
30129a84457aed4c45bc900998b5e11c03023264208James Dong        }
30229a84457aed4c45bc900998b5e11c03023264208James Dong    }
30329a84457aed4c45bc900998b5e11c03023264208James Dong
30429a84457aed4c45bc900998b5e11c03023264208James Dong    // get DC mode
30529a84457aed4c45bc900998b5e11c03023264208James Dong    if (!video->intraAvailA && !video->intraAvailB)
30629a84457aed4c45bc900998b5e11c03023264208James Dong    {
30729a84457aed4c45bc900998b5e11c03023264208James Dong        sum = 0x80808080;
30829a84457aed4c45bc900998b5e11c03023264208James Dong    }
30929a84457aed4c45bc900998b5e11c03023264208James Dong    else
31029a84457aed4c45bc900998b5e11c03023264208James Dong    {
31129a84457aed4c45bc900998b5e11c03023264208James Dong        sum = (sum << 8) | sum;
31229a84457aed4c45bc900998b5e11c03023264208James Dong        sum = (sum << 16) | sum;
31329a84457aed4c45bc900998b5e11c03023264208James Dong    }
31429a84457aed4c45bc900998b5e11c03023264208James Dong
31529a84457aed4c45bc900998b5e11c03023264208James Dong    pred = encvid->pred_i16[AVC_I16_DC] - 16;
31629a84457aed4c45bc900998b5e11c03023264208James Dong    for (i = 0; i < 16; i++)
31729a84457aed4c45bc900998b5e11c03023264208James Dong    {
31829a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(pred += 16)) = sum;
31929a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(pred + 4)) = sum;
32029a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(pred + 8)) = sum;
32129a84457aed4c45bc900998b5e11c03023264208James Dong        *((uint32*)(pred + 12)) = sum;
32229a84457aed4c45bc900998b5e11c03023264208James Dong    }
32329a84457aed4c45bc900998b5e11c03023264208James Dong
32429a84457aed4c45bc900998b5e11c03023264208James Dong    // get plane mode
32529a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->intraAvailA && video->intraAvailB && video->intraAvailD)
32629a84457aed4c45bc900998b5e11c03023264208James Dong    {
32729a84457aed4c45bc900998b5e11c03023264208James Dong        pred = encvid->pred_i16[AVC_I16_Plane] - 16;
32829a84457aed4c45bc900998b5e11c03023264208James Dong
32929a84457aed4c45bc900998b5e11c03023264208James Dong        comp_ref_x0 = curL - pitch + 8;
33029a84457aed4c45bc900998b5e11c03023264208James Dong        comp_ref_x1 = curL - pitch + 6;
33129a84457aed4c45bc900998b5e11c03023264208James Dong        comp_ref_y0 = curL - 1 + (pitch << 3);
33229a84457aed4c45bc900998b5e11c03023264208James Dong        comp_ref_y1 = curL - 1 + 6 * pitch;
33329a84457aed4c45bc900998b5e11c03023264208James Dong
33429a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 1; i < 8; i++)
33529a84457aed4c45bc900998b5e11c03023264208James Dong        {
33629a84457aed4c45bc900998b5e11c03023264208James Dong            H += i * (*comp_ref_x0++ - *comp_ref_x1--);
33729a84457aed4c45bc900998b5e11c03023264208James Dong            V += i * (*comp_ref_y0 - *comp_ref_y1);
33829a84457aed4c45bc900998b5e11c03023264208James Dong            comp_ref_y0 += pitch;
33929a84457aed4c45bc900998b5e11c03023264208James Dong            comp_ref_y1 -= pitch;
34029a84457aed4c45bc900998b5e11c03023264208James Dong        }
34129a84457aed4c45bc900998b5e11c03023264208James Dong
34229a84457aed4c45bc900998b5e11c03023264208James Dong        H += i * (*comp_ref_x0++ - curL[-pitch-1]);
34329a84457aed4c45bc900998b5e11c03023264208James Dong        V += i * (*comp_ref_y0 - *comp_ref_y1);
34429a84457aed4c45bc900998b5e11c03023264208James Dong
34529a84457aed4c45bc900998b5e11c03023264208James Dong
34629a84457aed4c45bc900998b5e11c03023264208James Dong        a_16 = ((*(curL - pitch + 15) + *(curL - 1 + 15 * pitch)) << 4) + 16;;
34729a84457aed4c45bc900998b5e11c03023264208James Dong        b = (5 * H + 32) >> 6;
34829a84457aed4c45bc900998b5e11c03023264208James Dong        c = (5 * V + 32) >> 6;
34929a84457aed4c45bc900998b5e11c03023264208James Dong
35029a84457aed4c45bc900998b5e11c03023264208James Dong        tmp = 0;
35129a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 0; i < 16; i++)
35229a84457aed4c45bc900998b5e11c03023264208James Dong        {
35329a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c = a_16 + c * (tmp++ - 7);
35429a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c -= 7 * b;
35529a84457aed4c45bc900998b5e11c03023264208James Dong
35629a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
35729a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
35829a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
35929a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = value;
36029a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
36129a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
36229a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
36329a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 8);
36429a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
36529a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
36629a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
36729a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 16);
36829a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
36929a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
37029a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
37129a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 24);
37229a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(pred += 16)) = word1;
37329a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
37429a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
37529a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
37629a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = value;
37729a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
37829a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
37929a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
38029a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 8);
38129a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
38229a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
38329a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
38429a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 16);
38529a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
38629a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
38729a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
38829a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 24);
38929a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(pred + 4)) = word1;
39029a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
39129a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
39229a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
39329a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = value;
39429a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
39529a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
39629a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
39729a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 8);
39829a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
39929a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
40029a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
40129a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 16);
40229a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
40329a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
40429a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
40529a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 24);
40629a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(pred + 8)) = word1;
40729a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
40829a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
40929a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
41029a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = value;
41129a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
41229a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
41329a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
41429a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 8);
41529a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
41629a84457aed4c45bc900998b5e11c03023264208James Dong            factor_c += b;
41729a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
41829a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 16);
41929a84457aed4c45bc900998b5e11c03023264208James Dong            value = factor_c >> 5;
42029a84457aed4c45bc900998b5e11c03023264208James Dong            CLIP_RESULT(value)
42129a84457aed4c45bc900998b5e11c03023264208James Dong            word1 = (word1) | (value << 24);
42229a84457aed4c45bc900998b5e11c03023264208James Dong            *((uint32*)(pred + 12)) = word1;
42329a84457aed4c45bc900998b5e11c03023264208James Dong        }
42429a84457aed4c45bc900998b5e11c03023264208James Dong    }
42529a84457aed4c45bc900998b5e11c03023264208James Dong
42629a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
42729a84457aed4c45bc900998b5e11c03023264208James Dong}
42829a84457aed4c45bc900998b5e11c03023264208James Dong
42929a84457aed4c45bc900998b5e11c03023264208James Dong
43029a84457aed4c45bc900998b5e11c03023264208James Dong/* evaluate each prediction mode of I16 */
43129a84457aed4c45bc900998b5e11c03023264208James Dongvoid find_cost_16x16(AVCEncObject *encvid, uint8 *orgY, int *min_cost)
43229a84457aed4c45bc900998b5e11c03023264208James Dong{
43329a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
43429a84457aed4c45bc900998b5e11c03023264208James Dong    AVCMacroblock *currMB = video->currMB;
43529a84457aed4c45bc900998b5e11c03023264208James Dong    int cost;
43629a84457aed4c45bc900998b5e11c03023264208James Dong    int org_pitch = encvid->currInput->pitch;
43729a84457aed4c45bc900998b5e11c03023264208James Dong
43829a84457aed4c45bc900998b5e11c03023264208James Dong    /* evaluate vertical mode */
43929a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->intraAvailB)
44029a84457aed4c45bc900998b5e11c03023264208James Dong    {
44129a84457aed4c45bc900998b5e11c03023264208James Dong        cost = cost_i16(orgY, org_pitch, encvid->pred_i16[AVC_I16_Vertical], *min_cost);
44229a84457aed4c45bc900998b5e11c03023264208James Dong        if (cost < *min_cost)
44329a84457aed4c45bc900998b5e11c03023264208James Dong        {
44429a84457aed4c45bc900998b5e11c03023264208James Dong            *min_cost = cost;
44529a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->mbMode = AVC_I16;
44629a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->mb_intra = 1;
44729a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->i16Mode = AVC_I16_Vertical;
44829a84457aed4c45bc900998b5e11c03023264208James Dong        }
44929a84457aed4c45bc900998b5e11c03023264208James Dong    }
45029a84457aed4c45bc900998b5e11c03023264208James Dong
45129a84457aed4c45bc900998b5e11c03023264208James Dong
45229a84457aed4c45bc900998b5e11c03023264208James Dong    /* evaluate horizontal mode */
45329a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->intraAvailA)
45429a84457aed4c45bc900998b5e11c03023264208James Dong    {
45529a84457aed4c45bc900998b5e11c03023264208James Dong        cost = cost_i16(orgY, org_pitch, encvid->pred_i16[AVC_I16_Horizontal], *min_cost);
45629a84457aed4c45bc900998b5e11c03023264208James Dong        if (cost < *min_cost)
45729a84457aed4c45bc900998b5e11c03023264208James Dong        {
45829a84457aed4c45bc900998b5e11c03023264208James Dong            *min_cost = cost;
45929a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->mbMode = AVC_I16;
46029a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->mb_intra = 1;
46129a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->i16Mode = AVC_I16_Horizontal;
46229a84457aed4c45bc900998b5e11c03023264208James Dong        }
46329a84457aed4c45bc900998b5e11c03023264208James Dong    }
46429a84457aed4c45bc900998b5e11c03023264208James Dong
46529a84457aed4c45bc900998b5e11c03023264208James Dong    /* evaluate DC mode */
46629a84457aed4c45bc900998b5e11c03023264208James Dong    cost = cost_i16(orgY, org_pitch, encvid->pred_i16[AVC_I16_DC], *min_cost);
46729a84457aed4c45bc900998b5e11c03023264208James Dong    if (cost < *min_cost)
46829a84457aed4c45bc900998b5e11c03023264208James Dong    {
46929a84457aed4c45bc900998b5e11c03023264208James Dong        *min_cost = cost;
47029a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->mbMode = AVC_I16;
47129a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->mb_intra = 1;
47229a84457aed4c45bc900998b5e11c03023264208James Dong        currMB->i16Mode = AVC_I16_DC;
47329a84457aed4c45bc900998b5e11c03023264208James Dong    }
47429a84457aed4c45bc900998b5e11c03023264208James Dong
47529a84457aed4c45bc900998b5e11c03023264208James Dong    /* evaluate plane mode */
47629a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->intraAvailA && video->intraAvailB && video->intraAvailD)
47729a84457aed4c45bc900998b5e11c03023264208James Dong    {
47829a84457aed4c45bc900998b5e11c03023264208James Dong        cost = cost_i16(orgY, org_pitch, encvid->pred_i16[AVC_I16_Plane], *min_cost);
47929a84457aed4c45bc900998b5e11c03023264208James Dong        if (cost < *min_cost)
48029a84457aed4c45bc900998b5e11c03023264208James Dong        {
48129a84457aed4c45bc900998b5e11c03023264208James Dong            *min_cost = cost;
48229a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->mbMode = AVC_I16;
48329a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->mb_intra = 1;
48429a84457aed4c45bc900998b5e11c03023264208James Dong            currMB->i16Mode = AVC_I16_Plane;
48529a84457aed4c45bc900998b5e11c03023264208James Dong        }
48629a84457aed4c45bc900998b5e11c03023264208James Dong    }
48729a84457aed4c45bc900998b5e11c03023264208James Dong
48829a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
48929a84457aed4c45bc900998b5e11c03023264208James Dong}
49029a84457aed4c45bc900998b5e11c03023264208James Dong
49129a84457aed4c45bc900998b5e11c03023264208James Dong
49229a84457aed4c45bc900998b5e11c03023264208James Dongint cost_i16(uint8 *org, int org_pitch, uint8 *pred, int min_cost)
49329a84457aed4c45bc900998b5e11c03023264208James Dong{
49429a84457aed4c45bc900998b5e11c03023264208James Dong
49529a84457aed4c45bc900998b5e11c03023264208James Dong    int cost;
49629a84457aed4c45bc900998b5e11c03023264208James Dong    int j, k;
49729a84457aed4c45bc900998b5e11c03023264208James Dong    int16 res[256], *pres; // residue
49829a84457aed4c45bc900998b5e11c03023264208James Dong    int m0, m1, m2, m3;
49929a84457aed4c45bc900998b5e11c03023264208James Dong
50029a84457aed4c45bc900998b5e11c03023264208James Dong    // calculate SATD
50129a84457aed4c45bc900998b5e11c03023264208James Dong    org_pitch -= 16;
50229a84457aed4c45bc900998b5e11c03023264208James Dong    pres = res;
50329a84457aed4c45bc900998b5e11c03023264208James Dong    // horizontal transform
50429a84457aed4c45bc900998b5e11c03023264208James Dong    for (j = 0; j < 16; j++)
50529a84457aed4c45bc900998b5e11c03023264208James Dong    {
50629a84457aed4c45bc900998b5e11c03023264208James Dong        k = 4;
50729a84457aed4c45bc900998b5e11c03023264208James Dong        while (k > 0)
50829a84457aed4c45bc900998b5e11c03023264208James Dong        {
50929a84457aed4c45bc900998b5e11c03023264208James Dong            m0 = org[0] - pred[0];
51029a84457aed4c45bc900998b5e11c03023264208James Dong            m3 = org[3] - pred[3];
51129a84457aed4c45bc900998b5e11c03023264208James Dong            m0 += m3;
51229a84457aed4c45bc900998b5e11c03023264208James Dong            m3 = m0 - (m3 << 1);
51329a84457aed4c45bc900998b5e11c03023264208James Dong            m1 = org[1] - pred[1];
51429a84457aed4c45bc900998b5e11c03023264208James Dong            m2 = org[2] - pred[2];
51529a84457aed4c45bc900998b5e11c03023264208James Dong            m1 += m2;
51629a84457aed4c45bc900998b5e11c03023264208James Dong            m2 = m1 - (m2 << 1);
51729a84457aed4c45bc900998b5e11c03023264208James Dong            pres[0] = m0 + m1;
51829a84457aed4c45bc900998b5e11c03023264208James Dong            pres[2] = m0 - m1;
51929a84457aed4c45bc900998b5e11c03023264208James Dong            pres[1] = m2 + m3;
52029a84457aed4c45bc900998b5e11c03023264208James Dong            pres[3] = m3 - m2;
52129a84457aed4c45bc900998b5e11c03023264208James Dong
52229a84457aed4c45bc900998b5e11c03023264208James Dong            org += 4;
52329a84457aed4c45bc900998b5e11c03023264208James Dong            pres += 4;
52429a84457aed4c45bc900998b5e11c03023264208James Dong            pred += 4;
52529a84457aed4c45bc900998b5e11c03023264208James Dong            k--;
52629a84457aed4c45bc900998b5e11c03023264208James Dong        }
52729a84457aed4c45bc900998b5e11c03023264208James Dong        org += org_pitch;
52829a84457aed4c45bc900998b5e11c03023264208James Dong    }
52929a84457aed4c45bc900998b5e11c03023264208James Dong    /* vertical transform */
53029a84457aed4c45bc900998b5e11c03023264208James Dong    cost = 0;
53129a84457aed4c45bc900998b5e11c03023264208James Dong    for (j = 0; j < 4; j++)
53229a84457aed4c45bc900998b5e11c03023264208James Dong    {
53329a84457aed4c45bc900998b5e11c03023264208James Dong        pres = res + (j << 6);
53429a84457aed4c45bc900998b5e11c03023264208James Dong        k = 16;
53529a84457aed4c45bc900998b5e11c03023264208James Dong        while (k > 0)
53629a84457aed4c45bc900998b5e11c03023264208James Dong        {
53729a84457aed4c45bc900998b5e11c03023264208James Dong            m0 = pres[0];
53829a84457aed4c45bc900998b5e11c03023264208James Dong            m3 = pres[3<<4];
53929a84457aed4c45bc900998b5e11c03023264208James Dong            m0 += m3;
54029a84457aed4c45bc900998b5e11c03023264208James Dong            m3 = m0 - (m3 << 1);
54129a84457aed4c45bc900998b5e11c03023264208James Dong            m1 = pres[1<<4];
54229a84457aed4c45bc900998b5e11c03023264208James Dong            m2 = pres[2<<4];
54329a84457aed4c45bc900998b5e11c03023264208James Dong            m1 += m2;
54429a84457aed4c45bc900998b5e11c03023264208James Dong            m2 = m1 - (m2 << 1);
54529a84457aed4c45bc900998b5e11c03023264208James Dong            pres[0] = m0 = m0 + m1;
54629a84457aed4c45bc900998b5e11c03023264208James Dong
54729a84457aed4c45bc900998b5e11c03023264208James Dong            if (k&0x3)  // only sum up non DC values.
54829a84457aed4c45bc900998b5e11c03023264208James Dong            {
54929a84457aed4c45bc900998b5e11c03023264208James Dong                cost += ((m0 > 0) ? m0 : -m0);
55029a84457aed4c45bc900998b5e11c03023264208James Dong            }
55129a84457aed4c45bc900998b5e11c03023264208James Dong
55229a84457aed4c45bc900998b5e11c03023264208James Dong            m1 = m0 - (m1 << 1);
55329a84457aed4c45bc900998b5e11c03023264208James Dong            cost += ((m1 > 0) ? m1 : -m1);
55429a84457aed4c45bc900998b5e11c03023264208James Dong            m3 = m2 + m3;
55529a84457aed4c45bc900998b5e11c03023264208James Dong            cost += ((m3 > 0) ? m3 : -m3);
55629a84457aed4c45bc900998b5e11c03023264208James Dong            m2 = m3 - (m2 << 1);
55729a84457aed4c45bc900998b5e11c03023264208James Dong            cost += ((m2 > 0) ? m2 : -m2);
55829a84457aed4c45bc900998b5e11c03023264208James Dong
55929a84457aed4c45bc900998b5e11c03023264208James Dong            pres++;
56029a84457aed4c45bc900998b5e11c03023264208James Dong            k--;
56129a84457aed4c45bc900998b5e11c03023264208James Dong        }
56229a84457aed4c45bc900998b5e11c03023264208James Dong        if ((cost >> 1) > min_cost) /* early drop out */
56329a84457aed4c45bc900998b5e11c03023264208James Dong        {
56429a84457aed4c45bc900998b5e11c03023264208James Dong            return (cost >> 1);
56529a84457aed4c45bc900998b5e11c03023264208James Dong        }
56629a84457aed4c45bc900998b5e11c03023264208James Dong    }
56729a84457aed4c45bc900998b5e11c03023264208James Dong
56829a84457aed4c45bc900998b5e11c03023264208James Dong    /* Hadamard of the DC coefficient */
56929a84457aed4c45bc900998b5e11c03023264208James Dong    pres = res;
57029a84457aed4c45bc900998b5e11c03023264208James Dong    k = 4;
57129a84457aed4c45bc900998b5e11c03023264208James Dong    while (k > 0)
57229a84457aed4c45bc900998b5e11c03023264208James Dong    {
57329a84457aed4c45bc900998b5e11c03023264208James Dong        m0 = pres[0];
57429a84457aed4c45bc900998b5e11c03023264208James Dong        m3 = pres[3<<2];
57529a84457aed4c45bc900998b5e11c03023264208James Dong        m0 >>= 2;
57629a84457aed4c45bc900998b5e11c03023264208James Dong        m0 += (m3 >> 2);
57729a84457aed4c45bc900998b5e11c03023264208James Dong        m3 = m0 - (m3 >> 1);
57829a84457aed4c45bc900998b5e11c03023264208James Dong        m1 = pres[1<<2];
57929a84457aed4c45bc900998b5e11c03023264208James Dong        m2 = pres[2<<2];
58029a84457aed4c45bc900998b5e11c03023264208James Dong        m1 >>= 2;
58129a84457aed4c45bc900998b5e11c03023264208James Dong        m1 += (m2 >> 2);
58229a84457aed4c45bc900998b5e11c03023264208James Dong        m2 = m1 - (m2 >> 1);
58329a84457aed4c45bc900998b5e11c03023264208James Dong        pres[0] = (m0 + m1);
58429a84457aed4c45bc900998b5e11c03023264208James Dong        pres[2<<2] = (m0 - m1);
58529a84457aed4c45bc900998b5e11c03023264208James Dong        pres[1<<2] = (m2 + m3);
58629a84457aed4c45bc900998b5e11c03023264208James Dong        pres[3<<2] = (m3 - m2);
58729a84457aed4c45bc900998b5e11c03023264208James Dong        pres += (4 << 4);
58829a84457aed4c45bc900998b5e11c03023264208James Dong        k--;
58929a84457aed4c45bc900998b5e11c03023264208James Dong    }
59029a84457aed4c45bc900998b5e11c03023264208James Dong
59129a84457aed4c45bc900998b5e11c03023264208James Dong    pres = res;
59229a84457aed4c45bc900998b5e11c03023264208James Dong    k = 4;
59329a84457aed4c45bc900998b5e11c03023264208James Dong    while (k > 0)
59429a84457aed4c45bc900998b5e11c03023264208James Dong    {
59529a84457aed4c45bc900998b5e11c03023264208James Dong        m0 = pres[0];
59629a84457aed4c45bc900998b5e11c03023264208James Dong        m3 = pres[3<<6];
59729a84457aed4c45bc900998b5e11c03023264208James Dong        m0 += m3;
59829a84457aed4c45bc900998b5e11c03023264208James Dong        m3 = m0 - (m3 << 1);
59929a84457aed4c45bc900998b5e11c03023264208James Dong        m1 = pres[1<<6];
60029a84457aed4c45bc900998b5e11c03023264208James Dong        m2 = pres[2<<6];
60129a84457aed4c45bc900998b5e11c03023264208James Dong        m1 += m2;
60229a84457aed4c45bc900998b5e11c03023264208James Dong        m2 = m1 - (m2 << 1);
60329a84457aed4c45bc900998b5e11c03023264208James Dong        m0 = m0 + m1;
60429a84457aed4c45bc900998b5e11c03023264208James Dong        cost += ((m0 >= 0) ? m0 : -m0);
60529a84457aed4c45bc900998b5e11c03023264208James Dong        m1 = m0 - (m1 << 1);
60629a84457aed4c45bc900998b5e11c03023264208James Dong        cost += ((m1 >= 0) ? m1 : -m1);
60729a84457aed4c45bc900998b5e11c03023264208James Dong        m3 = m2 + m3;
60829a84457aed4c45bc900998b5e11c03023264208James Dong        cost += ((m3 >= 0) ? m3 : -m3);
60929a84457aed4c45bc900998b5e11c03023264208James Dong        m2 = m3 - (m2 << 1);
61029a84457aed4c45bc900998b5e11c03023264208James Dong        cost += ((m2 >= 0) ? m2 : -m2);
61129a84457aed4c45bc900998b5e11c03023264208James Dong        pres += 4;
61229a84457aed4c45bc900998b5e11c03023264208James Dong
61329a84457aed4c45bc900998b5e11c03023264208James Dong        if ((cost >> 1) > min_cost) /* early drop out */
61429a84457aed4c45bc900998b5e11c03023264208James Dong        {
61529a84457aed4c45bc900998b5e11c03023264208James Dong            return (cost >> 1);
61629a84457aed4c45bc900998b5e11c03023264208James Dong        }
61729a84457aed4c45bc900998b5e11c03023264208James Dong
61829a84457aed4c45bc900998b5e11c03023264208James Dong        k--;
61929a84457aed4c45bc900998b5e11c03023264208James Dong    }
62029a84457aed4c45bc900998b5e11c03023264208James Dong
62129a84457aed4c45bc900998b5e11c03023264208James Dong    return (cost >> 1);
62229a84457aed4c45bc900998b5e11c03023264208James Dong}
62329a84457aed4c45bc900998b5e11c03023264208James Dong
62429a84457aed4c45bc900998b5e11c03023264208James Dong
62529a84457aed4c45bc900998b5e11c03023264208James Dongvoid mb_intra4x4_search(AVCEncObject *encvid, int *min_cost)
62629a84457aed4c45bc900998b5e11c03023264208James Dong{
62729a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
62829a84457aed4c45bc900998b5e11c03023264208James Dong    AVCMacroblock *currMB = video->currMB;
62929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCPictureData *currPic = video->currPic;
63029a84457aed4c45bc900998b5e11c03023264208James Dong    AVCFrameIO *currInput = encvid->currInput;
63129a84457aed4c45bc900998b5e11c03023264208James Dong    int pitch = currPic->pitch;
63229a84457aed4c45bc900998b5e11c03023264208James Dong    int org_pitch = currInput->pitch;
63329a84457aed4c45bc900998b5e11c03023264208James Dong    int offset;
63429a84457aed4c45bc900998b5e11c03023264208James Dong    uint8 *curL, *comp, *org4, *org8;
63529a84457aed4c45bc900998b5e11c03023264208James Dong    int y = video->mb_y << 4;
63629a84457aed4c45bc900998b5e11c03023264208James Dong    int x = video->mb_x << 4;
63729a84457aed4c45bc900998b5e11c03023264208James Dong
63829a84457aed4c45bc900998b5e11c03023264208James Dong    int b8, b4, cost4x4, blkidx;
63929a84457aed4c45bc900998b5e11c03023264208James Dong    int cost = 0;
64029a84457aed4c45bc900998b5e11c03023264208James Dong    int numcoef;
64129a84457aed4c45bc900998b5e11c03023264208James Dong    int dummy = 0;
642