Home | History | Annotate | Download | only in source
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      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 express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 /*------------------------------------------------------------------------------
     18 
     19     Table of contents
     20 
     21      1. Include headers
     22      2. External compiler flags
     23      3. Module defines
     24      4. Local function prototypes
     25      5. Functions
     26           h264bsdFilterPicture
     27           FilterVerLumaEdge
     28           FilterHorLumaEdge
     29           FilterHorLuma
     30           FilterVerChromaEdge
     31           FilterHorChromaEdge
     32           FilterHorChroma
     33           InnerBoundaryStrength
     34           EdgeBoundaryStrength
     35           GetBoundaryStrengths
     36           IsSliceBoundaryOnLeft
     37           IsSliceBoundaryOnTop
     38           GetMbFilteringFlags
     39           GetLumaEdgeThresholds
     40           GetChromaEdgeThresholds
     41           FilterLuma
     42           FilterChroma
     43 
     44 ------------------------------------------------------------------------------*/
     45 
     46 /*------------------------------------------------------------------------------
     47     1. Include headers
     48 ------------------------------------------------------------------------------*/
     49 
     50 #include "basetype.h"
     51 #include "h264bsd_util.h"
     52 #include "h264bsd_macroblock_layer.h"
     53 #include "h264bsd_deblocking.h"
     54 #include "h264bsd_dpb.h"
     55 
     56 #ifdef H264DEC_OMXDL
     57 #include "omxtypes.h"
     58 #include "omxVC.h"
     59 #include "armVC.h"
     60 #endif /* H264DEC_OMXDL */
     61 
     62 /*------------------------------------------------------------------------------
     63     2. External compiler flags
     64 --------------------------------------------------------------------------------
     65 
     66 --------------------------------------------------------------------------------
     67     3. Module defines
     68 ------------------------------------------------------------------------------*/
     69 
     70 /* Switch off the following Lint messages for this file:
     71  * Info 701: Shift left of signed quantity (int)
     72  * Info 702: Shift right of signed quantity (int)
     73  */
     74 /*lint -e701 -e702 */
     75 
     76 /* array of alpha values, from the standard */
     77 static const u8 alphas[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,
     78     12,13,15,17,20,22,25,28,32,36,40,45,50,56,63,71,80,90,101,113,127,144,162,
     79     182,203,226,255,255};
     80 
     81 /* array of beta values, from the standard */
     82 static const u8 betas[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,
     83     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};
     84 
     85 
     86 
     87 #ifndef H264DEC_OMXDL
     88 /* array of tc0 values, from the standard, each triplet corresponds to a
     89  * column in the table. Indexing goes as tc0[indexA][bS-1] */
     90 static const u8 tc0[52][3] = {
     91     {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
     92     {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
     93     {0,0,0},{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,1,1},{0,1,1},{1,1,1},
     94     {1,1,1},{1,1,1},{1,1,1},{1,1,2},{1,1,2},{1,1,2},{1,1,2},{1,2,3},
     95     {1,2,3},{2,2,3},{2,2,4},{2,3,4},{2,3,4},{3,3,5},{3,4,6},{3,4,6},
     96     {4,5,7},{4,5,8},{4,6,9},{5,7,10},{6,8,11},{6,8,13},{7,10,14},{8,11,16},
     97     {9,12,18},{10,13,20},{11,15,23},{13,17,25}
     98 };
     99 #else
    100 /* array of tc0 values, from the standard, each triplet corresponds to a
    101  * column in the table. Indexing goes as tc0[indexA][bS] */
    102 static const u8 tc0[52][5] = {
    103     {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
    104     {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
    105     {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
    106     {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0},
    107     {0, 0, 0, 0, 0}, {0, 0, 0, 1, 0}, {0, 0, 0, 1, 0}, {0, 0, 0, 1, 0},
    108     {0, 0, 0, 1, 0}, {0, 0, 1, 1, 0}, {0, 0, 1, 1, 0}, {0, 1, 1, 1, 0},
    109     {0, 1, 1, 1, 0}, {0, 1, 1, 1, 0}, {0, 1, 1, 1, 0}, {0, 1, 1, 2, 0},
    110     {0, 1, 1, 2, 0}, {0, 1, 1, 2, 0}, {0, 1, 1, 2, 0}, {0, 1, 2, 3, 0},
    111     {0, 1, 2, 3, 0}, {0, 2, 2, 3, 0}, {0, 2, 2, 4, 0}, {0, 2, 3, 4, 0},
    112     {0, 2, 3, 4, 0}, {0, 3, 3, 5, 0}, {0, 3, 4, 6, 0}, {0, 3, 4, 6, 0},
    113     {0, 4, 5, 7, 0}, {0, 4, 5, 8, 0}, {0, 4, 6, 9, 0}, {0, 5, 7, 10, 0},
    114     {0, 6, 8, 11, 0}, {0, 6, 8, 13, 0}, {0, 7, 10, 14, 0},
    115     {0, 8, 11, 16, 0}, {0, 9, 12, 18, 0}, {0, 10, 13, 20, 0},
    116     {0, 11, 15, 23, 0}, {0, 13, 17, 25, 0}
    117 };
    118 #endif
    119 
    120 
    121 #ifndef H264DEC_OMXDL
    122 /* mapping of raster scan block index to 4x4 block index */
    123 static const u32 mb4x4Index[16] =
    124     {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
    125 
    126 typedef struct {
    127     const u8 *tc0;
    128     u32 alpha;
    129     u32 beta;
    130 } edgeThreshold_t;
    131 
    132 typedef struct {
    133     u32 top;
    134     u32 left;
    135 } bS_t;
    136 
    137 enum { TOP = 0, LEFT = 1, INNER = 2 };
    138 #endif /* H264DEC_OMXDL */
    139 
    140 #define FILTER_LEFT_EDGE    0x04
    141 #define FILTER_TOP_EDGE     0x02
    142 #define FILTER_INNER_EDGE   0x01
    143 
    144 
    145 /* clipping table defined in intra_prediction.c */
    146 extern const u8 h264bsdClip[];
    147 
    148 /*------------------------------------------------------------------------------
    149     4. Local function prototypes
    150 ------------------------------------------------------------------------------*/
    151 
    152 static u32 InnerBoundaryStrength(mbStorage_t *mb1, u32 i1, u32 i2);
    153 
    154 #ifndef H264DEC_OMXDL
    155 static u32 EdgeBoundaryStrength(mbStorage_t *mb1, mbStorage_t *mb2,
    156     u32 i1, u32 i2);
    157 #else
    158 static u32 InnerBoundaryStrength2(mbStorage_t *mb1, u32 i1, u32 i2);
    159 static u32 EdgeBoundaryStrengthLeft(mbStorage_t *mb1, mbStorage_t *mb2);
    160 static u32 EdgeBoundaryStrengthTop(mbStorage_t *mb1, mbStorage_t *mb2);
    161 #endif
    162 
    163 static u32 IsSliceBoundaryOnLeft(mbStorage_t *mb);
    164 
    165 static u32 IsSliceBoundaryOnTop(mbStorage_t *mb);
    166 
    167 static u32 GetMbFilteringFlags(mbStorage_t *mb);
    168 
    169 #ifndef H264DEC_OMXDL
    170 
    171 static u32 GetBoundaryStrengths(mbStorage_t *mb, bS_t *bs, u32 flags);
    172 
    173 static void FilterLuma(u8 *data, bS_t *bS, edgeThreshold_t *thresholds,
    174         u32 imageWidth);
    175 
    176 static void FilterChroma(u8 *cb, u8 *cr, bS_t *bS, edgeThreshold_t *thresholds,
    177         u32 imageWidth);
    178 
    179 static void FilterVerLumaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
    180         u32 imageWidth);
    181 static void FilterHorLumaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
    182         i32 imageWidth);
    183 static void FilterHorLuma( u8 *data, u32 bS, edgeThreshold_t *thresholds,
    184         i32 imageWidth);
    185 
    186 static void FilterVerChromaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
    187   u32 imageWidth);
    188 static void FilterHorChromaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
    189   i32 imageWidth);
    190 static void FilterHorChroma( u8 *data, u32 bS, edgeThreshold_t *thresholds,
    191   i32 imageWidth);
    192 
    193 static void GetLumaEdgeThresholds(
    194   edgeThreshold_t *thresholds,
    195   mbStorage_t *mb,
    196   u32 filteringFlags);
    197 
    198 static void GetChromaEdgeThresholds(
    199   edgeThreshold_t *thresholds,
    200   mbStorage_t *mb,
    201   u32 filteringFlags,
    202   i32 chromaQpIndexOffset);
    203 
    204 #else /* H264DEC_OMXDL */
    205 
    206 static u32 GetBoundaryStrengths(mbStorage_t *mb, u8 (*bs)[16], u32 flags);
    207 
    208 static void GetLumaEdgeThresholds(
    209     mbStorage_t *mb,
    210     u8 (*alpha)[2],
    211     u8 (*beta)[2],
    212     u8 (*threshold)[16],
    213     u8 (*bs)[16],
    214     u32 filteringFlags );
    215 
    216 static void GetChromaEdgeThresholds(
    217     mbStorage_t *mb,
    218     u8 (*alpha)[2],
    219     u8 (*beta)[2],
    220     u8 (*threshold)[8],
    221     u8 (*bs)[16],
    222     u32 filteringFlags,
    223     i32 chromaQpIndexOffset);
    224 
    225 #endif /* H264DEC_OMXDL */
    226 
    227 /*------------------------------------------------------------------------------
    228 
    229     Function: IsSliceBoundaryOnLeft
    230 
    231         Functional description:
    232             Function to determine if there is a slice boundary on the left side
    233             of a macroblock.
    234 
    235 ------------------------------------------------------------------------------*/
    236 u32 IsSliceBoundaryOnLeft(mbStorage_t *mb)
    237 {
    238 
    239 /* Variables */
    240 
    241 /* Code */
    242 
    243     ASSERT(mb && mb->mbA);
    244 
    245     if (mb->sliceId != mb->mbA->sliceId)
    246         return(HANTRO_TRUE);
    247     else
    248         return(HANTRO_FALSE);
    249 
    250 }
    251 
    252 /*------------------------------------------------------------------------------
    253 
    254     Function: IsSliceBoundaryOnTop
    255 
    256         Functional description:
    257             Function to determine if there is a slice boundary above the
    258             current macroblock.
    259 
    260 ------------------------------------------------------------------------------*/
    261 u32 IsSliceBoundaryOnTop(mbStorage_t *mb)
    262 {
    263 
    264 /* Variables */
    265 
    266 /* Code */
    267 
    268     ASSERT(mb && mb->mbB);
    269 
    270     if (mb->sliceId != mb->mbB->sliceId)
    271         return(HANTRO_TRUE);
    272     else
    273         return(HANTRO_FALSE);
    274 
    275 }
    276 
    277 /*------------------------------------------------------------------------------
    278 
    279     Function: GetMbFilteringFlags
    280 
    281         Functional description:
    282           Function to determine which edges of a macroblock has to be
    283           filtered. Output is a bit-wise OR of FILTER_LEFT_EDGE,
    284           FILTER_TOP_EDGE and FILTER_INNER_EDGE, depending on which edges
    285           shall be filtered.
    286 
    287 ------------------------------------------------------------------------------*/
    288 u32 GetMbFilteringFlags(mbStorage_t *mb)
    289 {
    290 
    291 /* Variables */
    292 
    293     u32 flags = 0;
    294 
    295 /* Code */
    296 
    297     ASSERT(mb);
    298 
    299     /* nothing will be filtered if disableDeblockingFilterIdc == 1 */
    300     if (mb->disableDeblockingFilterIdc != 1)
    301     {
    302         flags |= FILTER_INNER_EDGE;
    303 
    304         /* filterLeftMbEdgeFlag, left mb is MB_A */
    305         if (mb->mbA &&
    306             ((mb->disableDeblockingFilterIdc != 2) ||
    307              !IsSliceBoundaryOnLeft(mb)))
    308             flags |= FILTER_LEFT_EDGE;
    309 
    310         /* filterTopMbEdgeFlag */
    311         if (mb->mbB &&
    312             ((mb->disableDeblockingFilterIdc != 2) ||
    313              !IsSliceBoundaryOnTop(mb)))
    314             flags |= FILTER_TOP_EDGE;
    315     }
    316 
    317     return(flags);
    318 
    319 }
    320 
    321 /*------------------------------------------------------------------------------
    322 
    323     Function: InnerBoundaryStrength
    324 
    325         Functional description:
    326             Function to calculate boundary strength value bs for an inner
    327             edge of a macroblock. Macroblock type is checked before this is
    328             called -> no intra mb condition here.
    329 
    330 ------------------------------------------------------------------------------*/
    331 u32 InnerBoundaryStrength(mbStorage_t *mb1, u32 ind1, u32 ind2)
    332 {
    333     i32 tmp1, tmp2;
    334     i32 mv1, mv2, mv3, mv4;
    335 
    336     tmp1 = mb1->totalCoeff[ind1];
    337     tmp2 = mb1->totalCoeff[ind2];
    338     mv1 = mb1->mv[ind1].hor;
    339     mv2 = mb1->mv[ind2].hor;
    340     mv3 = mb1->mv[ind1].ver;
    341     mv4 = mb1->mv[ind2].ver;
    342 
    343     if (tmp1 || tmp2)
    344     {
    345         return 2;
    346     }
    347     else if ( (ABS(mv1 - mv2) >= 4) || (ABS(mv3 - mv4) >= 4) ||
    348               (mb1->refAddr[ind1 >> 2] != mb1->refAddr[ind2 >> 2]) )
    349     {
    350         return 1;
    351     }
    352     else
    353         return 0;
    354 }
    355 
    356 /*------------------------------------------------------------------------------
    357 
    358     Function: InnerBoundaryStrength2
    359 
    360         Functional description:
    361             Function to calculate boundary strength value bs for an inner
    362             edge of a macroblock. The function is the same as
    363             InnerBoundaryStrength but without checking totalCoeff.
    364 
    365 ------------------------------------------------------------------------------*/
    366 u32 InnerBoundaryStrength2(mbStorage_t *mb1, u32 ind1, u32 ind2)
    367 {
    368     i32 tmp1, tmp2, tmp3, tmp4;
    369 
    370     tmp1 = mb1->mv[ind1].hor;
    371     tmp2 = mb1->mv[ind2].hor;
    372     tmp3 = mb1->mv[ind1].ver;
    373     tmp4 = mb1->mv[ind2].ver;
    374 
    375     if ( (ABS(tmp1 - tmp2) >= 4) || (ABS(tmp3 - tmp4) >= 4) ||
    376          (mb1->refAddr[ind1 >> 2] != mb1->refAddr[ind2 >> 2]))
    377     {
    378         return 1;
    379     }
    380     else
    381         return 0;
    382 }
    383 #ifndef H264DEC_OMXDL
    384 /*------------------------------------------------------------------------------
    385 
    386     Function: EdgeBoundaryStrength
    387 
    388         Functional description:
    389             Function to calculate boundary strength value bs for left- or
    390             top-most edge of a macroblock. Macroblock types are checked
    391             before this is called -> no intra mb conditions here.
    392 
    393 ------------------------------------------------------------------------------*/
    394 u32 EdgeBoundaryStrength(mbStorage_t *mb1, mbStorage_t *mb2,
    395     u32 ind1, u32 ind2)
    396 {
    397 
    398     if (mb1->totalCoeff[ind1] || mb2->totalCoeff[ind2])
    399     {
    400         return 2;
    401     }
    402     else if ((mb1->refAddr[ind1 >> 2] != mb2->refAddr[ind2 >> 2]) ||
    403              (ABS(mb1->mv[ind1].hor - mb2->mv[ind2].hor) >= 4) ||
    404              (ABS(mb1->mv[ind1].ver - mb2->mv[ind2].ver) >= 4))
    405     {
    406         return 1;
    407     }
    408     else
    409         return 0;
    410 }
    411 
    412 #else /* H264DEC_OMXDL */
    413 
    414 /*------------------------------------------------------------------------------
    415 
    416     Function: EdgeBoundaryStrengthTop
    417 
    418         Functional description:
    419             Function to calculate boundary strength value bs for
    420             top-most edge of a macroblock. Macroblock types are checked
    421             before this is called -> no intra mb conditions here.
    422 
    423 ------------------------------------------------------------------------------*/
    424 u32 EdgeBoundaryStrengthTop(mbStorage_t *mb1, mbStorage_t *mb2)
    425 {
    426     u32 topBs = 0;
    427     u32 tmp1, tmp2, tmp3, tmp4;
    428 
    429     tmp1 = mb1->totalCoeff[0];
    430     tmp2 = mb2->totalCoeff[10];
    431     tmp3 = mb1->totalCoeff[1];
    432     tmp4 = mb2->totalCoeff[11];
    433     if (tmp1 || tmp2)
    434     {
    435         topBs = 2<<0;
    436     }
    437     else if ((ABS(mb1->mv[0].hor - mb2->mv[10].hor) >= 4) ||
    438              (ABS(mb1->mv[0].ver - mb2->mv[10].ver) >= 4) ||
    439              (mb1->refAddr[0] != mb2->refAddr[10 >> 2]))
    440     {
    441         topBs = 1<<0;
    442     }
    443     tmp1 = mb1->totalCoeff[4];
    444     tmp2 = mb2->totalCoeff[14];
    445     if (tmp3 || tmp4)
    446     {
    447         topBs += 2<<8;
    448     }
    449     else if ((ABS(mb1->mv[1].hor - mb2->mv[11].hor) >= 4) ||
    450              (ABS(mb1->mv[1].ver - mb2->mv[11].ver) >= 4) ||
    451              (mb1->refAddr[0] != mb2->refAddr[11 >> 2]))
    452     {
    453         topBs += 1<<8;
    454     }
    455     tmp3 = mb1->totalCoeff[5];
    456     tmp4 = mb2->totalCoeff[15];
    457     if (tmp1 || tmp2)
    458     {
    459         topBs += 2<<16;
    460     }
    461     else if ((ABS(mb1->mv[4].hor - mb2->mv[14].hor) >= 4) ||
    462              (ABS(mb1->mv[4].ver - mb2->mv[14].ver) >= 4) ||
    463              (mb1->refAddr[4 >> 2] != mb2->refAddr[14 >> 2]))
    464     {
    465         topBs += 1<<16;
    466     }
    467     if (tmp3 || tmp4)
    468     {
    469         topBs += 2<<24;
    470     }
    471     else if ((ABS(mb1->mv[5].hor - mb2->mv[15].hor) >= 4) ||
    472              (ABS(mb1->mv[5].ver - mb2->mv[15].ver) >= 4) ||
    473              (mb1->refAddr[5 >> 2] != mb2->refAddr[15 >> 2]))
    474     {
    475         topBs += 1<<24;
    476     }
    477 
    478     return topBs;
    479 }
    480 
    481 /*------------------------------------------------------------------------------
    482 
    483     Function: EdgeBoundaryStrengthLeft
    484 
    485         Functional description:
    486             Function to calculate boundary strength value bs for left-
    487             edge of a macroblock. Macroblock types are checked
    488             before this is called -> no intra mb conditions here.
    489 
    490 ------------------------------------------------------------------------------*/
    491 u32 EdgeBoundaryStrengthLeft(mbStorage_t *mb1, mbStorage_t *mb2)
    492 {
    493     u32 leftBs = 0;
    494     u32 tmp1, tmp2, tmp3, tmp4;
    495 
    496     tmp1 = mb1->totalCoeff[0];
    497     tmp2 = mb2->totalCoeff[5];
    498     tmp3 = mb1->totalCoeff[2];
    499     tmp4 = mb2->totalCoeff[7];
    500 
    501     if (tmp1 || tmp2)
    502     {
    503         leftBs = 2<<0;
    504     }
    505     else if ((ABS(mb1->mv[0].hor - mb2->mv[5].hor) >= 4) ||
    506              (ABS(mb1->mv[0].ver - mb2->mv[5].ver) >= 4) ||
    507              (mb1->refAddr[0] != mb2->refAddr[5 >> 2]))
    508     {
    509         leftBs = 1<<0;
    510     }
    511     tmp1 = mb1->totalCoeff[8];
    512     tmp2 = mb2->totalCoeff[13];
    513     if (tmp3 || tmp4)
    514     {
    515         leftBs += 2<<8;
    516     }
    517     else if ((ABS(mb1->mv[2].hor - mb2->mv[7].hor) >= 4) ||
    518              (ABS(mb1->mv[2].ver - mb2->mv[7].ver) >= 4) ||
    519              (mb1->refAddr[0] != mb2->refAddr[7 >> 2]))
    520     {
    521         leftBs += 1<<8;
    522     }
    523     tmp3 = mb1->totalCoeff[10];
    524     tmp4 = mb2->totalCoeff[15];
    525     if (tmp1 || tmp2)
    526     {
    527         leftBs += 2<<16;
    528     }
    529     else if ((ABS(mb1->mv[8].hor - mb2->mv[13].hor) >= 4) ||
    530              (ABS(mb1->mv[8].ver - mb2->mv[13].ver) >= 4) ||
    531              (mb1->refAddr[8 >> 2] != mb2->refAddr[13 >> 2]))
    532     {
    533         leftBs += 1<<16;
    534     }
    535     if (tmp3 || tmp4)
    536     {
    537         leftBs += 2<<24;
    538     }
    539     else if ((ABS(mb1->mv[10].hor - mb2->mv[15].hor) >= 4) ||
    540              (ABS(mb1->mv[10].ver - mb2->mv[15].ver) >= 4) ||
    541              (mb1->refAddr[10 >> 2] != mb2->refAddr[15 >> 2]))
    542     {
    543         leftBs += 1<<24;
    544     }
    545 
    546     return leftBs;
    547 }
    548 #endif /* H264DEC_OMXDL */
    549 /*------------------------------------------------------------------------------
    550 
    551     Function: h264bsdFilterPicture
    552 
    553         Functional description:
    554           Perform deblocking filtering for a picture. Filter does not copy
    555           the original picture anywhere but filtering is performed directly
    556           on the original image. Parameters controlling the filtering process
    557           are computed based on information in macroblock structures of the
    558           filtered macroblock, macroblock above and macroblock on the left of
    559           the filtered one.
    560 
    561         Inputs:
    562           image         pointer to image to be filtered
    563           mb            pointer to macroblock data structure of the top-left
    564                         macroblock of the picture
    565 
    566         Outputs:
    567           image         filtered image stored here
    568 
    569         Returns:
    570           none
    571 
    572 ------------------------------------------------------------------------------*/
    573 #ifndef H264DEC_OMXDL
    574 void h264bsdFilterPicture(
    575   image_t *image,
    576   mbStorage_t *mb)
    577 {
    578 
    579 /* Variables */
    580 
    581     u32 flags;
    582     u32 picSizeInMbs, mbRow, mbCol;
    583     u32 picWidthInMbs;
    584     u8 *data;
    585     mbStorage_t *pMb;
    586     bS_t bS[16];
    587     edgeThreshold_t thresholds[3];
    588 
    589 /* Code */
    590 
    591     ASSERT(image);
    592     ASSERT(mb);
    593     ASSERT(image->data);
    594     ASSERT(image->width);
    595     ASSERT(image->height);
    596 
    597     picWidthInMbs = image->width;
    598     data = image->data;
    599     picSizeInMbs = picWidthInMbs * image->height;
    600 
    601     pMb = mb;
    602 
    603     for (mbRow = 0, mbCol = 0; mbRow < image->height; pMb++)
    604     {
    605         flags = GetMbFilteringFlags(pMb);
    606 
    607         if (flags)
    608         {
    609             /* GetBoundaryStrengths function returns non-zero value if any of
    610              * the bS values for the macroblock being processed was non-zero */
    611             if (GetBoundaryStrengths(pMb, bS, flags))
    612             {
    613                 /* luma */
    614                 GetLumaEdgeThresholds(thresholds, pMb, flags);
    615                 data = image->data + mbRow * picWidthInMbs * 256 + mbCol * 16;
    616 
    617                 FilterLuma((u8*)data, bS, thresholds, picWidthInMbs*16);
    618 
    619                 /* chroma */
    620                 GetChromaEdgeThresholds(thresholds, pMb, flags,
    621                     pMb->chromaQpIndexOffset);
    622                 data = image->data + picSizeInMbs * 256 +
    623                     mbRow * picWidthInMbs * 64 + mbCol * 8;
    624 
    625                 FilterChroma((u8*)data, data + 64*picSizeInMbs, bS,
    626                         thresholds, picWidthInMbs*8);
    627 
    628             }
    629         }
    630 
    631         mbCol++;
    632         if (mbCol == picWidthInMbs)
    633         {
    634             mbCol = 0;
    635             mbRow++;
    636         }
    637     }
    638 
    639 }
    640 
    641 /*------------------------------------------------------------------------------
    642 
    643     Function: FilterVerLumaEdge
    644 
    645         Functional description:
    646             Filter one vertical 4-pixel luma edge.
    647 
    648 ------------------------------------------------------------------------------*/
    649 void FilterVerLumaEdge(
    650   u8 *data,
    651   u32 bS,
    652   edgeThreshold_t *thresholds,
    653   u32 imageWidth)
    654 {
    655 
    656 /* Variables */
    657 
    658     i32 delta, tc, tmp;
    659     u32 i;
    660     u8 p0, q0, p1, q1, p2, q2;
    661     u32 tmpFlag;
    662     const u8 *clp = h264bsdClip + 512;
    663 
    664 /* Code */
    665 
    666     ASSERT(data);
    667     ASSERT(bS && bS <= 4);
    668     ASSERT(thresholds);
    669 
    670     if (bS < 4)
    671     {
    672         tc = thresholds->tc0[bS-1];
    673         tmp = tc;
    674         for (i = 4; i; i--, data += imageWidth)
    675         {
    676             p1 = data[-2]; p0 = data[-1];
    677             q0 = data[0]; q1 = data[1];
    678             if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
    679                  ((unsigned)ABS(p1-p0) < thresholds->beta)  &&
    680                  ((unsigned)ABS(q1-q0) < thresholds->beta) )
    681             {
    682                 p2 = data[-3];
    683                 q2 = data[2];
    684 
    685                 if ((unsigned)ABS(p2-p0) < thresholds->beta)
    686                 {
    687                     data[-2] = (u8)(p1 + CLIP3(-tc,tc,
    688                         (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
    689                     tmp++;
    690                 }
    691 
    692                 if ((unsigned)ABS(q2-q0) < thresholds->beta)
    693                 {
    694                     data[1] = (u8)(q1 + CLIP3(-tc,tc,
    695                         (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
    696                     tmp++;
    697                 }
    698 
    699                 delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
    700                           (p1 - q1) + 4) >> 3));
    701 
    702                 p0 = clp[p0 + delta];
    703                 q0 = clp[q0 - delta];
    704                 tmp = tc;
    705                 data[-1] = p0;
    706                 data[ 0] = q0;
    707             }
    708         }
    709     }
    710     else
    711     {
    712         for (i = 4; i; i--, data += imageWidth)
    713         {
    714             p1 = data[-2]; p0 = data[-1];
    715             q0 = data[0]; q1 = data[1];
    716             if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
    717                  ((unsigned)ABS(p1-p0) < thresholds->beta)  &&
    718                  ((unsigned)ABS(q1-q0) < thresholds->beta) )
    719             {
    720                 tmpFlag =
    721                     ((unsigned)ABS(p0-q0) < ((thresholds->alpha >> 2) +2)) ?
    722                         HANTRO_TRUE : HANTRO_FALSE;
    723 
    724                 p2 = data[-3];
    725                 q2 = data[2];
    726 
    727                 if (tmpFlag && (unsigned)ABS(p2-p0) < thresholds->beta)
    728                 {
    729                     tmp = p1 + p0 + q0;
    730                     data[-1] = (u8)((p2 + 2 * tmp + q1 + 4) >> 3);
    731                     data[-2] = (u8)((p2 + tmp + 2) >> 2);
    732                     data[-3] = (u8)((2 * data[-4] + 3 * p2 + tmp + 4) >> 3);
    733                 }
    734                 else
    735                     data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
    736 
    737                 if (tmpFlag && (unsigned)ABS(q2-q0) < thresholds->beta)
    738                 {
    739                     tmp = p0 + q0 + q1;
    740                     data[0] = (u8)((p1 + 2 * tmp + q2 + 4) >> 3);
    741                     data[1] = (u8)((tmp + q2 + 2) >> 2);
    742                     data[2] = (u8)((2 * data[3] + 3 * q2 + tmp + 4) >> 3);
    743                 }
    744                 else
    745                     data[0] = (u8)((2 * q1 + q0 + p1 + 2) >> 2);
    746             }
    747         }
    748     }
    749 
    750 }
    751 
    752 /*------------------------------------------------------------------------------
    753 
    754     Function: FilterHorLumaEdge
    755 
    756         Functional description:
    757             Filter one horizontal 4-pixel luma edge
    758 
    759 ------------------------------------------------------------------------------*/
    760 void FilterHorLumaEdge(
    761   u8 *data,
    762   u32 bS,
    763   edgeThreshold_t *thresholds,
    764   i32 imageWidth)
    765 {
    766 
    767 /* Variables */
    768 
    769     i32 delta, tc, tmp;
    770     u32 i;
    771     u8 p0, q0, p1, q1, p2, q2;
    772     const u8 *clp = h264bsdClip + 512;
    773 
    774 /* Code */
    775 
    776     ASSERT(data);
    777     ASSERT(bS < 4);
    778     ASSERT(thresholds);
    779 
    780     tc = thresholds->tc0[bS-1];
    781     tmp = tc;
    782     for (i = 4; i; i--, data++)
    783     {
    784         p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
    785         q0 = data[0]; q1 = data[imageWidth];
    786         if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
    787              ((unsigned)ABS(p1-p0) < thresholds->beta)  &&
    788              ((unsigned)ABS(q1-q0) < thresholds->beta) )
    789         {
    790             p2 = data[-imageWidth*3];
    791 
    792             if ((unsigned)ABS(p2-p0) < thresholds->beta)
    793             {
    794                 data[-imageWidth*2] = (u8)(p1 + CLIP3(-tc,tc,
    795                     (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
    796                 tmp++;
    797             }
    798 
    799             q2 = data[imageWidth*2];
    800 
    801             if ((unsigned)ABS(q2-q0) < thresholds->beta)
    802             {
    803                 data[imageWidth] = (u8)(q1 + CLIP3(-tc,tc,
    804                     (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
    805                 tmp++;
    806             }
    807 
    808             delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
    809                       (p1 - q1) + 4) >> 3));
    810 
    811             p0 = clp[p0 + delta];
    812             q0 = clp[q0 - delta];
    813             tmp = tc;
    814             data[-imageWidth] = p0;
    815             data[  0] = q0;
    816         }
    817     }
    818 }
    819 
    820 /*------------------------------------------------------------------------------
    821 
    822     Function: FilterHorLuma
    823 
    824         Functional description:
    825             Filter all four successive horizontal 4-pixel luma edges. This can
    826             be done when bS is equal to all four edges.
    827 
    828 ------------------------------------------------------------------------------*/
    829 void FilterHorLuma(
    830   u8 *data,
    831   u32 bS,
    832   edgeThreshold_t *thresholds,
    833   i32 imageWidth)
    834 {
    835 
    836 /* Variables */
    837 
    838     i32 delta, tc, tmp;
    839     u32 i;
    840     u8 p0, q0, p1, q1, p2, q2;
    841     u32 tmpFlag;
    842     const u8 *clp = h264bsdClip + 512;
    843 
    844 /* Code */
    845 
    846     ASSERT(data);
    847     ASSERT(bS <= 4);
    848     ASSERT(thresholds);
    849 
    850     if (bS < 4)
    851     {
    852         tc = thresholds->tc0[bS-1];
    853         tmp = tc;
    854         for (i = 16; i; i--, data++)
    855         {
    856             p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
    857             q0 = data[0]; q1 = data[imageWidth];
    858             if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
    859                  ((unsigned)ABS(p1-p0) < thresholds->beta)  &&
    860                  ((unsigned)ABS(q1-q0) < thresholds->beta) )
    861             {
    862                 p2 = data[-imageWidth*3];
    863 
    864                 if ((unsigned)ABS(p2-p0) < thresholds->beta)
    865                 {
    866                     data[-imageWidth*2] = (u8)(p1 + CLIP3(-tc,tc,
    867                         (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
    868                     tmp++;
    869                 }
    870 
    871                 q2 = data[imageWidth*2];
    872 
    873                 if ((unsigned)ABS(q2-q0) < thresholds->beta)
    874                 {
    875                     data[imageWidth] = (u8)(q1 + CLIP3(-tc,tc,
    876                         (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
    877                     tmp++;
    878                 }
    879 
    880                 delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
    881                           (p1 - q1) + 4) >> 3));
    882 
    883                 p0 = clp[p0 + delta];
    884                 q0 = clp[q0 - delta];
    885                 tmp = tc;
    886                 data[-imageWidth] = p0;
    887                 data[  0] = q0;
    888             }
    889         }
    890     }
    891     else
    892     {
    893         for (i = 16; i; i--, data++)
    894         {
    895             p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
    896             q0 = data[0]; q1 = data[imageWidth];
    897             if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
    898                  ((unsigned)ABS(p1-p0) < thresholds->beta)  &&
    899                  ((unsigned)ABS(q1-q0) < thresholds->beta) )
    900             {
    901                 tmpFlag = ((unsigned)ABS(p0-q0) < ((thresholds->alpha >> 2) +2))
    902                             ? HANTRO_TRUE : HANTRO_FALSE;
    903 
    904                 p2 = data[-imageWidth*3];
    905                 q2 = data[imageWidth*2];
    906 
    907                 if (tmpFlag && (unsigned)ABS(p2-p0) < thresholds->beta)
    908                 {
    909                     tmp = p1 + p0 + q0;
    910                     data[-imageWidth] = (u8)((p2 + 2 * tmp + q1 + 4) >> 3);
    911                     data[-imageWidth*2] = (u8)((p2 + tmp + 2) >> 2);
    912                     data[-imageWidth*3] = (u8)((2 * data[-imageWidth*4] +
    913                                            3 * p2 + tmp + 4) >> 3);
    914                 }
    915                 else
    916                     data[-imageWidth] = (u8)((2 * p1 + p0 + q1 + 2) >> 2);
    917 
    918                 if (tmpFlag && (unsigned)ABS(q2-q0) < thresholds->beta)
    919                 {
    920                     tmp = p0 + q0 + q1;
    921                     data[ 0] = (u8)((p1 + 2 * tmp + q2 + 4) >> 3);
    922                     data[imageWidth] = (u8)((tmp + q2 + 2) >> 2);
    923                     data[imageWidth*2] = (u8)((2 * data[imageWidth*3] +
    924                                           3 * q2 + tmp + 4) >> 3);
    925                 }
    926                 else
    927                     data[0] = (2 * q1 + q0 + p1 + 2) >> 2;
    928             }
    929         }
    930     }
    931 
    932 }
    933 
    934 /*------------------------------------------------------------------------------
    935 
    936     Function: FilterVerChromaEdge
    937 
    938         Functional description:
    939             Filter one vertical 2-pixel chroma edge
    940 
    941 ------------------------------------------------------------------------------*/
    942 void FilterVerChromaEdge(
    943   u8 *data,
    944   u32 bS,
    945   edgeThreshold_t *thresholds,
    946   u32 width)
    947 {
    948 
    949 /* Variables */
    950 
    951     i32 delta, tc;
    952     u8 p0, q0, p1, q1;
    953     const u8 *clp = h264bsdClip + 512;
    954 
    955 /* Code */
    956 
    957     ASSERT(data);
    958     ASSERT(bS <= 4);
    959     ASSERT(thresholds);
    960 
    961     p1 = data[-2]; p0 = data[-1];
    962     q0 = data[0]; q1 = data[1];
    963     if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
    964          ((unsigned)ABS(p1-p0) < thresholds->beta)  &&
    965          ((unsigned)ABS(q1-q0) < thresholds->beta) )
    966     {
    967         if (bS < 4)
    968         {
    969             tc = thresholds->tc0[bS-1] + 1;
    970             delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
    971                       (p1 - q1) + 4) >> 3));
    972             p0 = clp[p0 + delta];
    973             q0 = clp[q0 - delta];
    974             data[-1] = p0;
    975             data[ 0] = q0;
    976         }
    977         else
    978         {
    979             data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
    980             data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
    981         }
    982     }
    983     data += width;
    984     p1 = data[-2]; p0 = data[-1];
    985     q0 = data[0]; q1 = data[1];
    986     if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
    987          ((unsigned)ABS(p1-p0) < thresholds->beta)  &&
    988          ((unsigned)ABS(q1-q0) < thresholds->beta) )
    989     {
    990         if (bS < 4)
    991         {
    992             tc = thresholds->tc0[bS-1] + 1;
    993             delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
    994                       (p1 - q1) + 4) >> 3));
    995             p0 = clp[p0 + delta];
    996             q0 = clp[q0 - delta];
    997             data[-1] = p0;
    998             data[ 0] = q0;
    999         }
   1000         else
   1001         {
   1002             data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
   1003             data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
   1004         }
   1005     }
   1006 
   1007 }
   1008 
   1009 /*------------------------------------------------------------------------------
   1010 
   1011     Function: FilterHorChromaEdge
   1012 
   1013         Functional description:
   1014             Filter one horizontal 2-pixel chroma edge
   1015 
   1016 ------------------------------------------------------------------------------*/
   1017 void FilterHorChromaEdge(
   1018   u8 *data,
   1019   u32 bS,
   1020   edgeThreshold_t *thresholds,
   1021   i32 width)
   1022 {
   1023 
   1024 /* Variables */
   1025 
   1026     i32 delta, tc;
   1027     u32 i;
   1028     u8 p0, q0, p1, q1;
   1029     const u8 *clp = h264bsdClip + 512;
   1030 
   1031 /* Code */
   1032 
   1033     ASSERT(data);
   1034     ASSERT(bS < 4);
   1035     ASSERT(thresholds);
   1036 
   1037     tc = thresholds->tc0[bS-1] + 1;
   1038     for (i = 2; i; i--, data++)
   1039     {
   1040         p1 = data[-width*2]; p0 = data[-width];
   1041         q0 = data[0]; q1 = data[width];
   1042         if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
   1043              ((unsigned)ABS(p1-p0) < thresholds->beta)  &&
   1044              ((unsigned)ABS(q1-q0) < thresholds->beta) )
   1045         {
   1046             delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
   1047                       (p1 - q1) + 4) >> 3));
   1048             p0 = clp[p0 + delta];
   1049             q0 = clp[q0 - delta];
   1050             data[-width] = p0;
   1051             data[  0] = q0;
   1052         }
   1053     }
   1054 }
   1055 
   1056 /*------------------------------------------------------------------------------
   1057 
   1058     Function: FilterHorChroma
   1059 
   1060         Functional description:
   1061             Filter all four successive horizontal 2-pixel chroma edges. This
   1062             can be done if bS is equal for all four edges.
   1063 
   1064 ------------------------------------------------------------------------------*/
   1065 void FilterHorChroma(
   1066   u8 *data,
   1067   u32 bS,
   1068   edgeThreshold_t *thresholds,
   1069   i32 width)
   1070 {
   1071 
   1072 /* Variables */
   1073 
   1074     i32 delta, tc;
   1075     u32 i;
   1076     u8 p0, q0, p1, q1;
   1077     const u8 *clp = h264bsdClip + 512;
   1078 
   1079 /* Code */
   1080 
   1081     ASSERT(data);
   1082     ASSERT(bS <= 4);
   1083     ASSERT(thresholds);
   1084 
   1085     if (bS < 4)
   1086     {
   1087         tc = thresholds->tc0[bS-1] + 1;
   1088         for (i = 8; i; i--, data++)
   1089         {
   1090             p1 = data[-width*2]; p0 = data[-width];
   1091             q0 = data[0]; q1 = data[width];
   1092             if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
   1093                  ((unsigned)ABS(p1-p0) < thresholds->beta)  &&
   1094                  ((unsigned)ABS(q1-q0) < thresholds->beta) )
   1095             {
   1096                 delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
   1097                           (p1 - q1) + 4) >> 3));
   1098                 p0 = clp[p0 + delta];
   1099                 q0 = clp[q0 - delta];
   1100                 data[-width] = p0;
   1101                 data[  0] = q0;
   1102             }
   1103         }
   1104     }
   1105     else
   1106     {
   1107         for (i = 8; i; i--, data++)
   1108         {
   1109             p1 = data[-width*2]; p0 = data[-width];
   1110             q0 = data[0]; q1 = data[width];
   1111             if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
   1112                  ((unsigned)ABS(p1-p0) < thresholds->beta)  &&
   1113                  ((unsigned)ABS(q1-q0) < thresholds->beta) )
   1114             {
   1115                     data[-width] = (2 * p1 + p0 + q1 + 2) >> 2;
   1116                     data[  0] = (2 * q1 + q0 + p1 + 2) >> 2;
   1117             }
   1118         }
   1119     }
   1120 
   1121 }
   1122 
   1123 
   1124 /*------------------------------------------------------------------------------
   1125 
   1126     Function: GetBoundaryStrengths
   1127 
   1128         Functional description:
   1129             Function to calculate boundary strengths for all edges of a
   1130             macroblock. Function returns HANTRO_TRUE if any of the bS values for
   1131             the macroblock had non-zero value, HANTRO_FALSE otherwise.
   1132 
   1133 ------------------------------------------------------------------------------*/
   1134 u32 GetBoundaryStrengths(mbStorage_t *mb, bS_t *bS, u32 flags)
   1135 {
   1136 
   1137 /* Variables */
   1138 
   1139     /* this flag is set HANTRO_TRUE as soon as any boundary strength value is
   1140      * non-zero */
   1141     u32 nonZeroBs = HANTRO_FALSE;
   1142 
   1143 /* Code */
   1144 
   1145     ASSERT(mb);
   1146     ASSERT(bS);
   1147     ASSERT(flags);
   1148 
   1149     /* top edges */
   1150     if (flags & FILTER_TOP_EDGE)
   1151     {
   1152         if (IS_INTRA_MB(*mb) || IS_INTRA_MB(*mb->mbB))
   1153         {
   1154             bS[0].top = bS[1].top = bS[2].top = bS[3].top = 4;
   1155             nonZeroBs = HANTRO_TRUE;
   1156         }
   1157         else
   1158         {
   1159             bS[0].top = EdgeBoundaryStrength(mb, mb->mbB, 0, 10);
   1160             bS[1].top = EdgeBoundaryStrength(mb, mb->mbB, 1, 11);
   1161             bS[2].top = EdgeBoundaryStrength(mb, mb->mbB, 4, 14);
   1162             bS[3].top = EdgeBoundaryStrength(mb, mb->mbB, 5, 15);
   1163             if (bS[0].top || bS[1].top || bS[2].top || bS[3].top)
   1164                 nonZeroBs = HANTRO_TRUE;
   1165         }
   1166     }
   1167     else
   1168     {
   1169         bS[0].top = bS[1].top = bS[2].top = bS[3].top = 0;
   1170     }
   1171 
   1172     /* left edges */
   1173     if (flags & FILTER_LEFT_EDGE)
   1174     {
   1175         if (IS_INTRA_MB(*mb) || IS_INTRA_MB(*mb->mbA))
   1176         {
   1177             bS[0].left = bS[4].left = bS[8].left = bS[12].left = 4;
   1178             nonZeroBs = HANTRO_TRUE;
   1179         }
   1180         else
   1181         {
   1182             bS[0].left = EdgeBoundaryStrength(mb, mb->mbA, 0, 5);
   1183             bS[4].left = EdgeBoundaryStrength(mb, mb->mbA, 2, 7);
   1184             bS[8].left = EdgeBoundaryStrength(mb, mb->mbA, 8, 13);
   1185             bS[12].left = EdgeBoundaryStrength(mb, mb->mbA, 10, 15);
   1186             if (!nonZeroBs &&
   1187                 (bS[0].left || bS[4].left || bS[8].left || bS[12].left))
   1188                 nonZeroBs = HANTRO_TRUE;
   1189         }
   1190     }
   1191     else
   1192     {
   1193         bS[0].left = bS[4].left = bS[8].left = bS[12].left = 0;
   1194     }
   1195 
   1196     /* inner edges */
   1197     if (IS_INTRA_MB(*mb))
   1198     {
   1199         bS[4].top  = bS[5].top  = bS[6].top  = bS[7].top  =
   1200         bS[8].top  = bS[9].top  = bS[10].top = bS[11].top =
   1201         bS[12].top = bS[13].top = bS[14].top = bS[15].top = 3;
   1202 
   1203         bS[1].left  = bS[2].left  = bS[3].left  =
   1204         bS[5].left  = bS[6].left  = bS[7].left  =
   1205         bS[9].left  = bS[10].left = bS[11].left =
   1206         bS[13].left = bS[14].left = bS[15].left = 3;
   1207         nonZeroBs = HANTRO_TRUE;
   1208     }
   1209     else
   1210     {
   1211         /* 16x16 inter mb -> ref addresses or motion vectors cannot differ,
   1212          * only check if either of the blocks contain coefficients */
   1213         if (h264bsdNumMbPart(mb->mbType) == 1)
   1214         {
   1215             bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
   1216             bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
   1217             bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
   1218             bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
   1219             bS[8].top = mb->totalCoeff[8] || mb->totalCoeff[2] ? 2 : 0;
   1220             bS[9].top = mb->totalCoeff[9] || mb->totalCoeff[3] ? 2 : 0;
   1221             bS[10].top = mb->totalCoeff[12] || mb->totalCoeff[6] ? 2 : 0;
   1222             bS[11].top = mb->totalCoeff[13] || mb->totalCoeff[7] ? 2 : 0;
   1223             bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
   1224             bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
   1225             bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
   1226             bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
   1227 
   1228             bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
   1229             bS[2].left = mb->totalCoeff[4] || mb->totalCoeff[1] ? 2 : 0;
   1230             bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
   1231             bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
   1232             bS[6].left = mb->totalCoeff[6] || mb->totalCoeff[3] ? 2 : 0;
   1233             bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
   1234             bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
   1235             bS[10].left = mb->totalCoeff[12] || mb->totalCoeff[9] ? 2 : 0;
   1236             bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
   1237             bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
   1238             bS[14].left = mb->totalCoeff[14] || mb->totalCoeff[11] ? 2 : 0;
   1239             bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
   1240         }
   1241         /* 16x8 inter mb -> ref addresses and motion vectors can be different
   1242          * only for the middle horizontal edge, for the other top edges it is
   1243          * enough to check whether the blocks contain coefficients or not. The
   1244          * same applies to all internal left edges. */
   1245         else if (mb->mbType == P_L0_L0_16x8)
   1246         {
   1247             bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
   1248             bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
   1249             bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
   1250             bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
   1251             bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
   1252             bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
   1253             bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
   1254             bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
   1255             bS[8].top = InnerBoundaryStrength(mb, 8, 2);
   1256             bS[9].top = InnerBoundaryStrength(mb, 9, 3);
   1257             bS[10].top = InnerBoundaryStrength(mb, 12, 6);
   1258             bS[11].top = InnerBoundaryStrength(mb, 13, 7);
   1259 
   1260             bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
   1261             bS[2].left = mb->totalCoeff[4] || mb->totalCoeff[1] ? 2 : 0;
   1262             bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
   1263             bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
   1264             bS[6].left = mb->totalCoeff[6] || mb->totalCoeff[3] ? 2 : 0;
   1265             bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
   1266             bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
   1267             bS[10].left = mb->totalCoeff[12] || mb->totalCoeff[9] ? 2 : 0;
   1268             bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
   1269             bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
   1270             bS[14].left = mb->totalCoeff[14] || mb->totalCoeff[11] ? 2 : 0;
   1271             bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
   1272         }
   1273         /* 8x16 inter mb -> ref addresses and motion vectors can be different
   1274          * only for the middle vertical edge, for the other left edges it is
   1275          * enough to check whether the blocks contain coefficients or not. The
   1276          * same applies to all internal top edges. */
   1277         else if (mb->mbType == P_L0_L0_8x16)
   1278         {
   1279             bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
   1280             bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
   1281             bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
   1282             bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
   1283             bS[8].top = mb->totalCoeff[8] || mb->totalCoeff[2] ? 2 : 0;
   1284             bS[9].top = mb->totalCoeff[9] || mb->totalCoeff[3] ? 2 : 0;
   1285             bS[10].top = mb->totalCoeff[12] || mb->totalCoeff[6] ? 2 : 0;
   1286             bS[11].top = mb->totalCoeff[13] || mb->totalCoeff[7] ? 2 : 0;
   1287             bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
   1288             bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
   1289             bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
   1290             bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
   1291 
   1292             bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
   1293             bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
   1294             bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
   1295             bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
   1296             bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
   1297             bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
   1298             bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
   1299             bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
   1300             bS[2].left = InnerBoundaryStrength(mb, 4, 1);
   1301             bS[6].left = InnerBoundaryStrength(mb, 6, 3);
   1302             bS[10].left = InnerBoundaryStrength(mb, 12, 9);
   1303             bS[14].left = InnerBoundaryStrength(mb, 14, 11);
   1304         }
   1305         else
   1306         {
   1307             bS[4].top =
   1308                 InnerBoundaryStrength(mb, mb4x4Index[4], mb4x4Index[0]);
   1309             bS[5].top =
   1310                 InnerBoundaryStrength(mb, mb4x4Index[5], mb4x4Index[1]);
   1311             bS[6].top =
   1312                 InnerBoundaryStrength(mb, mb4x4Index[6], mb4x4Index[2]);
   1313             bS[7].top =
   1314                 InnerBoundaryStrength(mb, mb4x4Index[7], mb4x4Index[3]);
   1315             bS[8].top =
   1316                 InnerBoundaryStrength(mb, mb4x4Index[8], mb4x4Index[4]);
   1317             bS[9].top =
   1318                 InnerBoundaryStrength(mb, mb4x4Index[9], mb4x4Index[5]);
   1319             bS[10].top =
   1320                 InnerBoundaryStrength(mb, mb4x4Index[10], mb4x4Index[6]);
   1321             bS[11].top =
   1322                 InnerBoundaryStrength(mb, mb4x4Index[11], mb4x4Index[7]);
   1323             bS[12].top =
   1324                 InnerBoundaryStrength(mb, mb4x4Index[12], mb4x4Index[8]);
   1325             bS[13].top =
   1326                 InnerBoundaryStrength(mb, mb4x4Index[13], mb4x4Index[9]);
   1327             bS[14].top =
   1328                 InnerBoundaryStrength(mb, mb4x4Index[14], mb4x4Index[10]);
   1329             bS[15].top =
   1330                 InnerBoundaryStrength(mb, mb4x4Index[15], mb4x4Index[11]);
   1331 
   1332             bS[1].left =
   1333                 InnerBoundaryStrength(mb, mb4x4Index[1], mb4x4Index[0]);
   1334             bS[2].left =
   1335                 InnerBoundaryStrength(mb, mb4x4Index[2], mb4x4Index[1]);
   1336             bS[3].left =
   1337                 InnerBoundaryStrength(mb, mb4x4Index[3], mb4x4Index[2]);
   1338             bS[5].left =
   1339                 InnerBoundaryStrength(mb, mb4x4Index[5], mb4x4Index[4]);
   1340             bS[6].left =
   1341                 InnerBoundaryStrength(mb, mb4x4Index[6], mb4x4Index[5]);
   1342             bS[7].left =
   1343                 InnerBoundaryStrength(mb, mb4x4Index[7], mb4x4Index[6]);
   1344             bS[9].left =
   1345                 InnerBoundaryStrength(mb, mb4x4Index[9], mb4x4Index[8]);
   1346             bS[10].left =
   1347                 InnerBoundaryStrength(mb, mb4x4Index[10], mb4x4Index[9]);
   1348             bS[11].left =
   1349                 InnerBoundaryStrength(mb, mb4x4Index[11], mb4x4Index[10]);
   1350             bS[13].left =
   1351                 InnerBoundaryStrength(mb, mb4x4Index[13], mb4x4Index[12]);
   1352             bS[14].left =
   1353                 InnerBoundaryStrength(mb, mb4x4Index[14], mb4x4Index[13]);
   1354             bS[15].left =
   1355                 InnerBoundaryStrength(mb, mb4x4Index[15], mb4x4Index[14]);
   1356         }
   1357         if (!nonZeroBs &&
   1358             (bS[4].top || bS[5].top || bS[6].top || bS[7].top ||
   1359              bS[8].top || bS[9].top || bS[10].top || bS[11].top ||
   1360              bS[12].top || bS[13].top || bS[14].top || bS[15].top ||
   1361              bS[1].left || bS[2].left || bS[3].left ||
   1362              bS[5].left || bS[6].left || bS[7].left ||
   1363              bS[9].left || bS[10].left || bS[11].left ||
   1364              bS[13].left || bS[14].left || bS[15].left))
   1365             nonZeroBs = HANTRO_TRUE;
   1366     }
   1367 
   1368     return(nonZeroBs);
   1369 
   1370 }
   1371 
   1372 /*------------------------------------------------------------------------------
   1373 
   1374     Function: GetLumaEdgeThresholds
   1375 
   1376         Functional description:
   1377             Compute alpha, beta and tc0 thresholds for inner, left and top
   1378             luma edges of a macroblock.
   1379 
   1380 ------------------------------------------------------------------------------*/
   1381 void GetLumaEdgeThresholds(
   1382   edgeThreshold_t *thresholds,
   1383   mbStorage_t *mb,
   1384   u32 filteringFlags)
   1385 {
   1386 
   1387 /* Variables */
   1388 
   1389     u32 indexA, indexB;
   1390     u32 qpAv, qp, qpTmp;
   1391 
   1392 /* Code */
   1393 
   1394     ASSERT(thresholds);
   1395     ASSERT(mb);
   1396 
   1397     qp = mb->qpY;
   1398 
   1399     indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
   1400     indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
   1401 
   1402     thresholds[INNER].alpha = alphas[indexA];
   1403     thresholds[INNER].beta = betas[indexB];
   1404     thresholds[INNER].tc0 = tc0[indexA];
   1405 
   1406     if (filteringFlags & FILTER_TOP_EDGE)
   1407     {
   1408         qpTmp = mb->mbB->qpY;
   1409         if (qpTmp != qp)
   1410         {
   1411             qpAv = (qp + qpTmp + 1) >> 1;
   1412 
   1413             indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
   1414             indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
   1415 
   1416             thresholds[TOP].alpha = alphas[indexA];
   1417             thresholds[TOP].beta = betas[indexB];
   1418             thresholds[TOP].tc0 = tc0[indexA];
   1419         }
   1420         else
   1421         {
   1422             thresholds[TOP].alpha = thresholds[INNER].alpha;
   1423             thresholds[TOP].beta = thresholds[INNER].beta;
   1424             thresholds[TOP].tc0 = thresholds[INNER].tc0;
   1425         }
   1426     }
   1427     if (filteringFlags & FILTER_LEFT_EDGE)
   1428     {
   1429         qpTmp = mb->mbA->qpY;
   1430         if (qpTmp != qp)
   1431         {
   1432             qpAv = (qp + qpTmp + 1) >> 1;
   1433 
   1434             indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
   1435             indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
   1436 
   1437             thresholds[LEFT].alpha = alphas[indexA];
   1438             thresholds[LEFT].beta = betas[indexB];
   1439             thresholds[LEFT].tc0 = tc0[indexA];
   1440         }
   1441         else
   1442         {
   1443             thresholds[LEFT].alpha = thresholds[INNER].alpha;
   1444             thresholds[LEFT].beta = thresholds[INNER].beta;
   1445             thresholds[LEFT].tc0 = thresholds[INNER].tc0;
   1446         }
   1447     }
   1448 
   1449 }
   1450 
   1451 /*------------------------------------------------------------------------------
   1452 
   1453     Function: GetChromaEdgeThresholds
   1454 
   1455         Functional description:
   1456             Compute alpha, beta and tc0 thresholds for inner, left and top
   1457             chroma edges of a macroblock.
   1458 
   1459 ------------------------------------------------------------------------------*/
   1460 void GetChromaEdgeThresholds(
   1461   edgeThreshold_t *thresholds,
   1462   mbStorage_t *mb,
   1463   u32 filteringFlags,
   1464   i32 chromaQpIndexOffset)
   1465 {
   1466 
   1467 /* Variables */
   1468 
   1469     u32 indexA, indexB;
   1470     u32 qpAv, qp, qpTmp;
   1471 
   1472 /* Code */
   1473 
   1474     ASSERT(thresholds);
   1475     ASSERT(mb);
   1476 
   1477     qp = mb->qpY;
   1478     qp = h264bsdQpC[CLIP3(0, 51, (i32)qp + chromaQpIndexOffset)];
   1479 
   1480     indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
   1481     indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
   1482 
   1483     thresholds[INNER].alpha = alphas[indexA];
   1484     thresholds[INNER].beta = betas[indexB];
   1485     thresholds[INNER].tc0 = tc0[indexA];
   1486 
   1487     if (filteringFlags & FILTER_TOP_EDGE)
   1488     {
   1489         qpTmp = mb->mbB->qpY;
   1490         if (qpTmp != mb->qpY)
   1491         {
   1492             qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
   1493             qpAv = (qp + qpTmp + 1) >> 1;
   1494 
   1495             indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
   1496             indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
   1497 
   1498             thresholds[TOP].alpha = alphas[indexA];
   1499             thresholds[TOP].beta = betas[indexB];
   1500             thresholds[TOP].tc0 = tc0[indexA];
   1501         }
   1502         else
   1503         {
   1504             thresholds[TOP].alpha = thresholds[INNER].alpha;
   1505             thresholds[TOP].beta = thresholds[INNER].beta;
   1506             thresholds[TOP].tc0 = thresholds[INNER].tc0;
   1507         }
   1508     }
   1509     if (filteringFlags & FILTER_LEFT_EDGE)
   1510     {
   1511         qpTmp = mb->mbA->qpY;
   1512         if (qpTmp != mb->qpY)
   1513         {
   1514             qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
   1515             qpAv = (qp + qpTmp + 1) >> 1;
   1516 
   1517             indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
   1518             indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
   1519 
   1520             thresholds[LEFT].alpha = alphas[indexA];
   1521             thresholds[LEFT].beta = betas[indexB];
   1522             thresholds[LEFT].tc0 = tc0[indexA];
   1523         }
   1524         else
   1525         {
   1526             thresholds[LEFT].alpha = thresholds[INNER].alpha;
   1527             thresholds[LEFT].beta = thresholds[INNER].beta;
   1528             thresholds[LEFT].tc0 = thresholds[INNER].tc0;
   1529         }
   1530     }
   1531 
   1532 }
   1533 
   1534 /*------------------------------------------------------------------------------
   1535 
   1536     Function: FilterLuma
   1537 
   1538         Functional description:
   1539             Function to filter all luma edges of a macroblock
   1540 
   1541 ------------------------------------------------------------------------------*/
   1542 void FilterLuma(
   1543   u8 *data,
   1544   bS_t *bS,
   1545   edgeThreshold_t *thresholds,
   1546   u32 width)
   1547 {
   1548 
   1549 /* Variables */
   1550 
   1551     u32 vblock;
   1552     bS_t *tmp;
   1553     u8 *ptr;
   1554     u32 offset;
   1555 
   1556 /* Code */
   1557 
   1558     ASSERT(data);
   1559     ASSERT(bS);
   1560     ASSERT(thresholds);
   1561 
   1562     ptr = data;
   1563     tmp = bS;
   1564 
   1565     offset  = TOP;
   1566 
   1567     /* loop block rows, perform filtering for all vertical edges of the block
   1568      * row first, then filter each horizontal edge of the row */
   1569     for (vblock = 4; vblock--;)
   1570     {
   1571         /* only perform filtering if bS is non-zero, first of the four
   1572          * FilterVerLumaEdge handles the left edge of the macroblock, others
   1573          * filter inner edges */
   1574         if (tmp[0].left)
   1575             FilterVerLumaEdge(ptr, tmp[0].left, thresholds + LEFT, width);
   1576         if (tmp[1].left)
   1577             FilterVerLumaEdge(ptr+4, tmp[1].left, thresholds + INNER, width);
   1578         if (tmp[2].left)
   1579             FilterVerLumaEdge(ptr+8, tmp[2].left, thresholds + INNER, width);
   1580         if (tmp[3].left)
   1581             FilterVerLumaEdge(ptr+12, tmp[3].left, thresholds + INNER, width);
   1582 
   1583         /* if bS is equal for all horizontal edges of the row -> perform
   1584          * filtering with FilterHorLuma, otherwise use FilterHorLumaEdge for
   1585          * each edge separately. offset variable indicates top macroblock edge
   1586          * on the first loop round, inner edge for the other rounds */
   1587         if (tmp[0].top == tmp[1].top && tmp[1].top == tmp[2].top &&
   1588             tmp[2].top == tmp[3].top)
   1589         {
   1590             if(tmp[0].top)
   1591                 FilterHorLuma(ptr, tmp[0].top, thresholds + offset, (i32)width);
   1592         }
   1593         else
   1594         {
   1595             if(tmp[0].top)
   1596                 FilterHorLumaEdge(ptr, tmp[0].top, thresholds+offset,
   1597                     (i32)width);
   1598             if(tmp[1].top)
   1599                 FilterHorLumaEdge(ptr+4, tmp[1].top, thresholds+offset,
   1600                     (i32)width);
   1601             if(tmp[2].top)
   1602                 FilterHorLumaEdge(ptr+8, tmp[2].top, thresholds+offset,
   1603                     (i32)width);
   1604             if(tmp[3].top)
   1605                 FilterHorLumaEdge(ptr+12, tmp[3].top, thresholds+offset,
   1606                     (i32)width);
   1607         }
   1608 
   1609         /* four pixel rows ahead, i.e. next row of 4x4-blocks */
   1610         ptr += width*4;
   1611         tmp += 4;
   1612         offset = INNER;
   1613     }
   1614 }
   1615 
   1616 /*------------------------------------------------------------------------------
   1617 
   1618     Function: FilterChroma
   1619 
   1620         Functional description:
   1621             Function to filter all chroma edges of a macroblock
   1622 
   1623 ------------------------------------------------------------------------------*/
   1624 void FilterChroma(
   1625   u8 *dataCb,
   1626   u8 *dataCr,
   1627   bS_t *bS,
   1628   edgeThreshold_t *thresholds,
   1629   u32 width)
   1630 {
   1631 
   1632 /* Variables */
   1633 
   1634     u32 vblock;
   1635     bS_t *tmp;
   1636     u32 offset;
   1637 
   1638 /* Code */
   1639 
   1640     ASSERT(dataCb);
   1641     ASSERT(dataCr);
   1642     ASSERT(bS);
   1643     ASSERT(thresholds);
   1644 
   1645     tmp = bS;
   1646     offset = TOP;
   1647 
   1648     /* loop block rows, perform filtering for all vertical edges of the block
   1649      * row first, then filter each horizontal edge of the row */
   1650     for (vblock = 0; vblock < 2; vblock++)
   1651     {
   1652         /* only perform filtering if bS is non-zero, first two of the four
   1653          * FilterVerChromaEdge calls handle the left edge of the macroblock,
   1654          * others filter the inner edge. Note that as chroma uses bS values
   1655          * determined for luma edges, each bS is used only for 2 pixels of
   1656          * a 4-pixel edge */
   1657         if (tmp[0].left)
   1658         {
   1659             FilterVerChromaEdge(dataCb, tmp[0].left, thresholds + LEFT, width);
   1660             FilterVerChromaEdge(dataCr, tmp[0].left, thresholds + LEFT, width);
   1661         }
   1662         if (tmp[4].left)
   1663         {
   1664             FilterVerChromaEdge(dataCb+2*width, tmp[4].left, thresholds + LEFT,
   1665                 width);
   1666             FilterVerChromaEdge(dataCr+2*width, tmp[4].left, thresholds + LEFT,
   1667                 width);
   1668         }
   1669         if (tmp[2].left)
   1670         {
   1671             FilterVerChromaEdge(dataCb+4, tmp[2].left, thresholds + INNER,
   1672                 width);
   1673             FilterVerChromaEdge(dataCr+4, tmp[2].left, thresholds + INNER,
   1674                 width);
   1675         }
   1676         if (tmp[6].left)
   1677         {
   1678             FilterVerChromaEdge(dataCb+2*width+4, tmp[6].left,
   1679                 thresholds + INNER, width);
   1680             FilterVerChromaEdge(dataCr+2*width+4, tmp[6].left,
   1681                 thresholds + INNER, width);
   1682         }
   1683 
   1684         /* if bS is equal for all horizontal edges of the row -> perform
   1685          * filtering with FilterHorChroma, otherwise use FilterHorChromaEdge
   1686          * for each edge separately. offset variable indicates top macroblock
   1687          * edge on the first loop round, inner edge for the second */
   1688         if (tmp[0].top == tmp[1].top && tmp[1].top == tmp[2].top &&
   1689             tmp[2].top == tmp[3].top)
   1690         {
   1691             if(tmp[0].top)
   1692             {
   1693                 FilterHorChroma(dataCb, tmp[0].top, thresholds+offset,
   1694                     (i32)width);
   1695                 FilterHorChroma(dataCr, tmp[0].top, thresholds+offset,
   1696                     (i32)width);
   1697             }
   1698         }
   1699         else
   1700         {
   1701             if (tmp[0].top)
   1702             {
   1703                 FilterHorChromaEdge(dataCb, tmp[0].top, thresholds+offset,
   1704                     (i32)width);
   1705                 FilterHorChromaEdge(dataCr, tmp[0].top, thresholds+offset,
   1706                     (i32)width);
   1707             }
   1708             if (tmp[1].top)
   1709             {
   1710                 FilterHorChromaEdge(dataCb+2, tmp[1].top, thresholds+offset,
   1711                     (i32)width);
   1712                 FilterHorChromaEdge(dataCr+2, tmp[1].top, thresholds+offset,
   1713                     (i32)width);
   1714             }
   1715             if (tmp[2].top)
   1716             {
   1717                 FilterHorChromaEdge(dataCb+4, tmp[2].top, thresholds+offset,
   1718                     (i32)width);
   1719                 FilterHorChromaEdge(dataCr+4, tmp[2].top, thresholds+offset,
   1720                     (i32)width);
   1721             }
   1722             if (tmp[3].top)
   1723             {
   1724                 FilterHorChromaEdge(dataCb+6, tmp[3].top, thresholds+offset,
   1725                     (i32)width);
   1726                 FilterHorChromaEdge(dataCr+6, tmp[3].top, thresholds+offset,
   1727                     (i32)width);
   1728             }
   1729         }
   1730 
   1731         tmp += 8;
   1732         dataCb += width*4;
   1733         dataCr += width*4;
   1734         offset = INNER;
   1735     }
   1736 }
   1737 
   1738 #else /* H264DEC_OMXDL */
   1739 
   1740 /*------------------------------------------------------------------------------
   1741 
   1742     Function: h264bsdFilterPicture
   1743 
   1744         Functional description:
   1745           Perform deblocking filtering for a picture. Filter does not copy
   1746           the original picture anywhere but filtering is performed directly
   1747           on the original image. Parameters controlling the filtering process
   1748           are computed based on information in macroblock structures of the
   1749           filtered macroblock, macroblock above and macroblock on the left of
   1750           the filtered one.
   1751 
   1752         Inputs:
   1753           image         pointer to image to be filtered
   1754           mb            pointer to macroblock data structure of the top-left
   1755                         macroblock of the picture
   1756 
   1757         Outputs:
   1758           image         filtered image stored here
   1759 
   1760         Returns:
   1761           none
   1762 
   1763 ------------------------------------------------------------------------------*/
   1764 
   1765 /*lint --e{550} Symbol not accessed */
   1766 void h264bsdFilterPicture(
   1767   image_t *image,
   1768   mbStorage_t *mb)
   1769 {
   1770 
   1771 /* Variables */
   1772 
   1773     u32 flags;
   1774     u32 picSizeInMbs, mbRow, mbCol;
   1775     u32 picWidthInMbs;
   1776     u8 *data;
   1777     mbStorage_t *pMb;
   1778     u8 bS[2][16];
   1779     u8 thresholdLuma[2][16];
   1780     u8 thresholdChroma[2][8];
   1781     u8 alpha[2][2];
   1782     u8 beta[2][2];
   1783     OMXResult res;
   1784 
   1785 /* Code */
   1786 
   1787     ASSERT(image);
   1788     ASSERT(mb);
   1789     ASSERT(image->data);
   1790     ASSERT(image->width);
   1791     ASSERT(image->height);
   1792 
   1793     picWidthInMbs = image->width;
   1794     data = image->data;
   1795     picSizeInMbs = picWidthInMbs * image->height;
   1796 
   1797     pMb = mb;
   1798 
   1799     for (mbRow = 0, mbCol = 0; mbRow < image->height; pMb++)
   1800     {
   1801         flags = GetMbFilteringFlags(pMb);
   1802 
   1803         if (flags)
   1804         {
   1805             /* GetBoundaryStrengths function returns non-zero value if any of
   1806              * the bS values for the macroblock being processed was non-zero */
   1807             if (GetBoundaryStrengths(pMb, bS, flags))
   1808             {
   1809 
   1810                 /* Luma */
   1811                 GetLumaEdgeThresholds(pMb,alpha,beta,thresholdLuma,bS,flags);
   1812                 data = image->data + mbRow * picWidthInMbs * 256 + mbCol * 16;
   1813 
   1814                 res = omxVCM4P10_FilterDeblockingLuma_VerEdge_I( data,
   1815                                                 (OMX_S32)(picWidthInMbs*16),
   1816                                                 (const OMX_U8*)alpha,
   1817                                                 (const OMX_U8*)beta,
   1818                                                 (const OMX_U8*)thresholdLuma,
   1819                                                 (const OMX_U8*)bS );
   1820 
   1821                 res = omxVCM4P10_FilterDeblockingLuma_HorEdge_I( data,
   1822                                                 (OMX_S32)(picWidthInMbs*16),
   1823                                                 (const OMX_U8*)alpha+2,
   1824                                                 (const OMX_U8*)beta+2,
   1825                                                 (const OMX_U8*)thresholdLuma+16,
   1826                                                 (const OMX_U8*)bS+16 );
   1827                 /* Cb */
   1828                 GetChromaEdgeThresholds(pMb, alpha, beta, thresholdChroma,
   1829                                         bS, flags, pMb->chromaQpIndexOffset);
   1830                 data = image->data + picSizeInMbs * 256 +
   1831                     mbRow * picWidthInMbs * 64 + mbCol * 8;
   1832 
   1833                 res = omxVCM4P10_FilterDeblockingChroma_VerEdge_I( data,
   1834                                               (OMX_S32)(picWidthInMbs*8),
   1835                                               (const OMX_U8*)alpha,
   1836                                               (const OMX_U8*)beta,
   1837                                               (const OMX_U8*)thresholdChroma,
   1838                                               (const OMX_U8*)bS );
   1839                 res = omxVCM4P10_FilterDeblockingChroma_HorEdge_I( data,
   1840                                               (OMX_S32)(picWidthInMbs*8),
   1841                                               (const OMX_U8*)alpha+2,
   1842                                               (const OMX_U8*)beta+2,
   1843                                               (const OMX_U8*)thresholdChroma+8,
   1844                                               (const OMX_U8*)bS+16 );
   1845                 /* Cr */
   1846                 data += (picSizeInMbs * 64);
   1847                 res = omxVCM4P10_FilterDeblockingChroma_VerEdge_I( data,
   1848                                               (OMX_S32)(picWidthInMbs*8),
   1849                                               (const OMX_U8*)alpha,
   1850                                               (const OMX_U8*)beta,
   1851                                               (const OMX_U8*)thresholdChroma,
   1852                                               (const OMX_U8*)bS );
   1853                 res = omxVCM4P10_FilterDeblockingChroma_HorEdge_I( data,
   1854                                               (OMX_S32)(picWidthInMbs*8),
   1855                                               (const OMX_U8*)alpha+2,
   1856                                               (const OMX_U8*)beta+2,
   1857                                               (const OMX_U8*)thresholdChroma+8,
   1858                                               (const OMX_U8*)bS+16 );
   1859             }
   1860         }
   1861 
   1862         mbCol++;
   1863         if (mbCol == picWidthInMbs)
   1864         {
   1865             mbCol = 0;
   1866             mbRow++;
   1867         }
   1868     }
   1869 
   1870 }
   1871 
   1872 /*------------------------------------------------------------------------------
   1873 
   1874     Function: GetBoundaryStrengths
   1875 
   1876         Functional description:
   1877             Function to calculate boundary strengths for all edges of a
   1878             macroblock. Function returns HANTRO_TRUE if any of the bS values for
   1879             the macroblock had non-zero value, HANTRO_FALSE otherwise.
   1880 
   1881 ------------------------------------------------------------------------------*/
   1882 u32 GetBoundaryStrengths(mbStorage_t *mb, u8 (*bS)[16], u32 flags)
   1883 {
   1884 
   1885 /* Variables */
   1886 
   1887     /* this flag is set HANTRO_TRUE as soon as any boundary strength value is
   1888      * non-zero */
   1889     u32 nonZeroBs = HANTRO_FALSE;
   1890     u32 *pTmp;
   1891     u32 tmp1, tmp2, isIntraMb;
   1892 
   1893 /* Code */
   1894 
   1895     ASSERT(mb);
   1896     ASSERT(bS);
   1897     ASSERT(flags);
   1898 
   1899     isIntraMb = IS_INTRA_MB(*mb);
   1900 
   1901     /* top edges */
   1902     pTmp = (u32*)&bS[1][0];
   1903     if (flags & FILTER_TOP_EDGE)
   1904     {
   1905         if (isIntraMb || IS_INTRA_MB(*mb->mbB))
   1906         {
   1907             *pTmp = 0x04040404;
   1908             nonZeroBs = HANTRO_TRUE;
   1909         }
   1910         else
   1911         {
   1912             *pTmp = EdgeBoundaryStrengthTop(mb, mb->mbB);
   1913             if (*pTmp)
   1914                 nonZeroBs = HANTRO_TRUE;
   1915         }
   1916     }
   1917     else
   1918     {
   1919         *pTmp = 0;
   1920     }
   1921 
   1922     /* left edges */
   1923     pTmp = (u32*)&bS[0][0];
   1924     if (flags & FILTER_LEFT_EDGE)
   1925     {
   1926         if (isIntraMb || IS_INTRA_MB(*mb->mbA))
   1927         {
   1928             /*bS[0][0] = bS[0][1] = bS[0][2] = bS[0][3] = 4;*/
   1929             *pTmp = 0x04040404;
   1930             nonZeroBs = HANTRO_TRUE;
   1931         }
   1932         else
   1933         {
   1934             *pTmp = EdgeBoundaryStrengthLeft(mb, mb->mbA);
   1935             if (!nonZeroBs && *pTmp)
   1936                 nonZeroBs = HANTRO_TRUE;
   1937         }
   1938     }
   1939     else
   1940     {
   1941         *pTmp = 0;
   1942     }
   1943 
   1944     /* inner edges */
   1945     if (isIntraMb)
   1946     {
   1947         pTmp++;
   1948         *pTmp++ = 0x03030303;
   1949         *pTmp++ = 0x03030303;
   1950         *pTmp++ = 0x03030303;
   1951         pTmp++;
   1952         *pTmp++ = 0x03030303;
   1953         *pTmp++ = 0x03030303;
   1954         *pTmp = 0x03030303;
   1955 
   1956         nonZeroBs = HANTRO_TRUE;
   1957     }
   1958     else
   1959     {
   1960         pTmp = (u32*)mb->totalCoeff;
   1961 
   1962         /* 16x16 inter mb -> ref addresses or motion vectors cannot differ,
   1963          * only check if either of the blocks contain coefficients */
   1964         if (h264bsdNumMbPart(mb->mbType) == 1)
   1965         {
   1966             tmp1 = *pTmp++;
   1967             tmp2 = *pTmp++;
   1968             bS[1][4]  = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2]  || [0] */
   1969             bS[1][5]  = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3]  || [1] */
   1970             bS[0][4]  = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1]  || [0] */
   1971             bS[0][5]  = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3]  || [2] */
   1972 
   1973             tmp1 = *pTmp++;
   1974             bS[1][6]  = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6]  || [4] */
   1975             bS[1][7]  = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7]  || [5] */
   1976             bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5]  || [4] */
   1977             bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7]  || [6] */
   1978             tmp2 = *pTmp;
   1979             bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
   1980             bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
   1981             bS[0][6]  = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9]  || [8] */
   1982             bS[0][7]  = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
   1983 
   1984             bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
   1985             bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
   1986             bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
   1987             bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
   1988 
   1989             {
   1990             u32 tmp3, tmp4;
   1991 
   1992             tmp1 = mb->totalCoeff[8];
   1993             tmp2 = mb->totalCoeff[2];
   1994             tmp3 = mb->totalCoeff[9];
   1995             tmp4 = mb->totalCoeff[3];
   1996 
   1997             bS[1][8] = tmp1 || tmp2 ? 2 : 0;
   1998             tmp1 = mb->totalCoeff[12];
   1999             tmp2 = mb->totalCoeff[6];
   2000             bS[1][9] = tmp3 || tmp4 ? 2 : 0;
   2001             tmp3 = mb->totalCoeff[13];
   2002             tmp4 = mb->totalCoeff[7];
   2003             bS[1][10] = tmp1 || tmp2 ? 2 : 0;
   2004             tmp1 = mb->totalCoeff[4];
   2005             tmp2 = mb->totalCoeff[1];
   2006             bS[1][11] = tmp3 || tmp4 ? 2 : 0;
   2007             tmp3 = mb->totalCoeff[6];
   2008             tmp4 = mb->totalCoeff[3];
   2009             bS[0][8] = tmp1 || tmp2 ? 2 : 0;
   2010             tmp1 = mb->totalCoeff[12];
   2011             tmp2 = mb->totalCoeff[9];
   2012             bS[0][9] = tmp3 || tmp4 ? 2 : 0;
   2013             tmp3 = mb->totalCoeff[14];
   2014             tmp4 = mb->totalCoeff[11];
   2015             bS[0][10] = tmp1 || tmp2 ? 2 : 0;
   2016             bS[0][11] = tmp3 || tmp4 ? 2 : 0;
   2017             }
   2018         }
   2019 
   2020         /* 16x8 inter mb -> ref addresses and motion vectors can be different
   2021          * only for the middle horizontal edge, for the other top edges it is
   2022          * enough to check whether the blocks contain coefficients or not. The
   2023          * same applies to all internal left edges. */
   2024         else if (mb->mbType == P_L0_L0_16x8)
   2025         {
   2026             tmp1 = *pTmp++;
   2027             tmp2 = *pTmp++;
   2028             bS[1][4]  = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2]  || [0] */
   2029             bS[1][5]  = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3]  || [1] */
   2030             bS[0][4]  = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1]  || [0] */
   2031             bS[0][5]  = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3]  || [2] */
   2032             tmp1 = *pTmp++;
   2033             bS[1][6]  = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6]  || [4] */
   2034             bS[1][7]  = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7]  || [5] */
   2035             bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5]  || [4] */
   2036             bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7]  || [6] */
   2037             tmp2 = *pTmp;
   2038             bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
   2039             bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
   2040             bS[0][6]  = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9]  || [8] */
   2041             bS[0][7]  = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
   2042 
   2043             bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
   2044             bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
   2045             bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
   2046             bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
   2047 
   2048             bS[1][8] = (u8)InnerBoundaryStrength(mb, 8, 2);
   2049             bS[1][9] = (u8)InnerBoundaryStrength(mb, 9, 3);
   2050             bS[1][10] = (u8)InnerBoundaryStrength(mb, 12, 6);
   2051             bS[1][11] = (u8)InnerBoundaryStrength(mb, 13, 7);
   2052 
   2053             {
   2054             u32 tmp3, tmp4;
   2055 
   2056             tmp1 = mb->totalCoeff[4];
   2057             tmp2 = mb->totalCoeff[1];
   2058             tmp3 = mb->totalCoeff[6];
   2059             tmp4 = mb->totalCoeff[3];
   2060             bS[0][8] = tmp1 || tmp2 ? 2 : 0;
   2061             tmp1 = mb->totalCoeff[12];
   2062             tmp2 = mb->totalCoeff[9];
   2063             bS[0][9] = tmp3 || tmp4 ? 2 : 0;
   2064             tmp3 = mb->totalCoeff[14];
   2065             tmp4 = mb->totalCoeff[11];
   2066             bS[0][10] = tmp1 || tmp2 ? 2 : 0;
   2067             bS[0][11] = tmp3 || tmp4 ? 2 : 0;
   2068             }
   2069         }
   2070         /* 8x16 inter mb -> ref addresses and motion vectors can be different
   2071          * only for the middle vertical edge, for the other left edges it is
   2072          * enough to check whether the blocks contain coefficients or not. The
   2073          * same applies to all internal top edges. */
   2074         else if (mb->mbType == P_L0_L0_8x16)
   2075         {
   2076             tmp1 = *pTmp++;
   2077             tmp2 = *pTmp++;
   2078             bS[1][4]  = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2]  || [0] */
   2079             bS[1][5]  = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3]  || [1] */
   2080             bS[0][4]  = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1]  || [0] */
   2081             bS[0][5]  = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3]  || [2] */
   2082             tmp1 = *pTmp++;
   2083             bS[1][6]  = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6]  || [4] */
   2084             bS[1][7]  = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7]  || [5] */
   2085             bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5]  || [4] */
   2086             bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7]  || [6] */
   2087             tmp2 = *pTmp;
   2088             bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
   2089             bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
   2090             bS[0][6]  = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9]  || [8] */
   2091             bS[0][7]  = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
   2092 
   2093             bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
   2094             bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
   2095             bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
   2096             bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
   2097 
   2098             bS[0][8] = (u8)InnerBoundaryStrength(mb, 4, 1);
   2099             bS[0][9] = (u8)InnerBoundaryStrength(mb, 6, 3);
   2100             bS[0][10] = (u8)InnerBoundaryStrength(mb, 12, 9);
   2101             bS[0][11] = (u8)InnerBoundaryStrength(mb, 14, 11);
   2102 
   2103             {
   2104             u32 tmp3, tmp4;
   2105 
   2106             tmp1 = mb->totalCoeff[8];
   2107             tmp2 = mb->totalCoeff[2];
   2108             tmp3 = mb->totalCoeff[9];
   2109             tmp4 = mb->totalCoeff[3];
   2110             bS[1][8] = tmp1 || tmp2 ? 2 : 0;
   2111             tmp1 = mb->totalCoeff[12];
   2112             tmp2 = mb->totalCoeff[6];
   2113             bS[1][9] = tmp3 || tmp4 ? 2 : 0;
   2114             tmp3 = mb->totalCoeff[13];
   2115             tmp4 = mb->totalCoeff[7];
   2116             bS[1][10] = tmp1 || tmp2 ? 2 : 0;
   2117             bS[1][11] = tmp3 || tmp4 ? 2 : 0;
   2118             }
   2119         }
   2120         else
   2121         {
   2122             tmp1 = *pTmp++;
   2123             bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 2, 0);
   2124             bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 3, 1);
   2125             bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 1, 0);
   2126             bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 3, 2);
   2127             tmp1 = *pTmp++;
   2128             bS[1][6]  = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 6, 4);
   2129             bS[1][7]  = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 7, 5);
   2130             bS[0][12] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 5, 4);
   2131             bS[0][13] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 7, 6);
   2132             tmp1 = *pTmp++;
   2133             bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 10, 8);
   2134             bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 11, 9);
   2135             bS[0][6]  = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 9, 8);
   2136             bS[0][7]  = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 11, 10);
   2137             tmp1 = *pTmp;
   2138             bS[1][14] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 14, 12);
   2139             bS[1][15] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 15, 13);
   2140             bS[0][14] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 13, 12);
   2141             bS[0][15] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 15, 14);
   2142 
   2143             bS[1][8] = (u8)InnerBoundaryStrength(mb, 8, 2);
   2144             bS[1][9] = (u8)InnerBoundaryStrength(mb, 9, 3);
   2145             bS[1][10] = (u8)InnerBoundaryStrength(mb, 12, 6);
   2146             bS[1][11] = (u8)InnerBoundaryStrength(mb, 13, 7);
   2147 
   2148             bS[0][8] = (u8)InnerBoundaryStrength(mb, 4, 1);
   2149             bS[0][9] = (u8)InnerBoundaryStrength(mb, 6, 3);
   2150             bS[0][10] = (u8)InnerBoundaryStrength(mb, 12, 9);
   2151             bS[0][11] = (u8)InnerBoundaryStrength(mb, 14, 11);
   2152         }
   2153         pTmp = (u32*)&bS[0][0];
   2154         if (!nonZeroBs && (pTmp[1] || pTmp[2] || pTmp[3] ||
   2155                            pTmp[5] || pTmp[6] || pTmp[7]) )
   2156         {
   2157             nonZeroBs = HANTRO_TRUE;
   2158         }
   2159     }
   2160 
   2161     return(nonZeroBs);
   2162 
   2163 }
   2164 
   2165 /*------------------------------------------------------------------------------
   2166 
   2167     Function: GetLumaEdgeThresholds
   2168 
   2169         Functional description:
   2170             Compute alpha, beta and tc0 thresholds for inner, left and top
   2171             luma edges of a macroblock.
   2172 
   2173 ------------------------------------------------------------------------------*/
   2174 void GetLumaEdgeThresholds(
   2175     mbStorage_t *mb,
   2176     u8 (*alpha)[2],
   2177     u8 (*beta)[2],
   2178     u8 (*threshold)[16],
   2179     u8 (*bs)[16],
   2180     u32 filteringFlags )
   2181 {
   2182 
   2183 /* Variables */
   2184 
   2185     u32 indexA, indexB;
   2186     u32 qpAv, qp, qpTmp;
   2187     u32 i;
   2188 
   2189 /* Code */
   2190 
   2191     ASSERT(threshold);
   2192     ASSERT(bs);
   2193     ASSERT(beta);
   2194     ASSERT(alpha);
   2195     ASSERT(mb);
   2196 
   2197     qp = mb->qpY;
   2198 
   2199     indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
   2200     indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
   2201 
   2202     /* Internal edge values */
   2203     alpha[0][1] = alphas[indexA];
   2204     alpha[1][1] = alphas[indexA];
   2205     alpha[1][0] = alphas[indexA];
   2206     alpha[0][0] = alphas[indexA];
   2207     beta[0][1] = betas[indexB];
   2208     beta[1][1] = betas[indexB];
   2209     beta[1][0] = betas[indexB];
   2210     beta[0][0] = betas[indexB];
   2211 
   2212     /* vertical scan order */
   2213     for (i = 0; i < 2; i++)
   2214     {
   2215         u32 t1, t2;
   2216 
   2217         t1 = bs[i][0];
   2218         t2 = bs[i][1];
   2219         threshold[i][0]  = (t1) ? tc0[indexA][t1] : 0;
   2220         t1 = bs[i][2];
   2221         threshold[i][1]  = (t2) ? tc0[indexA][t2] : 0;
   2222         t2 = bs[i][3];
   2223         threshold[i][2]  = (t1) ? tc0[indexA][t1] : 0;
   2224         t1 = bs[i][4];
   2225         threshold[i][3]  = (t2) ? tc0[indexA][t2] : 0;
   2226         t2 = bs[i][5];
   2227         threshold[i][4]  = (t1) ? tc0[indexA][t1] : 0;
   2228         t1 = bs[i][6];
   2229         threshold[i][5]  = (t2) ? tc0[indexA][t2] : 0;
   2230         t2 = bs[i][7];
   2231         threshold[i][6]  = (t1) ? tc0[indexA][t1] : 0;
   2232         t1 = bs[i][8];
   2233         threshold[i][7]  = (t2) ? tc0[indexA][t2] : 0;
   2234         t2 = bs[i][9];
   2235         threshold[i][8]  = (t1) ? tc0[indexA][t1] : 0;
   2236         t1 = bs[i][10];
   2237         threshold[i][9]  = (t2) ? tc0[indexA][t2] : 0;
   2238         t2 = bs[i][11];
   2239         threshold[i][10] = (t1) ? tc0[indexA][t1] : 0;
   2240         t1 = bs[i][12];
   2241         threshold[i][11] = (t2) ? tc0[indexA][t2] : 0;
   2242         t2 = bs[i][13];
   2243         threshold[i][12] = (t1) ? tc0[indexA][t1] : 0;
   2244         t1 = bs[i][14];
   2245         threshold[i][13] = (t2) ? tc0[indexA][t2] : 0;
   2246         t2 = bs[i][15];
   2247         threshold[i][14] = (t1) ? tc0[indexA][t1] : 0;
   2248         threshold[i][15] = (t2) ? tc0[indexA][t2] : 0;
   2249     }
   2250 
   2251     if (filteringFlags & FILTER_TOP_EDGE)
   2252     {
   2253         qpTmp = mb->mbB->qpY;
   2254         if (qpTmp != qp)
   2255         {
   2256             u32 t1, t2, t3, t4;
   2257             qpAv = (qp + qpTmp + 1) >> 1;
   2258 
   2259             indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
   2260             indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
   2261 
   2262             alpha[1][0] = alphas[indexA];
   2263             beta[1][0] = betas[indexB];
   2264             t1 = bs[1][0];
   2265             t2 = bs[1][1];
   2266             t3 = bs[1][2];
   2267             t4 = bs[1][3];
   2268             threshold[1][0] = (t1 && (t1 < 4)) ? tc0[indexA][t1] : 0;
   2269             threshold[1][1] = (t2 && (t2 < 4)) ? tc0[indexA][t2] : 0;
   2270             threshold[1][2] = (t3 && (t3 < 4)) ? tc0[indexA][t3] : 0;
   2271             threshold[1][3] = (t4 && (t4 < 4)) ? tc0[indexA][t4] : 0;
   2272         }
   2273     }
   2274     if (filteringFlags & FILTER_LEFT_EDGE)
   2275     {
   2276         qpTmp = mb->mbA->qpY;
   2277         if (qpTmp != qp)
   2278         {
   2279             qpAv = (qp + qpTmp + 1) >> 1;
   2280 
   2281             indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
   2282             indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
   2283 
   2284             alpha[0][0] = alphas[indexA];
   2285             beta[0][0] = betas[indexB];
   2286             threshold[0][0] = (bs[0][0] && (bs[0][0] < 4)) ? tc0[indexA][bs[0][0]] : 0;
   2287             threshold[0][1] = (bs[0][1] && (bs[0][1] < 4)) ? tc0[indexA][bs[0][1]] : 0;
   2288             threshold[0][2] = (bs[0][2] && (bs[0][2] < 4)) ? tc0[indexA][bs[0][2]] : 0;
   2289             threshold[0][3] = (bs[0][3] && (bs[0][3] < 4)) ? tc0[indexA][bs[0][3]] : 0;
   2290         }
   2291     }
   2292 
   2293 }
   2294 
   2295 /*------------------------------------------------------------------------------
   2296 
   2297     Function: GetChromaEdgeThresholds
   2298 
   2299         Functional description:
   2300             Compute alpha, beta and tc0 thresholds for inner, left and top
   2301             chroma edges of a macroblock.
   2302 
   2303 ------------------------------------------------------------------------------*/
   2304 void GetChromaEdgeThresholds(
   2305     mbStorage_t *mb,
   2306     u8 (*alpha)[2],
   2307     u8 (*beta)[2],
   2308     u8 (*threshold)[8],
   2309     u8 (*bs)[16],
   2310     u32 filteringFlags,
   2311     i32 chromaQpIndexOffset)
   2312 {
   2313 
   2314 /* Variables */
   2315 
   2316     u32 indexA, indexB;
   2317     u32 qpAv, qp, qpTmp;
   2318     u32 i;
   2319 
   2320 /* Code */
   2321 
   2322     ASSERT(threshold);
   2323     ASSERT(bs);
   2324     ASSERT(beta);
   2325     ASSERT(alpha);
   2326     ASSERT(mb);
   2327     ASSERT(mb);
   2328 
   2329     qp = mb->qpY;
   2330     qp = h264bsdQpC[CLIP3(0, 51, (i32)qp + chromaQpIndexOffset)];
   2331 
   2332     indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
   2333     indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
   2334 
   2335     alpha[0][1] = alphas[indexA];
   2336     alpha[1][1] = alphas[indexA];
   2337     alpha[1][0] = alphas[indexA];
   2338     alpha[0][0] = alphas[indexA];
   2339     beta[0][1] = betas[indexB];
   2340     beta[1][1] = betas[indexB];
   2341     beta[1][0] = betas[indexB];
   2342     beta[0][0] = betas[indexB];
   2343 
   2344     for (i = 0; i < 2; i++)
   2345     {
   2346         u32 t1, t2;
   2347 
   2348         t1 = bs[i][0];
   2349         t2 = bs[i][1];
   2350         threshold[i][0]  = (t1) ? tc0[indexA][t1] : 0;
   2351         t1 = bs[i][2];
   2352         threshold[i][1]  = (t2) ? tc0[indexA][t2] : 0;
   2353         t2 = bs[i][3];
   2354         threshold[i][2]  = (t1) ? tc0[indexA][t1] : 0;
   2355         t1 = bs[i][8];
   2356         threshold[i][3]  = (t2) ? tc0[indexA][t2] : 0;
   2357         t2 = bs[i][9];
   2358         threshold[i][4]  = (t1) ? tc0[indexA][t1] : 0;
   2359         t1 = bs[i][10];
   2360         threshold[i][5]  = (t2) ? tc0[indexA][t2] : 0;
   2361         t2 = bs[i][11];
   2362         threshold[i][6]  = (t1) ? tc0[indexA][t1] : 0;
   2363         threshold[i][7]  = (t2) ? tc0[indexA][t2] : 0;
   2364     }
   2365 
   2366     if (filteringFlags & FILTER_TOP_EDGE)
   2367     {
   2368         qpTmp = mb->mbB->qpY;
   2369         if (qpTmp != mb->qpY)
   2370         {
   2371             u32 t1, t2, t3, t4;
   2372             qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
   2373             qpAv = (qp + qpTmp + 1) >> 1;
   2374 
   2375             indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
   2376             indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
   2377 
   2378             alpha[1][0] = alphas[indexA];
   2379             beta[1][0] = betas[indexB];
   2380 
   2381             t1 = bs[1][0];
   2382             t2 = bs[1][1];
   2383             t3 = bs[1][2];
   2384             t4 = bs[1][3];
   2385             threshold[1][0] = (t1) ? tc0[indexA][t1] : 0;
   2386             threshold[1][1] = (t2) ? tc0[indexA][t2] : 0;
   2387             threshold[1][2] = (t3) ? tc0[indexA][t3] : 0;
   2388             threshold[1][3] = (t4) ? tc0[indexA][t4] : 0;
   2389         }
   2390     }
   2391     if (filteringFlags & FILTER_LEFT_EDGE)
   2392     {
   2393         qpTmp = mb->mbA->qpY;
   2394         if (qpTmp != mb->qpY)
   2395         {
   2396 
   2397             qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
   2398             qpAv = (qp + qpTmp + 1) >> 1;
   2399 
   2400             indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
   2401             indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
   2402 
   2403             alpha[0][0] = alphas[indexA];
   2404             beta[0][0] = betas[indexB];
   2405             threshold[0][0] = (bs[0][0]) ? tc0[indexA][bs[0][0]] : 0;
   2406             threshold[0][1] = (bs[0][1]) ? tc0[indexA][bs[0][1]] : 0;
   2407             threshold[0][2] = (bs[0][2]) ? tc0[indexA][bs[0][2]] : 0;
   2408             threshold[0][3] = (bs[0][3]) ? tc0[indexA][bs[0][3]] : 0;
   2409         }
   2410     }
   2411 
   2412 }
   2413 
   2414 #endif /* H264DEC_OMXDL */
   2415 
   2416 /*lint +e701 +e702 */
   2417 
   2418