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           h264bsdIntraPrediction
     27           h264bsdGetNeighbourPels
     28           h264bsdIntra16x16Prediction
     29           h264bsdIntra4x4Prediction
     30           h264bsdIntraChromaPrediction
     31           h264bsdAddResidual
     32           Intra16x16VerticalPrediction
     33           Intra16x16HorizontalPrediction
     34           Intra16x16DcPrediction
     35           Intra16x16PlanePrediction
     36           IntraChromaDcPrediction
     37           IntraChromaHorizontalPrediction
     38           IntraChromaVerticalPrediction
     39           IntraChromaPlanePrediction
     40           Get4x4NeighbourPels
     41           Write4x4To16x16
     42           Intra4x4VerticalPrediction
     43           Intra4x4HorizontalPrediction
     44           Intra4x4DcPrediction
     45           Intra4x4DiagonalDownLeftPrediction
     46           Intra4x4DiagonalDownRightPrediction
     47           Intra4x4VerticalRightPrediction
     48           Intra4x4HorizontalDownPrediction
     49           Intra4x4VerticalLeftPrediction
     50           Intra4x4HorizontalUpPrediction
     51           DetermineIntra4x4PredMode
     52 
     53 ------------------------------------------------------------------------------*/
     54 
     55 /*------------------------------------------------------------------------------
     56     1. Include headers
     57 ------------------------------------------------------------------------------*/
     58 
     59 #include "h264bsd_intra_prediction.h"
     60 #include "h264bsd_util.h"
     61 #include "h264bsd_macroblock_layer.h"
     62 #include "h264bsd_neighbour.h"
     63 #include "h264bsd_image.h"
     64 
     65 #ifdef H264DEC_OMXDL
     66 #include "omxtypes.h"
     67 #include "omxVC.h"
     68 #endif /* H264DEC_OMXDL */
     69 
     70 /*------------------------------------------------------------------------------
     71     2. External compiler flags
     72 --------------------------------------------------------------------------------
     73 
     74 --------------------------------------------------------------------------------
     75     3. Module defines
     76 ------------------------------------------------------------------------------*/
     77 
     78 /* Switch off the following Lint messages for this file:
     79  * Info 702: Shift right of signed quantity (int)
     80  */
     81 /*lint -e702 */
     82 
     83 
     84 /* x- and y-coordinates for each block */
     85 const u32 h264bsdBlockX[16] =
     86     { 0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12 };
     87 const u32 h264bsdBlockY[16] =
     88     { 0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12 };
     89 
     90 const u8 h264bsdClip[1280] =
     91 {
     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,0,0,0,0,0,0,0,0,
     93     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     94     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     95     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     96     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     97     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     98     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
     99     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    100     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    101     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    102     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    103     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    104     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    105     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    106     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    107     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    108     0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
    109     16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
    110     32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
    111     48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
    112     64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
    113     80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
    114     96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
    115     112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
    116     128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
    117     144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
    118     160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
    119     176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
    120     192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
    121     208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
    122     224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
    123     240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,
    124     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    125     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    126     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    127     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    128     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    129     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    130     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    131     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    132     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    133     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    134     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    135     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    136     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    137     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    138     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    139     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    140     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    141     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    142     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    143     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    144     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    145     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    146     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    147     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    148     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    149     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    150     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    151     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    152     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    153     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    154     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    155     255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
    156 };
    157 
    158 #ifndef H264DEC_OMXDL
    159 /*------------------------------------------------------------------------------
    160     4. Local function prototypes
    161 ------------------------------------------------------------------------------*/
    162 static void Get4x4NeighbourPels(u8 *a, u8 *l, u8 *data, u8 *above, u8 *left,
    163     u32 blockNum);
    164 static void Intra16x16VerticalPrediction(u8 *data, u8 *above);
    165 static void Intra16x16HorizontalPrediction(u8 *data, u8 *left);
    166 static void Intra16x16DcPrediction(u8 *data, u8 *above, u8 *left,
    167     u32 A, u32 B);
    168 static void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left);
    169 static void IntraChromaDcPrediction(u8 *data, u8 *above, u8 *left,
    170     u32 A, u32 B);
    171 static void IntraChromaHorizontalPrediction(u8 *data, u8 *left);
    172 static void IntraChromaVerticalPrediction(u8 *data, u8 *above);
    173 static void IntraChromaPlanePrediction(u8 *data, u8 *above, u8 *left);
    174 
    175 static void Intra4x4VerticalPrediction(u8 *data, u8 *above);
    176 static void Intra4x4HorizontalPrediction(u8 *data, u8 *left);
    177 static void Intra4x4DcPrediction(u8 *data, u8 *above, u8 *left, u32 A, u32 B);
    178 static void Intra4x4DiagonalDownLeftPrediction(u8 *data, u8 *above);
    179 static void Intra4x4DiagonalDownRightPrediction(u8 *data, u8 *above, u8 *left);
    180 static void Intra4x4VerticalRightPrediction(u8 *data, u8 *above, u8 *left);
    181 static void Intra4x4HorizontalDownPrediction(u8 *data, u8 *above, u8 *left);
    182 static void Intra4x4VerticalLeftPrediction(u8 *data, u8 *above);
    183 static void Intra4x4HorizontalUpPrediction(u8 *data, u8 *left);
    184 void h264bsdAddResidual(u8 *data, i32 *residual, u32 blockNum);
    185 
    186 static void Write4x4To16x16(u8 *data, u8 *data4x4, u32 blockNum);
    187 #endif /* H264DEC_OMXDL */
    188 
    189 static u32 DetermineIntra4x4PredMode(macroblockLayer_t *pMbLayer,
    190     u32 available, neighbour_t *nA, neighbour_t *nB, u32 index,
    191     mbStorage_t *nMbA, mbStorage_t *nMbB);
    192 
    193 
    194 #ifdef H264DEC_OMXDL
    195 
    196 /*------------------------------------------------------------------------------
    197 
    198     Function: h264bsdIntra16x16Prediction
    199 
    200         Functional description:
    201           Perform intra 16x16 prediction mode for luma pixels and add
    202           residual into prediction. The resulting luma pixels are
    203           stored in macroblock array 'data'.
    204 
    205 ------------------------------------------------------------------------------*/
    206 u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, u8 *ptr,
    207                                 u32 width, u32 constrainedIntraPred)
    208 {
    209 
    210 /* Variables */
    211 
    212     u32 availableA, availableB, availableD;
    213     OMXResult omxRes;
    214 
    215 /* Code */
    216     ASSERT(pMb);
    217     ASSERT(data);
    218     ASSERT(ptr);
    219     ASSERT(h264bsdPredModeIntra16x16(pMb->mbType) < 4);
    220 
    221     availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
    222     if (availableA && constrainedIntraPred &&
    223        (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
    224         availableA = HANTRO_FALSE;
    225     availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
    226     if (availableB && constrainedIntraPred &&
    227        (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
    228         availableB = HANTRO_FALSE;
    229     availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
    230     if (availableD && constrainedIntraPred &&
    231        (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
    232         availableD = HANTRO_FALSE;
    233 
    234     omxRes = omxVCM4P10_PredictIntra_16x16( (ptr-1),
    235                                     (ptr - width),
    236                                     (ptr - width-1),
    237                                     data,
    238                                     (i32)width,
    239                                     16,
    240                                     (OMXVCM4P10Intra16x16PredMode)
    241                                     h264bsdPredModeIntra16x16(pMb->mbType),
    242                                     (i32)(availableB + (availableA<<1) +
    243                                      (availableD<<5)) );
    244     if (omxRes != OMX_Sts_NoErr)
    245         return HANTRO_NOK;
    246     else
    247         return(HANTRO_OK);
    248 }
    249 
    250 /*------------------------------------------------------------------------------
    251 
    252     Function: h264bsdIntra4x4Prediction
    253 
    254         Functional description:
    255           Perform intra 4x4 prediction for luma pixels and add residual
    256           into prediction. The resulting luma pixels are stored in
    257           macroblock array 'data'. The intra 4x4 prediction mode for each
    258           block is stored in 'pMb' structure.
    259 
    260 ------------------------------------------------------------------------------*/
    261 u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
    262                               macroblockLayer_t *mbLayer,
    263                               u8 *ptr, u32 width,
    264                               u32 constrainedIntraPred, u32 block)
    265 {
    266 
    267 /* Variables */
    268     u32 mode;
    269     neighbour_t neighbour, neighbourB;
    270     mbStorage_t *nMb, *nMb2;
    271     u32 availableA, availableB, availableC, availableD;
    272 
    273     OMXResult omxRes;
    274     u32 x, y;
    275     u8 *l, *a, *al;
    276 /* Code */
    277     ASSERT(pMb);
    278     ASSERT(data);
    279     ASSERT(mbLayer);
    280     ASSERT(ptr);
    281     ASSERT(pMb->intra4x4PredMode[block] < 9);
    282 
    283     neighbour = *h264bsdNeighbour4x4BlockA(block);
    284     nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
    285     availableA = h264bsdIsNeighbourAvailable(pMb, nMb);
    286     if (availableA && constrainedIntraPred &&
    287        ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
    288     {
    289         availableA = HANTRO_FALSE;
    290     }
    291 
    292     neighbourB = *h264bsdNeighbour4x4BlockB(block);
    293     nMb2 = h264bsdGetNeighbourMb(pMb, neighbourB.mb);
    294     availableB = h264bsdIsNeighbourAvailable(pMb, nMb2);
    295     if (availableB && constrainedIntraPred &&
    296        ( h264bsdMbPartPredMode(nMb2->mbType) == PRED_MODE_INTER) )
    297     {
    298         availableB = HANTRO_FALSE;
    299     }
    300 
    301     mode = DetermineIntra4x4PredMode(mbLayer,
    302         (u32)(availableA && availableB),
    303         &neighbour, &neighbourB, block, nMb, nMb2);
    304     pMb->intra4x4PredMode[block] = (u8)mode;
    305 
    306     neighbour = *h264bsdNeighbour4x4BlockC(block);
    307     nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
    308     availableC = h264bsdIsNeighbourAvailable(pMb, nMb);
    309     if (availableC && constrainedIntraPred &&
    310        ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
    311     {
    312         availableC = HANTRO_FALSE;
    313     }
    314 
    315     neighbour = *h264bsdNeighbour4x4BlockD(block);
    316     nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
    317     availableD = h264bsdIsNeighbourAvailable(pMb, nMb);
    318     if (availableD && constrainedIntraPred &&
    319        ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
    320     {
    321         availableD = HANTRO_FALSE;
    322     }
    323 
    324     x = h264bsdBlockX[block];
    325     y = h264bsdBlockY[block];
    326 
    327     if (y == 0)
    328         a = ptr - width + x;
    329     else
    330         a = data-16;
    331 
    332     if (x == 0)
    333         l = ptr + y * width -1;
    334     else
    335     {
    336         l = data-1;
    337         width = 16;
    338     }
    339 
    340     if (x == 0)
    341         al = l-width;
    342     else
    343         al = a-1;
    344 
    345     omxRes = omxVCM4P10_PredictIntra_4x4( l,
    346                                           a,
    347                                           al,
    348                                           data,
    349                                           (i32)width,
    350                                           16,
    351                                           (OMXVCM4P10Intra4x4PredMode)mode,
    352                                           (i32)(availableB +
    353                                           (availableA<<1) +
    354                                           (availableD<<5) +
    355                                           (availableC<<6)) );
    356     if (omxRes != OMX_Sts_NoErr)
    357         return HANTRO_NOK;
    358 
    359     return(HANTRO_OK);
    360 
    361 }
    362 
    363 /*------------------------------------------------------------------------------
    364 
    365     Function: h264bsdIntraChromaPrediction
    366 
    367         Functional description:
    368           Perform intra prediction for chroma pixels and add residual
    369           into prediction. The resulting chroma pixels are stored in 'data'.
    370 
    371 ------------------------------------------------------------------------------*/
    372 u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, image_t *image,
    373                                         u32 predMode, u32 constrainedIntraPred)
    374 {
    375 
    376 /* Variables */
    377 
    378     u32 availableA, availableB, availableD;
    379     OMXResult omxRes;
    380     u8 *ptr;
    381     u32 width;
    382 
    383 /* Code */
    384     ASSERT(pMb);
    385     ASSERT(data);
    386     ASSERT(image);
    387     ASSERT(predMode < 4);
    388 
    389     availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
    390     if (availableA && constrainedIntraPred &&
    391        (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
    392         availableA = HANTRO_FALSE;
    393     availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
    394     if (availableB && constrainedIntraPred &&
    395        (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
    396         availableB = HANTRO_FALSE;
    397     availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
    398     if (availableD && constrainedIntraPred &&
    399        (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
    400         availableD = HANTRO_FALSE;
    401 
    402     ptr = image->cb;
    403     width = image->width*8;
    404 
    405     omxRes = omxVCM4P10_PredictIntraChroma_8x8( (ptr-1),
    406                                                 (ptr - width),
    407                                                 (ptr - width -1),
    408                                                 data,
    409                                                 (i32)width,
    410                                                 8,
    411                                                 (OMXVCM4P10IntraChromaPredMode)
    412                                                 predMode,
    413                                                 (i32)(availableB +
    414                                                  (availableA<<1) +
    415                                                  (availableD<<5)) );
    416     if (omxRes != OMX_Sts_NoErr)
    417         return HANTRO_NOK;
    418 
    419     /* advance pointers */
    420     data += 64;
    421     ptr = image->cr;
    422 
    423     omxRes = omxVCM4P10_PredictIntraChroma_8x8( (ptr-1),
    424                                                 (ptr - width),
    425                                                 (ptr - width -1),
    426                                                 data,
    427                                                 (i32)width,
    428                                                 8,
    429                                                 (OMXVCM4P10IntraChromaPredMode)
    430                                                 predMode,
    431                                                 (i32)(availableB +
    432                                                  (availableA<<1) +
    433                                                  (availableD<<5)) );
    434     if (omxRes != OMX_Sts_NoErr)
    435         return HANTRO_NOK;
    436 
    437     return(HANTRO_OK);
    438 
    439 }
    440 
    441 
    442 #else /* H264DEC_OMXDL */
    443 
    444 
    445 /*------------------------------------------------------------------------------
    446 
    447     Function: h264bsdIntraPrediction
    448 
    449         Functional description:
    450           Processes one intra macroblock. Performs intra prediction using
    451           specified prediction mode. Writes the final macroblock
    452           (prediction + residual) into the output image (image)
    453 
    454         Inputs:
    455           pMb           pointer to macroblock specific information
    456           mbLayer       pointer to current macroblock data from stream
    457           image         pointer to output image
    458           mbNum         current macroblock number
    459           constrainedIntraPred  flag specifying if neighbouring inter
    460                                 macroblocks are used in intra prediction
    461           data          pointer where output macroblock will be stored
    462 
    463         Outputs:
    464           pMb           structure is updated with current macroblock
    465           image         current macroblock is written into image
    466           data          current macroblock is stored here
    467 
    468         Returns:
    469           HANTRO_OK     success
    470           HANTRO_NOK    error in intra prediction
    471 
    472 ------------------------------------------------------------------------------*/
    473 u32 h264bsdIntraPrediction(mbStorage_t *pMb, macroblockLayer_t *mbLayer,
    474     image_t *image, u32 mbNum, u32 constrainedIntraPred, u8 *data)
    475 {
    476 
    477 /* Variables */
    478 
    479     /* pelAbove and pelLeft contain samples above and left to the current
    480      * macroblock. Above array contains also sample above-left to the current
    481      * mb as well as 4 samples above-right to the current mb (latter only for
    482      * luma) */
    483     /* lumD + lumB + lumC + cbD + cbB + crD + crB */
    484     u8 pelAbove[1 + 16 + 4 + 1 + 8 + 1 + 8];
    485     /* lumA + cbA + crA */
    486     u8 pelLeft[16 + 8 + 8];
    487     u32 tmp;
    488 
    489 /* Code */
    490 
    491     ASSERT(pMb);
    492     ASSERT(image);
    493     ASSERT(mbNum < image->width * image->height);
    494     ASSERT(h264bsdMbPartPredMode(pMb->mbType) != PRED_MODE_INTER);
    495 
    496     h264bsdGetNeighbourPels(image, pelAbove, pelLeft, mbNum);
    497 
    498     if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA16x16)
    499     {
    500         tmp = h264bsdIntra16x16Prediction(pMb, data, mbLayer->residual.level,
    501             pelAbove, pelLeft, constrainedIntraPred);
    502         if (tmp != HANTRO_OK)
    503             return(tmp);
    504     }
    505     else
    506     {
    507         tmp = h264bsdIntra4x4Prediction(pMb, data, mbLayer,
    508             pelAbove, pelLeft, constrainedIntraPred);
    509         if (tmp != HANTRO_OK)
    510             return(tmp);
    511     }
    512 
    513     tmp = h264bsdIntraChromaPrediction(pMb, data + 256,
    514             mbLayer->residual.level+16, pelAbove + 21, pelLeft + 16,
    515             mbLayer->mbPred.intraChromaPredMode, constrainedIntraPred);
    516     if (tmp != HANTRO_OK)
    517         return(tmp);
    518 
    519     /* if decoded flag > 1 -> mb has already been successfully decoded and
    520      * written to output -> do not write again */
    521     if (pMb->decoded > 1)
    522         return HANTRO_OK;
    523 
    524     h264bsdWriteMacroblock(image, data);
    525 
    526     return(HANTRO_OK);
    527 
    528 }
    529 
    530 /*------------------------------------------------------------------------------
    531 
    532     Function: h264bsdGetNeighbourPels
    533 
    534         Functional description:
    535           Get pixel values from neighbouring macroblocks into 'above'
    536           and 'left' arrays.
    537 
    538 ------------------------------------------------------------------------------*/
    539 
    540 void h264bsdGetNeighbourPels(image_t *image, u8 *above, u8 *left, u32 mbNum)
    541 {
    542 
    543 /* Variables */
    544 
    545     u32 i;
    546     u32 width, picSize;
    547     u8 *ptr, *tmp;
    548     u32 row, col;
    549 
    550 /* Code */
    551 
    552     ASSERT(image);
    553     ASSERT(above);
    554     ASSERT(left);
    555     ASSERT(mbNum < image->width * image->height);
    556 
    557     if (!mbNum)
    558         return;
    559 
    560     width = image->width;
    561     picSize = width * image->height;
    562     row = mbNum / width;
    563     col = mbNum - row * width;
    564 
    565     width *= 16;
    566     ptr = image->data + row * 16 * width  + col * 16;
    567 
    568     /* note that luma samples above-right to current macroblock do not make
    569      * sense when current mb is the right-most mb in a row. Same applies to
    570      * sample above-left if col is zero. However, usage of pels in prediction
    571      * is controlled by neighbour availability information in actual prediction
    572      * process */
    573     if (row)
    574     {
    575         tmp = ptr - (width + 1);
    576         for (i = 21; i--;)
    577             *above++ = *tmp++;
    578     }
    579 
    580     if (col)
    581     {
    582         ptr--;
    583         for (i = 16; i--; ptr+=width)
    584             *left++ = *ptr;
    585     }
    586 
    587     width >>= 1;
    588     ptr = image->data + picSize * 256 + row * 8 * width  + col * 8;
    589 
    590     if (row)
    591     {
    592         tmp = ptr - (width + 1);
    593         for (i = 9; i--;)
    594             *above++ = *tmp++;
    595         tmp += (picSize * 64) - 9;
    596         for (i = 9; i--;)
    597             *above++ = *tmp++;
    598     }
    599 
    600     if (col)
    601     {
    602         ptr--;
    603         for (i = 8; i--; ptr+=width)
    604             *left++ = *ptr;
    605         ptr += (picSize * 64) - 8 * width;
    606         for (i = 8; i--; ptr+=width)
    607             *left++ = *ptr;
    608     }
    609 }
    610 
    611 /*------------------------------------------------------------------------------
    612 
    613     Function: Intra16x16Prediction
    614 
    615         Functional description:
    616           Perform intra 16x16 prediction mode for luma pixels and add
    617           residual into prediction. The resulting luma pixels are
    618           stored in macroblock array 'data'.
    619 
    620 ------------------------------------------------------------------------------*/
    621 
    622 u32 h264bsdIntra16x16Prediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
    623                                 u8 *above, u8 *left, u32 constrainedIntraPred)
    624 {
    625 
    626 /* Variables */
    627 
    628     u32 i;
    629     u32 availableA, availableB, availableD;
    630 
    631 /* Code */
    632 
    633     ASSERT(data);
    634     ASSERT(residual);
    635     ASSERT(above);
    636     ASSERT(left);
    637     ASSERT(h264bsdPredModeIntra16x16(pMb->mbType) < 4);
    638 
    639     availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
    640     if (availableA && constrainedIntraPred &&
    641        (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
    642         availableA = HANTRO_FALSE;
    643     availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
    644     if (availableB && constrainedIntraPred &&
    645        (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
    646         availableB = HANTRO_FALSE;
    647     availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
    648     if (availableD && constrainedIntraPred &&
    649        (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
    650         availableD = HANTRO_FALSE;
    651 
    652     switch(h264bsdPredModeIntra16x16(pMb->mbType))
    653     {
    654         case 0: /* Intra_16x16_Vertical */
    655             if (!availableB)
    656                 return(HANTRO_NOK);
    657             Intra16x16VerticalPrediction(data, above+1);
    658             break;
    659 
    660         case 1: /* Intra_16x16_Horizontal */
    661             if (!availableA)
    662                 return(HANTRO_NOK);
    663             Intra16x16HorizontalPrediction(data, left);
    664             break;
    665 
    666         case 2: /* Intra_16x16_DC */
    667             Intra16x16DcPrediction(data, above+1, left, availableA, availableB);
    668             break;
    669 
    670         default: /* case 3: Intra_16x16_Plane */
    671             if (!availableA || !availableB || !availableD)
    672                 return(HANTRO_NOK);
    673             Intra16x16PlanePrediction(data, above+1, left);
    674             break;
    675     }
    676     /* add residual */
    677     for (i = 0; i < 16; i++)
    678         h264bsdAddResidual(data, residual[i], i);
    679 
    680     return(HANTRO_OK);
    681 
    682 }
    683 
    684 /*------------------------------------------------------------------------------
    685 
    686     Function: Intra4x4Prediction
    687 
    688         Functional description:
    689           Perform intra 4x4 prediction for luma pixels and add residual
    690           into prediction. The resulting luma pixels are stored in
    691           macroblock array 'data'. The intra 4x4 prediction mode for each
    692           block is stored in 'pMb' structure.
    693 
    694 ------------------------------------------------------------------------------*/
    695 
    696 u32 h264bsdIntra4x4Prediction(mbStorage_t *pMb, u8 *data,
    697                               macroblockLayer_t *mbLayer, u8 *above,
    698                               u8 *left, u32 constrainedIntraPred)
    699 {
    700 
    701 /* Variables */
    702 
    703     u32 block;
    704     u32 mode;
    705     neighbour_t neighbour, neighbourB;
    706     mbStorage_t *nMb, *nMb2;
    707     u8 a[1 + 4 + 4], l[1 + 4];
    708     u32 data4x4[4];
    709     u32 availableA, availableB, availableC, availableD;
    710 
    711 /* Code */
    712 
    713     ASSERT(data);
    714     ASSERT(mbLayer);
    715     ASSERT(above);
    716     ASSERT(left);
    717 
    718     for (block = 0; block < 16; block++)
    719     {
    720 
    721         ASSERT(pMb->intra4x4PredMode[block] < 9);
    722 
    723         neighbour = *h264bsdNeighbour4x4BlockA(block);
    724         nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
    725         availableA = h264bsdIsNeighbourAvailable(pMb, nMb);
    726         if (availableA && constrainedIntraPred &&
    727            ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
    728         {
    729             availableA = HANTRO_FALSE;
    730         }
    731 
    732         neighbourB = *h264bsdNeighbour4x4BlockB(block);
    733         nMb2 = h264bsdGetNeighbourMb(pMb, neighbourB.mb);
    734         availableB = h264bsdIsNeighbourAvailable(pMb, nMb2);
    735         if (availableB && constrainedIntraPred &&
    736            ( h264bsdMbPartPredMode(nMb2->mbType) == PRED_MODE_INTER) )
    737         {
    738             availableB = HANTRO_FALSE;
    739         }
    740 
    741         mode = DetermineIntra4x4PredMode(mbLayer,
    742             (u32)(availableA && availableB),
    743             &neighbour, &neighbourB, block, nMb, nMb2);
    744         pMb->intra4x4PredMode[block] = (u8)mode;
    745 
    746         neighbour = *h264bsdNeighbour4x4BlockC(block);
    747         nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
    748         availableC = h264bsdIsNeighbourAvailable(pMb, nMb);
    749         if (availableC && constrainedIntraPred &&
    750            ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
    751         {
    752             availableC = HANTRO_FALSE;
    753         }
    754 
    755         neighbour = *h264bsdNeighbour4x4BlockD(block);
    756         nMb = h264bsdGetNeighbourMb(pMb, neighbour.mb);
    757         availableD = h264bsdIsNeighbourAvailable(pMb, nMb);
    758         if (availableD && constrainedIntraPred &&
    759            ( h264bsdMbPartPredMode(nMb->mbType) == PRED_MODE_INTER) )
    760         {
    761             availableD = HANTRO_FALSE;
    762         }
    763 
    764         Get4x4NeighbourPels(a, l, data, above, left, block);
    765 
    766         switch(mode)
    767         {
    768             case 0: /* Intra_4x4_Vertical */
    769                 if (!availableB)
    770                     return(HANTRO_NOK);
    771                 Intra4x4VerticalPrediction((u8*)data4x4, a + 1);
    772                 break;
    773             case 1: /* Intra_4x4_Horizontal */
    774                 if (!availableA)
    775                     return(HANTRO_NOK);
    776                 Intra4x4HorizontalPrediction((u8*)data4x4, l + 1);
    777                 break;
    778             case 2: /* Intra_4x4_DC */
    779                 Intra4x4DcPrediction((u8*)data4x4, a + 1, l + 1,
    780                     availableA, availableB);
    781                 break;
    782             case 3: /* Intra_4x4_Diagonal_Down_Left */
    783                 if (!availableB)
    784                     return(HANTRO_NOK);
    785                 if (!availableC)
    786                 {
    787                     a[5] = a[6] = a[7] = a[8] = a[4];
    788                 }
    789                 Intra4x4DiagonalDownLeftPrediction((u8*)data4x4, a + 1);
    790                 break;
    791             case 4: /* Intra_4x4_Diagonal_Down_Right */
    792                 if (!availableA || !availableB || !availableD)
    793                     return(HANTRO_NOK);
    794                 Intra4x4DiagonalDownRightPrediction((u8*)data4x4, a + 1, l + 1);
    795                 break;
    796             case 5: /* Intra_4x4_Vertical_Right */
    797                 if (!availableA || !availableB || !availableD)
    798                     return(HANTRO_NOK);
    799                 Intra4x4VerticalRightPrediction((u8*)data4x4, a + 1, l + 1);
    800                 break;
    801             case 6: /* Intra_4x4_Horizontal_Down */
    802                 if (!availableA || !availableB || !availableD)
    803                     return(HANTRO_NOK);
    804                 Intra4x4HorizontalDownPrediction((u8*)data4x4, a + 1, l + 1);
    805                 break;
    806             case 7: /* Intra_4x4_Vertical_Left */
    807                 if (!availableB)
    808                     return(HANTRO_NOK);
    809                 if (!availableC)
    810                 {
    811                     a[5] = a[6] = a[7] = a[8] = a[4];
    812                 }
    813                 Intra4x4VerticalLeftPrediction((u8*)data4x4, a + 1);
    814                 break;
    815             default: /* case 8 Intra_4x4_Horizontal_Up */
    816                 if (!availableA)
    817                     return(HANTRO_NOK);
    818                 Intra4x4HorizontalUpPrediction((u8*)data4x4, l + 1);
    819                 break;
    820         }
    821 
    822         Write4x4To16x16(data, (u8*)data4x4, block);
    823         h264bsdAddResidual(data, mbLayer->residual.level[block], block);
    824     }
    825 
    826     return(HANTRO_OK);
    827 
    828 }
    829 
    830 /*------------------------------------------------------------------------------
    831 
    832     Function: IntraChromaPrediction
    833 
    834         Functional description:
    835           Perform intra prediction for chroma pixels and add residual
    836           into prediction. The resulting chroma pixels are stored in 'data'.
    837 
    838 ------------------------------------------------------------------------------*/
    839 
    840 u32 h264bsdIntraChromaPrediction(mbStorage_t *pMb, u8 *data, i32 residual[][16],
    841                     u8 *above, u8 *left, u32 predMode, u32 constrainedIntraPred)
    842 {
    843 
    844 /* Variables */
    845 
    846     u32 i, comp, block;
    847     u32 availableA, availableB, availableD;
    848 
    849 /* Code */
    850 
    851     ASSERT(data);
    852     ASSERT(residual);
    853     ASSERT(above);
    854     ASSERT(left);
    855     ASSERT(predMode < 4);
    856 
    857     availableA = h264bsdIsNeighbourAvailable(pMb, pMb->mbA);
    858     if (availableA && constrainedIntraPred &&
    859        (h264bsdMbPartPredMode(pMb->mbA->mbType) == PRED_MODE_INTER))
    860         availableA = HANTRO_FALSE;
    861     availableB = h264bsdIsNeighbourAvailable(pMb, pMb->mbB);
    862     if (availableB && constrainedIntraPred &&
    863        (h264bsdMbPartPredMode(pMb->mbB->mbType) == PRED_MODE_INTER))
    864         availableB = HANTRO_FALSE;
    865     availableD = h264bsdIsNeighbourAvailable(pMb, pMb->mbD);
    866     if (availableD && constrainedIntraPred &&
    867        (h264bsdMbPartPredMode(pMb->mbD->mbType) == PRED_MODE_INTER))
    868         availableD = HANTRO_FALSE;
    869 
    870     for (comp = 0, block = 16; comp < 2; comp++)
    871     {
    872         switch(predMode)
    873         {
    874             case 0: /* Intra_Chroma_DC */
    875                 IntraChromaDcPrediction(data, above+1, left, availableA,
    876                     availableB);
    877                 break;
    878 
    879             case 1: /* Intra_Chroma_Horizontal */
    880                 if (!availableA)
    881                     return(HANTRO_NOK);
    882                 IntraChromaHorizontalPrediction(data, left);
    883                 break;
    884 
    885             case 2: /* Intra_Chroma_Vertical */
    886                 if (!availableB)
    887                     return(HANTRO_NOK);
    888                 IntraChromaVerticalPrediction(data, above+1);
    889 
    890                 break;
    891 
    892             default: /* case 3: Intra_Chroma_Plane */
    893                 if (!availableA || !availableB || !availableD)
    894                     return(HANTRO_NOK);
    895                 IntraChromaPlanePrediction(data, above+1, left);
    896                 break;
    897         }
    898         for (i = 0; i < 4; i++, block++)
    899             h264bsdAddResidual(data, residual[i], block);
    900 
    901         /* advance pointers */
    902         data += 64;
    903         above += 9;
    904         left += 8;
    905         residual += 4;
    906     }
    907 
    908     return(HANTRO_OK);
    909 
    910 }
    911 
    912 /*------------------------------------------------------------------------------
    913 
    914     Function: h264bsdAddResidual
    915 
    916         Functional description:
    917           Add residual of a block into prediction in macroblock array 'data'.
    918           The result (residual + prediction) is stored in 'data'.
    919 
    920 ------------------------------------------------------------------------------*/
    921 #ifndef H264DEC_OMXDL
    922 void h264bsdAddResidual(u8 *data, i32 *residual, u32 blockNum)
    923 {
    924 
    925 /* Variables */
    926 
    927     u32 i;
    928     u32 x, y;
    929     u32 width;
    930     i32 tmp1, tmp2, tmp3, tmp4;
    931     u8 *tmp;
    932     const u8 *clp = h264bsdClip + 512;
    933 
    934 /* Code */
    935 
    936     ASSERT(data);
    937     ASSERT(residual);
    938     ASSERT(blockNum < 16 + 4 + 4);
    939 
    940     if (IS_RESIDUAL_EMPTY(residual))
    941         return;
    942 
    943     RANGE_CHECK_ARRAY(residual, -512, 511, 16);
    944 
    945     if (blockNum < 16)
    946     {
    947         width = 16;
    948         x = h264bsdBlockX[blockNum];
    949         y = h264bsdBlockY[blockNum];
    950     }
    951     else
    952     {
    953         width = 8;
    954         x = h264bsdBlockX[blockNum & 0x3];
    955         y = h264bsdBlockY[blockNum & 0x3];
    956     }
    957 
    958     tmp = data + y*width + x;
    959     for (i = 4; i; i--)
    960     {
    961         tmp1 = *residual++;
    962         tmp2 = tmp[0];
    963         tmp3 = *residual++;
    964         tmp4 = tmp[1];
    965 
    966         tmp[0] = clp[tmp1 + tmp2];
    967 
    968         tmp1 = *residual++;
    969         tmp2 = tmp[2];
    970 
    971         tmp[1] = clp[tmp3 + tmp4];
    972 
    973         tmp3 = *residual++;
    974         tmp4 = tmp[3];
    975 
    976         tmp1 = clp[tmp1 + tmp2];
    977         tmp3 = clp[tmp3 + tmp4];
    978         tmp[2] = (u8)tmp1;
    979         tmp[3] = (u8)tmp3;
    980 
    981         tmp += width;
    982     }
    983 
    984 }
    985 #endif
    986 /*------------------------------------------------------------------------------
    987 
    988     Function: Intra16x16VerticalPrediction
    989 
    990         Functional description:
    991           Perform intra 16x16 vertical prediction mode.
    992 
    993 ------------------------------------------------------------------------------*/
    994 
    995 void Intra16x16VerticalPrediction(u8 *data, u8 *above)
    996 {
    997 
    998 /* Variables */
    999 
   1000     u32 i, j;
   1001 
   1002 /* Code */
   1003 
   1004     ASSERT(data);
   1005     ASSERT(above);
   1006 
   1007     for (i = 0; i < 16; i++)
   1008     {
   1009         for (j = 0; j < 16; j++)
   1010         {
   1011             *data++ = above[j];
   1012         }
   1013     }
   1014 
   1015 }
   1016 
   1017 /*------------------------------------------------------------------------------
   1018 
   1019     Function: Intra16x16HorizontalPrediction
   1020 
   1021         Functional description:
   1022           Perform intra 16x16 horizontal prediction mode.
   1023 
   1024 ------------------------------------------------------------------------------*/
   1025 
   1026 void Intra16x16HorizontalPrediction(u8 *data, u8 *left)
   1027 {
   1028 
   1029 /* Variables */
   1030 
   1031     u32 i, j;
   1032 
   1033 /* Code */
   1034 
   1035     ASSERT(data);
   1036     ASSERT(left);
   1037 
   1038     for (i = 0; i < 16; i++)
   1039     {
   1040         for (j = 0; j < 16; j++)
   1041         {
   1042             *data++ = left[i];
   1043         }
   1044     }
   1045 
   1046 }
   1047 
   1048 /*------------------------------------------------------------------------------
   1049 
   1050     Function: Intra16x16DcPrediction
   1051 
   1052         Functional description:
   1053           Perform intra 16x16 DC prediction mode.
   1054 
   1055 ------------------------------------------------------------------------------*/
   1056 
   1057 void Intra16x16DcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
   1058     u32 availableB)
   1059 {
   1060 
   1061 /* Variables */
   1062 
   1063     u32 i, tmp;
   1064 
   1065 /* Code */
   1066 
   1067     ASSERT(data);
   1068     ASSERT(above);
   1069     ASSERT(left);
   1070 
   1071     if (availableA && availableB)
   1072     {
   1073         for (i = 0, tmp = 0; i < 16; i++)
   1074             tmp += above[i] + left[i];
   1075         tmp = (tmp + 16) >> 5;
   1076     }
   1077     else if (availableA)
   1078     {
   1079         for (i = 0, tmp = 0; i < 16; i++)
   1080             tmp += left[i];
   1081         tmp = (tmp + 8) >> 4;
   1082     }
   1083     else if (availableB)
   1084     {
   1085         for (i = 0, tmp = 0; i < 16; i++)
   1086             tmp += above[i];
   1087         tmp = (tmp + 8) >> 4;
   1088     }
   1089     /* neither A nor B available */
   1090     else
   1091     {
   1092         tmp = 128;
   1093     }
   1094     for (i = 0; i < 256; i++)
   1095         data[i] = (u8)tmp;
   1096 
   1097 }
   1098 
   1099 /*------------------------------------------------------------------------------
   1100 
   1101     Function: Intra16x16PlanePrediction
   1102 
   1103         Functional description:
   1104           Perform intra 16x16 plane prediction mode.
   1105 
   1106 ------------------------------------------------------------------------------*/
   1107 
   1108 void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left)
   1109 {
   1110 
   1111 /* Variables */
   1112 
   1113     i32 i, j;
   1114     i32 a, b, c;
   1115     i32 tmp;
   1116 
   1117 /* Code */
   1118 
   1119     ASSERT(data);
   1120     ASSERT(above);
   1121     ASSERT(left);
   1122 
   1123     a = 16 * (above[15] + left[15]);
   1124 
   1125     for (i = 0, b = 0; i < 8; i++)
   1126         b += (i + 1) * (above[8+i] - above[6-i]);
   1127     b = (5 * b + 32) >> 6;
   1128 
   1129     for (i = 0, c = 0; i < 7; i++)
   1130         c += (i + 1) * (left[8+i] - left[6-i]);
   1131     /* p[-1,-1] has to be accessed through above pointer */
   1132     c += (i + 1) * (left[8+i] - above[-1]);
   1133     c = (5 * c + 32) >> 6;
   1134 
   1135     for (i = 0; i < 16; i++)
   1136     {
   1137         for (j = 0; j < 16; j++)
   1138         {
   1139             tmp = (a + b * (j - 7) + c * (i - 7) + 16) >> 5;
   1140             data[i*16+j] = (u8)CLIP1(tmp);
   1141         }
   1142     }
   1143 
   1144 }
   1145 
   1146 /*------------------------------------------------------------------------------
   1147 
   1148     Function: IntraChromaDcPrediction
   1149 
   1150         Functional description:
   1151           Perform intra chroma DC prediction mode.
   1152 
   1153 ------------------------------------------------------------------------------*/
   1154 
   1155 void IntraChromaDcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
   1156     u32 availableB)
   1157 {
   1158 
   1159 /* Variables */
   1160 
   1161     u32 i;
   1162     u32 tmp1, tmp2;
   1163 
   1164 /* Code */
   1165 
   1166     ASSERT(data);
   1167     ASSERT(above);
   1168     ASSERT(left);
   1169 
   1170     /* y = 0..3 */
   1171     if (availableA && availableB)
   1172     {
   1173         tmp1 = above[0] + above[1] + above[2] + above[3] +
   1174               left[0] + left[1] + left[2] + left[3];
   1175         tmp1 = (tmp1 + 4) >> 3;
   1176         tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
   1177     }
   1178     else if (availableB)
   1179     {
   1180         tmp1 = (above[0] + above[1] + above[2] + above[3] + 2) >> 2;
   1181         tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
   1182     }
   1183     else if (availableA)
   1184     {
   1185         tmp1 = (left[0] + left[1] + left[2] + left[3] + 2) >> 2;
   1186         tmp2 = tmp1;
   1187     }
   1188     /* neither A nor B available */
   1189     else
   1190     {
   1191         tmp1 = tmp2 = 128;
   1192     }
   1193 
   1194     ASSERT(tmp1 < 256 && tmp2 < 256);
   1195     for (i = 4; i--;)
   1196     {
   1197         *data++ = (u8)tmp1;
   1198         *data++ = (u8)tmp1;
   1199         *data++ = (u8)tmp1;
   1200         *data++ = (u8)tmp1;
   1201         *data++ = (u8)tmp2;
   1202         *data++ = (u8)tmp2;
   1203         *data++ = (u8)tmp2;
   1204         *data++ = (u8)tmp2;
   1205     }
   1206 
   1207     /* y = 4...7 */
   1208     if (availableA)
   1209     {
   1210         tmp1 = (left[4] + left[5] + left[6] + left[7] + 2) >> 2;
   1211         if (availableB)
   1212         {
   1213             tmp2 = above[4] + above[5] + above[6] + above[7] +
   1214                    left[4] + left[5] + left[6] + left[7];
   1215             tmp2 = (tmp2 + 4) >> 3;
   1216         }
   1217         else
   1218             tmp2 = tmp1;
   1219     }
   1220     else if (availableB)
   1221     {
   1222         tmp1 = (above[0] + above[1] + above[2] + above[3] + 2) >> 2;
   1223         tmp2 = (above[4] + above[5] + above[6] + above[7] + 2) >> 2;
   1224     }
   1225     else
   1226     {
   1227         tmp1 = tmp2 = 128;
   1228     }
   1229 
   1230     ASSERT(tmp1 < 256 && tmp2 < 256);
   1231     for (i = 4; i--;)
   1232     {
   1233         *data++ = (u8)tmp1;
   1234         *data++ = (u8)tmp1;
   1235         *data++ = (u8)tmp1;
   1236         *data++ = (u8)tmp1;
   1237         *data++ = (u8)tmp2;
   1238         *data++ = (u8)tmp2;
   1239         *data++ = (u8)tmp2;
   1240         *data++ = (u8)tmp2;
   1241     }
   1242 }
   1243 
   1244 /*------------------------------------------------------------------------------
   1245 
   1246     Function: IntraChromaHorizontalPrediction
   1247 
   1248         Functional description:
   1249           Perform intra chroma horizontal prediction mode.
   1250 
   1251 ------------------------------------------------------------------------------*/
   1252 
   1253 void IntraChromaHorizontalPrediction(u8 *data, u8 *left)
   1254 {
   1255 
   1256 /* Variables */
   1257 
   1258     u32 i;
   1259 
   1260 /* Code */
   1261 
   1262     ASSERT(data);
   1263     ASSERT(left);
   1264 
   1265     for (i = 8; i--;)
   1266     {
   1267         *data++ = *left;
   1268         *data++ = *left;
   1269         *data++ = *left;
   1270         *data++ = *left;
   1271         *data++ = *left;
   1272         *data++ = *left;
   1273         *data++ = *left;
   1274         *data++ = *left++;
   1275     }
   1276 
   1277 }
   1278 
   1279 /*------------------------------------------------------------------------------
   1280 
   1281     Function: IntraChromaVerticalPrediction
   1282 
   1283         Functional description:
   1284           Perform intra chroma vertical prediction mode.
   1285 
   1286 ------------------------------------------------------------------------------*/
   1287 
   1288 void IntraChromaVerticalPrediction(u8 *data, u8 *above)
   1289 {
   1290 
   1291 /* Variables */
   1292 
   1293     u32 i;
   1294 
   1295 /* Code */
   1296 
   1297     ASSERT(data);
   1298     ASSERT(above);
   1299 
   1300     for (i = 8; i--;data++/*above-=8*/)
   1301     {
   1302         data[0] = *above;
   1303         data[8] = *above;
   1304         data[16] = *above;
   1305         data[24] = *above;
   1306         data[32] = *above;
   1307         data[40] = *above;
   1308         data[48] = *above;
   1309         data[56] = *above++;
   1310     }
   1311 
   1312 }
   1313 
   1314 /*------------------------------------------------------------------------------
   1315 
   1316     Function: IntraChromaPlanePrediction
   1317 
   1318         Functional description:
   1319           Perform intra chroma plane prediction mode.
   1320 
   1321 ------------------------------------------------------------------------------*/
   1322 
   1323 void IntraChromaPlanePrediction(u8 *data, u8 *above, u8 *left)
   1324 {
   1325 
   1326 /* Variables */
   1327 
   1328     u32 i;
   1329     i32 a, b, c;
   1330     i32 tmp;
   1331     const u8 *clp = h264bsdClip + 512;
   1332 
   1333 /* Code */
   1334 
   1335     ASSERT(data);
   1336     ASSERT(above);
   1337     ASSERT(left);
   1338 
   1339     a = 16 * (above[7] + left[7]);
   1340 
   1341     b = (above[4] - above[2]) + 2 * (above[5] - above[1])
   1342         + 3 * (above[6] - above[0]) + 4 * (above[7] - above[-1]);
   1343     b = (17 * b + 16) >> 5;
   1344 
   1345     /* p[-1,-1] has to be accessed through above pointer */
   1346     c = (left[4] - left[2]) + 2 * (left[5] - left[1])
   1347         + 3 * (left[6] - left[0]) + 4 * (left[7] - above[-1]);
   1348     c = (17 * c + 16) >> 5;
   1349 
   1350     /*a += 16;*/
   1351     a = a - 3 * c + 16;
   1352     for (i = 8; i--; a += c)
   1353     {
   1354         tmp = (a - 3 * b);
   1355         *data++ = clp[tmp>>5];
   1356         tmp += b;
   1357         *data++ = clp[tmp>>5];
   1358         tmp += b;
   1359         *data++ = clp[tmp>>5];
   1360         tmp += b;
   1361         *data++ = clp[tmp>>5];
   1362         tmp += b;
   1363         *data++ = clp[tmp>>5];
   1364         tmp += b;
   1365         *data++ = clp[tmp>>5];
   1366         tmp += b;
   1367         *data++ = clp[tmp>>5];
   1368         tmp += b;
   1369         *data++ = clp[tmp>>5];
   1370     }
   1371 
   1372 }
   1373 
   1374 /*------------------------------------------------------------------------------
   1375 
   1376     Function: Get4x4NeighbourPels
   1377 
   1378         Functional description:
   1379           Get neighbouring pixels of a 4x4 block into 'a' and 'l'.
   1380 
   1381 ------------------------------------------------------------------------------*/
   1382 
   1383 void Get4x4NeighbourPels(u8 *a, u8 *l, u8 *data, u8 *above, u8 *left,
   1384     u32 blockNum)
   1385 {
   1386 
   1387 /* Variables */
   1388 
   1389     u32 x, y;
   1390     u8 t1, t2;
   1391 
   1392 /* Code */
   1393 
   1394     ASSERT(a);
   1395     ASSERT(l);
   1396     ASSERT(data);
   1397     ASSERT(above);
   1398     ASSERT(left);
   1399     ASSERT(blockNum < 16);
   1400 
   1401     x = h264bsdBlockX[blockNum];
   1402     y = h264bsdBlockY[blockNum];
   1403 
   1404     /* A and D */
   1405     if (x == 0)
   1406     {
   1407         t1 = left[y    ];
   1408         t2 = left[y + 1];
   1409         l[1] = t1;
   1410         l[2] = t2;
   1411         t1 = left[y + 2];
   1412         t2 = left[y + 3];
   1413         l[3] = t1;
   1414         l[4] = t2;
   1415     }
   1416     else
   1417     {
   1418         t1 = data[y * 16 + x - 1     ];
   1419         t2 = data[y * 16 + x - 1 + 16];
   1420         l[1] = t1;
   1421         l[2] = t2;
   1422         t1 = data[y * 16 + x - 1 + 32];
   1423         t2 = data[y * 16 + x - 1 + 48];
   1424         l[3] = t1;
   1425         l[4] = t2;
   1426     }
   1427 
   1428     /* B, C and D */
   1429     if (y == 0)
   1430     {
   1431         t1 = above[x    ];
   1432         t2 = above[x    ];
   1433         l[0] = t1;
   1434         a[0] = t2;
   1435         t1 = above[x + 1];
   1436         t2 = above[x + 2];
   1437         a[1] = t1;
   1438         a[2] = t2;
   1439         t1 = above[x + 3];
   1440         t2 = above[x + 4];
   1441         a[3] = t1;
   1442         a[4] = t2;
   1443         t1 = above[x + 5];
   1444         t2 = above[x + 6];
   1445         a[5] = t1;
   1446         a[6] = t2;
   1447         t1 = above[x + 7];
   1448         t2 = above[x + 8];
   1449         a[7] = t1;
   1450         a[8] = t2;
   1451     }
   1452     else
   1453     {
   1454         t1 = data[(y - 1) * 16 + x    ];
   1455         t2 = data[(y - 1) * 16 + x + 1];
   1456         a[1] = t1;
   1457         a[2] = t2;
   1458         t1 = data[(y - 1) * 16 + x + 2];
   1459         t2 = data[(y - 1) * 16 + x + 3];
   1460         a[3] = t1;
   1461         a[4] = t2;
   1462         t1 = data[(y - 1) * 16 + x + 4];
   1463         t2 = data[(y - 1) * 16 + x + 5];
   1464         a[5] = t1;
   1465         a[6] = t2;
   1466         t1 = data[(y - 1) * 16 + x + 6];
   1467         t2 = data[(y - 1) * 16 + x + 7];
   1468         a[7] = t1;
   1469         a[8] = t2;
   1470 
   1471         if (x == 0)
   1472             l[0] = a[0] = left[y-1];
   1473         else
   1474             l[0] = a[0] = data[(y - 1) * 16 + x - 1];
   1475     }
   1476 }
   1477 
   1478 
   1479 /*------------------------------------------------------------------------------
   1480 
   1481     Function: Intra4x4VerticalPrediction
   1482 
   1483         Functional description:
   1484           Perform intra 4x4 vertical prediction mode.
   1485 
   1486 ------------------------------------------------------------------------------*/
   1487 
   1488 void Intra4x4VerticalPrediction(u8 *data, u8 *above)
   1489 {
   1490 
   1491 /* Variables */
   1492 
   1493     u8 t1, t2;
   1494 
   1495 /* Code */
   1496 
   1497     ASSERT(data);
   1498     ASSERT(above);
   1499 
   1500     t1 = above[0];
   1501     t2 = above[1];
   1502     data[0] = data[4] = data[8] = data[12] = t1;
   1503     data[1] = data[5] = data[9] = data[13] = t2;
   1504     t1 = above[2];
   1505     t2 = above[3];
   1506     data[2] = data[6] = data[10] = data[14] = t1;
   1507     data[3] = data[7] = data[11] = data[15] = t2;
   1508 
   1509 }
   1510 
   1511 /*------------------------------------------------------------------------------
   1512 
   1513     Function: Intra4x4HorizontalPrediction
   1514 
   1515         Functional description:
   1516           Perform intra 4x4 horizontal prediction mode.
   1517 
   1518 ------------------------------------------------------------------------------*/
   1519 
   1520 void Intra4x4HorizontalPrediction(u8 *data, u8 *left)
   1521 {
   1522 
   1523 /* Variables */
   1524 
   1525     u8 t1, t2;
   1526 
   1527 /* Code */
   1528 
   1529     ASSERT(data);
   1530     ASSERT(left);
   1531 
   1532     t1 = left[0];
   1533     t2 = left[1];
   1534     data[0] = data[1] = data[2] = data[3] = t1;
   1535     data[4] = data[5] = data[6] = data[7] = t2;
   1536     t1 = left[2];
   1537     t2 = left[3];
   1538     data[8] = data[9] = data[10] = data[11] = t1;
   1539     data[12] = data[13] = data[14] = data[15] = t2;
   1540 
   1541 }
   1542 
   1543 /*------------------------------------------------------------------------------
   1544 
   1545     Function: Intra4x4DcPrediction
   1546 
   1547         Functional description:
   1548           Perform intra 4x4 DC prediction mode.
   1549 
   1550 ------------------------------------------------------------------------------*/
   1551 
   1552 void Intra4x4DcPrediction(u8 *data, u8 *above, u8 *left, u32 availableA,
   1553     u32 availableB)
   1554 {
   1555 
   1556 /* Variables */
   1557 
   1558     u32 tmp;
   1559     u8 t1, t2, t3, t4;
   1560 
   1561 /* Code */
   1562 
   1563     ASSERT(data);
   1564     ASSERT(above);
   1565     ASSERT(left);
   1566 
   1567     if (availableA && availableB)
   1568     {
   1569         t1 = above[0]; t2 = above[1]; t3 = above[2]; t4 = above[3];
   1570         tmp = t1 + t2 + t3 + t4;
   1571         t1 = left[0]; t2 = left[1]; t3 = left[2]; t4 = left[3];
   1572         tmp += t1 + t2 + t3 + t4;
   1573         tmp = (tmp + 4) >> 3;
   1574     }
   1575     else if (availableA)
   1576     {
   1577         t1 = left[0]; t2 = left[1]; t3 = left[2]; t4 = left[3];
   1578         tmp = (t1 + t2 + t3 + t4 + 2) >> 2;
   1579     }
   1580     else if (availableB)
   1581     {
   1582         t1 = above[0]; t2 = above[1]; t3 = above[2]; t4 = above[3];
   1583         tmp = (t1 + t2 + t3 + t4 + 2) >> 2;
   1584     }
   1585     else
   1586     {
   1587         tmp = 128;
   1588     }
   1589 
   1590     ASSERT(tmp < 256);
   1591     data[0] = data[1] = data[2] = data[3] =
   1592     data[4] = data[5] = data[6] = data[7] =
   1593     data[8] = data[9] = data[10] = data[11] =
   1594     data[12] = data[13] = data[14] = data[15] = (u8)tmp;
   1595 
   1596 }
   1597 
   1598 /*------------------------------------------------------------------------------
   1599 
   1600     Function: Intra4x4DiagonalDownLeftPrediction
   1601 
   1602         Functional description:
   1603           Perform intra 4x4 diagonal down-left prediction mode.
   1604 
   1605 ------------------------------------------------------------------------------*/
   1606 
   1607 void Intra4x4DiagonalDownLeftPrediction(u8 *data, u8 *above)
   1608 {
   1609 
   1610 /* Variables */
   1611 
   1612 /* Code */
   1613 
   1614     ASSERT(data);
   1615     ASSERT(above);
   1616 
   1617     data[ 0] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
   1618     data[ 1] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
   1619     data[ 4] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
   1620     data[ 2] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
   1621     data[ 5] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
   1622     data[ 8] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
   1623     data[ 3] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
   1624     data[ 6] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
   1625     data[ 9] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
   1626     data[12] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
   1627     data[ 7] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
   1628     data[10] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
   1629     data[13] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
   1630     data[11] = (above[5] + 2 * above[6] + above[7] + 2) >> 2;
   1631     data[14] = (above[5] + 2 * above[6] + above[7] + 2) >> 2;
   1632     data[15] = (above[6] + 3 * above[7] + 2) >> 2;
   1633 
   1634 }
   1635 
   1636 /*------------------------------------------------------------------------------
   1637 
   1638     Function: Intra4x4DiagonalDownRightPrediction
   1639 
   1640         Functional description:
   1641           Perform intra 4x4 diagonal down-right prediction mode.
   1642 
   1643 ------------------------------------------------------------------------------*/
   1644 
   1645 void Intra4x4DiagonalDownRightPrediction(u8 *data, u8 *above, u8 *left)
   1646 {
   1647 
   1648 /* Variables */
   1649 
   1650 /* Code */
   1651 
   1652     ASSERT(data);
   1653     ASSERT(above);
   1654     ASSERT(left);
   1655 
   1656     data[ 0] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
   1657     data[ 5] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
   1658     data[10] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
   1659     data[15] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
   1660     data[ 1] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
   1661     data[ 6] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
   1662     data[11] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
   1663     data[ 2] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
   1664     data[ 7] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
   1665     data[ 3] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
   1666     data[ 4] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
   1667     data[ 9] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
   1668     data[14] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
   1669     data[ 8] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
   1670     data[13] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
   1671     data[12] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
   1672 }
   1673 
   1674 /*------------------------------------------------------------------------------
   1675 
   1676     Function: Intra4x4VerticalRightPrediction
   1677 
   1678         Functional description:
   1679           Perform intra 4x4 vertical right prediction mode.
   1680 
   1681 ------------------------------------------------------------------------------*/
   1682 
   1683 void Intra4x4VerticalRightPrediction(u8 *data, u8 *above, u8 *left)
   1684 {
   1685 
   1686 /* Variables */
   1687 
   1688 /* Code */
   1689 
   1690     ASSERT(data);
   1691     ASSERT(above);
   1692     ASSERT(left);
   1693 
   1694     data[ 0] = (above[-1] + above[0] + 1) >> 1;
   1695     data[ 9] = (above[-1] + above[0] + 1) >> 1;
   1696     data[ 5] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
   1697     data[14] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2;
   1698     data[ 4] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
   1699     data[13] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
   1700     data[ 1] = (above[0] + above[1] + 1) >> 1;
   1701     data[10] = (above[0] + above[1] + 1) >> 1;
   1702     data[ 6] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
   1703     data[15] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
   1704     data[ 2] = (above[1] + above[2] + 1) >> 1;
   1705     data[11] = (above[1] + above[2] + 1) >> 1;
   1706     data[ 7] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
   1707     data[ 3] = (above[2] + above[3] + 1) >> 1;
   1708     data[ 8] = (left[1] + 2 * left[0] + left[-1] + 2) >> 2;
   1709     data[12] = (left[2] + 2 * left[1] + left[0] + 2) >> 2;
   1710 
   1711 }
   1712 
   1713 /*------------------------------------------------------------------------------
   1714 
   1715     Function: Intra4x4HorizontalDownPrediction
   1716 
   1717         Functional description:
   1718           Perform intra 4x4 horizontal down prediction mode.
   1719 
   1720 ------------------------------------------------------------------------------*/
   1721 
   1722 void Intra4x4HorizontalDownPrediction(u8 *data, u8 *above, u8 *left)
   1723 {
   1724 
   1725 /* Variables */
   1726 
   1727 /* Code */
   1728 
   1729     ASSERT(data);
   1730     ASSERT(above);
   1731     ASSERT(left);
   1732 
   1733     data[ 0] = (left[-1] + left[0] + 1) >> 1;
   1734     data[ 6] = (left[-1] + left[0] + 1) >> 1;
   1735     data[ 5] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
   1736     data[11] = (left[-1] + 2 * left[0] + left[1] + 2) >> 2;
   1737     data[ 4] = (left[0] + left[1] + 1) >> 1;
   1738     data[10] = (left[0] + left[1] + 1) >> 1;
   1739     data[ 9] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
   1740     data[15] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
   1741     data[ 8] = (left[1] + left[2] + 1) >> 1;
   1742     data[14] = (left[1] + left[2] + 1) >> 1;
   1743     data[13] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
   1744     data[12] = (left[2] + left[3] + 1) >> 1;
   1745     data[ 1] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
   1746     data[ 7] = (above[0] + 2 * above[-1] + left[0] + 2) >> 2;
   1747     data[ 2] = (above[1] + 2 * above[0] + above[-1] + 2) >> 2;
   1748     data[ 3] = (above[2] + 2 * above[1] + above[0] + 2) >> 2;
   1749 }
   1750 
   1751 /*------------------------------------------------------------------------------
   1752 
   1753     Function: Intra4x4VerticalLeftPrediction
   1754 
   1755         Functional description:
   1756           Perform intra 4x4 vertical left prediction mode.
   1757 
   1758 ------------------------------------------------------------------------------*/
   1759 
   1760 void Intra4x4VerticalLeftPrediction(u8 *data, u8 *above)
   1761 {
   1762 
   1763 /* Variables */
   1764 
   1765 /* Code */
   1766 
   1767     ASSERT(data);
   1768     ASSERT(above);
   1769 
   1770     data[ 0] = (above[0] + above[1] + 1) >> 1;
   1771     data[ 1] = (above[1] + above[2] + 1) >> 1;
   1772     data[ 2] = (above[2] + above[3] + 1) >> 1;
   1773     data[ 3] = (above[3] + above[4] + 1) >> 1;
   1774     data[ 4] = (above[0] + 2 * above[1] + above[2] + 2) >> 2;
   1775     data[ 5] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
   1776     data[ 6] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
   1777     data[ 7] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
   1778     data[ 8] = (above[1] + above[2] + 1) >> 1;
   1779     data[ 9] = (above[2] + above[3] + 1) >> 1;
   1780     data[10] = (above[3] + above[4] + 1) >> 1;
   1781     data[11] = (above[4] + above[5] + 1) >> 1;
   1782     data[12] = (above[1] + 2 * above[2] + above[3] + 2) >> 2;
   1783     data[13] = (above[2] + 2 * above[3] + above[4] + 2) >> 2;
   1784     data[14] = (above[3] + 2 * above[4] + above[5] + 2) >> 2;
   1785     data[15] = (above[4] + 2 * above[5] + above[6] + 2) >> 2;
   1786 
   1787 }
   1788 
   1789 /*------------------------------------------------------------------------------
   1790 
   1791     Function: Intra4x4HorizontalUpPrediction
   1792 
   1793         Functional description:
   1794           Perform intra 4x4 horizontal up prediction mode.
   1795 
   1796 ------------------------------------------------------------------------------*/
   1797 
   1798 void Intra4x4HorizontalUpPrediction(u8 *data, u8 *left)
   1799 {
   1800 
   1801 /* Variables */
   1802 
   1803 /* Code */
   1804 
   1805     ASSERT(data);
   1806     ASSERT(left);
   1807 
   1808     data[ 0] = (left[0] + left[1] + 1) >> 1;
   1809     data[ 1] = (left[0] + 2 * left[1] + left[2] + 2) >> 2;
   1810     data[ 2] = (left[1] + left[2] + 1) >> 1;
   1811     data[ 3] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
   1812     data[ 4] = (left[1] + left[2] + 1) >> 1;
   1813     data[ 5] = (left[1] + 2 * left[2] + left[3] + 2) >> 2;
   1814     data[ 6] = (left[2] + left[3] + 1) >> 1;
   1815     data[ 7] = (left[2] + 3 * left[3] + 2) >> 2;
   1816     data[ 8] = (left[2] + left[3] + 1) >> 1;
   1817     data[ 9] = (left[2] + 3 * left[3] + 2) >> 2;
   1818     data[10] = left[3];
   1819     data[11] = left[3];
   1820     data[12] = left[3];
   1821     data[13] = left[3];
   1822     data[14] = left[3];
   1823     data[15] = left[3];
   1824 
   1825 }
   1826 
   1827 #endif /* H264DEC_OMXDL */
   1828 
   1829 /*------------------------------------------------------------------------------
   1830 
   1831     Function: Write4x4To16x16
   1832 
   1833         Functional description:
   1834           Write a 4x4 block (data4x4) into correct position
   1835           in 16x16 macroblock (data).
   1836 
   1837 ------------------------------------------------------------------------------*/
   1838 
   1839 void Write4x4To16x16(u8 *data, u8 *data4x4, u32 blockNum)
   1840 {
   1841 
   1842 /* Variables */
   1843 
   1844     u32 x, y;
   1845     u32 *in32, *out32;
   1846 
   1847 /* Code */
   1848 
   1849     ASSERT(data);
   1850     ASSERT(data4x4);
   1851     ASSERT(blockNum < 16);
   1852 
   1853     x = h264bsdBlockX[blockNum];
   1854     y = h264bsdBlockY[blockNum];
   1855 
   1856     data += y*16+x;
   1857 
   1858     ASSERT(((u32)data&0x3) == 0);
   1859 
   1860     /*lint --e(826) */
   1861     out32 = (u32 *)data;
   1862     /*lint --e(826) */
   1863     in32 = (u32 *)data4x4;
   1864 
   1865     out32[0] = *in32++;
   1866     out32[4] = *in32++;
   1867     out32[8] = *in32++;
   1868     out32[12] = *in32++;
   1869 }
   1870 
   1871 /*------------------------------------------------------------------------------
   1872 
   1873     Function: DetermineIntra4x4PredMode
   1874 
   1875         Functional description:
   1876           Returns the intra 4x4 prediction mode of a block based on the
   1877           neighbouring macroblocks and information parsed from stream.
   1878 
   1879 ------------------------------------------------------------------------------*/
   1880 
   1881 u32 DetermineIntra4x4PredMode(macroblockLayer_t *pMbLayer,
   1882     u32 available, neighbour_t *nA, neighbour_t *nB, u32 index,
   1883     mbStorage_t *nMbA, mbStorage_t *nMbB)
   1884 {
   1885 
   1886 /* Variables */
   1887 
   1888     u32 mode1, mode2;
   1889     mbStorage_t *pMb;
   1890 
   1891 /* Code */
   1892 
   1893     ASSERT(pMbLayer);
   1894 
   1895     /* dc only prediction? */
   1896     if (!available)
   1897         mode1 = 2;
   1898     else
   1899     {
   1900         pMb = nMbA;
   1901         if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA4x4)
   1902         {
   1903             mode1 = pMb->intra4x4PredMode[nA->index];
   1904         }
   1905         else
   1906             mode1 = 2;
   1907 
   1908         pMb = nMbB;
   1909         if (h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTRA4x4)
   1910         {
   1911             mode2 = pMb->intra4x4PredMode[nB->index];
   1912         }
   1913         else
   1914             mode2 = 2;
   1915 
   1916         mode1 = MIN(mode1, mode2);
   1917     }
   1918 
   1919     if (!pMbLayer->mbPred.prevIntra4x4PredModeFlag[index])
   1920     {
   1921         if (pMbLayer->mbPred.remIntra4x4PredMode[index] < mode1)
   1922         {
   1923             mode1 = pMbLayer->mbPred.remIntra4x4PredMode[index];
   1924         }
   1925         else
   1926         {
   1927             mode1 = pMbLayer->mbPred.remIntra4x4PredMode[index] + 1;
   1928         }
   1929     }
   1930 
   1931     return(mode1);
   1932 }
   1933 
   1934 
   1935 /*lint +e702 */
   1936 
   1937 
   1938