PageRenderTime 66ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/H264Dec/source/h264bsd_deblocking.c

http://github.com/mbebenita/Broadway
C | 2417 lines | 1698 code | 295 blank | 424 comment | 323 complexity | 7c34d152f359d1bdba24d54c513ce489 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. h264bsdFilterPicture
  24. FilterVerLumaEdge
  25. FilterHorLumaEdge
  26. FilterHorLuma
  27. FilterVerChromaEdge
  28. FilterHorChromaEdge
  29. FilterHorChroma
  30. InnerBoundaryStrength
  31. EdgeBoundaryStrength
  32. GetBoundaryStrengths
  33. IsSliceBoundaryOnLeft
  34. IsSliceBoundaryOnTop
  35. GetMbFilteringFlags
  36. GetLumaEdgeThresholds
  37. GetChromaEdgeThresholds
  38. FilterLuma
  39. FilterChroma
  40. ------------------------------------------------------------------------------*/
  41. /*------------------------------------------------------------------------------
  42. 1. Include headers
  43. ------------------------------------------------------------------------------*/
  44. #include "basetype.h"
  45. #include "h264bsd_util.h"
  46. #include "h264bsd_macroblock_layer.h"
  47. #include "h264bsd_deblocking.h"
  48. #include "h264bsd_dpb.h"
  49. #ifdef H264DEC_OMXDL
  50. #include "omxtypes.h"
  51. #include "omxVC.h"
  52. #include "armVC.h"
  53. #endif /* H264DEC_OMXDL */
  54. /*------------------------------------------------------------------------------
  55. 2. External compiler flags
  56. --------------------------------------------------------------------------------
  57. --------------------------------------------------------------------------------
  58. 3. Module defines
  59. ------------------------------------------------------------------------------*/
  60. /* Switch off the following Lint messages for this file:
  61. * Info 701: Shift left of signed quantity (int)
  62. * Info 702: Shift right of signed quantity (int)
  63. */
  64. /*lint -e701 -e702 */
  65. /* array of alpha values, from the standard */
  66. static const u8 alphas[52] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,5,6,7,8,9,10,
  67. 12,13,15,17,20,22,25,28,32,36,40,45,50,56,63,71,80,90,101,113,127,144,162,
  68. 182,203,226,255,255};
  69. /* array of beta values, from the standard */
  70. static const u8 betas[52] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,3,4,4,
  71. 4,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18};
  72. #ifndef H264DEC_OMXDL
  73. /* array of tc0 values, from the standard, each triplet corresponds to a
  74. * column in the table. Indexing goes as tc0[indexA][bS-1] */
  75. static const u8 tc0[52][3] = {
  76. {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
  77. {0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0},
  78. {0,0,0},{0,0,1},{0,0,1},{0,0,1},{0,0,1},{0,1,1},{0,1,1},{1,1,1},
  79. {1,1,1},{1,1,1},{1,1,1},{1,1,2},{1,1,2},{1,1,2},{1,1,2},{1,2,3},
  80. {1,2,3},{2,2,3},{2,2,4},{2,3,4},{2,3,4},{3,3,5},{3,4,6},{3,4,6},
  81. {4,5,7},{4,5,8},{4,6,9},{5,7,10},{6,8,11},{6,8,13},{7,10,14},{8,11,16},
  82. {9,12,18},{10,13,20},{11,15,23},{13,17,25}
  83. };
  84. #else
  85. /* array of tc0 values, from the standard, each triplet corresponds to a
  86. * column in the table. Indexing goes as tc0[indexA][bS] */
  87. static const u8 tc0[52][5] = {
  88. {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},
  90. {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},
  92. {0, 0, 0, 0, 0}, {0, 0, 0, 1, 0}, {0, 0, 0, 1, 0}, {0, 0, 0, 1, 0},
  93. {0, 0, 0, 1, 0}, {0, 0, 1, 1, 0}, {0, 0, 1, 1, 0}, {0, 1, 1, 1, 0},
  94. {0, 1, 1, 1, 0}, {0, 1, 1, 1, 0}, {0, 1, 1, 1, 0}, {0, 1, 1, 2, 0},
  95. {0, 1, 1, 2, 0}, {0, 1, 1, 2, 0}, {0, 1, 1, 2, 0}, {0, 1, 2, 3, 0},
  96. {0, 1, 2, 3, 0}, {0, 2, 2, 3, 0}, {0, 2, 2, 4, 0}, {0, 2, 3, 4, 0},
  97. {0, 2, 3, 4, 0}, {0, 3, 3, 5, 0}, {0, 3, 4, 6, 0}, {0, 3, 4, 6, 0},
  98. {0, 4, 5, 7, 0}, {0, 4, 5, 8, 0}, {0, 4, 6, 9, 0}, {0, 5, 7, 10, 0},
  99. {0, 6, 8, 11, 0}, {0, 6, 8, 13, 0}, {0, 7, 10, 14, 0},
  100. {0, 8, 11, 16, 0}, {0, 9, 12, 18, 0}, {0, 10, 13, 20, 0},
  101. {0, 11, 15, 23, 0}, {0, 13, 17, 25, 0}
  102. };
  103. #endif
  104. #ifndef H264DEC_OMXDL
  105. /* mapping of raster scan block index to 4x4 block index */
  106. static const u32 mb4x4Index[16] =
  107. {0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15};
  108. typedef struct {
  109. const u8 *tc0;
  110. u32 alpha;
  111. u32 beta;
  112. } edgeThreshold_t;
  113. typedef struct {
  114. u32 top;
  115. u32 left;
  116. } bS_t;
  117. enum { TOP = 0, LEFT = 1, INNER = 2 };
  118. #endif /* H264DEC_OMXDL */
  119. #define FILTER_LEFT_EDGE 0x04
  120. #define FILTER_TOP_EDGE 0x02
  121. #define FILTER_INNER_EDGE 0x01
  122. /* clipping table defined in intra_prediction.c */
  123. extern const u8 h264bsdClip[];
  124. /*------------------------------------------------------------------------------
  125. 4. Local function prototypes
  126. ------------------------------------------------------------------------------*/
  127. static u32 InnerBoundaryStrength(mbStorage_t *mb1, u32 i1, u32 i2);
  128. #ifndef H264DEC_OMXDL
  129. static u32 EdgeBoundaryStrength(mbStorage_t *mb1, mbStorage_t *mb2,
  130. u32 i1, u32 i2);
  131. #else
  132. static u32 InnerBoundaryStrength2(mbStorage_t *mb1, u32 i1, u32 i2);
  133. static u32 EdgeBoundaryStrengthLeft(mbStorage_t *mb1, mbStorage_t *mb2);
  134. static u32 EdgeBoundaryStrengthTop(mbStorage_t *mb1, mbStorage_t *mb2);
  135. #endif
  136. static u32 IsSliceBoundaryOnLeft(mbStorage_t *mb);
  137. static u32 IsSliceBoundaryOnTop(mbStorage_t *mb);
  138. static u32 GetMbFilteringFlags(mbStorage_t *mb);
  139. #ifndef H264DEC_OMXDL
  140. static u32 GetBoundaryStrengths(mbStorage_t *mb, bS_t *bs, u32 flags);
  141. static void FilterLuma(u8 *data, bS_t *bS, edgeThreshold_t *thresholds,
  142. u32 imageWidth);
  143. static void FilterChroma(u8 *cb, u8 *cr, bS_t *bS, edgeThreshold_t *thresholds,
  144. u32 imageWidth);
  145. static void FilterVerLumaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
  146. u32 imageWidth);
  147. static void FilterHorLumaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
  148. i32 imageWidth);
  149. static void FilterHorLuma( u8 *data, u32 bS, edgeThreshold_t *thresholds,
  150. i32 imageWidth);
  151. static void FilterVerChromaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
  152. u32 imageWidth);
  153. static void FilterHorChromaEdge( u8 *data, u32 bS, edgeThreshold_t *thresholds,
  154. i32 imageWidth);
  155. static void FilterHorChroma( u8 *data, u32 bS, edgeThreshold_t *thresholds,
  156. i32 imageWidth);
  157. static void GetLumaEdgeThresholds(
  158. edgeThreshold_t *thresholds,
  159. mbStorage_t *mb,
  160. u32 filteringFlags);
  161. static void GetChromaEdgeThresholds(
  162. edgeThreshold_t *thresholds,
  163. mbStorage_t *mb,
  164. u32 filteringFlags,
  165. i32 chromaQpIndexOffset);
  166. #else /* H264DEC_OMXDL */
  167. static u32 GetBoundaryStrengths(mbStorage_t *mb, u8 (*bs)[16], u32 flags);
  168. static void GetLumaEdgeThresholds(
  169. mbStorage_t *mb,
  170. u8 (*alpha)[2],
  171. u8 (*beta)[2],
  172. u8 (*threshold)[16],
  173. u8 (*bs)[16],
  174. u32 filteringFlags );
  175. static void GetChromaEdgeThresholds(
  176. mbStorage_t *mb,
  177. u8 (*alpha)[2],
  178. u8 (*beta)[2],
  179. u8 (*threshold)[8],
  180. u8 (*bs)[16],
  181. u32 filteringFlags,
  182. i32 chromaQpIndexOffset);
  183. #endif /* H264DEC_OMXDL */
  184. /*------------------------------------------------------------------------------
  185. Function: IsSliceBoundaryOnLeft
  186. Functional description:
  187. Function to determine if there is a slice boundary on the left side
  188. of a macroblock.
  189. ------------------------------------------------------------------------------*/
  190. u32 IsSliceBoundaryOnLeft(mbStorage_t *mb)
  191. {
  192. /* Variables */
  193. /* Code */
  194. ASSERT(mb && mb->mbA);
  195. if (mb->sliceId != mb->mbA->sliceId)
  196. return(HANTRO_TRUE);
  197. else
  198. return(HANTRO_FALSE);
  199. }
  200. /*------------------------------------------------------------------------------
  201. Function: IsSliceBoundaryOnTop
  202. Functional description:
  203. Function to determine if there is a slice boundary above the
  204. current macroblock.
  205. ------------------------------------------------------------------------------*/
  206. u32 IsSliceBoundaryOnTop(mbStorage_t *mb)
  207. {
  208. /* Variables */
  209. /* Code */
  210. ASSERT(mb && mb->mbB);
  211. if (mb->sliceId != mb->mbB->sliceId)
  212. return(HANTRO_TRUE);
  213. else
  214. return(HANTRO_FALSE);
  215. }
  216. /*------------------------------------------------------------------------------
  217. Function: GetMbFilteringFlags
  218. Functional description:
  219. Function to determine which edges of a macroblock has to be
  220. filtered. Output is a bit-wise OR of FILTER_LEFT_EDGE,
  221. FILTER_TOP_EDGE and FILTER_INNER_EDGE, depending on which edges
  222. shall be filtered.
  223. ------------------------------------------------------------------------------*/
  224. u32 GetMbFilteringFlags(mbStorage_t *mb)
  225. {
  226. /* Variables */
  227. u32 flags = 0;
  228. /* Code */
  229. ASSERT(mb);
  230. /* nothing will be filtered if disableDeblockingFilterIdc == 1 */
  231. if (mb->disableDeblockingFilterIdc != 1)
  232. {
  233. flags |= FILTER_INNER_EDGE;
  234. /* filterLeftMbEdgeFlag, left mb is MB_A */
  235. if (mb->mbA &&
  236. ((mb->disableDeblockingFilterIdc != 2) ||
  237. !IsSliceBoundaryOnLeft(mb)))
  238. flags |= FILTER_LEFT_EDGE;
  239. /* filterTopMbEdgeFlag */
  240. if (mb->mbB &&
  241. ((mb->disableDeblockingFilterIdc != 2) ||
  242. !IsSliceBoundaryOnTop(mb)))
  243. flags |= FILTER_TOP_EDGE;
  244. }
  245. return(flags);
  246. }
  247. /*------------------------------------------------------------------------------
  248. Function: InnerBoundaryStrength
  249. Functional description:
  250. Function to calculate boundary strength value bs for an inner
  251. edge of a macroblock. Macroblock type is checked before this is
  252. called -> no intra mb condition here.
  253. ------------------------------------------------------------------------------*/
  254. u32 InnerBoundaryStrength(mbStorage_t *mb1, u32 ind1, u32 ind2)
  255. {
  256. i32 tmp1, tmp2;
  257. i32 mv1, mv2, mv3, mv4;
  258. tmp1 = mb1->totalCoeff[ind1];
  259. tmp2 = mb1->totalCoeff[ind2];
  260. mv1 = mb1->mv[ind1].hor;
  261. mv2 = mb1->mv[ind2].hor;
  262. mv3 = mb1->mv[ind1].ver;
  263. mv4 = mb1->mv[ind2].ver;
  264. if (tmp1 || tmp2)
  265. {
  266. return 2;
  267. }
  268. else if ( (ABS(mv1 - mv2) >= 4) || (ABS(mv3 - mv4) >= 4) ||
  269. (mb1->refAddr[ind1 >> 2] != mb1->refAddr[ind2 >> 2]) )
  270. {
  271. return 1;
  272. }
  273. else
  274. return 0;
  275. }
  276. /*------------------------------------------------------------------------------
  277. Function: InnerBoundaryStrength2
  278. Functional description:
  279. Function to calculate boundary strength value bs for an inner
  280. edge of a macroblock. The function is the same as
  281. InnerBoundaryStrength but without checking totalCoeff.
  282. ------------------------------------------------------------------------------*/
  283. u32 InnerBoundaryStrength2(mbStorage_t *mb1, u32 ind1, u32 ind2)
  284. {
  285. i32 tmp1, tmp2, tmp3, tmp4;
  286. tmp1 = mb1->mv[ind1].hor;
  287. tmp2 = mb1->mv[ind2].hor;
  288. tmp3 = mb1->mv[ind1].ver;
  289. tmp4 = mb1->mv[ind2].ver;
  290. if ( (ABS(tmp1 - tmp2) >= 4) || (ABS(tmp3 - tmp4) >= 4) ||
  291. (mb1->refAddr[ind1 >> 2] != mb1->refAddr[ind2 >> 2]))
  292. {
  293. return 1;
  294. }
  295. else
  296. return 0;
  297. }
  298. #ifndef H264DEC_OMXDL
  299. /*------------------------------------------------------------------------------
  300. Function: EdgeBoundaryStrength
  301. Functional description:
  302. Function to calculate boundary strength value bs for left- or
  303. top-most edge of a macroblock. Macroblock types are checked
  304. before this is called -> no intra mb conditions here.
  305. ------------------------------------------------------------------------------*/
  306. u32 EdgeBoundaryStrength(mbStorage_t *mb1, mbStorage_t *mb2,
  307. u32 ind1, u32 ind2)
  308. {
  309. if (mb1->totalCoeff[ind1] || mb2->totalCoeff[ind2])
  310. {
  311. return 2;
  312. }
  313. else if ((mb1->refAddr[ind1 >> 2] != mb2->refAddr[ind2 >> 2]) ||
  314. (ABS(mb1->mv[ind1].hor - mb2->mv[ind2].hor) >= 4) ||
  315. (ABS(mb1->mv[ind1].ver - mb2->mv[ind2].ver) >= 4))
  316. {
  317. return 1;
  318. }
  319. else
  320. return 0;
  321. }
  322. #else /* H264DEC_OMXDL */
  323. /*------------------------------------------------------------------------------
  324. Function: EdgeBoundaryStrengthTop
  325. Functional description:
  326. Function to calculate boundary strength value bs for
  327. top-most edge of a macroblock. Macroblock types are checked
  328. before this is called -> no intra mb conditions here.
  329. ------------------------------------------------------------------------------*/
  330. u32 EdgeBoundaryStrengthTop(mbStorage_t *mb1, mbStorage_t *mb2)
  331. {
  332. u32 topBs = 0;
  333. u32 tmp1, tmp2, tmp3, tmp4;
  334. tmp1 = mb1->totalCoeff[0];
  335. tmp2 = mb2->totalCoeff[10];
  336. tmp3 = mb1->totalCoeff[1];
  337. tmp4 = mb2->totalCoeff[11];
  338. if (tmp1 || tmp2)
  339. {
  340. topBs = 2<<0;
  341. }
  342. else if ((ABS(mb1->mv[0].hor - mb2->mv[10].hor) >= 4) ||
  343. (ABS(mb1->mv[0].ver - mb2->mv[10].ver) >= 4) ||
  344. (mb1->refAddr[0] != mb2->refAddr[10 >> 2]))
  345. {
  346. topBs = 1<<0;
  347. }
  348. tmp1 = mb1->totalCoeff[4];
  349. tmp2 = mb2->totalCoeff[14];
  350. if (tmp3 || tmp4)
  351. {
  352. topBs += 2<<8;
  353. }
  354. else if ((ABS(mb1->mv[1].hor - mb2->mv[11].hor) >= 4) ||
  355. (ABS(mb1->mv[1].ver - mb2->mv[11].ver) >= 4) ||
  356. (mb1->refAddr[0] != mb2->refAddr[11 >> 2]))
  357. {
  358. topBs += 1<<8;
  359. }
  360. tmp3 = mb1->totalCoeff[5];
  361. tmp4 = mb2->totalCoeff[15];
  362. if (tmp1 || tmp2)
  363. {
  364. topBs += 2<<16;
  365. }
  366. else if ((ABS(mb1->mv[4].hor - mb2->mv[14].hor) >= 4) ||
  367. (ABS(mb1->mv[4].ver - mb2->mv[14].ver) >= 4) ||
  368. (mb1->refAddr[4 >> 2] != mb2->refAddr[14 >> 2]))
  369. {
  370. topBs += 1<<16;
  371. }
  372. if (tmp3 || tmp4)
  373. {
  374. topBs += 2<<24;
  375. }
  376. else if ((ABS(mb1->mv[5].hor - mb2->mv[15].hor) >= 4) ||
  377. (ABS(mb1->mv[5].ver - mb2->mv[15].ver) >= 4) ||
  378. (mb1->refAddr[5 >> 2] != mb2->refAddr[15 >> 2]))
  379. {
  380. topBs += 1<<24;
  381. }
  382. return topBs;
  383. }
  384. /*------------------------------------------------------------------------------
  385. Function: EdgeBoundaryStrengthLeft
  386. Functional description:
  387. Function to calculate boundary strength value bs for left-
  388. edge of a macroblock. Macroblock types are checked
  389. before this is called -> no intra mb conditions here.
  390. ------------------------------------------------------------------------------*/
  391. u32 EdgeBoundaryStrengthLeft(mbStorage_t *mb1, mbStorage_t *mb2)
  392. {
  393. u32 leftBs = 0;
  394. u32 tmp1, tmp2, tmp3, tmp4;
  395. tmp1 = mb1->totalCoeff[0];
  396. tmp2 = mb2->totalCoeff[5];
  397. tmp3 = mb1->totalCoeff[2];
  398. tmp4 = mb2->totalCoeff[7];
  399. if (tmp1 || tmp2)
  400. {
  401. leftBs = 2<<0;
  402. }
  403. else if ((ABS(mb1->mv[0].hor - mb2->mv[5].hor) >= 4) ||
  404. (ABS(mb1->mv[0].ver - mb2->mv[5].ver) >= 4) ||
  405. (mb1->refAddr[0] != mb2->refAddr[5 >> 2]))
  406. {
  407. leftBs = 1<<0;
  408. }
  409. tmp1 = mb1->totalCoeff[8];
  410. tmp2 = mb2->totalCoeff[13];
  411. if (tmp3 || tmp4)
  412. {
  413. leftBs += 2<<8;
  414. }
  415. else if ((ABS(mb1->mv[2].hor - mb2->mv[7].hor) >= 4) ||
  416. (ABS(mb1->mv[2].ver - mb2->mv[7].ver) >= 4) ||
  417. (mb1->refAddr[0] != mb2->refAddr[7 >> 2]))
  418. {
  419. leftBs += 1<<8;
  420. }
  421. tmp3 = mb1->totalCoeff[10];
  422. tmp4 = mb2->totalCoeff[15];
  423. if (tmp1 || tmp2)
  424. {
  425. leftBs += 2<<16;
  426. }
  427. else if ((ABS(mb1->mv[8].hor - mb2->mv[13].hor) >= 4) ||
  428. (ABS(mb1->mv[8].ver - mb2->mv[13].ver) >= 4) ||
  429. (mb1->refAddr[8 >> 2] != mb2->refAddr[13 >> 2]))
  430. {
  431. leftBs += 1<<16;
  432. }
  433. if (tmp3 || tmp4)
  434. {
  435. leftBs += 2<<24;
  436. }
  437. else if ((ABS(mb1->mv[10].hor - mb2->mv[15].hor) >= 4) ||
  438. (ABS(mb1->mv[10].ver - mb2->mv[15].ver) >= 4) ||
  439. (mb1->refAddr[10 >> 2] != mb2->refAddr[15 >> 2]))
  440. {
  441. leftBs += 1<<24;
  442. }
  443. return leftBs;
  444. }
  445. #endif /* H264DEC_OMXDL */
  446. /*------------------------------------------------------------------------------
  447. Function: h264bsdFilterPicture
  448. Functional description:
  449. Perform deblocking filtering for a picture. Filter does not copy
  450. the original picture anywhere but filtering is performed directly
  451. on the original image. Parameters controlling the filtering process
  452. are computed based on information in macroblock structures of the
  453. filtered macroblock, macroblock above and macroblock on the left of
  454. the filtered one.
  455. Inputs:
  456. image pointer to image to be filtered
  457. mb pointer to macroblock data structure of the top-left
  458. macroblock of the picture
  459. Outputs:
  460. image filtered image stored here
  461. Returns:
  462. none
  463. ------------------------------------------------------------------------------*/
  464. #ifndef H264DEC_OMXDL
  465. void h264bsdFilterPicture(
  466. image_t *image,
  467. mbStorage_t *mb)
  468. {
  469. /* Variables */
  470. u32 flags;
  471. u32 picSizeInMbs, mbRow, mbCol;
  472. u32 picWidthInMbs;
  473. u8 *data;
  474. mbStorage_t *pMb;
  475. bS_t bS[16];
  476. edgeThreshold_t thresholds[3];
  477. /* Code */
  478. ASSERT(image);
  479. ASSERT(mb);
  480. ASSERT(image->data);
  481. ASSERT(image->width);
  482. ASSERT(image->height);
  483. picWidthInMbs = image->width;
  484. data = image->data;
  485. picSizeInMbs = picWidthInMbs * image->height;
  486. pMb = mb;
  487. for (mbRow = 0, mbCol = 0; mbRow < image->height; pMb++)
  488. {
  489. flags = GetMbFilteringFlags(pMb);
  490. if (flags)
  491. {
  492. /* GetBoundaryStrengths function returns non-zero value if any of
  493. * the bS values for the macroblock being processed was non-zero */
  494. if (GetBoundaryStrengths(pMb, bS, flags))
  495. {
  496. /* luma */
  497. GetLumaEdgeThresholds(thresholds, pMb, flags);
  498. data = image->data + mbRow * picWidthInMbs * 256 + mbCol * 16;
  499. FilterLuma((u8*)data, bS, thresholds, picWidthInMbs*16);
  500. /* chroma */
  501. GetChromaEdgeThresholds(thresholds, pMb, flags,
  502. pMb->chromaQpIndexOffset);
  503. data = image->data + picSizeInMbs * 256 +
  504. mbRow * picWidthInMbs * 64 + mbCol * 8;
  505. FilterChroma((u8*)data, data + 64*picSizeInMbs, bS,
  506. thresholds, picWidthInMbs*8);
  507. }
  508. }
  509. mbCol++;
  510. if (mbCol == picWidthInMbs)
  511. {
  512. mbCol = 0;
  513. mbRow++;
  514. }
  515. }
  516. }
  517. /*------------------------------------------------------------------------------
  518. Function: FilterVerLumaEdge
  519. Functional description:
  520. Filter one vertical 4-pixel luma edge.
  521. ------------------------------------------------------------------------------*/
  522. void FilterVerLumaEdge(
  523. u8 *data,
  524. u32 bS,
  525. edgeThreshold_t *thresholds,
  526. u32 imageWidth)
  527. {
  528. /* Variables */
  529. i32 delta, tc, tmp;
  530. u32 i;
  531. u8 p0, q0, p1, q1, p2, q2;
  532. u32 tmpFlag;
  533. const u8 *clp = h264bsdClip + 512;
  534. /* Code */
  535. ASSERT(data);
  536. ASSERT(bS && bS <= 4);
  537. ASSERT(thresholds);
  538. if (bS < 4)
  539. {
  540. tc = thresholds->tc0[bS-1];
  541. tmp = tc;
  542. for (i = 4; i; i--, data += imageWidth)
  543. {
  544. p1 = data[-2]; p0 = data[-1];
  545. q0 = data[0]; q1 = data[1];
  546. if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
  547. ((unsigned)ABS(p1-p0) < thresholds->beta) &&
  548. ((unsigned)ABS(q1-q0) < thresholds->beta) )
  549. {
  550. p2 = data[-3];
  551. q2 = data[2];
  552. if ((unsigned)ABS(p2-p0) < thresholds->beta)
  553. {
  554. data[-2] = (u8)(p1 + CLIP3(-tc,tc,
  555. (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
  556. tmp++;
  557. }
  558. if ((unsigned)ABS(q2-q0) < thresholds->beta)
  559. {
  560. data[1] = (u8)(q1 + CLIP3(-tc,tc,
  561. (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
  562. tmp++;
  563. }
  564. delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
  565. (p1 - q1) + 4) >> 3));
  566. p0 = clp[p0 + delta];
  567. q0 = clp[q0 - delta];
  568. tmp = tc;
  569. data[-1] = p0;
  570. data[ 0] = q0;
  571. }
  572. }
  573. }
  574. else
  575. {
  576. for (i = 4; i; i--, data += imageWidth)
  577. {
  578. p1 = data[-2]; p0 = data[-1];
  579. q0 = data[0]; q1 = data[1];
  580. if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
  581. ((unsigned)ABS(p1-p0) < thresholds->beta) &&
  582. ((unsigned)ABS(q1-q0) < thresholds->beta) )
  583. {
  584. tmpFlag =
  585. ((unsigned)ABS(p0-q0) < ((thresholds->alpha >> 2) +2)) ?
  586. HANTRO_TRUE : HANTRO_FALSE;
  587. p2 = data[-3];
  588. q2 = data[2];
  589. if (tmpFlag && (unsigned)ABS(p2-p0) < thresholds->beta)
  590. {
  591. tmp = p1 + p0 + q0;
  592. data[-1] = (u8)((p2 + 2 * tmp + q1 + 4) >> 3);
  593. data[-2] = (u8)((p2 + tmp + 2) >> 2);
  594. data[-3] = (u8)((2 * data[-4] + 3 * p2 + tmp + 4) >> 3);
  595. }
  596. else
  597. data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
  598. if (tmpFlag && (unsigned)ABS(q2-q0) < thresholds->beta)
  599. {
  600. tmp = p0 + q0 + q1;
  601. data[0] = (u8)((p1 + 2 * tmp + q2 + 4) >> 3);
  602. data[1] = (u8)((tmp + q2 + 2) >> 2);
  603. data[2] = (u8)((2 * data[3] + 3 * q2 + tmp + 4) >> 3);
  604. }
  605. else
  606. data[0] = (u8)((2 * q1 + q0 + p1 + 2) >> 2);
  607. }
  608. }
  609. }
  610. }
  611. /*------------------------------------------------------------------------------
  612. Function: FilterHorLumaEdge
  613. Functional description:
  614. Filter one horizontal 4-pixel luma edge
  615. ------------------------------------------------------------------------------*/
  616. void FilterHorLumaEdge(
  617. u8 *data,
  618. u32 bS,
  619. edgeThreshold_t *thresholds,
  620. i32 imageWidth)
  621. {
  622. /* Variables */
  623. i32 delta, tc, tmp;
  624. u32 i;
  625. u8 p0, q0, p1, q1, p2, q2;
  626. const u8 *clp = h264bsdClip + 512;
  627. /* Code */
  628. ASSERT(data);
  629. ASSERT(bS < 4);
  630. ASSERT(thresholds);
  631. tc = thresholds->tc0[bS-1];
  632. tmp = tc;
  633. for (i = 4; i; i--, data++)
  634. {
  635. p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
  636. q0 = data[0]; q1 = data[imageWidth];
  637. if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
  638. ((unsigned)ABS(p1-p0) < thresholds->beta) &&
  639. ((unsigned)ABS(q1-q0) < thresholds->beta) )
  640. {
  641. p2 = data[-imageWidth*3];
  642. if ((unsigned)ABS(p2-p0) < thresholds->beta)
  643. {
  644. data[-imageWidth*2] = (u8)(p1 + CLIP3(-tc,tc,
  645. (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
  646. tmp++;
  647. }
  648. q2 = data[imageWidth*2];
  649. if ((unsigned)ABS(q2-q0) < thresholds->beta)
  650. {
  651. data[imageWidth] = (u8)(q1 + CLIP3(-tc,tc,
  652. (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
  653. tmp++;
  654. }
  655. delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
  656. (p1 - q1) + 4) >> 3));
  657. p0 = clp[p0 + delta];
  658. q0 = clp[q0 - delta];
  659. tmp = tc;
  660. data[-imageWidth] = p0;
  661. data[ 0] = q0;
  662. }
  663. }
  664. }
  665. /*------------------------------------------------------------------------------
  666. Function: FilterHorLuma
  667. Functional description:
  668. Filter all four successive horizontal 4-pixel luma edges. This can
  669. be done when bS is equal to all four edges.
  670. ------------------------------------------------------------------------------*/
  671. void FilterHorLuma(
  672. u8 *data,
  673. u32 bS,
  674. edgeThreshold_t *thresholds,
  675. i32 imageWidth)
  676. {
  677. /* Variables */
  678. i32 delta, tc, tmp;
  679. u32 i;
  680. u8 p0, q0, p1, q1, p2, q2;
  681. u32 tmpFlag;
  682. const u8 *clp = h264bsdClip + 512;
  683. /* Code */
  684. ASSERT(data);
  685. ASSERT(bS <= 4);
  686. ASSERT(thresholds);
  687. if (bS < 4)
  688. {
  689. tc = thresholds->tc0[bS-1];
  690. tmp = tc;
  691. for (i = 16; i; i--, data++)
  692. {
  693. p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
  694. q0 = data[0]; q1 = data[imageWidth];
  695. if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
  696. ((unsigned)ABS(p1-p0) < thresholds->beta) &&
  697. ((unsigned)ABS(q1-q0) < thresholds->beta) )
  698. {
  699. p2 = data[-imageWidth*3];
  700. if ((unsigned)ABS(p2-p0) < thresholds->beta)
  701. {
  702. data[-imageWidth*2] = (u8)(p1 + CLIP3(-tc,tc,
  703. (p2 + ((p0 + q0 + 1) >> 1) - (p1 << 1)) >> 1));
  704. tmp++;
  705. }
  706. q2 = data[imageWidth*2];
  707. if ((unsigned)ABS(q2-q0) < thresholds->beta)
  708. {
  709. data[imageWidth] = (u8)(q1 + CLIP3(-tc,tc,
  710. (q2 + ((p0 + q0 + 1) >> 1) - (q1 << 1)) >> 1));
  711. tmp++;
  712. }
  713. delta = CLIP3(-tmp, tmp, ((((q0 - p0) << 2) +
  714. (p1 - q1) + 4) >> 3));
  715. p0 = clp[p0 + delta];
  716. q0 = clp[q0 - delta];
  717. tmp = tc;
  718. data[-imageWidth] = p0;
  719. data[ 0] = q0;
  720. }
  721. }
  722. }
  723. else
  724. {
  725. for (i = 16; i; i--, data++)
  726. {
  727. p1 = data[-imageWidth*2]; p0 = data[-imageWidth];
  728. q0 = data[0]; q1 = data[imageWidth];
  729. if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
  730. ((unsigned)ABS(p1-p0) < thresholds->beta) &&
  731. ((unsigned)ABS(q1-q0) < thresholds->beta) )
  732. {
  733. tmpFlag = ((unsigned)ABS(p0-q0) < ((thresholds->alpha >> 2) +2))
  734. ? HANTRO_TRUE : HANTRO_FALSE;
  735. p2 = data[-imageWidth*3];
  736. q2 = data[imageWidth*2];
  737. if (tmpFlag && (unsigned)ABS(p2-p0) < thresholds->beta)
  738. {
  739. tmp = p1 + p0 + q0;
  740. data[-imageWidth] = (u8)((p2 + 2 * tmp + q1 + 4) >> 3);
  741. data[-imageWidth*2] = (u8)((p2 + tmp + 2) >> 2);
  742. data[-imageWidth*3] = (u8)((2 * data[-imageWidth*4] +
  743. 3 * p2 + tmp + 4) >> 3);
  744. }
  745. else
  746. data[-imageWidth] = (u8)((2 * p1 + p0 + q1 + 2) >> 2);
  747. if (tmpFlag && (unsigned)ABS(q2-q0) < thresholds->beta)
  748. {
  749. tmp = p0 + q0 + q1;
  750. data[ 0] = (u8)((p1 + 2 * tmp + q2 + 4) >> 3);
  751. data[imageWidth] = (u8)((tmp + q2 + 2) >> 2);
  752. data[imageWidth*2] = (u8)((2 * data[imageWidth*3] +
  753. 3 * q2 + tmp + 4) >> 3);
  754. }
  755. else
  756. data[0] = (2 * q1 + q0 + p1 + 2) >> 2;
  757. }
  758. }
  759. }
  760. }
  761. /*------------------------------------------------------------------------------
  762. Function: FilterVerChromaEdge
  763. Functional description:
  764. Filter one vertical 2-pixel chroma edge
  765. ------------------------------------------------------------------------------*/
  766. void FilterVerChromaEdge(
  767. u8 *data,
  768. u32 bS,
  769. edgeThreshold_t *thresholds,
  770. u32 width)
  771. {
  772. /* Variables */
  773. i32 delta, tc;
  774. u8 p0, q0, p1, q1;
  775. const u8 *clp = h264bsdClip + 512;
  776. /* Code */
  777. ASSERT(data);
  778. ASSERT(bS <= 4);
  779. ASSERT(thresholds);
  780. p1 = data[-2]; p0 = data[-1];
  781. q0 = data[0]; q1 = data[1];
  782. if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
  783. ((unsigned)ABS(p1-p0) < thresholds->beta) &&
  784. ((unsigned)ABS(q1-q0) < thresholds->beta) )
  785. {
  786. if (bS < 4)
  787. {
  788. tc = thresholds->tc0[bS-1] + 1;
  789. delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
  790. (p1 - q1) + 4) >> 3));
  791. p0 = clp[p0 + delta];
  792. q0 = clp[q0 - delta];
  793. data[-1] = p0;
  794. data[ 0] = q0;
  795. }
  796. else
  797. {
  798. data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
  799. data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
  800. }
  801. }
  802. data += width;
  803. p1 = data[-2]; p0 = data[-1];
  804. q0 = data[0]; q1 = data[1];
  805. if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
  806. ((unsigned)ABS(p1-p0) < thresholds->beta) &&
  807. ((unsigned)ABS(q1-q0) < thresholds->beta) )
  808. {
  809. if (bS < 4)
  810. {
  811. tc = thresholds->tc0[bS-1] + 1;
  812. delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
  813. (p1 - q1) + 4) >> 3));
  814. p0 = clp[p0 + delta];
  815. q0 = clp[q0 - delta];
  816. data[-1] = p0;
  817. data[ 0] = q0;
  818. }
  819. else
  820. {
  821. data[-1] = (2 * p1 + p0 + q1 + 2) >> 2;
  822. data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
  823. }
  824. }
  825. }
  826. /*------------------------------------------------------------------------------
  827. Function: FilterHorChromaEdge
  828. Functional description:
  829. Filter one horizontal 2-pixel chroma edge
  830. ------------------------------------------------------------------------------*/
  831. void FilterHorChromaEdge(
  832. u8 *data,
  833. u32 bS,
  834. edgeThreshold_t *thresholds,
  835. i32 width)
  836. {
  837. /* Variables */
  838. i32 delta, tc;
  839. u32 i;
  840. u8 p0, q0, p1, q1;
  841. const u8 *clp = h264bsdClip + 512;
  842. /* Code */
  843. ASSERT(data);
  844. ASSERT(bS < 4);
  845. ASSERT(thresholds);
  846. tc = thresholds->tc0[bS-1] + 1;
  847. for (i = 2; i; i--, data++)
  848. {
  849. p1 = data[-width*2]; p0 = data[-width];
  850. q0 = data[0]; q1 = data[width];
  851. if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
  852. ((unsigned)ABS(p1-p0) < thresholds->beta) &&
  853. ((unsigned)ABS(q1-q0) < thresholds->beta) )
  854. {
  855. delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
  856. (p1 - q1) + 4) >> 3));
  857. p0 = clp[p0 + delta];
  858. q0 = clp[q0 - delta];
  859. data[-width] = p0;
  860. data[ 0] = q0;
  861. }
  862. }
  863. }
  864. /*------------------------------------------------------------------------------
  865. Function: FilterHorChroma
  866. Functional description:
  867. Filter all four successive horizontal 2-pixel chroma edges. This
  868. can be done if bS is equal for all four edges.
  869. ------------------------------------------------------------------------------*/
  870. void FilterHorChroma(
  871. u8 *data,
  872. u32 bS,
  873. edgeThreshold_t *thresholds,
  874. i32 width)
  875. {
  876. /* Variables */
  877. i32 delta, tc;
  878. u32 i;
  879. u8 p0, q0, p1, q1;
  880. const u8 *clp = h264bsdClip + 512;
  881. /* Code */
  882. ASSERT(data);
  883. ASSERT(bS <= 4);
  884. ASSERT(thresholds);
  885. if (bS < 4)
  886. {
  887. tc = thresholds->tc0[bS-1] + 1;
  888. for (i = 8; i; i--, data++)
  889. {
  890. p1 = data[-width*2]; p0 = data[-width];
  891. q0 = data[0]; q1 = data[width];
  892. if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
  893. ((unsigned)ABS(p1-p0) < thresholds->beta) &&
  894. ((unsigned)ABS(q1-q0) < thresholds->beta) )
  895. {
  896. delta = CLIP3(-tc, tc, ((((q0 - p0) << 2) +
  897. (p1 - q1) + 4) >> 3));
  898. p0 = clp[p0 + delta];
  899. q0 = clp[q0 - delta];
  900. data[-width] = p0;
  901. data[ 0] = q0;
  902. }
  903. }
  904. }
  905. else
  906. {
  907. for (i = 8; i; i--, data++)
  908. {
  909. p1 = data[-width*2]; p0 = data[-width];
  910. q0 = data[0]; q1 = data[width];
  911. if ( ((unsigned)ABS(p0-q0) < thresholds->alpha) &&
  912. ((unsigned)ABS(p1-p0) < thresholds->beta) &&
  913. ((unsigned)ABS(q1-q0) < thresholds->beta) )
  914. {
  915. data[-width] = (2 * p1 + p0 + q1 + 2) >> 2;
  916. data[ 0] = (2 * q1 + q0 + p1 + 2) >> 2;
  917. }
  918. }
  919. }
  920. }
  921. /*------------------------------------------------------------------------------
  922. Function: GetBoundaryStrengths
  923. Functional description:
  924. Function to calculate boundary strengths for all edges of a
  925. macroblock. Function returns HANTRO_TRUE if any of the bS values for
  926. the macroblock had non-zero value, HANTRO_FALSE otherwise.
  927. ------------------------------------------------------------------------------*/
  928. u32 GetBoundaryStrengths(mbStorage_t *mb, bS_t *bS, u32 flags)
  929. {
  930. /* Variables */
  931. /* this flag is set HANTRO_TRUE as soon as any boundary strength value is
  932. * non-zero */
  933. u32 nonZeroBs = HANTRO_FALSE;
  934. /* Code */
  935. ASSERT(mb);
  936. ASSERT(bS);
  937. ASSERT(flags);
  938. /* top edges */
  939. if (flags & FILTER_TOP_EDGE)
  940. {
  941. if (IS_INTRA_MB(*mb) || IS_INTRA_MB(*mb->mbB))
  942. {
  943. bS[0].top = bS[1].top = bS[2].top = bS[3].top = 4;
  944. nonZeroBs = HANTRO_TRUE;
  945. }
  946. else
  947. {
  948. bS[0].top = EdgeBoundaryStrength(mb, mb->mbB, 0, 10);
  949. bS[1].top = EdgeBoundaryStrength(mb, mb->mbB, 1, 11);
  950. bS[2].top = EdgeBoundaryStrength(mb, mb->mbB, 4, 14);
  951. bS[3].top = EdgeBoundaryStrength(mb, mb->mbB, 5, 15);
  952. if (bS[0].top || bS[1].top || bS[2].top || bS[3].top)
  953. nonZeroBs = HANTRO_TRUE;
  954. }
  955. }
  956. else
  957. {
  958. bS[0].top = bS[1].top = bS[2].top = bS[3].top = 0;
  959. }
  960. /* left edges */
  961. if (flags & FILTER_LEFT_EDGE)
  962. {
  963. if (IS_INTRA_MB(*mb) || IS_INTRA_MB(*mb->mbA))
  964. {
  965. bS[0].left = bS[4].left = bS[8].left = bS[12].left = 4;
  966. nonZeroBs = HANTRO_TRUE;
  967. }
  968. else
  969. {
  970. bS[0].left = EdgeBoundaryStrength(mb, mb->mbA, 0, 5);
  971. bS[4].left = EdgeBoundaryStrength(mb, mb->mbA, 2, 7);
  972. bS[8].left = EdgeBoundaryStrength(mb, mb->mbA, 8, 13);
  973. bS[12].left = EdgeBoundaryStrength(mb, mb->mbA, 10, 15);
  974. if (!nonZeroBs &&
  975. (bS[0].left || bS[4].left || bS[8].left || bS[12].left))
  976. nonZeroBs = HANTRO_TRUE;
  977. }
  978. }
  979. else
  980. {
  981. bS[0].left = bS[4].left = bS[8].left = bS[12].left = 0;
  982. }
  983. /* inner edges */
  984. if (IS_INTRA_MB(*mb))
  985. {
  986. bS[4].top = bS[5].top = bS[6].top = bS[7].top =
  987. bS[8].top = bS[9].top = bS[10].top = bS[11].top =
  988. bS[12].top = bS[13].top = bS[14].top = bS[15].top = 3;
  989. bS[1].left = bS[2].left = bS[3].left =
  990. bS[5].left = bS[6].left = bS[7].left =
  991. bS[9].left = bS[10].left = bS[11].left =
  992. bS[13].left = bS[14].left = bS[15].left = 3;
  993. nonZeroBs = HANTRO_TRUE;
  994. }
  995. else
  996. {
  997. /* 16x16 inter mb -> ref addresses or motion vectors cannot differ,
  998. * only check if either of the blocks contain coefficients */
  999. if (h264bsdNumMbPart(mb->mbType) == 1)
  1000. {
  1001. bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
  1002. bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
  1003. bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
  1004. bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
  1005. bS[8].top = mb->totalCoeff[8] || mb->totalCoeff[2] ? 2 : 0;
  1006. bS[9].top = mb->totalCoeff[9] || mb->totalCoeff[3] ? 2 : 0;
  1007. bS[10].top = mb->totalCoeff[12] || mb->totalCoeff[6] ? 2 : 0;
  1008. bS[11].top = mb->totalCoeff[13] || mb->totalCoeff[7] ? 2 : 0;
  1009. bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
  1010. bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
  1011. bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
  1012. bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
  1013. bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
  1014. bS[2].left = mb->totalCoeff[4] || mb->totalCoeff[1] ? 2 : 0;
  1015. bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
  1016. bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
  1017. bS[6].left = mb->totalCoeff[6] || mb->totalCoeff[3] ? 2 : 0;
  1018. bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
  1019. bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
  1020. bS[10].left = mb->totalCoeff[12] || mb->totalCoeff[9] ? 2 : 0;
  1021. bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
  1022. bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
  1023. bS[14].left = mb->totalCoeff[14] || mb->totalCoeff[11] ? 2 : 0;
  1024. bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
  1025. }
  1026. /* 16x8 inter mb -> ref addresses and motion vectors can be different
  1027. * only for the middle horizontal edge, for the other top edges it is
  1028. * enough to check whether the blocks contain coefficients or not. The
  1029. * same applies to all internal left edges. */
  1030. else if (mb->mbType == P_L0_L0_16x8)
  1031. {
  1032. bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
  1033. bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
  1034. bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
  1035. bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
  1036. bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
  1037. bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
  1038. bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
  1039. bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
  1040. bS[8].top = InnerBoundaryStrength(mb, 8, 2);
  1041. bS[9].top = InnerBoundaryStrength(mb, 9, 3);
  1042. bS[10].top = InnerBoundaryStrength(mb, 12, 6);
  1043. bS[11].top = InnerBoundaryStrength(mb, 13, 7);
  1044. bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
  1045. bS[2].left = mb->totalCoeff[4] || mb->totalCoeff[1] ? 2 : 0;
  1046. bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
  1047. bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
  1048. bS[6].left = mb->totalCoeff[6] || mb->totalCoeff[3] ? 2 : 0;
  1049. bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
  1050. bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
  1051. bS[10].left = mb->totalCoeff[12] || mb->totalCoeff[9] ? 2 : 0;
  1052. bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
  1053. bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
  1054. bS[14].left = mb->totalCoeff[14] || mb->totalCoeff[11] ? 2 : 0;
  1055. bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
  1056. }
  1057. /* 8x16 inter mb -> ref addresses and motion vectors can be different
  1058. * only for the middle vertical edge, for the other left edges it is
  1059. * enough to check whether the blocks contain coefficients or not. The
  1060. * same applies to all internal top edges. */
  1061. else if (mb->mbType == P_L0_L0_8x16)
  1062. {
  1063. bS[4].top = mb->totalCoeff[2] || mb->totalCoeff[0] ? 2 : 0;
  1064. bS[5].top = mb->totalCoeff[3] || mb->totalCoeff[1] ? 2 : 0;
  1065. bS[6].top = mb->totalCoeff[6] || mb->totalCoeff[4] ? 2 : 0;
  1066. bS[7].top = mb->totalCoeff[7] || mb->totalCoeff[5] ? 2 : 0;
  1067. bS[8].top = mb->totalCoeff[8] || mb->totalCoeff[2] ? 2 : 0;
  1068. bS[9].top = mb->totalCoeff[9] || mb->totalCoeff[3] ? 2 : 0;
  1069. bS[10].top = mb->totalCoeff[12] || mb->totalCoeff[6] ? 2 : 0;
  1070. bS[11].top = mb->totalCoeff[13] || mb->totalCoeff[7] ? 2 : 0;
  1071. bS[12].top = mb->totalCoeff[10] || mb->totalCoeff[8] ? 2 : 0;
  1072. bS[13].top = mb->totalCoeff[11] || mb->totalCoeff[9] ? 2 : 0;
  1073. bS[14].top = mb->totalCoeff[14] || mb->totalCoeff[12] ? 2 : 0;
  1074. bS[15].top = mb->totalCoeff[15] || mb->totalCoeff[13] ? 2 : 0;
  1075. bS[1].left = mb->totalCoeff[1] || mb->totalCoeff[0] ? 2 : 0;
  1076. bS[3].left = mb->totalCoeff[5] || mb->totalCoeff[4] ? 2 : 0;
  1077. bS[5].left = mb->totalCoeff[3] || mb->totalCoeff[2] ? 2 : 0;
  1078. bS[7].left = mb->totalCoeff[7] || mb->totalCoeff[6] ? 2 : 0;
  1079. bS[9].left = mb->totalCoeff[9] || mb->totalCoeff[8] ? 2 : 0;
  1080. bS[11].left = mb->totalCoeff[13] || mb->totalCoeff[12] ? 2 : 0;
  1081. bS[13].left = mb->totalCoeff[11] || mb->totalCoeff[10] ? 2 : 0;
  1082. bS[15].left = mb->totalCoeff[15] || mb->totalCoeff[14] ? 2 : 0;
  1083. bS[2].left = InnerBoundaryStrength(mb, 4, 1);
  1084. bS[6].left = InnerBoundaryStrength(mb, 6, 3);
  1085. bS[10].left = InnerBoundaryStrength(mb, 12, 9);
  1086. bS[14].left = InnerBoundaryStrength(mb, 14, 11);
  1087. }
  1088. else
  1089. {
  1090. bS[4].top =
  1091. InnerBoundaryStrength(mb, mb4x4Index[4], mb4x4Index[0]);
  1092. bS[5].top =
  1093. InnerBoundaryStrength(mb, mb4x4Index[5], mb4x4Index[1]);
  1094. bS[6].top =
  1095. InnerBoundaryStrength(mb, mb4x4Index[6], mb4x4Index[2]);
  1096. bS[7].top =
  1097. InnerBoundaryStrength(mb, mb4x4Index[7], mb4x4Index[3]);
  1098. bS[8].top =
  1099. InnerBoundaryStrength(mb, mb4x4Index[8], mb4x4Index[4]);
  1100. bS[9].top =
  1101. InnerBoundaryStrength(mb, mb4x4Index[9], mb4x4Index[5]);
  1102. bS[10].top =
  1103. InnerBoundaryStrength(mb, mb4x4Index[10], mb4x4Index[6]);
  1104. bS[11].top =
  1105. InnerBoundaryStrength(mb, mb4x4Index[11], mb4x4Index[7]);
  1106. bS[12].top =
  1107. InnerBoundaryStrength(mb, mb4x4Index[12], mb4x4Index[8]);
  1108. bS[13].top =
  1109. InnerBoundaryStrength(mb, mb4x4Index[13], mb4x4Index[9]);
  1110. bS[14].top =
  1111. InnerBoundaryStrength(mb, mb4x4Index[14], mb4x4Index[10]);
  1112. bS[15].top =
  1113. InnerBoundaryStrength(mb, mb4x4Index[15], mb4x4Index[11]);
  1114. bS[1].left =
  1115. InnerBoundaryStrength(mb, mb4x4Index[1], mb4x4Index[0]);
  1116. bS[2].left =
  1117. InnerBoundaryStrength(mb, mb4x4Index[2], mb4x4Index[1]);
  1118. bS[3].left =
  1119. InnerBoundaryStrength(mb, mb4x4Index[3], mb4x4Index[2]);
  1120. bS[5].left =
  1121. InnerBoundaryStrength(mb, mb4x4Index[5], mb4x4Index[4]);
  1122. bS[6].left =
  1123. InnerBoundaryStrength(mb, mb4x4Index[6], mb4x4Index[5]);
  1124. bS[7].left =
  1125. InnerBoundaryStrength(mb, mb4x4Index[7], mb4x4Index[6]);
  1126. bS[9].left =
  1127. InnerBoundaryStrength(mb, mb4x4Index[9], mb4x4Index[8]);
  1128. bS[10].left =
  1129. InnerBoundaryStrength(mb, mb4x4Index[10], mb4x4Index[9]);
  1130. bS[11].left =
  1131. InnerBoundaryStrength(mb, mb4x4Index[11], mb4x4Index[10]);
  1132. bS[13].left =
  1133. InnerBoundaryStrength(mb, mb4x4Index[13], mb4x4Index[12]);
  1134. bS[14].left =
  1135. InnerBoundaryStrength(mb, mb4x4Index[14], mb4x4Index[13]);
  1136. bS[15].left =
  1137. InnerBoundaryStrength(mb, mb4x4Index[15], mb4x4Index[14]);
  1138. }
  1139. if (!nonZeroBs &&
  1140. (bS[4].top || bS[5].top || bS[6].top || bS[7].top ||
  1141. bS[8].top || bS[9].top || bS[10].top || bS[11].top ||
  1142. bS[12].top || bS[13].top || bS[14].top || bS[15].top ||
  1143. bS[1].left || bS[2].left || bS[3].left ||
  1144. bS[5].left || bS[6].left || bS[7].left ||
  1145. bS[9].left || bS[10].left || bS[11].left ||
  1146. bS[13].left || bS[14].left || bS[15].left))
  1147. nonZeroBs = HANTRO_TRUE;
  1148. }
  1149. return(nonZeroBs);
  1150. }
  1151. /*------------------------------------------------------------------------------
  1152. Function: GetLumaEdgeThresholds
  1153. Functional description:
  1154. Compute alpha, beta and tc0 thresholds for inner, left and top
  1155. luma edges of a macroblock.
  1156. ------------------------------------------------------------------------------*/
  1157. void GetLumaEdgeThresholds(
  1158. edgeThreshold_t *thresholds,
  1159. mbStorage_t *mb,
  1160. u32 filteringFlags)
  1161. {
  1162. /* Variables */
  1163. u32 indexA, indexB;
  1164. u32 qpAv, qp, qpTmp;
  1165. /* Code */
  1166. ASSERT(thresholds);
  1167. ASSERT(mb);
  1168. qp = mb->qpY;
  1169. indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
  1170. indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
  1171. thresholds[INNER].alpha = alphas[indexA];
  1172. thresholds[INNER].beta = betas[indexB];
  1173. thresholds[INNER].tc0 = tc0[indexA];
  1174. if (filteringFlags & FILTER_TOP_EDGE)
  1175. {
  1176. qpTmp = mb->mbB->qpY;
  1177. if (qpTmp != qp)
  1178. {
  1179. qpAv = (qp + qpTmp + 1) >> 1;
  1180. indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
  1181. indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
  1182. thresholds[TOP].alpha = alphas[indexA];
  1183. thresholds[TOP].beta = betas[indexB];
  1184. thresholds[TOP].tc0 = tc0[indexA];
  1185. }
  1186. else
  1187. {
  1188. thresholds[TOP].alpha = thresholds[INNER].alpha;
  1189. thresholds[TOP].beta = thresholds[INNER].beta;
  1190. thresholds[TOP].tc0 = thresholds[INNER].tc0;
  1191. }
  1192. }
  1193. if (filteringFlags & FILTER_LEFT_EDGE)
  1194. {
  1195. qpTmp = mb->mbA->qpY;
  1196. if (qpTmp != qp)
  1197. {
  1198. qpAv = (qp + qpTmp + 1) >> 1;
  1199. indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
  1200. indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
  1201. thresholds[LEFT].alpha = alphas[indexA];
  1202. thresholds[LEFT].beta = betas[indexB];
  1203. thresholds[LEFT].tc0 = tc0[indexA];
  1204. }
  1205. else
  1206. {
  1207. thresholds[LEFT].alpha = thresholds[INNER].alpha;
  1208. thresholds[LEFT].beta = thresholds[INNER].beta;
  1209. thresholds[LEFT].tc0 = thresholds[INNER].tc0;
  1210. }
  1211. }
  1212. }
  1213. /*------------------------------------------------------------------------------
  1214. Function: GetChromaEdgeThresholds
  1215. Functional description:
  1216. Compute alpha, beta and tc0 thresholds for inner, left and top
  1217. chroma edges of a macroblock.
  1218. ------------------------------------------------------------------------------*/
  1219. void GetChromaEdgeThresholds(
  1220. edgeThreshold_t *thresholds,
  1221. mbStorage_t *mb,
  1222. u32 filteringFlags,
  1223. i32 chromaQpIndexOffset)
  1224. {
  1225. /* Variables */
  1226. u32 indexA, indexB;
  1227. u32 qpAv, qp, qpTmp;
  1228. /* Code */
  1229. ASSERT(thresholds);
  1230. ASSERT(mb);
  1231. qp = mb->qpY;
  1232. qp = h264bsdQpC[CLIP3(0, 51, (i32)qp + chromaQpIndexOffset)];
  1233. indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
  1234. indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
  1235. thresholds[INNER].alpha = alphas[indexA];
  1236. thresholds[INNER].beta = betas[indexB];
  1237. thresholds[INNER].tc0 = tc0[indexA];
  1238. if (filteringFlags & FILTER_TOP_EDGE)
  1239. {
  1240. qpTmp = mb->mbB->qpY;
  1241. if (qpTmp != mb->qpY)
  1242. {
  1243. qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
  1244. qpAv = (qp + qpTmp + 1) >> 1;
  1245. indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
  1246. indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
  1247. thresholds[TOP].alpha = alphas[indexA];
  1248. thresholds[TOP].beta = betas[indexB];
  1249. thresholds[TOP].tc0 = tc0[indexA];
  1250. }
  1251. else
  1252. {
  1253. thresholds[TOP].alpha = thresholds[INNER].alpha;
  1254. thresholds[TOP].beta = thresholds[INNER].beta;
  1255. thresholds[TOP].tc0 = thresholds[INNER].tc0;
  1256. }
  1257. }
  1258. if (filteringFlags & FILTER_LEFT_EDGE)
  1259. {
  1260. qpTmp = mb->mbA->qpY;
  1261. if (qpTmp != mb->qpY)
  1262. {
  1263. qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
  1264. qpAv = (qp + qpTmp + 1) >> 1;
  1265. indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
  1266. indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
  1267. thresholds[LEFT].alpha = alphas[indexA];
  1268. thresholds[LEFT].beta = betas[indexB];
  1269. thresholds[LEFT].tc0 = tc0[indexA];
  1270. }
  1271. else
  1272. {
  1273. thresholds[LEFT].alpha = thresholds[INNER].alpha;
  1274. thresholds[LEFT].beta = thresholds[INNER].beta;
  1275. thresholds[LEFT].tc0 = thresholds[INNER].tc0;
  1276. }
  1277. }
  1278. }
  1279. /*------------------------------------------------------------------------------
  1280. Function: FilterLuma
  1281. Functional description:
  1282. Function to filter all luma edges of a macroblock
  1283. ------------------------------------------------------------------------------*/
  1284. void FilterLuma(
  1285. u8 *data,
  1286. bS_t *bS,
  1287. edgeThreshold_t *thresholds,
  1288. u32 width)
  1289. {
  1290. /* Variables */
  1291. u32 vblock;
  1292. bS_t *tmp;
  1293. u8 *ptr;
  1294. u32 offset;
  1295. /* Code */
  1296. ASSERT(data);
  1297. ASSERT(bS);
  1298. ASSERT(thresholds);
  1299. ptr = data;
  1300. tmp = bS;
  1301. offset = TOP;
  1302. /* loop block rows, perform filtering for all vertical edges of the block
  1303. * row first, then filter each horizontal edge of the row */
  1304. for (vblock = 4; vblock--;)
  1305. {
  1306. /* only perform filtering if bS is non-zero, first of the four
  1307. * FilterVerLumaEdge handles the left edge of the macroblock, others
  1308. * filter inner edges */
  1309. if (tmp[0].left)
  1310. FilterVerLumaEdge(ptr, tmp[0].left, thresholds + LEFT, width);
  1311. if (tmp[1].left)
  1312. FilterVerLumaEdge(ptr+4, tmp[1].left, thresholds + INNER, width);
  1313. if (tmp[2].left)
  1314. FilterVerLumaEdge(ptr+8, tmp[2].left, thresholds + INNER, width);
  1315. if (tmp[3].left)
  1316. FilterVerLumaEdge(ptr+12, tmp[3].left, thresholds + INNER, width);
  1317. /* if bS is equal for all horizontal edges of the row -> perform
  1318. * filtering with FilterHorLuma, otherwise use FilterHorLumaEdge for
  1319. * each edge separately. offset variable indicates top macroblock edge
  1320. * on the first loop round, inner edge for the other rounds */
  1321. if (tmp[0].top == tmp[1].top && tmp[1].top == tmp[2].top &&
  1322. tmp[2].top == tmp[3].top)
  1323. {
  1324. if(tmp[0].top)
  1325. FilterHorLuma(ptr, tmp[0].top, thresholds + offset, (i32)width);
  1326. }
  1327. else
  1328. {
  1329. if(tmp[0].top)
  1330. FilterHorLumaEdge(ptr, tmp[0].top, thresholds+offset,
  1331. (i32)width);
  1332. if(tmp[1].top)
  1333. FilterHorLumaEdge(ptr+4, tmp[1].top, thresholds+offset,
  1334. (i32)width);
  1335. if(tmp[2].top)
  1336. FilterHorLumaEdge(ptr+8, tmp[2].top, thresholds+offset,
  1337. (i32)width);
  1338. if(tmp[3].top)
  1339. FilterHorLumaEdge(ptr+12, tmp[3].top, thresholds+offset,
  1340. (i32)width);
  1341. }
  1342. /* four pixel rows ahead, i.e. next row of 4x4-blocks */
  1343. ptr += width*4;
  1344. tmp += 4;
  1345. offset = INNER;
  1346. }
  1347. }
  1348. /*------------------------------------------------------------------------------
  1349. Function: FilterChroma
  1350. Functional description:
  1351. Function to filter all chroma edges of a macroblock
  1352. ------------------------------------------------------------------------------*/
  1353. void FilterChroma(
  1354. u8 *dataCb,
  1355. u8 *dataCr,
  1356. bS_t *bS,
  1357. edgeThreshold_t *thresholds,
  1358. u32 width)
  1359. {
  1360. /* Variables */
  1361. u32 vblock;
  1362. bS_t *tmp;
  1363. u32 offset;
  1364. /* Code */
  1365. ASSERT(dataCb);
  1366. ASSERT(dataCr);
  1367. ASSERT(bS);
  1368. ASSERT(thresholds);
  1369. tmp = bS;
  1370. offset = TOP;
  1371. /* loop block rows, perform filtering for all vertical edges of the block
  1372. * row first, then filter each horizontal edge of the row */
  1373. for (vblock = 0; vblock < 2; vblock++)
  1374. {
  1375. /* only perform filtering if bS is non-zero, first two of the four
  1376. * FilterVerChromaEdge calls handle the left edge of the macroblock,
  1377. * others filter the inner edge. Note that as chroma uses bS values
  1378. * determined for luma edges, each bS is used only for 2 pixels of
  1379. * a 4-pixel edge */
  1380. if (tmp[0].left)
  1381. {
  1382. FilterVerChromaEdge(dataCb, tmp[0].left, thresholds + LEFT, width);
  1383. FilterVerChromaEdge(dataCr, tmp[0].left, thresholds + LEFT, width);
  1384. }
  1385. if (tmp[4].left)
  1386. {
  1387. FilterVerChromaEdge(dataCb+2*width, tmp[4].left, thresholds + LEFT,
  1388. width);
  1389. FilterVerChromaEdge(dataCr+2*width, tmp[4].left, thresholds + LEFT,
  1390. width);
  1391. }
  1392. if (tmp[2].left)
  1393. {
  1394. FilterVerChromaEdge(dataCb+4, tmp[2].left, thresholds + INNER,
  1395. width);
  1396. FilterVerChromaEdge(dataCr+4, tmp[2].left, thresholds + INNER,
  1397. width);
  1398. }
  1399. if (tmp[6].left)
  1400. {
  1401. FilterVerChromaEdge(dataCb+2*width+4, tmp[6].left,
  1402. thresholds + INNER, width);
  1403. FilterVerChromaEdge(dataCr+2*width+4, tmp[6].left,
  1404. thresholds + INNER, width);
  1405. }
  1406. /* if bS is equal for all horizontal edges of the row -> perform
  1407. * filtering with FilterHorChroma, otherwise use FilterHorChromaEdge
  1408. * for each edge separately. offset variable indicates top macroblock
  1409. * edge on the first loop round, inner edge for the second */
  1410. if (tmp[0].top == tmp[1].top && tmp[1].top == tmp[2].top &&
  1411. tmp[2].top == tmp[3].top)
  1412. {
  1413. if(tmp[0].top)
  1414. {
  1415. FilterHorChroma(dataCb, tmp[0].top, thresholds+offset,
  1416. (i32)width);
  1417. FilterHorChroma(dataCr, tmp[0].top, thresholds+offset,
  1418. (i32)width);
  1419. }
  1420. }
  1421. else
  1422. {
  1423. if (tmp[0].top)
  1424. {
  1425. FilterHorChromaEdge(dataCb, tmp[0].top, thresholds+offset,
  1426. (i32)width);
  1427. FilterHorChromaEdge(dataCr, tmp[0].top, thresholds+offset,
  1428. (i32)width);
  1429. }
  1430. if (tmp[1].top)
  1431. {
  1432. FilterHorChromaEdge(dataCb+2, tmp[1].top, thresholds+offset,
  1433. (i32)width);
  1434. FilterHorChromaEdge(dataCr+2, tmp[1].top, thresholds+offset,
  1435. (i32)width);
  1436. }
  1437. if (tmp[2].top)
  1438. {
  1439. FilterHorChromaEdge(dataCb+4, tmp[2].top, thresholds+offset,
  1440. (i32)width);
  1441. FilterHorChromaEdge(dataCr+4, tmp[2].top, thresholds+offset,
  1442. (i32)width);
  1443. }
  1444. if (tmp[3].top)
  1445. {
  1446. FilterHorChromaEdge(dataCb+6, tmp[3].top, thresholds+offset,
  1447. (i32)width);
  1448. FilterHorChromaEdge(dataCr+6, tmp[3].top, thresholds+offset,
  1449. (i32)width);
  1450. }
  1451. }
  1452. tmp += 8;
  1453. dataCb += width*4;
  1454. dataCr += width*4;
  1455. offset = INNER;
  1456. }
  1457. }
  1458. #else /* H264DEC_OMXDL */
  1459. /*------------------------------------------------------------------------------
  1460. Function: h264bsdFilterPicture
  1461. Functional description:
  1462. Perform deblocking filtering for a picture. Filter does not copy
  1463. the original picture anywhere but filtering is performed directly
  1464. on the original image. Parameters controlling the filtering process
  1465. are computed based on information in macroblock structures of the
  1466. filtered macroblock, macroblock above and macroblock on the left of
  1467. the filtered one.
  1468. Inputs:
  1469. image pointer to image to be filtered
  1470. mb pointer to macroblock data structure of the top-left
  1471. macroblock of the picture
  1472. Outputs:
  1473. image filtered image stored here
  1474. Returns:
  1475. none
  1476. ------------------------------------------------------------------------------*/
  1477. /*lint --e{550} Symbol not accessed */
  1478. void h264bsdFilterPicture(
  1479. image_t *image,
  1480. mbStorage_t *mb)
  1481. {
  1482. /* Variables */
  1483. u32 flags;
  1484. u32 picSizeInMbs, mbRow, mbCol;
  1485. u32 picWidthInMbs;
  1486. u8 *data;
  1487. mbStorage_t *pMb;
  1488. u8 bS[2][16];
  1489. u8 thresholdLuma[2][16];
  1490. u8 thresholdChroma[2][8];
  1491. u8 alpha[2][2];
  1492. u8 beta[2][2];
  1493. OMXResult res;
  1494. /* Code */
  1495. ASSERT(image);
  1496. ASSERT(mb);
  1497. ASSERT(image->data);
  1498. ASSERT(image->width);
  1499. ASSERT(image->height);
  1500. picWidthInMbs = image->width;
  1501. data = image->data;
  1502. picSizeInMbs = picWidthInMbs * image->height;
  1503. pMb = mb;
  1504. for (mbRow = 0, mbCol = 0; mbRow < image->height; pMb++)
  1505. {
  1506. flags = GetMbFilteringFlags(pMb);
  1507. if (flags)
  1508. {
  1509. /* GetBoundaryStrengths function returns non-zero value if any of
  1510. * the bS values for the macroblock being processed was non-zero */
  1511. if (GetBoundaryStrengths(pMb, bS, flags))
  1512. {
  1513. /* Luma */
  1514. GetLumaEdgeThresholds(pMb,alpha,beta,thresholdLuma,bS,flags);
  1515. data = image->data + mbRow * picWidthInMbs * 256 + mbCol * 16;
  1516. res = omxVCM4P10_FilterDeblockingLuma_VerEdge_I( data,
  1517. (OMX_S32)(picWidthInMbs*16),
  1518. (const OMX_U8*)alpha,
  1519. (const OMX_U8*)beta,
  1520. (const OMX_U8*)thresholdLuma,
  1521. (const OMX_U8*)bS );
  1522. res = omxVCM4P10_FilterDeblockingLuma_HorEdge_I( data,
  1523. (OMX_S32)(picWidthInMbs*16),
  1524. (const OMX_U8*)alpha+2,
  1525. (const OMX_U8*)beta+2,
  1526. (const OMX_U8*)thresholdLuma+16,
  1527. (const OMX_U8*)bS+16 );
  1528. /* Cb */
  1529. GetChromaEdgeThresholds(pMb, alpha, beta, thresholdChroma,
  1530. bS, flags, pMb->chromaQpIndexOffset);
  1531. data = image->data + picSizeInMbs * 256 +
  1532. mbRow * picWidthInMbs * 64 + mbCol * 8;
  1533. res = omxVCM4P10_FilterDeblockingChroma_VerEdge_I( data,
  1534. (OMX_S32)(picWidthInMbs*8),
  1535. (const OMX_U8*)alpha,
  1536. (const OMX_U8*)beta,
  1537. (const OMX_U8*)thresholdChroma,
  1538. (const OMX_U8*)bS );
  1539. res = omxVCM4P10_FilterDeblockingChroma_HorEdge_I( data,
  1540. (OMX_S32)(picWidthInMbs*8),
  1541. (const OMX_U8*)alpha+2,
  1542. (const OMX_U8*)beta+2,
  1543. (const OMX_U8*)thresholdChroma+8,
  1544. (const OMX_U8*)bS+16 );
  1545. /* Cr */
  1546. data += (picSizeInMbs * 64);
  1547. res = omxVCM4P10_FilterDeblockingChroma_VerEdge_I( data,
  1548. (OMX_S32)(picWidthInMbs*8),
  1549. (const OMX_U8*)alpha,
  1550. (const OMX_U8*)beta,
  1551. (const OMX_U8*)thresholdChroma,
  1552. (const OMX_U8*)bS );
  1553. res = omxVCM4P10_FilterDeblockingChroma_HorEdge_I( data,
  1554. (OMX_S32)(picWidthInMbs*8),
  1555. (const OMX_U8*)alpha+2,
  1556. (const OMX_U8*)beta+2,
  1557. (const OMX_U8*)thresholdChroma+8,
  1558. (const OMX_U8*)bS+16 );
  1559. }
  1560. }
  1561. mbCol++;
  1562. if (mbCol == picWidthInMbs)
  1563. {
  1564. mbCol = 0;
  1565. mbRow++;
  1566. }
  1567. }
  1568. }
  1569. /*------------------------------------------------------------------------------
  1570. Function: GetBoundaryStrengths
  1571. Functional description:
  1572. Function to calculate boundary strengths for all edges of a
  1573. macroblock. Function returns HANTRO_TRUE if any of the bS values for
  1574. the macroblock had non-zero value, HANTRO_FALSE otherwise.
  1575. ------------------------------------------------------------------------------*/
  1576. u32 GetBoundaryStrengths(mbStorage_t *mb, u8 (*bS)[16], u32 flags)
  1577. {
  1578. /* Variables */
  1579. /* this flag is set HANTRO_TRUE as soon as any boundary strength value is
  1580. * non-zero */
  1581. u32 nonZeroBs = HANTRO_FALSE;
  1582. u32 *pTmp;
  1583. u32 tmp1, tmp2, isIntraMb;
  1584. /* Code */
  1585. ASSERT(mb);
  1586. ASSERT(bS);
  1587. ASSERT(flags);
  1588. isIntraMb = IS_INTRA_MB(*mb);
  1589. /* top edges */
  1590. pTmp = (u32*)&bS[1][0];
  1591. if (flags & FILTER_TOP_EDGE)
  1592. {
  1593. if (isIntraMb || IS_INTRA_MB(*mb->mbB))
  1594. {
  1595. *pTmp = 0x04040404;
  1596. nonZeroBs = HANTRO_TRUE;
  1597. }
  1598. else
  1599. {
  1600. *pTmp = EdgeBoundaryStrengthTop(mb, mb->mbB);
  1601. if (*pTmp)
  1602. nonZeroBs = HANTRO_TRUE;
  1603. }
  1604. }
  1605. else
  1606. {
  1607. *pTmp = 0;
  1608. }
  1609. /* left edges */
  1610. pTmp = (u32*)&bS[0][0];
  1611. if (flags & FILTER_LEFT_EDGE)
  1612. {
  1613. if (isIntraMb || IS_INTRA_MB(*mb->mbA))
  1614. {
  1615. /*bS[0][0] = bS[0][1] = bS[0][2] = bS[0][3] = 4;*/
  1616. *pTmp = 0x04040404;
  1617. nonZeroBs = HANTRO_TRUE;
  1618. }
  1619. else
  1620. {
  1621. *pTmp = EdgeBoundaryStrengthLeft(mb, mb->mbA);
  1622. if (!nonZeroBs && *pTmp)
  1623. nonZeroBs = HANTRO_TRUE;
  1624. }
  1625. }
  1626. else
  1627. {
  1628. *pTmp = 0;
  1629. }
  1630. /* inner edges */
  1631. if (isIntraMb)
  1632. {
  1633. pTmp++;
  1634. *pTmp++ = 0x03030303;
  1635. *pTmp++ = 0x03030303;
  1636. *pTmp++ = 0x03030303;
  1637. pTmp++;
  1638. *pTmp++ = 0x03030303;
  1639. *pTmp++ = 0x03030303;
  1640. *pTmp = 0x03030303;
  1641. nonZeroBs = HANTRO_TRUE;
  1642. }
  1643. else
  1644. {
  1645. pTmp = (u32*)mb->totalCoeff;
  1646. /* 16x16 inter mb -> ref addresses or motion vectors cannot differ,
  1647. * only check if either of the blocks contain coefficients */
  1648. if (h264bsdNumMbPart(mb->mbType) == 1)
  1649. {
  1650. tmp1 = *pTmp++;
  1651. tmp2 = *pTmp++;
  1652. bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
  1653. bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
  1654. bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
  1655. bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
  1656. tmp1 = *pTmp++;
  1657. bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
  1658. bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
  1659. bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
  1660. bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
  1661. tmp2 = *pTmp;
  1662. bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
  1663. bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
  1664. bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
  1665. bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
  1666. bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
  1667. bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
  1668. bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
  1669. bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
  1670. {
  1671. u32 tmp3, tmp4;
  1672. tmp1 = mb->totalCoeff[8];
  1673. tmp2 = mb->totalCoeff[2];
  1674. tmp3 = mb->totalCoeff[9];
  1675. tmp4 = mb->totalCoeff[3];
  1676. bS[1][8] = tmp1 || tmp2 ? 2 : 0;
  1677. tmp1 = mb->totalCoeff[12];
  1678. tmp2 = mb->totalCoeff[6];
  1679. bS[1][9] = tmp3 || tmp4 ? 2 : 0;
  1680. tmp3 = mb->totalCoeff[13];
  1681. tmp4 = mb->totalCoeff[7];
  1682. bS[1][10] = tmp1 || tmp2 ? 2 : 0;
  1683. tmp1 = mb->totalCoeff[4];
  1684. tmp2 = mb->totalCoeff[1];
  1685. bS[1][11] = tmp3 || tmp4 ? 2 : 0;
  1686. tmp3 = mb->totalCoeff[6];
  1687. tmp4 = mb->totalCoeff[3];
  1688. bS[0][8] = tmp1 || tmp2 ? 2 : 0;
  1689. tmp1 = mb->totalCoeff[12];
  1690. tmp2 = mb->totalCoeff[9];
  1691. bS[0][9] = tmp3 || tmp4 ? 2 : 0;
  1692. tmp3 = mb->totalCoeff[14];
  1693. tmp4 = mb->totalCoeff[11];
  1694. bS[0][10] = tmp1 || tmp2 ? 2 : 0;
  1695. bS[0][11] = tmp3 || tmp4 ? 2 : 0;
  1696. }
  1697. }
  1698. /* 16x8 inter mb -> ref addresses and motion vectors can be different
  1699. * only for the middle horizontal edge, for the other top edges it is
  1700. * enough to check whether the blocks contain coefficients or not. The
  1701. * same applies to all internal left edges. */
  1702. else if (mb->mbType == P_L0_L0_16x8)
  1703. {
  1704. tmp1 = *pTmp++;
  1705. tmp2 = *pTmp++;
  1706. bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
  1707. bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
  1708. bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
  1709. bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
  1710. tmp1 = *pTmp++;
  1711. bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
  1712. bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
  1713. bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
  1714. bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
  1715. tmp2 = *pTmp;
  1716. bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
  1717. bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
  1718. bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
  1719. bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
  1720. bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
  1721. bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
  1722. bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
  1723. bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
  1724. bS[1][8] = (u8)InnerBoundaryStrength(mb, 8, 2);
  1725. bS[1][9] = (u8)InnerBoundaryStrength(mb, 9, 3);
  1726. bS[1][10] = (u8)InnerBoundaryStrength(mb, 12, 6);
  1727. bS[1][11] = (u8)InnerBoundaryStrength(mb, 13, 7);
  1728. {
  1729. u32 tmp3, tmp4;
  1730. tmp1 = mb->totalCoeff[4];
  1731. tmp2 = mb->totalCoeff[1];
  1732. tmp3 = mb->totalCoeff[6];
  1733. tmp4 = mb->totalCoeff[3];
  1734. bS[0][8] = tmp1 || tmp2 ? 2 : 0;
  1735. tmp1 = mb->totalCoeff[12];
  1736. tmp2 = mb->totalCoeff[9];
  1737. bS[0][9] = tmp3 || tmp4 ? 2 : 0;
  1738. tmp3 = mb->totalCoeff[14];
  1739. tmp4 = mb->totalCoeff[11];
  1740. bS[0][10] = tmp1 || tmp2 ? 2 : 0;
  1741. bS[0][11] = tmp3 || tmp4 ? 2 : 0;
  1742. }
  1743. }
  1744. /* 8x16 inter mb -> ref addresses and motion vectors can be different
  1745. * only for the middle vertical edge, for the other left edges it is
  1746. * enough to check whether the blocks contain coefficients or not. The
  1747. * same applies to all internal top edges. */
  1748. else if (mb->mbType == P_L0_L0_8x16)
  1749. {
  1750. tmp1 = *pTmp++;
  1751. tmp2 = *pTmp++;
  1752. bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [2] || [0] */
  1753. bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [3] || [1] */
  1754. bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [1] || [0] */
  1755. bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [3] || [2] */
  1756. tmp1 = *pTmp++;
  1757. bS[1][6] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [6] || [4] */
  1758. bS[1][7] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [7] || [5] */
  1759. bS[0][12] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [5] || [4] */
  1760. bS[0][13] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [7] || [6] */
  1761. tmp2 = *pTmp;
  1762. bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : 0; /* [10] || [8] */
  1763. bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : 0; /* [11] || [9] */
  1764. bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : 0; /* [9] || [8] */
  1765. bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : 0; /* [11] || [10] */
  1766. bS[1][14] = (tmp2 & 0x00FF00FF) ? 2 : 0; /* [14] || [12] */
  1767. bS[1][15] = (tmp2 & 0xFF00FF00) ? 2 : 0; /* [15] || [13] */
  1768. bS[0][14] = (tmp2 & 0x0000FFFF) ? 2 : 0; /* [13] || [12] */
  1769. bS[0][15] = (tmp2 & 0xFFFF0000) ? 2 : 0; /* [15] || [14] */
  1770. bS[0][8] = (u8)InnerBoundaryStrength(mb, 4, 1);
  1771. bS[0][9] = (u8)InnerBoundaryStrength(mb, 6, 3);
  1772. bS[0][10] = (u8)InnerBoundaryStrength(mb, 12, 9);
  1773. bS[0][11] = (u8)InnerBoundaryStrength(mb, 14, 11);
  1774. {
  1775. u32 tmp3, tmp4;
  1776. tmp1 = mb->totalCoeff[8];
  1777. tmp2 = mb->totalCoeff[2];
  1778. tmp3 = mb->totalCoeff[9];
  1779. tmp4 = mb->totalCoeff[3];
  1780. bS[1][8] = tmp1 || tmp2 ? 2 : 0;
  1781. tmp1 = mb->totalCoeff[12];
  1782. tmp2 = mb->totalCoeff[6];
  1783. bS[1][9] = tmp3 || tmp4 ? 2 : 0;
  1784. tmp3 = mb->totalCoeff[13];
  1785. tmp4 = mb->totalCoeff[7];
  1786. bS[1][10] = tmp1 || tmp2 ? 2 : 0;
  1787. bS[1][11] = tmp3 || tmp4 ? 2 : 0;
  1788. }
  1789. }
  1790. else
  1791. {
  1792. tmp1 = *pTmp++;
  1793. bS[1][4] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 2, 0);
  1794. bS[1][5] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 3, 1);
  1795. bS[0][4] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 1, 0);
  1796. bS[0][5] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 3, 2);
  1797. tmp1 = *pTmp++;
  1798. bS[1][6] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 6, 4);
  1799. bS[1][7] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 7, 5);
  1800. bS[0][12] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 5, 4);
  1801. bS[0][13] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 7, 6);
  1802. tmp1 = *pTmp++;
  1803. bS[1][12] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 10, 8);
  1804. bS[1][13] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 11, 9);
  1805. bS[0][6] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 9, 8);
  1806. bS[0][7] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 11, 10);
  1807. tmp1 = *pTmp;
  1808. bS[1][14] = (tmp1 & 0x00FF00FF) ? 2 : (u8)InnerBoundaryStrength2(mb, 14, 12);
  1809. bS[1][15] = (tmp1 & 0xFF00FF00) ? 2 : (u8)InnerBoundaryStrength2(mb, 15, 13);
  1810. bS[0][14] = (tmp1 & 0x0000FFFF) ? 2 : (u8)InnerBoundaryStrength2(mb, 13, 12);
  1811. bS[0][15] = (tmp1 & 0xFFFF0000) ? 2 : (u8)InnerBoundaryStrength2(mb, 15, 14);
  1812. bS[1][8] = (u8)InnerBoundaryStrength(mb, 8, 2);
  1813. bS[1][9] = (u8)InnerBoundaryStrength(mb, 9, 3);
  1814. bS[1][10] = (u8)InnerBoundaryStrength(mb, 12, 6);
  1815. bS[1][11] = (u8)InnerBoundaryStrength(mb, 13, 7);
  1816. bS[0][8] = (u8)InnerBoundaryStrength(mb, 4, 1);
  1817. bS[0][9] = (u8)InnerBoundaryStrength(mb, 6, 3);
  1818. bS[0][10] = (u8)InnerBoundaryStrength(mb, 12, 9);
  1819. bS[0][11] = (u8)InnerBoundaryStrength(mb, 14, 11);
  1820. }
  1821. pTmp = (u32*)&bS[0][0];
  1822. if (!nonZeroBs && (pTmp[1] || pTmp[2] || pTmp[3] ||
  1823. pTmp[5] || pTmp[6] || pTmp[7]) )
  1824. {
  1825. nonZeroBs = HANTRO_TRUE;
  1826. }
  1827. }
  1828. return(nonZeroBs);
  1829. }
  1830. /*------------------------------------------------------------------------------
  1831. Function: GetLumaEdgeThresholds
  1832. Functional description:
  1833. Compute alpha, beta and tc0 thresholds for inner, left and top
  1834. luma edges of a macroblock.
  1835. ------------------------------------------------------------------------------*/
  1836. void GetLumaEdgeThresholds(
  1837. mbStorage_t *mb,
  1838. u8 (*alpha)[2],
  1839. u8 (*beta)[2],
  1840. u8 (*threshold)[16],
  1841. u8 (*bs)[16],
  1842. u32 filteringFlags )
  1843. {
  1844. /* Variables */
  1845. u32 indexA, indexB;
  1846. u32 qpAv, qp, qpTmp;
  1847. u32 i;
  1848. /* Code */
  1849. ASSERT(threshold);
  1850. ASSERT(bs);
  1851. ASSERT(beta);
  1852. ASSERT(alpha);
  1853. ASSERT(mb);
  1854. qp = mb->qpY;
  1855. indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
  1856. indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
  1857. /* Internal edge values */
  1858. alpha[0][1] = alphas[indexA];
  1859. alpha[1][1] = alphas[indexA];
  1860. alpha[1][0] = alphas[indexA];
  1861. alpha[0][0] = alphas[indexA];
  1862. beta[0][1] = betas[indexB];
  1863. beta[1][1] = betas[indexB];
  1864. beta[1][0] = betas[indexB];
  1865. beta[0][0] = betas[indexB];
  1866. /* vertical scan order */
  1867. for (i = 0; i < 2; i++)
  1868. {
  1869. u32 t1, t2;
  1870. t1 = bs[i][0];
  1871. t2 = bs[i][1];
  1872. threshold[i][0] = (t1) ? tc0[indexA][t1] : 0;
  1873. t1 = bs[i][2];
  1874. threshold[i][1] = (t2) ? tc0[indexA][t2] : 0;
  1875. t2 = bs[i][3];
  1876. threshold[i][2] = (t1) ? tc0[indexA][t1] : 0;
  1877. t1 = bs[i][4];
  1878. threshold[i][3] = (t2) ? tc0[indexA][t2] : 0;
  1879. t2 = bs[i][5];
  1880. threshold[i][4] = (t1) ? tc0[indexA][t1] : 0;
  1881. t1 = bs[i][6];
  1882. threshold[i][5] = (t2) ? tc0[indexA][t2] : 0;
  1883. t2 = bs[i][7];
  1884. threshold[i][6] = (t1) ? tc0[indexA][t1] : 0;
  1885. t1 = bs[i][8];
  1886. threshold[i][7] = (t2) ? tc0[indexA][t2] : 0;
  1887. t2 = bs[i][9];
  1888. threshold[i][8] = (t1) ? tc0[indexA][t1] : 0;
  1889. t1 = bs[i][10];
  1890. threshold[i][9] = (t2) ? tc0[indexA][t2] : 0;
  1891. t2 = bs[i][11];
  1892. threshold[i][10] = (t1) ? tc0[indexA][t1] : 0;
  1893. t1 = bs[i][12];
  1894. threshold[i][11] = (t2) ? tc0[indexA][t2] : 0;
  1895. t2 = bs[i][13];
  1896. threshold[i][12] = (t1) ? tc0[indexA][t1] : 0;
  1897. t1 = bs[i][14];
  1898. threshold[i][13] = (t2) ? tc0[indexA][t2] : 0;
  1899. t2 = bs[i][15];
  1900. threshold[i][14] = (t1) ? tc0[indexA][t1] : 0;
  1901. threshold[i][15] = (t2) ? tc0[indexA][t2] : 0;
  1902. }
  1903. if (filteringFlags & FILTER_TOP_EDGE)
  1904. {
  1905. qpTmp = mb->mbB->qpY;
  1906. if (qpTmp != qp)
  1907. {
  1908. u32 t1, t2, t3, t4;
  1909. qpAv = (qp + qpTmp + 1) >> 1;
  1910. indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
  1911. indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
  1912. alpha[1][0] = alphas[indexA];
  1913. beta[1][0] = betas[indexB];
  1914. t1 = bs[1][0];
  1915. t2 = bs[1][1];
  1916. t3 = bs[1][2];
  1917. t4 = bs[1][3];
  1918. threshold[1][0] = (t1 && (t1 < 4)) ? tc0[indexA][t1] : 0;
  1919. threshold[1][1] = (t2 && (t2 < 4)) ? tc0[indexA][t2] : 0;
  1920. threshold[1][2] = (t3 && (t3 < 4)) ? tc0[indexA][t3] : 0;
  1921. threshold[1][3] = (t4 && (t4 < 4)) ? tc0[indexA][t4] : 0;
  1922. }
  1923. }
  1924. if (filteringFlags & FILTER_LEFT_EDGE)
  1925. {
  1926. qpTmp = mb->mbA->qpY;
  1927. if (qpTmp != qp)
  1928. {
  1929. qpAv = (qp + qpTmp + 1) >> 1;
  1930. indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
  1931. indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
  1932. alpha[0][0] = alphas[indexA];
  1933. beta[0][0] = betas[indexB];
  1934. threshold[0][0] = (bs[0][0] && (bs[0][0] < 4)) ? tc0[indexA][bs[0][0]] : 0;
  1935. threshold[0][1] = (bs[0][1] && (bs[0][1] < 4)) ? tc0[indexA][bs[0][1]] : 0;
  1936. threshold[0][2] = (bs[0][2] && (bs[0][2] < 4)) ? tc0[indexA][bs[0][2]] : 0;
  1937. threshold[0][3] = (bs[0][3] && (bs[0][3] < 4)) ? tc0[indexA][bs[0][3]] : 0;
  1938. }
  1939. }
  1940. }
  1941. /*------------------------------------------------------------------------------
  1942. Function: GetChromaEdgeThresholds
  1943. Functional description:
  1944. Compute alpha, beta and tc0 thresholds for inner, left and top
  1945. chroma edges of a macroblock.
  1946. ------------------------------------------------------------------------------*/
  1947. void GetChromaEdgeThresholds(
  1948. mbStorage_t *mb,
  1949. u8 (*alpha)[2],
  1950. u8 (*beta)[2],
  1951. u8 (*threshold)[8],
  1952. u8 (*bs)[16],
  1953. u32 filteringFlags,
  1954. i32 chromaQpIndexOffset)
  1955. {
  1956. /* Variables */
  1957. u32 indexA, indexB;
  1958. u32 qpAv, qp, qpTmp;
  1959. u32 i;
  1960. /* Code */
  1961. ASSERT(threshold);
  1962. ASSERT(bs);
  1963. ASSERT(beta);
  1964. ASSERT(alpha);
  1965. ASSERT(mb);
  1966. ASSERT(mb);
  1967. qp = mb->qpY;
  1968. qp = h264bsdQpC[CLIP3(0, 51, (i32)qp + chromaQpIndexOffset)];
  1969. indexA = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetA);
  1970. indexB = (u32)CLIP3(0, 51, (i32)qp + mb->filterOffsetB);
  1971. alpha[0][1] = alphas[indexA];
  1972. alpha[1][1] = alphas[indexA];
  1973. alpha[1][0] = alphas[indexA];
  1974. alpha[0][0] = alphas[indexA];
  1975. beta[0][1] = betas[indexB];
  1976. beta[1][1] = betas[indexB];
  1977. beta[1][0] = betas[indexB];
  1978. beta[0][0] = betas[indexB];
  1979. for (i = 0; i < 2; i++)
  1980. {
  1981. u32 t1, t2;
  1982. t1 = bs[i][0];
  1983. t2 = bs[i][1];
  1984. threshold[i][0] = (t1) ? tc0[indexA][t1] : 0;
  1985. t1 = bs[i][2];
  1986. threshold[i][1] = (t2) ? tc0[indexA][t2] : 0;
  1987. t2 = bs[i][3];
  1988. threshold[i][2] = (t1) ? tc0[indexA][t1] : 0;
  1989. t1 = bs[i][8];
  1990. threshold[i][3] = (t2) ? tc0[indexA][t2] : 0;
  1991. t2 = bs[i][9];
  1992. threshold[i][4] = (t1) ? tc0[indexA][t1] : 0;
  1993. t1 = bs[i][10];
  1994. threshold[i][5] = (t2) ? tc0[indexA][t2] : 0;
  1995. t2 = bs[i][11];
  1996. threshold[i][6] = (t1) ? tc0[indexA][t1] : 0;
  1997. threshold[i][7] = (t2) ? tc0[indexA][t2] : 0;
  1998. }
  1999. if (filteringFlags & FILTER_TOP_EDGE)
  2000. {
  2001. qpTmp = mb->mbB->qpY;
  2002. if (qpTmp != mb->qpY)
  2003. {
  2004. u32 t1, t2, t3, t4;
  2005. qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
  2006. qpAv = (qp + qpTmp + 1) >> 1;
  2007. indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
  2008. indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
  2009. alpha[1][0] = alphas[indexA];
  2010. beta[1][0] = betas[indexB];
  2011. t1 = bs[1][0];
  2012. t2 = bs[1][1];
  2013. t3 = bs[1][2];
  2014. t4 = bs[1][3];
  2015. threshold[1][0] = (t1) ? tc0[indexA][t1] : 0;
  2016. threshold[1][1] = (t2) ? tc0[indexA][t2] : 0;
  2017. threshold[1][2] = (t3) ? tc0[indexA][t3] : 0;
  2018. threshold[1][3] = (t4) ? tc0[indexA][t4] : 0;
  2019. }
  2020. }
  2021. if (filteringFlags & FILTER_LEFT_EDGE)
  2022. {
  2023. qpTmp = mb->mbA->qpY;
  2024. if (qpTmp != mb->qpY)
  2025. {
  2026. qpTmp = h264bsdQpC[CLIP3(0, 51, (i32)qpTmp + chromaQpIndexOffset)];
  2027. qpAv = (qp + qpTmp + 1) >> 1;
  2028. indexA = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetA);
  2029. indexB = (u32)CLIP3(0, 51, (i32)qpAv + mb->filterOffsetB);
  2030. alpha[0][0] = alphas[indexA];
  2031. beta[0][0] = betas[indexB];
  2032. threshold[0][0] = (bs[0][0]) ? tc0[indexA][bs[0][0]] : 0;
  2033. threshold[0][1] = (bs[0][1]) ? tc0[indexA][bs[0][1]] : 0;
  2034. threshold[0][2] = (bs[0][2]) ? tc0[indexA][bs[0][2]] : 0;
  2035. threshold[0][3] = (bs[0][3]) ? tc0[indexA][bs[0][3]] : 0;
  2036. }
  2037. }
  2038. }
  2039. #endif /* H264DEC_OMXDL */
  2040. /*lint +e701 +e702 */