PageRenderTime 554ms CodeModel.GetById 101ms app.highlight 325ms RepoModel.GetById 97ms app.codeStats 1ms

/H264Dec/source/h264bsd_intra_prediction.c

http://github.com/mbebenita/Broadway
C | 1937 lines | 1200 code | 312 blank | 425 comment | 185 complexity | f549625fe28e971eebd8e4da72277536 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   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 */
  85const u32 h264bsdBlockX[16] =
  86    { 0, 4, 0, 4, 8, 12, 8, 12, 0, 4, 0, 4, 8, 12, 8, 12 };
  87const u32 h264bsdBlockY[16] =
  88    { 0, 0, 4, 4, 0, 0, 4, 4, 8, 8, 12, 12, 8, 8, 12, 12 };
  89
  90const 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------------------------------------------------------------------------------*/
 162static void Get4x4NeighbourPels(u8 *a, u8 *l, u8 *data, u8 *above, u8 *left,
 163    u32 blockNum);
 164static void Intra16x16VerticalPrediction(u8 *data, u8 *above);
 165static void Intra16x16HorizontalPrediction(u8 *data, u8 *left);
 166static void Intra16x16DcPrediction(u8 *data, u8 *above, u8 *left,
 167    u32 A, u32 B);
 168static void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left);
 169static void IntraChromaDcPrediction(u8 *data, u8 *above, u8 *left,
 170    u32 A, u32 B);
 171static void IntraChromaHorizontalPrediction(u8 *data, u8 *left);
 172static void IntraChromaVerticalPrediction(u8 *data, u8 *above);
 173static void IntraChromaPlanePrediction(u8 *data, u8 *above, u8 *left);
 174
 175static void Intra4x4VerticalPrediction(u8 *data, u8 *above);
 176static void Intra4x4HorizontalPrediction(u8 *data, u8 *left);
 177static void Intra4x4DcPrediction(u8 *data, u8 *above, u8 *left, u32 A, u32 B);
 178static void Intra4x4DiagonalDownLeftPrediction(u8 *data, u8 *above);
 179static void Intra4x4DiagonalDownRightPrediction(u8 *data, u8 *above, u8 *left);
 180static void Intra4x4VerticalRightPrediction(u8 *data, u8 *above, u8 *left);
 181static void Intra4x4HorizontalDownPrediction(u8 *data, u8 *above, u8 *left);
 182static void Intra4x4VerticalLeftPrediction(u8 *data, u8 *above);
 183static void Intra4x4HorizontalUpPrediction(u8 *data, u8 *left);
 184void h264bsdAddResidual(u8 *data, i32 *residual, u32 blockNum);
 185
 186static void Write4x4To16x16(u8 *data, u8 *data4x4, u32 blockNum);
 187#endif /* H264DEC_OMXDL */
 188
 189static 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------------------------------------------------------------------------------*/
 206u32 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------------------------------------------------------------------------------*/
 261u32 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------------------------------------------------------------------------------*/
 372u32 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------------------------------------------------------------------------------*/
 473u32 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
 540void 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
 622u32 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
 696u32 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
 840u32 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
 922void 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
 995void 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
1026void 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
1057void 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
1108void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left)
1109{
1110
1111/* Variables */
1112
1113    u32 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 += ((i32)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 += ((i32)i + 1) * (left[8+i] - left[6-i]);
1131    /* p[-1,-1] has to be accessed through above pointer */
1132    c += ((i32)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 * ((i32)j - 7) + c * ((i32)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
1155void 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
1253void 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
1288void 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
1323void 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
1383void 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
1488void 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
1520void 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
1552void 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
1607void 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
1645void 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[-

Large files files are truncated, but you can click here to view the full file