PageRenderTime 64ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/H264Dec/source/h264bsd_intra_prediction.c

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