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 h264bsdInterPrediction 27 MvPrediction16x16 28 MvPrediction16x8 29 MvPrediction8x16 30 MvPrediction8x8 31 MvPrediction 32 MedianFilter 33 GetInterNeighbour 34 GetPredictionMv 35 36 ------------------------------------------------------------------------------*/ 37 38 /*------------------------------------------------------------------------------ 39 1. Include headers 40 ------------------------------------------------------------------------------*/ 41 42 #include "h264bsd_inter_prediction.h" 43 #include "h264bsd_neighbour.h" 44 #include "h264bsd_util.h" 45 #include "h264bsd_reconstruct.h" 46 #include "h264bsd_dpb.h" 47 48 /*------------------------------------------------------------------------------ 49 2. External compiler flags 50 -------------------------------------------------------------------------------- 51 52 -------------------------------------------------------------------------------- 53 3. Module defines 54 ------------------------------------------------------------------------------*/ 55 56 typedef struct 57 { 58 u32 available; 59 u32 refIndex; 60 mv_t mv; 61 } interNeighbour_t; 62 63 /*------------------------------------------------------------------------------ 64 4. Local function prototypes 65 ------------------------------------------------------------------------------*/ 66 67 static u32 MvPrediction16x16(mbStorage_t *pMb, mbPred_t *mbPred, 68 dpbStorage_t *dpb); 69 static u32 MvPrediction16x8(mbStorage_t *pMb, mbPred_t *mbPred, 70 dpbStorage_t *dpb); 71 static u32 MvPrediction8x16(mbStorage_t *pMb, mbPred_t *mbPred, 72 dpbStorage_t *dpb); 73 static u32 MvPrediction8x8(mbStorage_t *pMb, subMbPred_t *subMbPred, 74 dpbStorage_t *dpb); 75 static u32 MvPrediction(mbStorage_t *pMb, subMbPred_t *subMbPred, 76 u32 mbPartIdx, u32 subMbPartIdx); 77 static i32 MedianFilter(i32 a, i32 b, i32 c); 78 79 static void GetInterNeighbour(u32 sliceId, mbStorage_t *nMb, 80 interNeighbour_t *n, u32 index); 81 static void GetPredictionMv(mv_t *mv, interNeighbour_t *a, u32 refIndex); 82 83 static const neighbour_t N_A_SUB_PART[4][4][4] = { 84 { { {MB_A,5}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 85 { {MB_A,5}, {MB_A,7}, {MB_NA,0}, {MB_NA,0} }, 86 { {MB_A,5}, {MB_CURR,0}, {MB_NA,0}, {MB_NA,0} }, 87 { {MB_A,5}, {MB_CURR,0}, {MB_A,7}, {MB_CURR,2} } }, 88 89 { { {MB_CURR,1}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 90 { {MB_CURR,1}, {MB_CURR,3}, {MB_NA,0}, {MB_NA,0} }, 91 { {MB_CURR,1}, {MB_CURR,4}, {MB_NA,0}, {MB_NA,0} }, 92 { {MB_CURR,1}, {MB_CURR,4}, {MB_CURR,3}, {MB_CURR,6} } }, 93 94 { { {MB_A,13}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 95 { {MB_A,13}, {MB_A,15}, {MB_NA,0}, {MB_NA,0} }, 96 { {MB_A,13}, {MB_CURR,8}, {MB_NA,0}, {MB_NA,0} }, 97 { {MB_A,13}, {MB_CURR,8}, {MB_A,15}, {MB_CURR,10} } }, 98 99 { { {MB_CURR,9}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 100 { {MB_CURR,9}, {MB_CURR,11}, {MB_NA,0}, {MB_NA,0} }, 101 { {MB_CURR,9}, {MB_CURR,12}, {MB_NA,0}, {MB_NA,0} }, 102 { {MB_CURR,9}, {MB_CURR,12}, {MB_CURR,11}, {MB_CURR,14} } } }; 103 104 static const neighbour_t N_B_SUB_PART[4][4][4] = { 105 { { {MB_B,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 106 { {MB_B,10}, {MB_CURR,0}, {MB_NA,0}, {MB_NA,0} }, 107 { {MB_B,10}, {MB_B,11}, {MB_NA,0}, {MB_NA,0} }, 108 { {MB_B,10}, {MB_B,11}, {MB_CURR,0}, {MB_CURR,1} } }, 109 110 { { {MB_B,14}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 111 { {MB_B,14}, {MB_CURR,4}, {MB_NA,0}, {MB_NA,0} }, 112 { {MB_B,14}, {MB_B,15}, {MB_NA,0}, {MB_NA,0} }, 113 { {MB_B,14}, {MB_B,15}, {MB_CURR,4}, {MB_CURR,5} } }, 114 115 { { {MB_CURR,2}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 116 { {MB_CURR,2}, {MB_CURR,8}, {MB_NA,0}, {MB_NA,0} }, 117 { {MB_CURR,2}, {MB_CURR,3}, {MB_NA,0}, {MB_NA,0} }, 118 { {MB_CURR,2}, {MB_CURR,3}, {MB_CURR,8}, {MB_CURR,9} } }, 119 120 { { {MB_CURR,6}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 121 { {MB_CURR,6}, {MB_CURR,12}, {MB_NA,0}, {MB_NA,0} }, 122 { {MB_CURR,6}, {MB_CURR,7}, {MB_NA,0}, {MB_NA,0} }, 123 { {MB_CURR,6}, {MB_CURR,7}, {MB_CURR,12}, {MB_CURR,13} } } }; 124 125 static const neighbour_t N_C_SUB_PART[4][4][4] = { 126 { { {MB_B,14}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 127 { {MB_B,14}, {MB_NA,4}, {MB_NA,0}, {MB_NA,0} }, 128 { {MB_B,11}, {MB_B,14}, {MB_NA,0}, {MB_NA,0} }, 129 { {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_NA,4} } }, 130 131 { { {MB_C,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 132 { {MB_C,10}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 133 { {MB_B,15}, {MB_C,10}, {MB_NA,0}, {MB_NA,0} }, 134 { {MB_B,15}, {MB_C,10}, {MB_CURR,5}, {MB_NA,0} } }, 135 136 { { {MB_CURR,6}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 137 { {MB_CURR,6}, {MB_NA,12}, {MB_NA,0}, {MB_NA,0} }, 138 { {MB_CURR,3}, {MB_CURR,6}, {MB_NA,0}, {MB_NA,0} }, 139 { {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_NA,12} } }, 140 141 { { {MB_NA,2}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 142 { {MB_NA,2}, {MB_NA,8}, {MB_NA,0}, {MB_NA,0} }, 143 { {MB_CURR,7}, {MB_NA,2}, {MB_NA,0}, {MB_NA,0} }, 144 { {MB_CURR,7}, {MB_NA,2}, {MB_CURR,13}, {MB_NA,8} } } }; 145 146 static const neighbour_t N_D_SUB_PART[4][4][4] = { 147 { { {MB_D,15}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 148 { {MB_D,15}, {MB_A,5}, {MB_NA,0}, {MB_NA,0} }, 149 { {MB_D,15}, {MB_B,10}, {MB_NA,0}, {MB_NA,0} }, 150 { {MB_D,15}, {MB_B,10}, {MB_A,5}, {MB_CURR,0} } }, 151 152 { { {MB_B,11}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 153 { {MB_B,11}, {MB_CURR,1}, {MB_NA,0}, {MB_NA,0} }, 154 { {MB_B,11}, {MB_B,14}, {MB_NA,0}, {MB_NA,0} }, 155 { {MB_B,11}, {MB_B,14}, {MB_CURR,1}, {MB_CURR,4} } }, 156 157 { { {MB_A,7}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 158 { {MB_A,7}, {MB_A,13}, {MB_NA,0}, {MB_NA,0} }, 159 { {MB_A,7}, {MB_CURR,2}, {MB_NA,0}, {MB_NA,0} }, 160 { {MB_A,7}, {MB_CURR,2}, {MB_A,13}, {MB_CURR,8} } }, 161 162 { { {MB_CURR,3}, {MB_NA,0}, {MB_NA,0}, {MB_NA,0} }, 163 { {MB_CURR,3}, {MB_CURR,9}, {MB_NA,0}, {MB_NA,0} }, 164 { {MB_CURR,3}, {MB_CURR,6}, {MB_NA,0}, {MB_NA,0} }, 165 { {MB_CURR,3}, {MB_CURR,6}, {MB_CURR,9}, {MB_CURR,12} } } }; 166 167 168 #ifdef H264DEC_OMXDL 169 170 /*------------------------------------------------------------------------------ 171 172 Function: h264bsdInterPrediction 173 174 Functional description: 175 Processes one inter macroblock. Performs motion vector prediction 176 and reconstructs prediction macroblock. Writes the final macroblock 177 (prediction + residual) into the output image (currImage) 178 179 Inputs: 180 pMb pointer to macroblock specific information 181 pMbLayer pointer to current macroblock data from stream 182 dpb pointer to decoded picture buffer 183 mbNum current macroblock number 184 currImage pointer to output image 185 data pointer where predicted macroblock will be stored 186 187 Outputs: 188 pMb structure is updated with current macroblock 189 currImage current macroblock is written into image 190 data prediction is stored here 191 192 Returns: 193 HANTRO_OK success 194 HANTRO_NOK error in motion vector prediction 195 196 ------------------------------------------------------------------------------*/ 197 u32 h264bsdInterPrediction(mbStorage_t *pMb, macroblockLayer_t *pMbLayer, 198 dpbStorage_t *dpb, u32 mbNum, image_t *currImage, u8 *data) 199 { 200 201 /* Variables */ 202 203 u32 i; 204 u32 x, y; 205 u32 colAndRow; 206 subMbPartMode_e subPartMode; 207 image_t refImage; 208 u8 fillBuff[32*21 + 15 + 32]; 209 u8 *pFill; 210 u32 tmp; 211 /* Code */ 212 213 ASSERT(pMb); 214 ASSERT(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTER); 215 ASSERT(pMbLayer); 216 217 /* 16-byte alignment */ 218 pFill = ALIGN(fillBuff, 16); 219 220 /* set row bits 15:0 */ 221 colAndRow = mbNum / currImage->width; 222 /*set col to bits 31:16 */ 223 colAndRow += (mbNum - colAndRow * currImage->width) << 16; 224 colAndRow <<= 4; 225 226 refImage.width = currImage->width; 227 refImage.height = currImage->height; 228 229 switch (pMb->mbType) 230 { 231 case P_Skip: 232 case P_L0_16x16: 233 if (MvPrediction16x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK) 234 return(HANTRO_NOK); 235 refImage.data = pMb->refAddr[0]; 236 tmp = (0<<24) + (0<<16) + (16<<8) + 16; 237 h264bsdPredictSamples(data, pMb->mv, &refImage, 238 colAndRow, tmp, pFill); 239 break; 240 241 case P_L0_L0_16x8: 242 if ( MvPrediction16x8(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK) 243 return(HANTRO_NOK); 244 refImage.data = pMb->refAddr[0]; 245 tmp = (0<<24) + (0<<16) + (16<<8) + 8; 246 h264bsdPredictSamples(data, pMb->mv, &refImage, 247 colAndRow, tmp, pFill); 248 249 refImage.data = pMb->refAddr[2]; 250 tmp = (0<<24) + (8<<16) + (16<<8) + 8; 251 h264bsdPredictSamples(data, pMb->mv+8, &refImage, 252 colAndRow, tmp, pFill); 253 break; 254 255 case P_L0_L0_8x16: 256 if ( MvPrediction8x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK) 257 return(HANTRO_NOK); 258 refImage.data = pMb->refAddr[0]; 259 tmp = (0<<24) + (0<<16) + (8<<8) + 16; 260 h264bsdPredictSamples(data, pMb->mv, &refImage, 261 colAndRow, tmp, pFill); 262 refImage.data = pMb->refAddr[1]; 263 tmp = (8<<24) + (0<<16) + (8<<8) + 16; 264 h264bsdPredictSamples(data, pMb->mv+4, &refImage, 265 colAndRow, tmp, pFill); 266 break; 267 268 default: /* P_8x8 and P_8x8ref0 */ 269 if ( MvPrediction8x8(pMb, &pMbLayer->subMbPred, dpb) != HANTRO_OK) 270 return(HANTRO_NOK); 271 for (i = 0; i < 4; i++) 272 { 273 refImage.data = pMb->refAddr[i]; 274 subPartMode = 275 h264bsdSubMbPartMode(pMbLayer->subMbPred.subMbType[i]); 276 x = i & 0x1 ? 8 : 0; 277 y = i < 2 ? 0 : 8; 278 switch (subPartMode) 279 { 280 case MB_SP_8x8: 281 tmp = (x<<24) + (y<<16) + (8<<8) + 8; 282 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage, 283 colAndRow, tmp, pFill); 284 break; 285 286 case MB_SP_8x4: 287 tmp = (x<<24) + (y<<16) + (8<<8) + 4; 288 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage, 289 colAndRow, tmp, pFill); 290 tmp = (x<<24) + ((y+4)<<16) + (8<<8) + 4; 291 h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage, 292 colAndRow, tmp, pFill); 293 break; 294 295 case MB_SP_4x8: 296 tmp = (x<<24) + (y<<16) + (4<<8) + 8; 297 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage, 298 colAndRow, tmp, pFill); 299 tmp = ((x+4)<<24) + (y<<16) + (4<<8) + 8; 300 h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage, 301 colAndRow, tmp, pFill); 302 break; 303 304 default: 305 tmp = (x<<24) + (y<<16) + (4<<8) + 4; 306 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage, 307 colAndRow, tmp, pFill); 308 tmp = ((x+4)<<24) + (y<<16) + (4<<8) + 4; 309 h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage, 310 colAndRow, tmp, pFill); 311 tmp = (x<<24) + ((y+4)<<16) + (4<<8) + 4; 312 h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage, 313 colAndRow, tmp, pFill); 314 tmp = ((x+4)<<24) + ((y+4)<<16) + (4<<8) + 4; 315 h264bsdPredictSamples(data, pMb->mv+4*i+3, &refImage, 316 colAndRow, tmp, pFill); 317 break; 318 } 319 } 320 break; 321 } 322 323 /* if decoded flag > 1 -> mb has already been successfully decoded and 324 * written to output -> do not write again */ 325 if (pMb->decoded > 1) 326 return HANTRO_OK; 327 328 return(HANTRO_OK); 329 } 330 331 #else /* H264DEC_OMXDL */ 332 333 /*------------------------------------------------------------------------------ 334 335 Function: h264bsdInterPrediction 336 337 Functional description: 338 Processes one inter macroblock. Performs motion vector prediction 339 and reconstructs prediction macroblock. Writes the final macroblock 340 (prediction + residual) into the output image (currImage) 341 342 Inputs: 343 pMb pointer to macroblock specific information 344 pMbLayer pointer to current macroblock data from stream 345 dpb pointer to decoded picture buffer 346 mbNum current macroblock number 347 currImage pointer to output image 348 data pointer where predicted macroblock will be stored 349 350 Outputs: 351 pMb structure is updated with current macroblock 352 currImage current macroblock is written into image 353 data prediction is stored here 354 355 Returns: 356 HANTRO_OK success 357 HANTRO_NOK error in motion vector prediction 358 359 ------------------------------------------------------------------------------*/ 360 u32 h264bsdInterPrediction(mbStorage_t *pMb, macroblockLayer_t *pMbLayer, 361 dpbStorage_t *dpb, u32 mbNum, image_t *currImage, u8 *data) 362 { 363 364 /* Variables */ 365 366 u32 i; 367 u32 x, y; 368 u32 row, col; 369 subMbPartMode_e subPartMode; 370 image_t refImage; 371 372 /* Code */ 373 374 ASSERT(pMb); 375 ASSERT(h264bsdMbPartPredMode(pMb->mbType) == PRED_MODE_INTER); 376 ASSERT(pMbLayer); 377 378 row = mbNum / currImage->width; 379 col = mbNum - row * currImage->width; 380 row *= 16; 381 col *= 16; 382 383 refImage.width = currImage->width; 384 refImage.height = currImage->height; 385 386 switch (pMb->mbType) 387 { 388 case P_Skip: 389 case P_L0_16x16: 390 if (MvPrediction16x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK) 391 return(HANTRO_NOK); 392 refImage.data = pMb->refAddr[0]; 393 h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0, 394 16, 16); 395 break; 396 397 case P_L0_L0_16x8: 398 if ( MvPrediction16x8(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK) 399 return(HANTRO_NOK); 400 refImage.data = pMb->refAddr[0]; 401 h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0, 402 16, 8); 403 refImage.data = pMb->refAddr[2]; 404 h264bsdPredictSamples(data, pMb->mv+8, &refImage, col, row, 0, 8, 405 16, 8); 406 break; 407 408 case P_L0_L0_8x16: 409 if ( MvPrediction8x16(pMb, &pMbLayer->mbPred, dpb) != HANTRO_OK) 410 return(HANTRO_NOK); 411 refImage.data = pMb->refAddr[0]; 412 h264bsdPredictSamples(data, pMb->mv, &refImage, col, row, 0, 0, 413 8, 16); 414 refImage.data = pMb->refAddr[1]; 415 h264bsdPredictSamples(data, pMb->mv+4, &refImage, col, row, 8, 0, 416 8, 16); 417 break; 418 419 default: /* P_8x8 and P_8x8ref0 */ 420 if ( MvPrediction8x8(pMb, &pMbLayer->subMbPred, dpb) != HANTRO_OK) 421 return(HANTRO_NOK); 422 for (i = 0; i < 4; i++) 423 { 424 refImage.data = pMb->refAddr[i]; 425 subPartMode = 426 h264bsdSubMbPartMode(pMbLayer->subMbPred.subMbType[i]); 427 x = i & 0x1 ? 8 : 0; 428 y = i < 2 ? 0 : 8; 429 switch (subPartMode) 430 { 431 case MB_SP_8x8: 432 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage, 433 col, row, x, y, 8, 8); 434 break; 435 436 case MB_SP_8x4: 437 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage, 438 col, row, x, y, 8, 4); 439 h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage, 440 col, row, x, y+4, 8, 4); 441 break; 442 443 case MB_SP_4x8: 444 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage, 445 col, row, x, y, 4, 8); 446 h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage, 447 col, row, x+4, y, 4, 8); 448 break; 449 450 default: 451 h264bsdPredictSamples(data, pMb->mv+4*i, &refImage, 452 col, row, x, y, 4, 4); 453 h264bsdPredictSamples(data, pMb->mv+4*i+1, &refImage, 454 col, row, x+4, y, 4, 4); 455 h264bsdPredictSamples(data, pMb->mv+4*i+2, &refImage, 456 col, row, x, y+4, 4, 4); 457 h264bsdPredictSamples(data, pMb->mv+4*i+3, &refImage, 458 col, row, x+4, y+4, 4, 4); 459 break; 460 } 461 } 462 break; 463 } 464 465 /* if decoded flag > 1 -> mb has already been successfully decoded and 466 * written to output -> do not write again */ 467 if (pMb->decoded > 1) 468 return HANTRO_OK; 469 470 if (pMb->mbType != P_Skip) 471 { 472 h264bsdWriteOutputBlocks(currImage, mbNum, data, 473 pMbLayer->residual.level); 474 } 475 else 476 { 477 h264bsdWriteMacroblock(currImage, data); 478 } 479 480 return(HANTRO_OK); 481 } 482 #endif /* H264DEC_OMXDL */ 483 484 /*------------------------------------------------------------------------------ 485 486 Function: MvPrediction16x16 487 488 Functional description: 489 Motion vector prediction for 16x16 partition mode 490 491 ------------------------------------------------------------------------------*/ 492 493 u32 MvPrediction16x16(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb) 494 { 495 496 /* Variables */ 497 498 mv_t mv; 499 mv_t mvPred; 500 interNeighbour_t a[3]; /* A, B, C */ 501 u32 refIndex; 502 u8 *tmp; 503 u32 *tmpMv1, *tmpMv2; 504 505 /* Code */ 506 507 refIndex = mbPred->refIdxL0[0]; 508 509 GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5); 510 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10); 511 /*lint --e(740) Unusual pointer cast (incompatible indirect types) */ 512 tmpMv1 = (u32*)(&a[0].mv); /* we test just that both MVs are zero */ 513 /*lint --e(740) */ 514 tmpMv2 = (u32*)(&a[1].mv); /* i.e. a[0].mv.hor == 0 && a[0].mv.ver == 0 */ 515 if (pMb->mbType == P_Skip && 516 (!a[0].available || !a[1].available || 517 ( a[0].refIndex == 0 && ((u32)(*tmpMv1) == 0) ) || 518 ( a[1].refIndex == 0 && ((u32)(*tmpMv2) == 0) ))) 519 { 520 mv.hor = mv.ver = 0; 521 } 522 else 523 { 524 mv = mbPred->mvdL0[0]; 525 GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10); 526 if (!a[2].available) 527 { 528 GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15); 529 } 530 531 GetPredictionMv(&mvPred, a, refIndex); 532 533 mv.hor += mvPred.hor; 534 mv.ver += mvPred.ver; 535 536 /* horizontal motion vector range [-2048, 2047.75] */ 537 if ((u32)(i32)(mv.hor+8192) >= (16384)) 538 return(HANTRO_NOK); 539 540 /* vertical motion vector range [-512, 511.75] 541 * (smaller for low levels) */ 542 if ((u32)(i32)(mv.ver+2048) >= (4096)) 543 return(HANTRO_NOK); 544 } 545 546 tmp = h264bsdGetRefPicData(dpb, refIndex); 547 if (tmp == NULL) 548 return(HANTRO_NOK); 549 550 pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] = 551 pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] = 552 pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] = 553 pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv; 554 555 pMb->refPic[0] = refIndex; 556 pMb->refPic[1] = refIndex; 557 pMb->refPic[2] = refIndex; 558 pMb->refPic[3] = refIndex; 559 pMb->refAddr[0] = tmp; 560 pMb->refAddr[1] = tmp; 561 pMb->refAddr[2] = tmp; 562 pMb->refAddr[3] = tmp; 563 564 return(HANTRO_OK); 565 566 } 567 568 /*------------------------------------------------------------------------------ 569 570 Function: MvPrediction16x8 571 572 Functional description: 573 Motion vector prediction for 16x8 partition mode 574 575 ------------------------------------------------------------------------------*/ 576 577 u32 MvPrediction16x8(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb) 578 { 579 580 /* Variables */ 581 582 mv_t mv; 583 mv_t mvPred; 584 interNeighbour_t a[3]; /* A, B, C */ 585 u32 refIndex; 586 u8 *tmp; 587 588 /* Code */ 589 590 mv = mbPred->mvdL0[0]; 591 refIndex = mbPred->refIdxL0[0]; 592 593 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10); 594 595 if (a[1].refIndex == refIndex) 596 mvPred = a[1].mv; 597 else 598 { 599 GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5); 600 GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10); 601 if (!a[2].available) 602 { 603 GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15); 604 } 605 606 GetPredictionMv(&mvPred, a, refIndex); 607 608 } 609 mv.hor += mvPred.hor; 610 mv.ver += mvPred.ver; 611 612 /* horizontal motion vector range [-2048, 2047.75] */ 613 if ((u32)(i32)(mv.hor+8192) >= (16384)) 614 return(HANTRO_NOK); 615 616 /* vertical motion vector range [-512, 511.75] (smaller for low levels) */ 617 if ((u32)(i32)(mv.ver+2048) >= (4096)) 618 return(HANTRO_NOK); 619 620 tmp = h264bsdGetRefPicData(dpb, refIndex); 621 if (tmp == NULL) 622 return(HANTRO_NOK); 623 624 pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] = 625 pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] = mv; 626 pMb->refPic[0] = refIndex; 627 pMb->refPic[1] = refIndex; 628 pMb->refAddr[0] = tmp; 629 pMb->refAddr[1] = tmp; 630 631 mv = mbPred->mvdL0[1]; 632 refIndex = mbPred->refIdxL0[1]; 633 634 GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 13); 635 if (a[0].refIndex == refIndex) 636 mvPred = a[0].mv; 637 else 638 { 639 a[1].available = HANTRO_TRUE; 640 a[1].refIndex = pMb->refPic[0]; 641 a[1].mv = pMb->mv[0]; 642 643 /* c is not available */ 644 GetInterNeighbour(pMb->sliceId, pMb->mbA, a+2, 7); 645 646 GetPredictionMv(&mvPred, a, refIndex); 647 648 } 649 mv.hor += mvPred.hor; 650 mv.ver += mvPred.ver; 651 652 /* horizontal motion vector range [-2048, 2047.75] */ 653 if ((u32)(i32)(mv.hor+8192) >= (16384)) 654 return(HANTRO_NOK); 655 656 /* vertical motion vector range [-512, 511.75] (smaller for low levels) */ 657 if ((u32)(i32)(mv.ver+2048) >= (4096)) 658 return(HANTRO_NOK); 659 660 tmp = h264bsdGetRefPicData(dpb, refIndex); 661 if (tmp == NULL) 662 return(HANTRO_NOK); 663 664 pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] = 665 pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv; 666 pMb->refPic[2] = refIndex; 667 pMb->refPic[3] = refIndex; 668 pMb->refAddr[2] = tmp; 669 pMb->refAddr[3] = tmp; 670 671 return(HANTRO_OK); 672 673 } 674 675 /*------------------------------------------------------------------------------ 676 677 Function: MvPrediction8x16 678 679 Functional description: 680 Motion vector prediction for 8x16 partition mode 681 682 ------------------------------------------------------------------------------*/ 683 684 u32 MvPrediction8x16(mbStorage_t *pMb, mbPred_t *mbPred, dpbStorage_t *dpb) 685 { 686 687 /* Variables */ 688 689 mv_t mv; 690 mv_t mvPred; 691 interNeighbour_t a[3]; /* A, B, C */ 692 u32 refIndex; 693 u8 *tmp; 694 695 /* Code */ 696 697 mv = mbPred->mvdL0[0]; 698 refIndex = mbPred->refIdxL0[0]; 699 700 GetInterNeighbour(pMb->sliceId, pMb->mbA, a, 5); 701 702 if (a[0].refIndex == refIndex) 703 mvPred = a[0].mv; 704 else 705 { 706 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 10); 707 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+2, 14); 708 if (!a[2].available) 709 { 710 GetInterNeighbour(pMb->sliceId, pMb->mbD, a+2, 15); 711 } 712 713 GetPredictionMv(&mvPred, a, refIndex); 714 715 } 716 mv.hor += mvPred.hor; 717 mv.ver += mvPred.ver; 718 719 /* horizontal motion vector range [-2048, 2047.75] */ 720 if ((u32)(i32)(mv.hor+8192) >= (16384)) 721 return(HANTRO_NOK); 722 723 /* vertical motion vector range [-512, 511.75] (smaller for low levels) */ 724 if ((u32)(i32)(mv.ver+2048) >= (4096)) 725 return(HANTRO_NOK); 726 727 tmp = h264bsdGetRefPicData(dpb, refIndex); 728 if (tmp == NULL) 729 return(HANTRO_NOK); 730 731 pMb->mv[0] = pMb->mv[1] = pMb->mv[2] = pMb->mv[3] = 732 pMb->mv[8] = pMb->mv[9] = pMb->mv[10] = pMb->mv[11] = mv; 733 pMb->refPic[0] = refIndex; 734 pMb->refPic[2] = refIndex; 735 pMb->refAddr[0] = tmp; 736 pMb->refAddr[2] = tmp; 737 738 mv = mbPred->mvdL0[1]; 739 refIndex = mbPred->refIdxL0[1]; 740 741 GetInterNeighbour(pMb->sliceId, pMb->mbC, a+2, 10); 742 if (!a[2].available) 743 { 744 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+2, 11); 745 } 746 if (a[2].refIndex == refIndex) 747 mvPred = a[2].mv; 748 else 749 { 750 a[0].available = HANTRO_TRUE; 751 a[0].refIndex = pMb->refPic[0]; 752 a[0].mv = pMb->mv[0]; 753 754 GetInterNeighbour(pMb->sliceId, pMb->mbB, a+1, 14); 755 756 GetPredictionMv(&mvPred, a, refIndex); 757 758 } 759 mv.hor += mvPred.hor; 760 mv.ver += mvPred.ver; 761 762 /* horizontal motion vector range [-2048, 2047.75] */ 763 if ((u32)(i32)(mv.hor+8192) >= (16384)) 764 return(HANTRO_NOK); 765 766 /* vertical motion vector range [-512, 511.75] (smaller for low levels) */ 767 if ((u32)(i32)(mv.ver+2048) >= (4096)) 768 return(HANTRO_NOK); 769 770 tmp = h264bsdGetRefPicData(dpb, refIndex); 771 if (tmp == NULL) 772 return(HANTRO_NOK); 773 774 pMb->mv[4] = pMb->mv[5] = pMb->mv[6] = pMb->mv[7] = 775 pMb->mv[12] = pMb->mv[13] = pMb->mv[14] = pMb->mv[15] = mv; 776 pMb->refPic[1] = refIndex; 777 pMb->refPic[3] = refIndex; 778 pMb->refAddr[1] = tmp; 779 pMb->refAddr[3] = tmp; 780 781 return(HANTRO_OK); 782 783 } 784 785 /*------------------------------------------------------------------------------ 786 787 Function: MvPrediction8x8 788 789 Functional description: 790 Motion vector prediction for 8x8 partition mode 791 792 ------------------------------------------------------------------------------*/ 793 794 u32 MvPrediction8x8(mbStorage_t *pMb, subMbPred_t *subMbPred, dpbStorage_t *dpb) 795 { 796 797 /* Variables */ 798 799 u32 i, j; 800 u32 numSubMbPart; 801 802 /* Code */ 803 804 for (i = 0; i < 4; i++) 805 { 806 numSubMbPart = h264bsdNumSubMbPart(subMbPred->subMbType[i]); 807 pMb->refPic[i] = subMbPred->refIdxL0[i]; 808 pMb->refAddr[i] = h264bsdGetRefPicData(dpb, subMbPred->refIdxL0[i]); 809 if (pMb->refAddr[i] == NULL) 810 return(HANTRO_NOK); 811 for (j = 0; j < numSubMbPart; j++) 812 { 813 if (MvPrediction(pMb, subMbPred, i, j) != HANTRO_OK) 814 return(HANTRO_NOK); 815 } 816 } 817 818 return(HANTRO_OK); 819 820 } 821 822 /*------------------------------------------------------------------------------ 823 824 Function: MvPrediction 825 826 Functional description: 827 Perform motion vector prediction for sub-partition 828 829 ------------------------------------------------------------------------------*/ 830 831 u32 MvPrediction(mbStorage_t *pMb, subMbPred_t *subMbPred, u32 mbPartIdx, 832 u32 subMbPartIdx) 833 { 834 835 /* Variables */ 836 837 mv_t mv, mvPred; 838 u32 refIndex; 839 subMbPartMode_e subMbPartMode; 840 const neighbour_t *n; 841 mbStorage_t *nMb; 842 interNeighbour_t a[3]; /* A, B, C */ 843 844 /* Code */ 845 846 mv = subMbPred->mvdL0[mbPartIdx][subMbPartIdx]; 847 subMbPartMode = h264bsdSubMbPartMode(subMbPred->subMbType[mbPartIdx]); 848 refIndex = subMbPred->refIdxL0[mbPartIdx]; 849 850 n = N_A_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx; 851 nMb = h264bsdGetNeighbourMb(pMb, n->mb); 852 GetInterNeighbour(pMb->sliceId, nMb, a, n->index); 853 854 n = N_B_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx; 855 nMb = h264bsdGetNeighbourMb(pMb, n->mb); 856 GetInterNeighbour(pMb->sliceId, nMb, a+1, n->index); 857 858 n = N_C_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx; 859 nMb = h264bsdGetNeighbourMb(pMb, n->mb); 860 GetInterNeighbour(pMb->sliceId, nMb, a+2, n->index); 861 862 if (!a[2].available) 863 { 864 n = N_D_SUB_PART[mbPartIdx][subMbPartMode]+subMbPartIdx; 865 nMb = h264bsdGetNeighbourMb(pMb, n->mb); 866 GetInterNeighbour(pMb->sliceId, nMb, a+2, n->index); 867 } 868 869 GetPredictionMv(&mvPred, a, refIndex); 870 871 mv.hor += mvPred.hor; 872 mv.ver += mvPred.ver; 873 874 /* horizontal motion vector range [-2048, 2047.75] */ 875 if (((u32)(i32)(mv.hor+8192) >= (16384))) 876 return(HANTRO_NOK); 877 878 /* vertical motion vector range [-512, 511.75] (smaller for low levels) */ 879 if (((u32)(i32)(mv.ver+2048) >= (4096))) 880 return(HANTRO_NOK); 881 882 switch (subMbPartMode) 883 { 884 case MB_SP_8x8: 885 pMb->mv[4*mbPartIdx] = mv; 886 pMb->mv[4*mbPartIdx + 1] = mv; 887 pMb->mv[4*mbPartIdx + 2] = mv; 888 pMb->mv[4*mbPartIdx + 3] = mv; 889 break; 890 891 case MB_SP_8x4: 892 pMb->mv[4*mbPartIdx + 2*subMbPartIdx] = mv; 893 pMb->mv[4*mbPartIdx + 2*subMbPartIdx + 1] = mv; 894 break; 895 896 case MB_SP_4x8: 897 pMb->mv[4*mbPartIdx + subMbPartIdx] = mv; 898 pMb->mv[4*mbPartIdx + subMbPartIdx + 2] = mv; 899 break; 900 901 case MB_SP_4x4: 902 pMb->mv[4*mbPartIdx + subMbPartIdx] = mv; 903 break; 904 } 905 906 return(HANTRO_OK); 907 908 } 909 910 /*------------------------------------------------------------------------------ 911 912 Function: MedianFilter 913 914 Functional description: 915 Median filtering for motion vector prediction 916 917 ------------------------------------------------------------------------------*/ 918 919 i32 MedianFilter(i32 a, i32 b, i32 c) 920 { 921 922 /* Variables */ 923 924 i32 max,min,med; 925 926 /* Code */ 927 928 max = min = med = a; 929 if (b > max) 930 { 931 max = b; 932 } 933 else if (b < min) 934 { 935 min = b; 936 } 937 if (c > max) 938 { 939 med = max; 940 } 941 else if (c < min) 942 { 943 med = min; 944 } 945 else 946 { 947 med = c; 948 } 949 950 return(med); 951 } 952 953 /*------------------------------------------------------------------------------ 954 955 Function: GetInterNeighbour 956 957 Functional description: 958 Get availability, reference index and motion vector of a neighbour 959 960 ------------------------------------------------------------------------------*/ 961 962 void GetInterNeighbour(u32 sliceId, mbStorage_t *nMb, 963 interNeighbour_t *n, u32 index) 964 { 965 966 n->available = HANTRO_FALSE; 967 n->refIndex = 0xFFFFFFFF; 968 n->mv.hor = n->mv.ver = 0; 969 970 if (nMb && (sliceId == nMb->sliceId)) 971 { 972 u32 tmp; 973 mv_t tmpMv; 974 975 tmp = nMb->mbType; 976 n->available = HANTRO_TRUE; 977 /* MbPartPredMode "inlined" */ 978 if (tmp <= P_8x8ref0) 979 { 980 tmpMv = nMb->mv[index]; 981 tmp = nMb->refPic[index>>2]; 982 n->refIndex = tmp; 983 n->mv = tmpMv; 984 } 985 } 986 987 } 988 989 /*------------------------------------------------------------------------------ 990 991 Function: GetPredictionMv 992 993 Functional description: 994 Compute motion vector predictor based on neighbours A, B and C 995 996 ------------------------------------------------------------------------------*/ 997 998 void GetPredictionMv(mv_t *mv, interNeighbour_t *a, u32 refIndex) 999 { 1000 1001 if ( a[1].available || a[2].available || !a[0].available) 1002 { 1003 u32 isA, isB, isC; 1004 isA = (a[0].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE; 1005 isB = (a[1].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE; 1006 isC = (a[2].refIndex == refIndex) ? HANTRO_TRUE : HANTRO_FALSE; 1007 1008 if (((u32)isA+(u32)isB+(u32)isC) != 1) 1009 { 1010 mv->hor = (i16)MedianFilter(a[0].mv.hor, a[1].mv.hor, a[2].mv.hor); 1011 mv->ver = (i16)MedianFilter(a[0].mv.ver, a[1].mv.ver, a[2].mv.ver); 1012 } 1013 else if (isA) 1014 *mv = a[0].mv; 1015 else if (isB) 1016 *mv = a[1].mv; 1017 else 1018 *mv = a[2].mv; 1019 } 1020 else 1021 { 1022 *mv = a[0].mv; 1023 } 1024 1025 } 1026 1027 1028