/H264Dec/source/h264bsd_inter_prediction.c

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