Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 
     19 #include <string.h>
     20 
     21 #include "avclib_common.h"
     22 
     23 #define MAX_QP 51
     24 #define MB_BLOCK_SIZE 16
     25 
     26 // NOTE: these 3 tables are for funtion GetStrength() only
     27 const static int ININT_STRENGTH[4] = {0x04040404, 0x03030303, 0x03030303, 0x03030303};
     28 
     29 
     30 // NOTE: these 3 tables are for funtion EdgeLoop() only
     31 // NOTE: to change the tables below for instance when the QP doubling is changed from 6 to 8 values
     32 
     33 const static int ALPHA_TABLE[52]  = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 5, 6,  7, 8, 9, 10, 12, 13, 15, 17,  20, 22, 25, 28, 32, 36, 40, 45,  50, 56, 63, 71, 80, 90, 101, 113,  127, 144, 162, 182, 203, 226, 255, 255} ;
     34 const static int BETA_TABLE[52]   = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3,  3, 3, 3, 4, 4, 4, 6, 6,   7, 7, 8, 8, 9, 9, 10, 10,  11, 11, 12, 12, 13, 13, 14, 14,   15, 15, 16, 16, 17, 17, 18, 18} ;
     35 const static int CLIP_TAB[52][5]  =
     36 {
     37     { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0},
     38     { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0},
     39     { 0, 0, 0, 0, 0}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 1, 1, 1}, { 0, 0, 1, 1, 1}, { 0, 1, 1, 1, 1},
     40     { 0, 1, 1, 1, 1}, { 0, 1, 1, 1, 1}, { 0, 1, 1, 1, 1}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 2, 3, 3},
     41     { 0, 1, 2, 3, 3}, { 0, 2, 2, 3, 3}, { 0, 2, 2, 4, 4}, { 0, 2, 3, 4, 4}, { 0, 2, 3, 4, 4}, { 0, 3, 3, 5, 5}, { 0, 3, 4, 6, 6}, { 0, 3, 4, 6, 6},
     42     { 0, 4, 5, 7, 7}, { 0, 4, 5, 8, 8}, { 0, 4, 6, 9, 9}, { 0, 5, 7, 10, 10}, { 0, 6, 8, 11, 11}, { 0, 6, 8, 13, 13}, { 0, 7, 10, 14, 14}, { 0, 8, 11, 16, 16},
     43     { 0, 9, 12, 18, 18}, { 0, 10, 13, 20, 20}, { 0, 11, 15, 23, 23}, { 0, 13, 17, 25, 25}
     44 };
     45 
     46 // NOTE: this table is only QP clipping, index = QP + video->FilterOffsetA/B, clipped to [0, 51]
     47 //       video->FilterOffsetA/B is in {-12, 12]
     48 const static int QP_CLIP_TAB[76] =
     49 {
     50     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,              // [-12, 0]
     51     1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
     52     13, 14, 15, 16, 17, 18, 19, 20, 21,
     53     22, 23, 24, 25, 26, 27, 28, 29, 30,
     54     31, 32, 33, 34, 35, 36, 37, 38, 39,
     55     40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // [1, 51]
     56     51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51      // [52,63]
     57 };
     58 
     59 static void DeblockMb(AVCCommonObj *video, int mb_x, int mb_y, uint8 *SrcY, uint8 *SrcU, uint8 *SrcV);
     60 //static void GetStrength(AVCCommonObj *video, uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir, int edge);
     61 static void GetStrength_Edge0(uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir);
     62 static void GetStrength_VerticalEdges(uint8 *Strength, AVCMacroblock* MbQ);
     63 static void GetStrength_HorizontalEdges(uint8 Strength[12], AVCMacroblock* MbQ);
     64 static void EdgeLoop_Luma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
     65 static void EdgeLoop_Luma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
     66 static void EdgeLoop_Chroma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
     67 static void EdgeLoop_Chroma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
     68 
     69 /*
     70  *****************************************************************************************
     71  * \brief Filter all macroblocks in order of increasing macroblock address.
     72  *****************************************************************************************
     73 */
     74 
     75 OSCL_EXPORT_REF AVCStatus DeblockPicture(AVCCommonObj *video)
     76 {
     77     uint   i, j;
     78     int   pitch = video->currPic->pitch, pitch_c, width;
     79     uint8 *SrcY, *SrcU, *SrcV;
     80 
     81     SrcY = video->currPic->Sl;      // pointers to source
     82     SrcU = video->currPic->Scb;
     83     SrcV = video->currPic->Scr;
     84     pitch_c = pitch >> 1;
     85     width = video->currPic->width;
     86 
     87     for (i = 0; i < video->PicHeightInMbs; i++)
     88     {
     89         for (j = 0; j < video->PicWidthInMbs; j++)
     90         {
     91             DeblockMb(video, j, i, SrcY, SrcU, SrcV);
     92             // update SrcY, SrcU, SrcV
     93             SrcY += MB_BLOCK_SIZE;
     94             SrcU += (MB_BLOCK_SIZE >> 1);
     95             SrcV += (MB_BLOCK_SIZE >> 1);
     96         }
     97 
     98         SrcY += ((pitch << 4) - width);
     99         SrcU += ((pitch_c << 3) - (width >> 1));
    100         SrcV += ((pitch_c << 3) - (width >> 1));
    101     }
    102 
    103     return AVC_SUCCESS;
    104 }
    105 
    106 #ifdef MB_BASED_DEBLOCK
    107 /*
    108  *****************************************************************************************
    109  * \brief Filter one macroblocks in a fast macroblock memory and copy it to frame
    110  *****************************************************************************************
    111 */
    112 void MBInLoopDeblock(AVCCommonObj *video)
    113 {
    114     AVCPictureData *currPic = video->currPic;
    115 #ifdef USE_PRED_BLOCK
    116     uint8 *predCb, *predCr, *pred_block;
    117     int i, j, dst_width, dst_height, dst_widthc, dst_heightc;
    118 #endif
    119     int pitch = currPic->pitch;
    120     int x_pos = video->mb_x;
    121     int y_pos = video->mb_y;
    122     uint8 *curL, *curCb, *curCr;
    123     int offset;
    124 
    125     offset = (y_pos << 4) * pitch;
    126 
    127     curL = currPic->Sl + offset + (x_pos << 4);
    128 
    129     offset >>= 2;
    130     offset += (x_pos << 3);
    131 
    132     curCb = currPic->Scb + offset;
    133     curCr = currPic->Scr + offset;
    134 
    135 #ifdef USE_PRED_BLOCK
    136     pred_block = video->pred;
    137 
    138     /* 1. copy neighboring pixels from frame to the video->pred_block */
    139     if (y_pos) /* not the 0th row */
    140     {
    141         /* copy to the top 4 lines of the macroblock */
    142         curL -= (pitch << 2); /* go back 4 lines */
    143 
    144         memcpy(pred_block + 4, curL, 16);
    145         curL += pitch;
    146         memcpy(pred_block + 24, curL, 16);
    147         curL += pitch;
    148         memcpy(pred_block + 44, curL, 16);
    149         curL += pitch;
    150         memcpy(pred_block + 64, curL, 16);
    151         curL += pitch;
    152 
    153         curCb -= (pitch << 1); /* go back 4 lines chroma */
    154         curCr -= (pitch << 1);
    155 
    156         pred_block += 400;
    157 
    158         memcpy(pred_block + 4, curCb, 8);
    159         curCb += (pitch >> 1);
    160         memcpy(pred_block + 16, curCb, 8);
    161         curCb += (pitch >> 1);
    162         memcpy(pred_block + 28, curCb, 8);
    163         curCb += (pitch >> 1);
    164         memcpy(pred_block + 40, curCb, 8);
    165         curCb += (pitch >> 1);
    166 
    167         pred_block += 144;
    168         memcpy(pred_block + 4, curCr, 8);
    169         curCr += (pitch >> 1);
    170         memcpy(pred_block + 16, curCr, 8);
    171         curCr += (pitch >> 1);
    172         memcpy(pred_block + 28, curCr, 8);
    173         curCr += (pitch >> 1);
    174         memcpy(pred_block + 40, curCr, 8);
    175         curCr += (pitch >> 1);
    176 
    177         pred_block = video->pred;
    178     }
    179 
    180     /* 2. perform deblocking. */
    181     DeblockMb(video, x_pos, y_pos, pred_block + 84, pred_block + 452, pred_block + 596);
    182 
    183     /* 3. copy it back to the frame and update pred_block */
    184     predCb = pred_block + 400;
    185     predCr = predCb + 144;
    186 
    187     /* find the range of the block inside pred_block to be copied back */
    188     if (y_pos)  /* the first row */
    189     {
    190         curL -= (pitch << 2);
    191         curCb -= (pitch << 1);
    192         curCr -= (pitch << 1);
    193 
    194         dst_height = 20;
    195         dst_heightc = 12;
    196     }
    197     else
    198     {
    199         pred_block += 80;
    200         predCb += 48;
    201         predCr += 48;
    202         dst_height = 16;
    203         dst_heightc = 8;
    204     }
    205 
    206     if (x_pos) /* find the width */
    207     {
    208         curL -= 4;
    209         curCb -= 4;
    210         curCr -= 4;
    211         if (x_pos == (int)(video->PicWidthInMbs - 1))
    212         {
    213             dst_width = 20;
    214             dst_widthc = 12;
    215         }
    216         else
    217         {
    218             dst_width = 16;
    219             dst_widthc = 8;
    220         }
    221     }
    222     else
    223     {
    224         pred_block += 4;
    225         predCb += 4;
    226         predCr += 4;
    227         dst_width = 12;
    228         dst_widthc = 4;
    229     }
    230 
    231     /* perform copy */
    232     for (j = 0; j < dst_height; j++)
    233     {
    234         memcpy(curL, pred_block, dst_width);
    235         curL += pitch;
    236         pred_block += 20;
    237     }
    238     for (j = 0; j < dst_heightc; j++)
    239     {
    240         memcpy(curCb, predCb, dst_widthc);
    241         memcpy(curCr, predCr, dst_widthc);
    242         curCb += (pitch >> 1);
    243         curCr += (pitch >> 1);
    244         predCb += 12;
    245         predCr += 12;
    246     }
    247 
    248     if (x_pos != (int)(video->PicWidthInMbs - 1)) /* now copy from the right-most 4 columns to the left-most 4 columns */
    249     {
    250         pred_block = video->pred;
    251         for (i = 0; i < 20; i += 4)
    252         {
    253             *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
    254             pred_block += 20;
    255             *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
    256             pred_block += 20;
    257             *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
    258             pred_block += 20;
    259             *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
    260             pred_block += 20;
    261         }
    262 
    263         for (i = 0; i < 24; i += 4)
    264         {
    265             *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
    266             pred_block += 12;
    267             *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
    268             pred_block += 12;
    269             *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
    270             pred_block += 12;
    271             *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
    272             pred_block += 12;
    273         }
    274 
    275     }
    276 #else
    277     DeblockMb(video, x_pos, y_pos, curL, curCb, curCr);
    278 #endif
    279 
    280     return ;
    281 }
    282 #endif
    283 
    284 /*
    285  *****************************************************************************************
    286  * \brief Deblocking filter for one macroblock.
    287  *****************************************************************************************
    288  */
    289 
    290 void DeblockMb(AVCCommonObj *video, int mb_x, int mb_y, uint8 *SrcY, uint8 *SrcU, uint8 *SrcV)
    291 {
    292     AVCMacroblock *MbP, *MbQ;
    293     int     edge, QP, QPC;
    294     int     filterLeftMbEdgeFlag = (mb_x != 0);
    295     int     filterTopMbEdgeFlag  = (mb_y != 0);
    296     int     pitch = video->currPic->pitch;
    297     int     indexA, indexB, tmp;
    298     int     Alpha, Beta, Alpha_c, Beta_c;
    299     int     mbNum = mb_y * video->PicWidthInMbs + mb_x;
    300     int     *clipTable, *clipTable_c, *qp_clip_tab;
    301     uint8   Strength[16];
    302     void*     str;
    303 
    304     MbQ = &(video->mblock[mbNum]);      // current Mb
    305 
    306 
    307     // If filter is disabled, return
    308     if (video->sliceHdr->disable_deblocking_filter_idc == 1) return;
    309 
    310     if (video->sliceHdr->disable_deblocking_filter_idc == 2)
    311     {
    312         // don't filter at slice boundaries
    313         filterLeftMbEdgeFlag = mb_is_available(video->mblock, video->PicSizeInMbs, mbNum - 1, mbNum);
    314         filterTopMbEdgeFlag  = mb_is_available(video->mblock, video->PicSizeInMbs, mbNum - video->PicWidthInMbs, mbNum);
    315     }
    316 
    317     /* NOTE: edge=0 and edge=1~3 are separate cases because of the difference of MbP, index A and indexB calculation */
    318     /*       for edge = 1~3, MbP, indexA and indexB remain the same, and thus there is no need to re-calculate them for each edge */
    319 
    320     qp_clip_tab = (int *)QP_CLIP_TAB + 12;
    321 
    322     /* 1.VERTICAL EDGE + MB BOUNDARY (edge = 0) */
    323     if (filterLeftMbEdgeFlag)
    324     {
    325         MbP = MbQ - 1;
    326         //GetStrength(video, Strength, MbP, MbQ, 0, 0); // Strength for 4 blks in 1 stripe, 0 => vertical edge
    327         GetStrength_Edge0(Strength, MbP, MbQ, 0);
    328 
    329         str = (void*)Strength; //de-ref type-punned pointer fix
    330         if (*((uint32*)str))    // only if one of the 4 Strength bytes is != 0
    331         {
    332             QP = (MbP->QPy + MbQ->QPy + 1) >> 1; // Average QP of the two blocks;
    333             indexA = QP + video->FilterOffsetA;
    334             indexB = QP + video->FilterOffsetB;
    335             indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
    336             indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
    337 
    338             Alpha  = ALPHA_TABLE[indexA];
    339             Beta = BETA_TABLE[indexB];
    340             clipTable = (int *) CLIP_TAB[indexA];
    341 
    342             if (Alpha > 0 && Beta > 0)
    343 #ifdef USE_PRED_BLOCK
    344                 EdgeLoop_Luma_vertical(SrcY, Strength,  Alpha, Beta, clipTable, 20);
    345 #else
    346                 EdgeLoop_Luma_vertical(SrcY, Strength,  Alpha, Beta, clipTable, pitch);
    347 #endif
    348 
    349             QPC = (MbP->QPc + MbQ->QPc + 1) >> 1;
    350             indexA = QPC + video->FilterOffsetA;
    351             indexB = QPC + video->FilterOffsetB;
    352             indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
    353             indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
    354 
    355             Alpha  = ALPHA_TABLE[indexA];
    356             Beta = BETA_TABLE[indexB];
    357             clipTable = (int *) CLIP_TAB[indexA];
    358             if (Alpha > 0 && Beta > 0)
    359             {
    360 #ifdef USE_PRED_BLOCK
    361                 EdgeLoop_Chroma_vertical(SrcU, Strength, Alpha, Beta, clipTable, 12);
    362                 EdgeLoop_Chroma_vertical(SrcV, Strength, Alpha, Beta, clipTable, 12);
    363 #else
    364                 EdgeLoop_Chroma_vertical(SrcU, Strength, Alpha, Beta, clipTable, pitch >> 1);
    365                 EdgeLoop_Chroma_vertical(SrcV, Strength, Alpha, Beta, clipTable, pitch >> 1);
    366 #endif
    367             }
    368         }
    369 
    370     } /* end of: if(filterLeftMbEdgeFlag) */
    371 
    372     /* 2.VERTICAL EDGE (no boundary), the edges are all inside a MB */
    373     /* First calculate the necesary parameters all at once, outside the loop */
    374     MbP = MbQ;
    375 
    376     indexA = MbQ->QPy + video->FilterOffsetA;
    377     indexB = MbQ->QPy + video->FilterOffsetB;
    378     //  index
    379     indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
    380     indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
    381 
    382     Alpha = ALPHA_TABLE[indexA];
    383     Beta = BETA_TABLE[indexB];
    384     clipTable = (int *)CLIP_TAB[indexA];
    385 
    386     /* Save Alpha,  Beta and clipTable for future use, with the obselete variables filterLeftMbEdgeFlag, mbNum amd tmp */
    387     filterLeftMbEdgeFlag = Alpha;
    388     mbNum = Beta;
    389     tmp = (int)clipTable;
    390 
    391     indexA = MbQ->QPc + video->FilterOffsetA;
    392     indexB = MbQ->QPc + video->FilterOffsetB;
    393     indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
    394     indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
    395 
    396     Alpha_c  = ALPHA_TABLE[indexA];
    397     Beta_c = BETA_TABLE[indexB];
    398     clipTable_c = (int *)CLIP_TAB[indexA];
    399 
    400     GetStrength_VerticalEdges(Strength + 4, MbQ); // Strength for 4 blks in 1 stripe, 0 => vertical edge
    401 
    402     for (edge = 1; edge < 4; edge++)  // 4 vertical strips of 16 pel
    403     {
    404         //GetStrength_VerticalEdges(video, Strength, MbP, MbQ, 0, edge); // Strength for 4 blks in 1 stripe, 0 => vertical edge
    405         if (*((int*)(Strength + (edge << 2))))   // only if one of the 4 Strength bytes is != 0
    406         {
    407             if (Alpha > 0 && Beta > 0)
    408 #ifdef USE_PRED_BLOCK
    409                 EdgeLoop_Luma_vertical(SrcY + (edge << 2), Strength + (edge << 2),  Alpha, Beta, clipTable, 20);
    410 #else
    411                 EdgeLoop_Luma_vertical(SrcY + (edge << 2), Strength + (edge << 2),  Alpha, Beta, clipTable, pitch);
    412 #endif
    413 
    414             if (!(edge & 1) && Alpha_c > 0 && Beta_c > 0)
    415             {
    416 #ifdef USE_PRED_BLOCK
    417                 EdgeLoop_Chroma_vertical(SrcU + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
    418                 EdgeLoop_Chroma_vertical(SrcV + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
    419 #else
    420                 EdgeLoop_Chroma_vertical(SrcU + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
    421                 EdgeLoop_Chroma_vertical(SrcV + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
    422 #endif
    423             }
    424         }
    425 
    426     } //end edge
    427 
    428 
    429 
    430     /* 3.HORIZONTAL EDGE + MB BOUNDARY (edge = 0) */
    431     if (filterTopMbEdgeFlag)
    432     {
    433         MbP = MbQ - video->PicWidthInMbs;
    434         //GetStrength(video, Strength, MbP, MbQ, 1, 0); // Strength for 4 blks in 1 stripe, 0 => vertical edge
    435         GetStrength_Edge0(Strength, MbP, MbQ, 1);
    436         str = (void*)Strength; //de-ref type-punned pointer fix
    437         if (*((uint32*)str))    // only if one of the 4 Strength bytes is != 0
    438         {
    439             QP = (MbP->QPy + MbQ->QPy + 1) >> 1; // Average QP of the two blocks;
    440             indexA = QP + video->FilterOffsetA;
    441             indexB = QP + video->FilterOffsetB;
    442             indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
    443             indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
    444 
    445             Alpha  = ALPHA_TABLE[indexA];
    446             Beta = BETA_TABLE[indexB];
    447             clipTable = (int *)CLIP_TAB[indexA];
    448 
    449             if (Alpha > 0 && Beta > 0)
    450             {
    451 #ifdef USE_PRED_BLOCK
    452                 EdgeLoop_Luma_horizontal(SrcY, Strength,  Alpha, Beta, clipTable, 20);
    453 #else
    454                 EdgeLoop_Luma_horizontal(SrcY, Strength,  Alpha, Beta, clipTable, pitch);
    455 #endif
    456             }
    457 
    458             QPC = (MbP->QPc + MbQ->QPc + 1) >> 1;
    459             indexA = QPC + video->FilterOffsetA;
    460             indexB = QPC + video->FilterOffsetB;
    461             indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
    462             indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
    463 
    464             Alpha  = ALPHA_TABLE[indexA];
    465             Beta = BETA_TABLE[indexB];
    466             clipTable = (int *)CLIP_TAB[indexA];
    467             if (Alpha > 0 && Beta > 0)
    468             {
    469 #ifdef USE_PRED_BLOCK
    470                 EdgeLoop_Chroma_horizontal(SrcU, Strength, Alpha, Beta, clipTable, 12);
    471                 EdgeLoop_Chroma_horizontal(SrcV, Strength, Alpha, Beta, clipTable, 12);
    472 #else
    473                 EdgeLoop_Chroma_horizontal(SrcU, Strength, Alpha, Beta, clipTable, pitch >> 1);
    474                 EdgeLoop_Chroma_horizontal(SrcV, Strength, Alpha, Beta, clipTable, pitch >> 1);
    475 #endif
    476             }
    477         }
    478 
    479     } /* end of: if(filterTopMbEdgeFlag) */
    480 
    481 
    482     /* 4.HORIZONTAL EDGE (no boundary), the edges are inside a MB */
    483     MbP = MbQ;
    484 
    485     /* Recover Alpha,  Beta and clipTable for edge!=0 with the variables filterLeftMbEdgeFlag, mbNum and tmp */
    486     /* Note that Alpha_c, Beta_c and clipTable_c for chroma is already calculated */
    487     Alpha = filterLeftMbEdgeFlag;
    488     Beta = mbNum;
    489     clipTable = (int *)tmp;
    490 
    491     GetStrength_HorizontalEdges(Strength + 4, MbQ); // Strength for 4 blks in 1 stripe, 0 => vertical edge
    492 
    493     for (edge = 1; edge < 4; edge++)  // 4 horicontal strips of 16 pel
    494     {
    495         //GetStrength(video, Strength, MbP, MbQ, 1, edge); // Strength for 4 blks in 1 stripe   1 => horizontal edge
    496         if (*((int*)(Strength + (edge << 2)))) // only if one of the 4 Strength bytes is != 0
    497         {
    498             if (Alpha > 0 && Beta > 0)
    499             {
    500 #ifdef USE_PRED_BLOCK
    501                 EdgeLoop_Luma_horizontal(SrcY + (edge << 2)*20, Strength + (edge << 2),  Alpha, Beta, clipTable, 20);
    502 #else
    503                 EdgeLoop_Luma_horizontal(SrcY + (edge << 2)*pitch, Strength + (edge << 2),  Alpha, Beta, clipTable, pitch);
    504 #endif
    505             }
    506 
    507             if (!(edge & 1) && Alpha_c > 0 && Beta_c > 0)
    508             {
    509 #ifdef USE_PRED_BLOCK
    510                 EdgeLoop_Chroma_horizontal(SrcU + (edge << 1)*12, Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
    511                 EdgeLoop_Chroma_horizontal(SrcV + (edge << 1)*12, Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
    512 #else
    513                 EdgeLoop_Chroma_horizontal(SrcU + (edge << 1)*(pitch >> 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
    514                 EdgeLoop_Chroma_horizontal(SrcV + (edge << 1)*(pitch >> 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
    515 #endif
    516             }
    517         }
    518 
    519     } //end edge
    520 
    521     return;
    522 }
    523 
    524 /*
    525  *****************************************************************************************************
    526  * \brief   returns a buffer of 4 Strength values for one stripe in a mb (for different Frame types)
    527  *****************************************************************************************************
    528 */
    529 
    530 void GetStrength_Edge0(uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir)
    531 {
    532     int tmp;
    533     int16 *ptrQ, *ptrP;
    534     void* vptr;
    535     uint8 *pStrength;
    536     void* refIdx;
    537 
    538     if (MbP->mbMode == AVC_I4 || MbP->mbMode == AVC_I16 ||
    539             MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
    540     {
    541 
    542         *((int*)Strength) = ININT_STRENGTH[0];      // Start with Strength=3. or Strength=4 for Mb-edge
    543 
    544     }
    545     else // if not intra or SP-frame
    546     {
    547         *((int*)Strength) = 0;
    548 
    549         if (dir == 0)  // Vertical Edge 0
    550         {
    551 
    552             //1. Check the ref_frame_id
    553             refIdx = (void*) MbQ->RefIdx; //de-ref type-punned pointer fix
    554             ptrQ = (int16*)refIdx;
    555             refIdx = (void*)MbP->RefIdx; //de-ref type-punned pointer fix
    556             ptrP = (int16*)refIdx;
    557             pStrength = Strength;
    558             if (ptrQ[0] != ptrP[1]) pStrength[0] = 1;
    559             if (ptrQ[2] != ptrP[3]) pStrength[2] = 1;
    560             pStrength[1] = pStrength[0];
    561             pStrength[3] = pStrength[2];
    562 
    563             //2. Check the non-zero coeff blocks (4x4)
    564             if (MbQ->nz_coeff[0] != 0 || MbP->nz_coeff[3] != 0) pStrength[0] = 2;
    565             if (MbQ->nz_coeff[4] != 0 || MbP->nz_coeff[7] != 0) pStrength[1] = 2;
    566             if (MbQ->nz_coeff[8] != 0 || MbP->nz_coeff[11] != 0) pStrength[2] = 2;
    567             if (MbQ->nz_coeff[12] != 0 || MbP->nz_coeff[15] != 0) pStrength[3] = 2;
    568 
    569             //3. Only need to check the mv difference
    570             vptr = (void*)MbQ->mvL0;  // for deref type-punned pointer
    571             ptrQ = (int16*)vptr;
    572             ptrP = (int16*)(MbP->mvL0 + 3); // points to 4x4 block #3 (the 4th column)
    573 
    574             // 1st blk
    575             if (*pStrength == 0)
    576             {
    577                 // check |mv difference| >= 4
    578                 tmp = *ptrQ++ - *ptrP++;
    579                 if (tmp < 0) tmp = -tmp;
    580                 if (tmp >= 4) *pStrength = 1;
    581 
    582                 tmp = *ptrQ-- - *ptrP--;
    583                 if (tmp < 0) tmp = -tmp;
    584                 if (tmp >= 4) *pStrength = 1;
    585             }
    586 
    587             pStrength++;
    588             ptrQ += 8;
    589             ptrP += 8;
    590 
    591             // 2nd blk
    592             if (*pStrength == 0)
    593             {
    594                 // check |mv difference| >= 4
    595                 tmp = *ptrQ++ - *ptrP++;
    596                 if (tmp < 0) tmp = -tmp;
    597                 if (tmp >= 4) *pStrength = 1;
    598 
    599                 tmp = *ptrQ-- - *ptrP--;
    600                 if (tmp < 0) tmp = -tmp;
    601                 if (tmp >= 4) *pStrength = 1;
    602             }
    603 
    604             pStrength++;
    605             ptrQ += 8;
    606             ptrP += 8;
    607 
    608             // 3rd blk
    609             if (*pStrength == 0)
    610             {
    611                 // check |mv difference| >= 4
    612                 tmp = *ptrQ++ - *ptrP++;
    613                 if (tmp < 0) tmp = -tmp;
    614                 if (tmp >= 4) *pStrength = 1;
    615 
    616                 tmp = *ptrQ-- - *ptrP--;
    617                 if (tmp < 0) tmp = -tmp;
    618                 if (tmp >= 4) *pStrength = 1;
    619             }
    620 
    621             pStrength++;
    622             ptrQ += 8;
    623             ptrP += 8;
    624 
    625             // 4th blk
    626             if (*pStrength == 0)
    627             {
    628                 // check |mv difference| >= 4
    629                 tmp = *ptrQ++ - *ptrP++;
    630                 if (tmp < 0) tmp = -tmp;
    631                 if (tmp >= 4) *pStrength = 1;
    632 
    633                 tmp = *ptrQ-- - *ptrP--;
    634                 if (tmp < 0) tmp = -tmp;
    635                 if (tmp >= 4) *pStrength = 1;
    636             }
    637         }
    638         else   // Horizontal Edge 0
    639         {
    640 
    641             //1. Check the ref_frame_id
    642             refIdx = (void*)MbQ->RefIdx;  //de-ref type-punned pointer
    643             ptrQ = (int16*)refIdx;
    644             refIdx = (void*)MbP->RefIdx;  //de-ref type-punned pointer
    645             ptrP = (int16*)refIdx;
    646             pStrength = Strength;
    647             if (ptrQ[0] != ptrP[2]) pStrength[0] = 1;
    648             if (ptrQ[1] != ptrP[3]) pStrength[2] = 1;
    649             pStrength[1] = pStrength[0];
    650             pStrength[3] = pStrength[2];
    651 
    652             //2. Check the non-zero coeff blocks (4x4)
    653             if (MbQ->nz_coeff[0] != 0 || MbP->nz_coeff[12] != 0) pStrength[0] = 2;
    654             if (MbQ->nz_coeff[1] != 0 || MbP->nz_coeff[13] != 0) pStrength[1] = 2;
    655             if (MbQ->nz_coeff[2] != 0 || MbP->nz_coeff[14] != 0) pStrength[2] = 2;
    656             if (MbQ->nz_coeff[3] != 0 || MbP->nz_coeff[15] != 0) pStrength[3] = 2;
    657 
    658             //3. Only need to check the mv difference
    659             vptr = (void*)MbQ->mvL0;
    660             ptrQ = (int16*)vptr;
    661             ptrP = (int16*)(MbP->mvL0 + 12); // points to 4x4 block #12 (the 4th row)
    662 
    663             // 1st blk
    664             if (*pStrength == 0)
    665             {
    666                 // check |mv difference| >= 4
    667                 tmp = *ptrQ++ - *ptrP++;
    668                 if (tmp < 0) tmp = -tmp;
    669                 if (tmp >= 4) *pStrength = 1;
    670 
    671                 tmp = *ptrQ-- - *ptrP--;
    672                 if (tmp < 0) tmp = -tmp;
    673                 if (tmp >= 4) *pStrength = 1;
    674             }
    675 
    676             pStrength++;
    677             ptrQ += 2;
    678             ptrP += 2;
    679 
    680             // 2nd blk
    681             if (*pStrength  == 0)
    682             {
    683                 // check |mv difference| >= 4
    684                 tmp = *ptrQ++ - *ptrP++;
    685                 if (tmp < 0) tmp = -tmp;
    686                 if (tmp >= 4) *pStrength = 1;
    687 
    688                 tmp = *ptrQ-- - *ptrP--;
    689                 if (tmp < 0) tmp = -tmp;
    690                 if (tmp >= 4) *pStrength = 1;
    691             }
    692 
    693             pStrength++;
    694             ptrQ += 2;
    695             ptrP += 2;
    696 
    697             // 3rd blk
    698             if (*pStrength  == 0)
    699             {
    700                 // check |mv difference| >= 4
    701                 tmp = *ptrQ++ - *ptrP++;
    702                 if (tmp < 0) tmp = -tmp;
    703                 if (tmp >= 4) *pStrength = 1;
    704 
    705                 tmp = *ptrQ-- - *ptrP--;
    706                 if (tmp < 0) tmp = -tmp;
    707                 if (tmp >= 4) *pStrength = 1;
    708             }
    709 
    710             pStrength++;
    711             ptrQ += 2;
    712             ptrP += 2;
    713 
    714             // 4th blk
    715             if (*pStrength  == 0)
    716             {
    717                 // check |mv difference| >= 4
    718                 tmp = *ptrQ++ - *ptrP++;
    719                 if (tmp < 0) tmp = -tmp;
    720                 if (tmp >= 4) *pStrength = 1;
    721 
    722                 tmp = *ptrQ-- - *ptrP--;
    723                 if (tmp < 0) tmp = -tmp;
    724                 if (tmp >= 4) *pStrength = 1;
    725             }
    726 
    727         } /* end of: else if(dir == 0) */
    728 
    729     } /* end of: if( !(MbP->mbMode == AVC_I4 ...) */
    730 }
    731 
    732 
    733 void GetStrength_VerticalEdges(uint8 *Strength, AVCMacroblock* MbQ)
    734 {
    735     int     idx, tmp;
    736     int16   *ptr, *pmvx, *pmvy;
    737     uint8   *pnz;
    738     uint8   *pStrength, *pStr;
    739     void* refIdx;
    740 
    741     if (MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
    742     {
    743         *((int*)Strength)     = ININT_STRENGTH[1];      // Start with Strength=3. or Strength=4 for Mb-edge
    744         *((int*)(Strength + 4)) = ININT_STRENGTH[2];
    745         *((int*)(Strength + 8)) = ININT_STRENGTH[3];
    746     }
    747     else   // Not intra or SP-frame
    748     {
    749 
    750         *((int*)Strength)     = 0; // for non-intra MB, strength = 0, 1 or 2.
    751         *((int*)(Strength + 4)) = 0;
    752         *((int*)(Strength + 8)) = 0;
    753 
    754         //1. Check the ref_frame_id
    755         refIdx = (void*)MbQ->RefIdx;  //de-ref type-punned pointer fix
    756         ptr = (int16*)refIdx;
    757         pStrength = Strength;
    758         if (ptr[0] != ptr[1]) pStrength[4] = 1;
    759         if (ptr[2] != ptr[3]) pStrength[6] = 1;
    760         pStrength[5] = pStrength[4];
    761         pStrength[7] = pStrength[6];
    762 
    763         //2. Check the nz_coeff block and mv difference
    764         pmvx = (int16*)(MbQ->mvL0 + 1); // points to 4x4 block #1,not #0
    765         pmvy = pmvx + 1;
    766         for (idx = 0; idx < 4; idx += 2) // unroll the loop, make 4 iterations to 2
    767         {
    768             // first/third row : 1,2,3 or 9,10,12
    769             // Strength = 2 for a whole row
    770             pnz = MbQ->nz_coeff + (idx << 2);
    771             if (*pnz++ != 0) *pStrength = 2;
    772             if (*pnz++ != 0)
    773             {
    774                 *pStrength = 2;
    775                 *(pStrength + 4) = 2;
    776             }
    777             if (*pnz++ != 0)
    778             {
    779                 *(pStrength + 4) = 2;
    780                 *(pStrength + 8) = 2;
    781             }
    782             if (*pnz != 0) *(pStrength + 8) = 2;
    783 
    784             // Then Strength = 1
    785             if (*pStrength == 0)
    786             {
    787                 //within the same 8x8 block, no need to check the reference id
    788                 //only need to check the |mv difference| >= 4
    789                 tmp = *pmvx - *(pmvx - 2);
    790                 if (tmp < 0) tmp = -tmp;
    791                 if (tmp >= 4) *pStrength = 1;
    792 
    793                 tmp = *pmvy - *(pmvy - 2);
    794                 if (tmp < 0) tmp = -tmp;
    795                 if (tmp >= 4) *pStrength = 1;
    796             }
    797 
    798             pmvx += 2;
    799             pmvy += 2;
    800             pStr = pStrength + 4;
    801 
    802             if (*pStr == 0)
    803             {
    804                 //check the |mv difference| >= 4
    805                 tmp = *pmvx - *(pmvx - 2);
    806                 if (tmp < 0) tmp = -tmp;
    807                 if (tmp >= 4) *pStr = 1;
    808 
    809                 tmp = *pmvy - *(pmvy - 2);
    810                 if (tmp < 0) tmp = -tmp;
    811                 if (tmp >= 4) *pStr = 1;
    812             }
    813 
    814             pmvx += 2;
    815             pmvy += 2;
    816             pStr = pStrength + 8;
    817 
    818             if (*pStr == 0)
    819             {
    820                 //within the same 8x8 block, no need to check the reference id
    821                 //only need to check the |mv difference| >= 4
    822                 tmp = *pmvx - *(pmvx - 2);
    823                 if (tmp < 0) tmp = -tmp;
    824                 if (tmp >= 4) *pStr = 1;
    825 
    826                 tmp = *pmvy - *(pmvy - 2);
    827                 if (tmp < 0) tmp = -tmp;
    828                 if (tmp >= 4) *pStr = 1;
    829             }
    830 
    831             // Second/fourth row: 5,6,7 or 14,15,16
    832             // Strength = 2 for a whole row
    833             pnz = MbQ->nz_coeff + ((idx + 1) << 2);
    834             if (*pnz++ != 0) *(pStrength + 1) = 2;
    835             if (*pnz++ != 0)
    836             {
    837                 *(pStrength + 1) = 2;
    838                 *(pStrength + 5) = 2;
    839             }
    840             if (*pnz++ != 0)
    841             {
    842                 *(pStrength + 5) = 2;
    843                 *(pStrength + 9) = 2;
    844             }
    845             if (*pnz != 0) *(pStrength + 9) = 2;
    846 
    847             // Then Strength = 1
    848             pmvx += 4;
    849             pmvy += 4;
    850             pStr = pStrength + 1;
    851             if (*pStr == 0)
    852             {
    853                 //within the same 8x8 block, no need to check the reference id
    854                 //only need to check the |mv difference| >= 4
    855                 tmp = *pmvx - *(pmvx - 2);
    856                 if (tmp < 0) tmp = -tmp;
    857                 if (tmp >= 4) *pStr = 1;
    858 
    859                 tmp = *pmvy - *(pmvy - 2);
    860                 if (tmp < 0) tmp = -tmp;
    861                 if (tmp >= 4) *pStr = 1;
    862             }
    863 
    864             pmvx += 2;
    865             pmvy += 2;
    866             pStr = pStrength + 5;
    867 
    868             if (*pStr == 0)
    869             {
    870                 //check the |mv difference| >= 4
    871                 tmp = *pmvx - *(pmvx - 2);
    872                 if (tmp < 0) tmp = -tmp;
    873                 if (tmp >= 4) *pStr = 1;
    874 
    875                 tmp = *pmvy - *(pmvy - 2);
    876                 if (tmp < 0) tmp = -tmp;
    877                 if (tmp >= 4) *pStr = 1;
    878             }
    879 
    880             pmvx += 2;
    881             pmvy += 2;
    882             pStr = pStrength + 9;
    883 
    884             if (*pStr == 0)
    885             {
    886                 //within the same 8x8 block, no need to check the reference id
    887                 //only need to check the |mv difference| >= 4
    888                 tmp = *pmvx - *(pmvx - 2);
    889                 if (tmp < 0) tmp = -tmp;
    890                 if (tmp >= 4) *pStr = 1;
    891 
    892                 tmp = *pmvy - *(pmvy - 2);
    893                 if (tmp < 0) tmp = -tmp;
    894                 if (tmp >= 4) *pStr = 1;
    895             }
    896 
    897             // update some variables for the next two rows
    898             pmvx += 4;
    899             pmvy += 4;
    900             pStrength += 2;
    901 
    902         } /* end of: for(idx=0; idx<2; idx++) */
    903 
    904     } /* end of: else if( MbQ->mbMode == AVC_I4 ...) */
    905 }
    906 
    907 
    908 void GetStrength_HorizontalEdges(uint8 Strength[12], AVCMacroblock* MbQ)
    909 {
    910     int     idx, tmp;
    911     int16   *ptr, *pmvx, *pmvy;
    912     uint8   *pStrength, *pStr;
    913     void* refIdx;
    914 
    915     if (MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
    916     {
    917         *((int*)Strength)     = ININT_STRENGTH[1];      // Start with Strength=3. or Strength=4 for Mb-edge
    918         *((int*)(Strength + 4)) = ININT_STRENGTH[2];
    919         *((int*)(Strength + 8)) = ININT_STRENGTH[3];
    920     }
    921     else   // Not intra or SP-frame
    922     {
    923 
    924         *((int*)Strength)     = 0; // for non-intra MB, strength = 0, 1 or 2.
    925         *((int*)(Strength + 4)) = 0; // for non-intra MB, strength = 0, 1 or 2.
    926         *((int*)(Strength + 8)) = 0; // for non-intra MB, strength = 0, 1 or 2.
    927 
    928 
    929         //1. Check the ref_frame_id
    930         refIdx = (void*) MbQ->RefIdx; // de-ref type-punned fix
    931         ptr = (int16*) refIdx;
    932         pStrength = Strength;
    933         if (ptr[0] != ptr[2]) pStrength[4] = 1;
    934         if (ptr[1] != ptr[3]) pStrength[6] = 1;
    935         pStrength[5] = pStrength[4];
    936         pStrength[7] = pStrength[6];
    937 
    938         //2. Check the nz_coeff block and mv difference
    939         pmvx = (int16*)(MbQ->mvL0 + 4); // points to 4x4 block #4,not #0
    940         pmvy = pmvx + 1;
    941         for (idx = 0; idx < 4; idx += 2) // unroll the loop, make 4 iterations to 2
    942         {
    943             // first/third row : 1,2,3 or 9,10,12
    944             // Strength = 2 for a whole row
    945             if (MbQ->nz_coeff[idx] != 0) *pStrength = 2;
    946             if (MbQ->nz_coeff[4+idx] != 0)
    947             {
    948                 *pStrength = 2;
    949                 *(pStrength + 4) = 2;
    950             }
    951             if (MbQ->nz_coeff[8+idx] != 0)
    952             {
    953                 *(pStrength + 4) = 2;
    954                 *(pStrength + 8) = 2;
    955             }
    956             if (MbQ->nz_coeff[12+idx] != 0) *(pStrength + 8) = 2;
    957 
    958             // Then Strength = 1
    959             if (*pStrength == 0)
    960             {
    961                 //within the same 8x8 block, no need to check the reference id
    962                 //only need to check the |mv difference| >= 4
    963                 tmp = *pmvx - *(pmvx - 8);
    964                 if (tmp < 0) tmp = -tmp;
    965                 if (tmp >= 4) *pStrength = 1;
    966 
    967                 tmp = *pmvy - *(pmvy - 8);
    968                 if (tmp < 0) tmp = -tmp;
    969                 if (tmp >= 4) *pStrength = 1;
    970             }
    971 
    972             pmvx += 8;
    973             pmvy += 8;
    974             pStr = pStrength + 4;
    975 
    976             if (*pStr == 0)
    977             {
    978                 //check the |mv difference| >= 4
    979                 tmp = *pmvx - *(pmvx - 8);
    980                 if (tmp < 0) tmp = -tmp;
    981                 if (tmp >= 4) *pStr = 1;
    982 
    983                 tmp = *pmvy - *(pmvy - 8);
    984                 if (tmp < 0) tmp = -tmp;
    985                 if (tmp >= 4) *pStr = 1;
    986             }
    987 
    988             pmvx += 8;
    989             pmvy += 8;
    990             pStr = pStrength + 8;
    991 
    992             if (*pStr == 0)
    993             {
    994                 //within the same 8x8 block, no need to check the reference id
    995                 //only need to check the |mv difference| >= 4
    996                 tmp = *pmvx - *(pmvx - 8);
    997                 if (tmp < 0) tmp = -tmp;
    998                 if (tmp >= 4) *pStr = 1;
    999 
   1000                 tmp = *pmvy - *(pmvy - 8);
   1001                 if (tmp < 0) tmp = -tmp;
   1002                 if (tmp >= 4) *pStr = 1;
   1003             }
   1004 
   1005             // Second/fourth row: 5,6,7 or 14,15,16
   1006             // Strength = 2 for a whole row
   1007             if (MbQ->nz_coeff[idx+1] != 0) *(pStrength + 1) = 2;
   1008             if (MbQ->nz_coeff[4+idx+1] != 0)
   1009             {
   1010                 *(pStrength + 1) = 2;
   1011                 *(pStrength + 5) = 2;
   1012             }
   1013             if (MbQ->nz_coeff[8+idx+1] != 0)
   1014             {
   1015                 *(pStrength + 5) = 2;
   1016                 *(pStrength + 9) = 2;
   1017             }
   1018             if (MbQ->nz_coeff[12+idx+1] != 0) *(pStrength + 9) = 2;
   1019 
   1020             // Then Strength = 1
   1021             pmvx -= 14;
   1022             pmvy -= 14; // -14 = -16 + 2
   1023             pStr = pStrength + 1;
   1024             if (*pStr == 0)
   1025             {
   1026                 //within the same 8x8 block, no need to check the reference id
   1027                 //only need to check the |mv difference| >= 4
   1028                 tmp = *pmvx - *(pmvx - 8);
   1029                 if (tmp < 0) tmp = -tmp;
   1030                 if (tmp >= 4) *pStr = 1;
   1031 
   1032                 tmp = *pmvy - *(pmvy - 8);
   1033                 if (tmp < 0) tmp = -tmp;
   1034                 if (tmp >= 4) *pStr = 1;
   1035             }
   1036 
   1037             pmvx += 8;
   1038             pmvy += 8;
   1039             pStr = pStrength + 5;
   1040 
   1041             if (*pStr == 0)
   1042             {
   1043                 //check the |mv difference| >= 4
   1044                 tmp = *pmvx - *(pmvx - 8);
   1045                 if (tmp < 0) tmp = -tmp;
   1046                 if (tmp >= 4) *pStr = 1;
   1047 
   1048                 tmp = *pmvy - *(pmvy - 8);
   1049                 if (tmp < 0) tmp = -tmp;
   1050                 if (tmp >= 4) *pStr = 1;
   1051             }
   1052 
   1053             pmvx += 8;
   1054             pmvy += 8;
   1055             pStr = pStrength + 9;
   1056 
   1057             if (*pStr == 0)
   1058             {
   1059                 //within the same 8x8 block, no need to check the reference id
   1060                 //only need to check the |mv difference| >= 4
   1061                 tmp = *pmvx - *(pmvx - 8);
   1062                 if (tmp < 0) tmp = -tmp;
   1063                 if (tmp >= 4) *pStr = 1;
   1064 
   1065                 tmp = *pmvy - *(pmvy - 8);
   1066                 if (tmp < 0) tmp = -tmp;
   1067                 if (tmp >= 4) *pStr = 1;
   1068             }
   1069 
   1070             // update some variables for the next two rows
   1071             pmvx -= 14;
   1072             pmvy -= 14; // -14 = -16 + 2
   1073             pStrength += 2;
   1074 
   1075         } /* end of: for(idx=0; idx<2; idx++) */
   1076 
   1077     } /* end of: else if( MbQ->mbMode == AVC_I4 ...) */
   1078 }
   1079 
   1080 /*
   1081  *****************************************************************************************
   1082  * \brief  Filters one edge of 16 (luma) or 8 (chroma) pel
   1083  *****************************************************************************************
   1084 */
   1085 
   1086 void EdgeLoop_Luma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
   1087 {
   1088     int  pel, ap = 0, aq = 0, Strng;
   1089     int  C0, c0, dif, AbsDelta, tmp, tmp1;
   1090     int  L2 = 0, L1, L0, R0, R1, R2 = 0, RL0;
   1091 
   1092 
   1093     if (Strength[0] == 4)  /* INTRA strong filtering */
   1094     {
   1095         for (pel = 0; pel < 16; pel++)
   1096         {
   1097             R0  = SrcPtr[0];
   1098             R1  = SrcPtr[pitch];
   1099             L0  = SrcPtr[-pitch];
   1100             L1  = SrcPtr[-(pitch<<1)];
   1101 
   1102             // |R0 - R1| < Beta
   1103             tmp1 = R0 - R1;
   1104             if (tmp1 < 0) tmp1 = -tmp1;
   1105             tmp = (tmp1 - Beta);
   1106 
   1107             //|L0 - L1| < Beta
   1108             tmp1 = L0 - L1;
   1109             if (tmp1 < 0) tmp1 = -tmp1;
   1110             tmp &= (tmp1 - Beta);
   1111 
   1112             //|R0 - L0| < Alpha
   1113             AbsDelta = R0 - L0;
   1114             if (AbsDelta < 0) AbsDelta = -AbsDelta;
   1115             tmp &= (AbsDelta - Alpha);
   1116 
   1117             if (tmp < 0)
   1118             {
   1119                 AbsDelta -= ((Alpha >> 2) + 2);
   1120                 R2 = SrcPtr[pitch<<1]; //inc2
   1121                 L2 = SrcPtr[-(pitch+(pitch<<1))]; // -inc3
   1122 
   1123                 // |R0 - R2| < Beta && |R0 - L0| < (Alpha/4 + 2)
   1124                 tmp = R0 - R2;
   1125                 if (tmp < 0) tmp = -tmp;
   1126                 aq = AbsDelta & (tmp - Beta);
   1127 
   1128                 // |L0 - L2| < Beta && |R0 - L0| < (Alpha/4 + 2)
   1129                 tmp = L0 - L2;
   1130                 if (tmp < 0) tmp = -tmp;
   1131                 ap = AbsDelta & (tmp - Beta);
   1132 
   1133                 if (aq < 0)
   1134                 {
   1135                     tmp = R1 + R0 + L0;
   1136                     SrcPtr[0] = (L1 + (tmp << 1) +  R2 + 4) >> 3;
   1137                     tmp += R2;
   1138                     SrcPtr[pitch]  = (tmp + 2) >> 2;
   1139                     SrcPtr[pitch<<1] = (((SrcPtr[(pitch+(pitch<<1))] + R2) << 1) + tmp + 4) >> 3;
   1140                 }
   1141                 else
   1142                     SrcPtr[0] = ((R1 << 1) + R0 + L1 + 2) >> 2;
   1143 
   1144                 if (ap < 0)
   1145                 {
   1146                     tmp = L1 + R0 + L0;
   1147                     SrcPtr[-pitch]  = (R1 + (tmp << 1) +  L2 + 4) >> 3;
   1148                     tmp += L2;
   1149                     SrcPtr[-(pitch<<1)] = (tmp + 2) >> 2;
   1150                     SrcPtr[-(pitch+(pitch<<1))] = (((SrcPtr[-(pitch<<2)] + L2) << 1) + tmp + 4) >> 3;
   1151                 }
   1152                 else
   1153                     SrcPtr[-pitch] = ((L1 << 1) + L0 + R1 + 2) >> 2;
   1154 
   1155             } /* if(tmp < 0) */
   1156 
   1157             SrcPtr ++; // Increment to next set of pixel
   1158 
   1159         } /* end of: for(pel=0; pel<16; pel++) */
   1160 
   1161     } /* if(Strength[0] == 4) */
   1162 
   1163     else   /* Normal filtering */
   1164     {
   1165         for (pel = 0; pel < 16; pel++)
   1166         {
   1167             Strng = Strength[pel >> 2];
   1168             if (Strng)
   1169             {
   1170                 R0  = SrcPtr[0];
   1171                 R1  = SrcPtr[pitch];
   1172                 L0  = SrcPtr[-pitch];
   1173                 L1  = SrcPtr[-(pitch<<1)]; // inc2
   1174 
   1175                 //|R0 - L0| < Alpha
   1176                 tmp1 = R0 - L0;
   1177                 if (tmp1 < 0) tmp1 = -tmp1;
   1178                 tmp = (tmp1 - Alpha);
   1179 
   1180                 // |R0 - R1| < Beta
   1181                 tmp1 = R0 - R1;
   1182                 if (tmp1 < 0) tmp1 = -tmp1;
   1183                 tmp &= (tmp1 - Beta);
   1184 
   1185                 //|L0 - L1| < Beta
   1186                 tmp1 = L0 - L1;
   1187                 if (tmp1 < 0) tmp1 = -tmp1;
   1188                 tmp &= (tmp1 - Beta);
   1189 
   1190                 if (tmp < 0)
   1191                 {
   1192                     R2 = SrcPtr[pitch<<1]; //inc2
   1193                     L2 = SrcPtr[-(pitch+(pitch<<1))]; // -inc3
   1194 
   1195                     // |R0 - R2| < Beta
   1196                     tmp = R0 - R2;
   1197                     if (tmp < 0) tmp = -tmp;
   1198                     aq = tmp - Beta;
   1199 
   1200                     // |L0 - L2| < Beta
   1201                     tmp = L0 - L2;
   1202                     if (tmp < 0) tmp = -tmp;
   1203                     ap = tmp - Beta;
   1204 
   1205 
   1206                     c0 = C0 = clipTable[Strng];
   1207                     if (ap < 0) c0++;
   1208                     if (aq < 0) c0++;
   1209 
   1210                     //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
   1211                     dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
   1212                     tmp = dif + c0;
   1213                     if ((uint)tmp > (uint)c0 << 1)
   1214                     {
   1215                         tmp = ~(tmp >> 31);
   1216                         dif = (tmp & (c0 << 1)) - c0;
   1217                     }
   1218 
   1219                     //SrcPtr[0]    = (uint8)IClip(0, 255, R0 - dif);
   1220                     //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
   1221                     RL0 = R0 + L0;
   1222                     R0 -= dif;
   1223                     L0 += dif;
   1224                     if ((uint)R0 > 255)
   1225                     {
   1226                         tmp = ~(R0 >> 31);
   1227                         R0 = tmp & 255;
   1228                     }
   1229                     if ((uint)L0 > 255)
   1230                     {
   1231                         tmp = ~(L0 >> 31);
   1232                         L0 = tmp & 255;
   1233                     }
   1234                     SrcPtr[-pitch] = L0;
   1235                     SrcPtr[0] = R0;
   1236 
   1237                     if (C0 != 0) /* Multiple zeros in the clip tables */
   1238                     {
   1239                         if (aq < 0)  // SrcPtr[inc]   += IClip(-C0, C0,(R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1);
   1240                         {
   1241                             R2 = (R2 + ((RL0 + 1) >> 1) - (R1 << 1)) >> 1;
   1242                             tmp = R2 + C0;
   1243                             if ((uint)tmp > (uint)C0 << 1)
   1244                             {
   1245                                 tmp = ~(tmp >> 31);
   1246                                 R2 = (tmp & (C0 << 1)) - C0;
   1247                             }
   1248                             SrcPtr[pitch] += R2;
   1249                         }
   1250 
   1251                         if (ap < 0)  //SrcPtr[-inc2] += IClip(-C0, C0,(L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1);
   1252                         {
   1253                             L2 = (L2 + ((RL0 + 1) >> 1) - (L1 << 1)) >> 1;
   1254                             tmp = L2 + C0;
   1255                             if ((uint)tmp > (uint)C0 << 1)
   1256                             {
   1257                                 tmp = ~(tmp >> 31);
   1258                                 L2 = (tmp & (C0 << 1)) - C0;
   1259                             }
   1260                             SrcPtr[-(pitch<<1)] += L2;
   1261                         }
   1262                     }
   1263 
   1264                 } /* if(tmp < 0) */
   1265 
   1266             } /* end of:  if((Strng = Strength[pel >> 2])) */
   1267 
   1268             SrcPtr ++; // Increment to next set of pixel
   1269 
   1270         } /* for(pel=0; pel<16; pel++) */
   1271 
   1272     } /* else if(Strength[0] == 4) */
   1273 }
   1274 
   1275 void EdgeLoop_Luma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
   1276 {
   1277     int  pel, ap = 1, aq = 1;
   1278     int  C0, c0, dif, AbsDelta, Strng, tmp, tmp1;
   1279     int  L2 = 0, L1, L0, R0, R1, R2 = 0;
   1280     uint8 *ptr, *ptr1;
   1281     register uint R_in, L_in;
   1282     uint R_out, L_out;
   1283 
   1284 
   1285     if (Strength[0] == 4)  /* INTRA strong filtering */
   1286     {
   1287 
   1288         for (pel = 0; pel < 16; pel++)
   1289         {
   1290 
   1291             // Read 8 pels
   1292             R_in = *((uint *)SrcPtr);       // R_in = {R3, R2, R1, R0}
   1293             L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
   1294             R1   = (R_in >> 8) & 0xff;
   1295             R0   = R_in & 0xff;
   1296             L0   = L_in >> 24;
   1297             L1   = (L_in >> 16) & 0xff;
   1298 
   1299             // |R0 - R1| < Beta
   1300             tmp1 = (R_in & 0xff) - R1;
   1301             if (tmp1 < 0) tmp1 = -tmp1;
   1302             tmp = (tmp1 - Beta);
   1303 
   1304 
   1305             //|L0 - L1| < Beta
   1306             tmp1 = (L_in >> 24) - L1;
   1307             if (tmp1 < 0) tmp1 = -tmp1;
   1308             tmp &= (tmp1 - Beta);
   1309 
   1310             //|R0 - L0| < Alpha
   1311             AbsDelta = (R_in & 0xff) - (L_in >> 24);
   1312             if (AbsDelta < 0) AbsDelta = -AbsDelta;
   1313             tmp &= (AbsDelta - Alpha);
   1314 
   1315             if (tmp < 0)
   1316             {
   1317                 AbsDelta -= ((Alpha >> 2) + 2);
   1318                 R2   = (R_in >> 16) & 0xff;
   1319                 L2   = (L_in >> 8) & 0xff;
   1320 
   1321                 // |R0 - R2| < Beta && |R0 - L0| < (Alpha/4 + 2)
   1322                 tmp1 = (R_in & 0xff) - R2;
   1323                 if (tmp1 < 0) tmp1 = -tmp1;
   1324                 aq = AbsDelta & (tmp1 - Beta);
   1325 
   1326                 // |L0 - L2| < Beta && |R0 - L0| < (Alpha/4 + 2)
   1327                 tmp1 = (L_in >> 24) - L2;
   1328                 if (tmp1 < 0) tmp1 = -tmp1;
   1329                 ap = AbsDelta & (tmp1 - Beta);
   1330 
   1331 
   1332                 ptr = SrcPtr;
   1333                 if (aq < 0)
   1334                 {
   1335                     R_out = (R_in >> 24) << 24; // Keep R3 at the fourth byte
   1336 
   1337                     tmp  = R0 + L0 + R1;
   1338                     R_out |= (((tmp << 1) +  L1 + R2 + 4) >> 3);
   1339                     tmp += R2;
   1340                     R_out |= (((tmp + 2) >> 2) << 8);
   1341                     tmp1 = ((R_in >> 24) + R2) << 1;
   1342                     R_out |= (((tmp1 + tmp + 4) >> 3) << 16);
   1343 
   1344                     *((uint *)SrcPtr) = R_out;
   1345                 }
   1346                 else
   1347                     *ptr = ((R1 << 1) + R0 + L1 + 2) >> 2;
   1348 
   1349 
   1350                 if (ap < 0)
   1351                 {
   1352                     L_out = (L_in << 24) >> 24; // Keep L3 at the first byte
   1353 
   1354                     tmp  = R0 + L0 + L1;
   1355                     L_out |= ((((tmp << 1) + R1 + L2 + 4) >> 3) << 24);
   1356                     tmp += L2;
   1357                     L_out |= (((tmp + 2) >> 2) << 16);
   1358                     tmp1 = ((L_in & 0xff) + L2) << 1;
   1359                     L_out |= (((tmp1 + tmp + 4) >> 3) << 8);
   1360 
   1361                     *((uint *)(SrcPtr - 4)) = L_out;
   1362                 }
   1363                 else
   1364                     *(--ptr) = ((L1 << 1) + L0 + R1 + 2) >> 2;
   1365 
   1366             } /* if(tmp < 0) */
   1367 
   1368             SrcPtr += pitch;    // Increment to next set of pixel
   1369 
   1370         } /* end of: for(pel=0; pel<16; pel++) */
   1371 
   1372     } /* if(Strength[0] == 4) */
   1373 
   1374     else   /* Normal filtering */
   1375     {
   1376 
   1377         for (pel = 0; pel < 16; pel++)
   1378         {
   1379             Strng = Strength[pel >> 2];
   1380             if (Strng)
   1381             {
   1382                 // Read 8 pels
   1383                 R_in = *((uint *)SrcPtr);       // R_in = {R3, R2, R1, R0}
   1384                 L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
   1385                 R1   = (R_in >> 8) & 0xff;
   1386                 R0   = R_in & 0xff;
   1387                 L0   = L_in >> 24;
   1388                 L1   = (L_in >> 16) & 0xff;
   1389 
   1390                 //|R0 - L0| < Alpha
   1391                 tmp = R0 - L0;
   1392                 if (tmp < 0) tmp = -tmp;
   1393                 tmp -= Alpha;
   1394 
   1395                 // |R0 - R1| < Beta
   1396                 tmp1 = R0 - R1;
   1397                 if (tmp1 < 0) tmp1 = -tmp1;
   1398                 tmp &= (tmp1 - Beta);
   1399 
   1400                 //|L0 - L1| < Beta
   1401                 tmp1 = L0 - L1;
   1402                 if (tmp1 < 0) tmp1 = -tmp1;
   1403                 tmp &= (tmp1 - Beta);
   1404 
   1405                 if (tmp < 0)
   1406                 {
   1407                     L2 = SrcPtr[-3];
   1408                     R2 = SrcPtr[2];
   1409 
   1410                     // |R0 - R2| < Beta
   1411                     tmp = R0 - R2;
   1412                     if (tmp < 0) tmp = -tmp;
   1413                     aq = tmp - Beta;
   1414 
   1415                     // |L0 - L2| < Beta
   1416                     tmp = L0 - L2;
   1417                     if (tmp < 0) tmp = -tmp;
   1418                     ap = tmp - Beta;
   1419 
   1420 
   1421                     c0 = C0 = clipTable[Strng];
   1422                     if (ap < 0) c0++;
   1423                     if (aq < 0) c0++;
   1424 
   1425                     //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
   1426                     dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
   1427                     tmp = dif + c0;
   1428                     if ((uint)tmp > (uint)c0 << 1)
   1429                     {
   1430                         tmp = ~(tmp >> 31);
   1431                         dif = (tmp & (c0 << 1)) - c0;
   1432                     }
   1433 
   1434                     ptr = SrcPtr;
   1435                     ptr1 = SrcPtr - 1;
   1436                     //SrcPtr[0]    = (uint8)IClip(0, 255, R0 - dif);
   1437                     //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
   1438                     R_in = R0 - dif;
   1439                     L_in = L0 + dif; /* cannot re-use R0 and L0 here */
   1440                     if ((uint)R_in > 255)
   1441                     {
   1442                         tmp = ~((int)R_in >> 31);
   1443                         R_in = tmp & 255;
   1444                     }
   1445                     if ((uint)L_in > 255)
   1446                     {
   1447                         tmp = ~((int)L_in >> 31);
   1448                         L_in = tmp & 255;
   1449                     }
   1450                     *ptr1-- = L_in;
   1451                     *ptr++  = R_in;
   1452 
   1453                     if (C0 != 0) // Multiple zeros in the clip tables
   1454                     {
   1455                         if (ap < 0)  //SrcPtr[-inc2] += IClip(-C0, C0,(L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1);
   1456                         {
   1457                             L2 = (L2 + ((R0 + L0 + 1) >> 1) - (L1 << 1)) >> 1;
   1458                             tmp = L2 + C0;
   1459                             if ((uint)tmp > (uint)C0 << 1)
   1460                             {
   1461                                 tmp = ~(tmp >> 31);
   1462                                 L2 = (tmp & (C0 << 1)) - C0;
   1463                             }
   1464                             *ptr1 += L2;
   1465                         }
   1466 
   1467                         if (aq < 0)  // SrcPtr[inc] += IClip(-C0, C0,(R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1);
   1468                         {
   1469                             R2 = (R2 + ((R0 + L0 + 1) >> 1) - (R1 << 1)) >> 1;
   1470                             tmp = R2 + C0;
   1471                             if ((uint)tmp > (uint)C0 << 1)
   1472                             {
   1473                                 tmp = ~(tmp >> 31);
   1474                                 R2 = (tmp & (C0 << 1)) - C0;
   1475                             }
   1476                             *ptr += R2;
   1477                         }
   1478                     }
   1479 
   1480                 } /* if(tmp < 0) */
   1481 
   1482             } /* end of:  if((Strng = Strength[pel >> 2])) */
   1483 
   1484             SrcPtr += pitch;    // Increment to next set of pixel
   1485 
   1486         } /* for(pel=0; pel<16; pel++) */
   1487 
   1488     } /* else if(Strength[0] == 4) */
   1489 
   1490 }
   1491 
   1492 void EdgeLoop_Chroma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
   1493 {
   1494     int     pel, Strng;
   1495     int     c0, dif;
   1496     int     L1, L0, R0, R1, tmp, tmp1;
   1497     uint8   *ptr;
   1498     uint    R_in, L_in;
   1499 
   1500 
   1501     for (pel = 0; pel < 16; pel++)
   1502     {
   1503         Strng = Strength[pel>>2];
   1504         if (Strng)
   1505         {
   1506             // Read 8 pels
   1507             R_in = *((uint *)SrcPtr);       // R_in = {R3, R2, R1, R0}
   1508             L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
   1509             R1   = (R_in >> 8) & 0xff;
   1510             R0   = R_in & 0xff;
   1511             L0   = L_in >> 24;
   1512             L1   = (L_in >> 16) & 0xff;
   1513 
   1514             // |R0 - R1| < Beta
   1515             tmp1 = R0 - R1;
   1516             if (tmp1 < 0) tmp1 = -tmp1;
   1517             tmp = (tmp1 - Beta);
   1518 
   1519             //|L0 - L1| < Beta
   1520             tmp1 = L0 - L1;
   1521             if (tmp1 < 0) tmp1 = -tmp1;
   1522             tmp &= (tmp1 - Beta);
   1523 
   1524             //|R0 - L0| < Alpha
   1525             tmp1 = R0 - L0;
   1526             if (tmp1 < 0) tmp1 = -tmp1;
   1527             tmp &= (tmp1 - Alpha);
   1528 
   1529             if (tmp < 0)
   1530             {
   1531                 ptr = SrcPtr;
   1532                 if (Strng == 4) /* INTRA strong filtering */
   1533                 {
   1534                     *ptr-- = ((R1 << 1) + R0 + L1 + 2) >> 2;
   1535                     *ptr   = ((L1 << 1) + L0 + R1 + 2) >> 2;
   1536                 }
   1537                 else  /* normal filtering */
   1538                 {
   1539                     c0  = clipTable[Strng] + 1;
   1540                     //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
   1541                     dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
   1542                     tmp = dif + c0;
   1543                     if ((uint)tmp > (uint)c0 << 1)
   1544                     {
   1545                         tmp = ~(tmp >> 31);
   1546                         dif = (tmp & (c0 << 1)) - c0;
   1547                     }
   1548 
   1549                     //SrcPtr[0]    = (uint8)IClip(0, 255, R0 - dif);
   1550                     //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
   1551                     L0 += dif;
   1552                     R0 -= dif;
   1553                     if ((uint)L0 > 255)
   1554                     {
   1555                         tmp = ~(L0 >> 31);
   1556                         L0 = tmp & 255;
   1557                     }
   1558                     if ((uint)R0 > 255)
   1559                     {
   1560                         tmp = ~(R0 >> 31);
   1561                         R0 = tmp & 255;
   1562                     }
   1563 
   1564                     *ptr-- = R0;
   1565                     *ptr = L0;
   1566                 }
   1567             }
   1568             pel ++;
   1569             SrcPtr += pitch;   // Increment to next set of pixel
   1570 
   1571         } /* end of: if((Strng = Strength[pel >> 2])) */
   1572         else
   1573         {
   1574             pel += 3;
   1575             SrcPtr += (pitch << 1); //PtrInc << 1;
   1576         }
   1577 
   1578     } /* end of: for(pel=0; pel<16; pel++) */
   1579 }
   1580 
   1581 
   1582 void EdgeLoop_Chroma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
   1583 {
   1584     int  pel, Strng;
   1585     int  c0, dif;
   1586     int  L1, L0, R0, R1, tmp, tmp1;
   1587 
   1588     for (pel = 0; pel < 16; pel++)
   1589     {
   1590         Strng = Strength[pel>>2];
   1591         if (Strng)
   1592         {
   1593             R0  = SrcPtr[0];
   1594             L0  = SrcPtr[-pitch];
   1595             L1  = SrcPtr[-(pitch<<1)]; //inc2
   1596             R1  = SrcPtr[pitch];
   1597 
   1598             // |R0 - R1| < Beta
   1599             tmp1 = R0 - R1;
   1600             if (tmp1 < 0) tmp1 = -tmp1;
   1601             tmp = (tmp1 - Beta);
   1602 
   1603             //|L0 - L1| < Beta
   1604             tmp1 = L0 - L1;
   1605             if (tmp1 < 0) tmp1 = -tmp1;
   1606             tmp &= (tmp1 - Beta);
   1607 
   1608             //|R0 - L0| < Alpha
   1609             tmp1 = R0 - L0;
   1610             if (tmp1 < 0) tmp1 = -tmp1;
   1611             tmp &= (tmp1 - Alpha);
   1612 
   1613             if (tmp < 0)
   1614             {
   1615                 if (Strng == 4) /* INTRA strong filtering */
   1616                 {
   1617                     SrcPtr[0]      = ((R1 << 1) + R0 + L1 + 2) >> 2;
   1618                     SrcPtr[-pitch] = ((L1 << 1) + L0 + R1 + 2) >> 2;
   1619                 }
   1620                 else  /* normal filtering */
   1621                 {
   1622                     c0  = clipTable[Strng] + 1;
   1623                     //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
   1624                     dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
   1625                     tmp = dif + c0;
   1626                     if ((uint)tmp > (uint)c0 << 1)
   1627                     {
   1628                         tmp = ~(tmp >> 31);
   1629                         dif = (tmp & (c0 << 1)) - c0;
   1630                     }
   1631 
   1632                     //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
   1633                     //SrcPtr[0]    = (uint8)IClip(0, 255, R0 - dif);
   1634                     L0 += dif;
   1635                     R0 -= dif;
   1636                     if ((uint)L0 > 255)
   1637                     {
   1638                         tmp = ~(L0 >> 31);
   1639                         L0 = tmp & 255;
   1640                     }
   1641                     if ((uint)R0 > 255)
   1642                     {
   1643                         tmp = ~(R0 >> 31);
   1644                         R0 = tmp & 255;
   1645                     }
   1646                     SrcPtr[0] = R0;
   1647                     SrcPtr[-pitch] = L0;
   1648                 }
   1649             }
   1650 
   1651             pel ++;
   1652             SrcPtr ++; // Increment to next set of pixel
   1653 
   1654         } /* end of: if((Strng = Strength[pel >> 2])) */
   1655         else
   1656         {
   1657             pel += 3;
   1658             SrcPtr += 2;
   1659         }
   1660 
   1661     } /* end of: for(pel=0; pel<16; pel++) */
   1662 }
   1663 
   1664 
   1665 
   1666 
   1667