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