PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/Show/avc/deblock.cpp

http://github.com/mbebenita/Broadway
C++ | 1667 lines | 1222 code | 272 blank | 173 comment | 354 complexity | fb2b58931080867affc66a4e435964ff MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /* ------------------------------------------------------------------
  2. * Copyright (C) 1998-2009 PacketVideo
  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
  13. * express or implied.
  14. * See the License for the specific language governing permissions
  15. * and limitations under the License.
  16. * -------------------------------------------------------------------
  17. */
  18. #include <string.h>
  19. #include "avclib_common.h"
  20. #define MAX_QP 51
  21. #define MB_BLOCK_SIZE 16
  22. // NOTE: these 3 tables are for funtion GetStrength() only
  23. const static int ININT_STRENGTH[4] = {0x04040404, 0x03030303, 0x03030303, 0x03030303};
  24. // NOTE: these 3 tables are for funtion EdgeLoop() only
  25. // NOTE: to change the tables below for instance when the QP doubling is changed from 6 to 8 values
  26. const static int ALPHA_TABLE[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, 12, 13, 15, 17, 20, 22, 25, 28, 32, 36, 40, 45, 50, 56, 63, 71, 80, 90, 101, 113, 127, 144, 162, 182, 203, 226, 255, 255} ;
  27. const static int BETA_TABLE[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, 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} ;
  28. const static int CLIP_TAB[52][5] =
  29. {
  30. { 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, 0, 0, 0}, { 0, 0, 0, 0, 0},
  31. { 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, 0, 0, 0}, { 0, 0, 0, 0, 0},
  32. { 0, 0, 0, 0, 0}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 0, 1, 1}, { 0, 0, 1, 1, 1}, { 0, 0, 1, 1, 1}, { 0, 1, 1, 1, 1},
  33. { 0, 1, 1, 1, 1}, { 0, 1, 1, 1, 1}, { 0, 1, 1, 1, 1}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 1, 2, 2}, { 0, 1, 2, 3, 3},
  34. { 0, 1, 2, 3, 3}, { 0, 2, 2, 3, 3}, { 0, 2, 2, 4, 4}, { 0, 2, 3, 4, 4}, { 0, 2, 3, 4, 4}, { 0, 3, 3, 5, 5}, { 0, 3, 4, 6, 6}, { 0, 3, 4, 6, 6},
  35. { 0, 4, 5, 7, 7}, { 0, 4, 5, 8, 8}, { 0, 4, 6, 9, 9}, { 0, 5, 7, 10, 10}, { 0, 6, 8, 11, 11}, { 0, 6, 8, 13, 13}, { 0, 7, 10, 14, 14}, { 0, 8, 11, 16, 16},
  36. { 0, 9, 12, 18, 18}, { 0, 10, 13, 20, 20}, { 0, 11, 15, 23, 23}, { 0, 13, 17, 25, 25}
  37. };
  38. // NOTE: this table is only QP clipping, index = QP + video->FilterOffsetA/B, clipped to [0, 51]
  39. // video->FilterOffsetA/B is in {-12, 12]
  40. const static int QP_CLIP_TAB[76] =
  41. {
  42. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // [-12, 0]
  43. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  44. 13, 14, 15, 16, 17, 18, 19, 20, 21,
  45. 22, 23, 24, 25, 26, 27, 28, 29, 30,
  46. 31, 32, 33, 34, 35, 36, 37, 38, 39,
  47. 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // [1, 51]
  48. 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51 // [52,63]
  49. };
  50. static void DeblockMb(AVCCommonObj *video, int mb_x, int mb_y, uint8 *SrcY, uint8 *SrcU, uint8 *SrcV);
  51. //static void GetStrength(AVCCommonObj *video, uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir, int edge);
  52. static void GetStrength_Edge0(uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir);
  53. static void GetStrength_VerticalEdges(uint8 *Strength, AVCMacroblock* MbQ);
  54. static void GetStrength_HorizontalEdges(uint8 Strength[12], AVCMacroblock* MbQ);
  55. static void EdgeLoop_Luma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
  56. static void EdgeLoop_Luma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
  57. static void EdgeLoop_Chroma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
  58. static void EdgeLoop_Chroma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch);
  59. /*
  60. *****************************************************************************************
  61. * \brief Filter all macroblocks in order of increasing macroblock address.
  62. *****************************************************************************************
  63. */
  64. OSCL_EXPORT_REF AVCStatus DeblockPicture(AVCCommonObj *video)
  65. {
  66. uint i, j;
  67. int pitch = video->currPic->pitch, pitch_c, width;
  68. uint8 *SrcY, *SrcU, *SrcV;
  69. SrcY = video->currPic->Sl; // pointers to source
  70. SrcU = video->currPic->Scb;
  71. SrcV = video->currPic->Scr;
  72. pitch_c = pitch >> 1;
  73. width = video->currPic->width;
  74. for (i = 0; i < video->PicHeightInMbs; i++)
  75. {
  76. for (j = 0; j < video->PicWidthInMbs; j++)
  77. {
  78. DeblockMb(video, j, i, SrcY, SrcU, SrcV);
  79. // update SrcY, SrcU, SrcV
  80. SrcY += MB_BLOCK_SIZE;
  81. SrcU += (MB_BLOCK_SIZE >> 1);
  82. SrcV += (MB_BLOCK_SIZE >> 1);
  83. }
  84. SrcY += ((pitch << 4) - width);
  85. SrcU += ((pitch_c << 3) - (width >> 1));
  86. SrcV += ((pitch_c << 3) - (width >> 1));
  87. }
  88. return AVC_SUCCESS;
  89. }
  90. #ifdef MB_BASED_DEBLOCK
  91. /*
  92. *****************************************************************************************
  93. * \brief Filter one macroblocks in a fast macroblock memory and copy it to frame
  94. *****************************************************************************************
  95. */
  96. void MBInLoopDeblock(AVCCommonObj *video)
  97. {
  98. AVCPictureData *currPic = video->currPic;
  99. #ifdef USE_PRED_BLOCK
  100. uint8 *predCb, *predCr, *pred_block;
  101. int i, j, dst_width, dst_height, dst_widthc, dst_heightc;
  102. #endif
  103. int pitch = currPic->pitch;
  104. int x_pos = video->mb_x;
  105. int y_pos = video->mb_y;
  106. uint8 *curL, *curCb, *curCr;
  107. int offset;
  108. offset = (y_pos << 4) * pitch;
  109. curL = currPic->Sl + offset + (x_pos << 4);
  110. offset >>= 2;
  111. offset += (x_pos << 3);
  112. curCb = currPic->Scb + offset;
  113. curCr = currPic->Scr + offset;
  114. #ifdef USE_PRED_BLOCK
  115. pred_block = video->pred;
  116. /* 1. copy neighboring pixels from frame to the video->pred_block */
  117. if (y_pos) /* not the 0th row */
  118. {
  119. /* copy to the top 4 lines of the macroblock */
  120. curL -= (pitch << 2); /* go back 4 lines */
  121. memcpy(pred_block + 4, curL, 16);
  122. curL += pitch;
  123. memcpy(pred_block + 24, curL, 16);
  124. curL += pitch;
  125. memcpy(pred_block + 44, curL, 16);
  126. curL += pitch;
  127. memcpy(pred_block + 64, curL, 16);
  128. curL += pitch;
  129. curCb -= (pitch << 1); /* go back 4 lines chroma */
  130. curCr -= (pitch << 1);
  131. pred_block += 400;
  132. memcpy(pred_block + 4, curCb, 8);
  133. curCb += (pitch >> 1);
  134. memcpy(pred_block + 16, curCb, 8);
  135. curCb += (pitch >> 1);
  136. memcpy(pred_block + 28, curCb, 8);
  137. curCb += (pitch >> 1);
  138. memcpy(pred_block + 40, curCb, 8);
  139. curCb += (pitch >> 1);
  140. pred_block += 144;
  141. memcpy(pred_block + 4, curCr, 8);
  142. curCr += (pitch >> 1);
  143. memcpy(pred_block + 16, curCr, 8);
  144. curCr += (pitch >> 1);
  145. memcpy(pred_block + 28, curCr, 8);
  146. curCr += (pitch >> 1);
  147. memcpy(pred_block + 40, curCr, 8);
  148. curCr += (pitch >> 1);
  149. pred_block = video->pred;
  150. }
  151. /* 2. perform deblocking. */
  152. DeblockMb(video, x_pos, y_pos, pred_block + 84, pred_block + 452, pred_block + 596);
  153. /* 3. copy it back to the frame and update pred_block */
  154. predCb = pred_block + 400;
  155. predCr = predCb + 144;
  156. /* find the range of the block inside pred_block to be copied back */
  157. if (y_pos) /* the first row */
  158. {
  159. curL -= (pitch << 2);
  160. curCb -= (pitch << 1);
  161. curCr -= (pitch << 1);
  162. dst_height = 20;
  163. dst_heightc = 12;
  164. }
  165. else
  166. {
  167. pred_block += 80;
  168. predCb += 48;
  169. predCr += 48;
  170. dst_height = 16;
  171. dst_heightc = 8;
  172. }
  173. if (x_pos) /* find the width */
  174. {
  175. curL -= 4;
  176. curCb -= 4;
  177. curCr -= 4;
  178. if (x_pos == (int)(video->PicWidthInMbs - 1))
  179. {
  180. dst_width = 20;
  181. dst_widthc = 12;
  182. }
  183. else
  184. {
  185. dst_width = 16;
  186. dst_widthc = 8;
  187. }
  188. }
  189. else
  190. {
  191. pred_block += 4;
  192. predCb += 4;
  193. predCr += 4;
  194. dst_width = 12;
  195. dst_widthc = 4;
  196. }
  197. /* perform copy */
  198. for (j = 0; j < dst_height; j++)
  199. {
  200. memcpy(curL, pred_block, dst_width);
  201. curL += pitch;
  202. pred_block += 20;
  203. }
  204. for (j = 0; j < dst_heightc; j++)
  205. {
  206. memcpy(curCb, predCb, dst_widthc);
  207. memcpy(curCr, predCr, dst_widthc);
  208. curCb += (pitch >> 1);
  209. curCr += (pitch >> 1);
  210. predCb += 12;
  211. predCr += 12;
  212. }
  213. if (x_pos != (int)(video->PicWidthInMbs - 1)) /* now copy from the right-most 4 columns to the left-most 4 columns */
  214. {
  215. pred_block = video->pred;
  216. for (i = 0; i < 20; i += 4)
  217. {
  218. *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
  219. pred_block += 20;
  220. *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
  221. pred_block += 20;
  222. *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
  223. pred_block += 20;
  224. *((uint32*)pred_block) = *((uint32*)(pred_block + 16));
  225. pred_block += 20;
  226. }
  227. for (i = 0; i < 24; i += 4)
  228. {
  229. *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
  230. pred_block += 12;
  231. *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
  232. pred_block += 12;
  233. *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
  234. pred_block += 12;
  235. *((uint32*)pred_block) = *((uint32*)(pred_block + 8));
  236. pred_block += 12;
  237. }
  238. }
  239. #else
  240. DeblockMb(video, x_pos, y_pos, curL, curCb, curCr);
  241. #endif
  242. return ;
  243. }
  244. #endif
  245. /*
  246. *****************************************************************************************
  247. * \brief Deblocking filter for one macroblock.
  248. *****************************************************************************************
  249. */
  250. void DeblockMb(AVCCommonObj *video, int mb_x, int mb_y, uint8 *SrcY, uint8 *SrcU, uint8 *SrcV)
  251. {
  252. AVCMacroblock *MbP, *MbQ;
  253. int edge, QP, QPC;
  254. int filterLeftMbEdgeFlag = (mb_x != 0);
  255. int filterTopMbEdgeFlag = (mb_y != 0);
  256. int pitch = video->currPic->pitch;
  257. int indexA, indexB;
  258. uintptr_t tmp;
  259. int Alpha, Beta, Alpha_c, Beta_c;
  260. int mbNum = mb_y * video->PicWidthInMbs + mb_x;
  261. int *clipTable, *clipTable_c, *qp_clip_tab;
  262. uint8 Strength[16];
  263. void* str;
  264. MbQ = &(video->mblock[mbNum]); // current Mb
  265. // If filter is disabled, return
  266. if (video->sliceHdr->disable_deblocking_filter_idc == 1) return;
  267. if (video->sliceHdr->disable_deblocking_filter_idc == 2)
  268. {
  269. // don't filter at slice boundaries
  270. filterLeftMbEdgeFlag = mb_is_available(video->mblock, video->PicSizeInMbs, mbNum - 1, mbNum);
  271. filterTopMbEdgeFlag = mb_is_available(video->mblock, video->PicSizeInMbs, mbNum - video->PicWidthInMbs, mbNum);
  272. }
  273. /* NOTE: edge=0 and edge=1~3 are separate cases because of the difference of MbP, index A and indexB calculation */
  274. /* for edge = 1~3, MbP, indexA and indexB remain the same, and thus there is no need to re-calculate them for each edge */
  275. qp_clip_tab = (int *)QP_CLIP_TAB + 12;
  276. /* 1.VERTICAL EDGE + MB BOUNDARY (edge = 0) */
  277. if (filterLeftMbEdgeFlag)
  278. {
  279. MbP = MbQ - 1;
  280. //GetStrength(video, Strength, MbP, MbQ, 0, 0); // Strength for 4 blks in 1 stripe, 0 => vertical edge
  281. GetStrength_Edge0(Strength, MbP, MbQ, 0);
  282. str = (void*)Strength; //de-ref type-punned pointer fix
  283. if (*((uint32*)str)) // only if one of the 4 Strength bytes is != 0
  284. {
  285. QP = (MbP->QPy + MbQ->QPy + 1) >> 1; // Average QP of the two blocks;
  286. indexA = QP + video->FilterOffsetA;
  287. indexB = QP + video->FilterOffsetB;
  288. indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
  289. indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
  290. Alpha = ALPHA_TABLE[indexA];
  291. Beta = BETA_TABLE[indexB];
  292. clipTable = (int *) CLIP_TAB[indexA];
  293. if (Alpha > 0 && Beta > 0)
  294. #ifdef USE_PRED_BLOCK
  295. EdgeLoop_Luma_vertical(SrcY, Strength, Alpha, Beta, clipTable, 20);
  296. #else
  297. EdgeLoop_Luma_vertical(SrcY, Strength, Alpha, Beta, clipTable, pitch);
  298. #endif
  299. QPC = (MbP->QPc + MbQ->QPc + 1) >> 1;
  300. indexA = QPC + video->FilterOffsetA;
  301. indexB = QPC + video->FilterOffsetB;
  302. indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
  303. indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
  304. Alpha = ALPHA_TABLE[indexA];
  305. Beta = BETA_TABLE[indexB];
  306. clipTable = (int *) CLIP_TAB[indexA];
  307. if (Alpha > 0 && Beta > 0)
  308. {
  309. #ifdef USE_PRED_BLOCK
  310. EdgeLoop_Chroma_vertical(SrcU, Strength, Alpha, Beta, clipTable, 12);
  311. EdgeLoop_Chroma_vertical(SrcV, Strength, Alpha, Beta, clipTable, 12);
  312. #else
  313. EdgeLoop_Chroma_vertical(SrcU, Strength, Alpha, Beta, clipTable, pitch >> 1);
  314. EdgeLoop_Chroma_vertical(SrcV, Strength, Alpha, Beta, clipTable, pitch >> 1);
  315. #endif
  316. }
  317. }
  318. } /* end of: if(filterLeftMbEdgeFlag) */
  319. /* 2.VERTICAL EDGE (no boundary), the edges are all inside a MB */
  320. /* First calculate the necesary parameters all at once, outside the loop */
  321. MbP = MbQ;
  322. indexA = MbQ->QPy + video->FilterOffsetA;
  323. indexB = MbQ->QPy + video->FilterOffsetB;
  324. // index
  325. indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
  326. indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
  327. Alpha = ALPHA_TABLE[indexA];
  328. Beta = BETA_TABLE[indexB];
  329. clipTable = (int *)CLIP_TAB[indexA];
  330. /* Save Alpha, Beta and clipTable for future use, with the obselete variables filterLeftMbEdgeFlag, mbNum amd tmp */
  331. filterLeftMbEdgeFlag = Alpha;
  332. mbNum = Beta;
  333. tmp = (uintptr_t)clipTable;
  334. indexA = MbQ->QPc + video->FilterOffsetA;
  335. indexB = MbQ->QPc + video->FilterOffsetB;
  336. indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
  337. indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
  338. Alpha_c = ALPHA_TABLE[indexA];
  339. Beta_c = BETA_TABLE[indexB];
  340. clipTable_c = (int *)CLIP_TAB[indexA];
  341. GetStrength_VerticalEdges(Strength + 4, MbQ); // Strength for 4 blks in 1 stripe, 0 => vertical edge
  342. for (edge = 1; edge < 4; edge++) // 4 vertical strips of 16 pel
  343. {
  344. //GetStrength_VerticalEdges(video, Strength, MbP, MbQ, 0, edge); // Strength for 4 blks in 1 stripe, 0 => vertical edge
  345. if (*((int*)(Strength + (edge << 2)))) // only if one of the 4 Strength bytes is != 0
  346. {
  347. if (Alpha > 0 && Beta > 0)
  348. #ifdef USE_PRED_BLOCK
  349. EdgeLoop_Luma_vertical(SrcY + (edge << 2), Strength + (edge << 2), Alpha, Beta, clipTable, 20);
  350. #else
  351. EdgeLoop_Luma_vertical(SrcY + (edge << 2), Strength + (edge << 2), Alpha, Beta, clipTable, pitch);
  352. #endif
  353. if (!(edge & 1) && Alpha_c > 0 && Beta_c > 0)
  354. {
  355. #ifdef USE_PRED_BLOCK
  356. EdgeLoop_Chroma_vertical(SrcU + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
  357. EdgeLoop_Chroma_vertical(SrcV + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
  358. #else
  359. EdgeLoop_Chroma_vertical(SrcU + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
  360. EdgeLoop_Chroma_vertical(SrcV + (edge << 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
  361. #endif
  362. }
  363. }
  364. } //end edge
  365. /* 3.HORIZONTAL EDGE + MB BOUNDARY (edge = 0) */
  366. if (filterTopMbEdgeFlag)
  367. {
  368. MbP = MbQ - video->PicWidthInMbs;
  369. //GetStrength(video, Strength, MbP, MbQ, 1, 0); // Strength for 4 blks in 1 stripe, 0 => vertical edge
  370. GetStrength_Edge0(Strength, MbP, MbQ, 1);
  371. str = (void*)Strength; //de-ref type-punned pointer fix
  372. if (*((uint32*)str)) // only if one of the 4 Strength bytes is != 0
  373. {
  374. QP = (MbP->QPy + MbQ->QPy + 1) >> 1; // Average QP of the two blocks;
  375. indexA = QP + video->FilterOffsetA;
  376. indexB = QP + video->FilterOffsetB;
  377. indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
  378. indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
  379. Alpha = ALPHA_TABLE[indexA];
  380. Beta = BETA_TABLE[indexB];
  381. clipTable = (int *)CLIP_TAB[indexA];
  382. if (Alpha > 0 && Beta > 0)
  383. {
  384. #ifdef USE_PRED_BLOCK
  385. EdgeLoop_Luma_horizontal(SrcY, Strength, Alpha, Beta, clipTable, 20);
  386. #else
  387. EdgeLoop_Luma_horizontal(SrcY, Strength, Alpha, Beta, clipTable, pitch);
  388. #endif
  389. }
  390. QPC = (MbP->QPc + MbQ->QPc + 1) >> 1;
  391. indexA = QPC + video->FilterOffsetA;
  392. indexB = QPC + video->FilterOffsetB;
  393. indexA = qp_clip_tab[indexA]; // IClip(0, MAX_QP, QP+video->FilterOffsetA)
  394. indexB = qp_clip_tab[indexB]; // IClip(0, MAX_QP, QP+video->FilterOffsetB)
  395. Alpha = ALPHA_TABLE[indexA];
  396. Beta = BETA_TABLE[indexB];
  397. clipTable = (int *)CLIP_TAB[indexA];
  398. if (Alpha > 0 && Beta > 0)
  399. {
  400. #ifdef USE_PRED_BLOCK
  401. EdgeLoop_Chroma_horizontal(SrcU, Strength, Alpha, Beta, clipTable, 12);
  402. EdgeLoop_Chroma_horizontal(SrcV, Strength, Alpha, Beta, clipTable, 12);
  403. #else
  404. EdgeLoop_Chroma_horizontal(SrcU, Strength, Alpha, Beta, clipTable, pitch >> 1);
  405. EdgeLoop_Chroma_horizontal(SrcV, Strength, Alpha, Beta, clipTable, pitch >> 1);
  406. #endif
  407. }
  408. }
  409. } /* end of: if(filterTopMbEdgeFlag) */
  410. /* 4.HORIZONTAL EDGE (no boundary), the edges are inside a MB */
  411. MbP = MbQ;
  412. /* Recover Alpha, Beta and clipTable for edge!=0 with the variables filterLeftMbEdgeFlag, mbNum and tmp */
  413. /* Note that Alpha_c, Beta_c and clipTable_c for chroma is already calculated */
  414. Alpha = filterLeftMbEdgeFlag;
  415. Beta = mbNum;
  416. clipTable = (int *)tmp;
  417. GetStrength_HorizontalEdges(Strength + 4, MbQ); // Strength for 4 blks in 1 stripe, 0 => vertical edge
  418. for (edge = 1; edge < 4; edge++) // 4 horicontal strips of 16 pel
  419. {
  420. //GetStrength(video, Strength, MbP, MbQ, 1, edge); // Strength for 4 blks in 1 stripe 1 => horizontal edge
  421. if (*((int*)(Strength + (edge << 2)))) // only if one of the 4 Strength bytes is != 0
  422. {
  423. if (Alpha > 0 && Beta > 0)
  424. {
  425. #ifdef USE_PRED_BLOCK
  426. EdgeLoop_Luma_horizontal(SrcY + (edge << 2)*20, Strength + (edge << 2), Alpha, Beta, clipTable, 20);
  427. #else
  428. EdgeLoop_Luma_horizontal(SrcY + (edge << 2)*pitch, Strength + (edge << 2), Alpha, Beta, clipTable, pitch);
  429. #endif
  430. }
  431. if (!(edge & 1) && Alpha_c > 0 && Beta_c > 0)
  432. {
  433. #ifdef USE_PRED_BLOCK
  434. EdgeLoop_Chroma_horizontal(SrcU + (edge << 1)*12, Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
  435. EdgeLoop_Chroma_horizontal(SrcV + (edge << 1)*12, Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, 12);
  436. #else
  437. EdgeLoop_Chroma_horizontal(SrcU + (edge << 1)*(pitch >> 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
  438. EdgeLoop_Chroma_horizontal(SrcV + (edge << 1)*(pitch >> 1), Strength + (edge << 2), Alpha_c, Beta_c, clipTable_c, pitch >> 1);
  439. #endif
  440. }
  441. }
  442. } //end edge
  443. return;
  444. }
  445. /*
  446. *****************************************************************************************************
  447. * \brief returns a buffer of 4 Strength values for one stripe in a mb (for different Frame types)
  448. *****************************************************************************************************
  449. */
  450. void GetStrength_Edge0(uint8 *Strength, AVCMacroblock* MbP, AVCMacroblock* MbQ, int dir)
  451. {
  452. int tmp;
  453. int16 *ptrQ, *ptrP;
  454. void* vptr;
  455. uint8 *pStrength;
  456. void* refIdx;
  457. if (MbP->mbMode == AVC_I4 || MbP->mbMode == AVC_I16 ||
  458. MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
  459. {
  460. *((int*)Strength) = ININT_STRENGTH[0]; // Start with Strength=3. or Strength=4 for Mb-edge
  461. }
  462. else // if not intra or SP-frame
  463. {
  464. *((int*)Strength) = 0;
  465. if (dir == 0) // Vertical Edge 0
  466. {
  467. //1. Check the ref_frame_id
  468. refIdx = (void*) MbQ->RefIdx; //de-ref type-punned pointer fix
  469. ptrQ = (int16*)refIdx;
  470. refIdx = (void*)MbP->RefIdx; //de-ref type-punned pointer fix
  471. ptrP = (int16*)refIdx;
  472. pStrength = Strength;
  473. if (ptrQ[0] != ptrP[1]) pStrength[0] = 1;
  474. if (ptrQ[2] != ptrP[3]) pStrength[2] = 1;
  475. pStrength[1] = pStrength[0];
  476. pStrength[3] = pStrength[2];
  477. //2. Check the non-zero coeff blocks (4x4)
  478. if (MbQ->nz_coeff[0] != 0 || MbP->nz_coeff[3] != 0) pStrength[0] = 2;
  479. if (MbQ->nz_coeff[4] != 0 || MbP->nz_coeff[7] != 0) pStrength[1] = 2;
  480. if (MbQ->nz_coeff[8] != 0 || MbP->nz_coeff[11] != 0) pStrength[2] = 2;
  481. if (MbQ->nz_coeff[12] != 0 || MbP->nz_coeff[15] != 0) pStrength[3] = 2;
  482. //3. Only need to check the mv difference
  483. vptr = (void*)MbQ->mvL0; // for deref type-punned pointer
  484. ptrQ = (int16*)vptr;
  485. ptrP = (int16*)(MbP->mvL0 + 3); // points to 4x4 block #3 (the 4th column)
  486. // 1st blk
  487. if (*pStrength == 0)
  488. {
  489. // check |mv difference| >= 4
  490. tmp = *ptrQ++ - *ptrP++;
  491. if (tmp < 0) tmp = -tmp;
  492. if (tmp >= 4) *pStrength = 1;
  493. tmp = *ptrQ-- - *ptrP--;
  494. if (tmp < 0) tmp = -tmp;
  495. if (tmp >= 4) *pStrength = 1;
  496. }
  497. pStrength++;
  498. ptrQ += 8;
  499. ptrP += 8;
  500. // 2nd blk
  501. if (*pStrength == 0)
  502. {
  503. // check |mv difference| >= 4
  504. tmp = *ptrQ++ - *ptrP++;
  505. if (tmp < 0) tmp = -tmp;
  506. if (tmp >= 4) *pStrength = 1;
  507. tmp = *ptrQ-- - *ptrP--;
  508. if (tmp < 0) tmp = -tmp;
  509. if (tmp >= 4) *pStrength = 1;
  510. }
  511. pStrength++;
  512. ptrQ += 8;
  513. ptrP += 8;
  514. // 3rd blk
  515. if (*pStrength == 0)
  516. {
  517. // check |mv difference| >= 4
  518. tmp = *ptrQ++ - *ptrP++;
  519. if (tmp < 0) tmp = -tmp;
  520. if (tmp >= 4) *pStrength = 1;
  521. tmp = *ptrQ-- - *ptrP--;
  522. if (tmp < 0) tmp = -tmp;
  523. if (tmp >= 4) *pStrength = 1;
  524. }
  525. pStrength++;
  526. ptrQ += 8;
  527. ptrP += 8;
  528. // 4th blk
  529. if (*pStrength == 0)
  530. {
  531. // check |mv difference| >= 4
  532. tmp = *ptrQ++ - *ptrP++;
  533. if (tmp < 0) tmp = -tmp;
  534. if (tmp >= 4) *pStrength = 1;
  535. tmp = *ptrQ-- - *ptrP--;
  536. if (tmp < 0) tmp = -tmp;
  537. if (tmp >= 4) *pStrength = 1;
  538. }
  539. }
  540. else // Horizontal Edge 0
  541. {
  542. //1. Check the ref_frame_id
  543. refIdx = (void*)MbQ->RefIdx; //de-ref type-punned pointer
  544. ptrQ = (int16*)refIdx;
  545. refIdx = (void*)MbP->RefIdx; //de-ref type-punned pointer
  546. ptrP = (int16*)refIdx;
  547. pStrength = Strength;
  548. if (ptrQ[0] != ptrP[2]) pStrength[0] = 1;
  549. if (ptrQ[1] != ptrP[3]) pStrength[2] = 1;
  550. pStrength[1] = pStrength[0];
  551. pStrength[3] = pStrength[2];
  552. //2. Check the non-zero coeff blocks (4x4)
  553. if (MbQ->nz_coeff[0] != 0 || MbP->nz_coeff[12] != 0) pStrength[0] = 2;
  554. if (MbQ->nz_coeff[1] != 0 || MbP->nz_coeff[13] != 0) pStrength[1] = 2;
  555. if (MbQ->nz_coeff[2] != 0 || MbP->nz_coeff[14] != 0) pStrength[2] = 2;
  556. if (MbQ->nz_coeff[3] != 0 || MbP->nz_coeff[15] != 0) pStrength[3] = 2;
  557. //3. Only need to check the mv difference
  558. vptr = (void*)MbQ->mvL0;
  559. ptrQ = (int16*)vptr;
  560. ptrP = (int16*)(MbP->mvL0 + 12); // points to 4x4 block #12 (the 4th row)
  561. // 1st blk
  562. if (*pStrength == 0)
  563. {
  564. // check |mv difference| >= 4
  565. tmp = *ptrQ++ - *ptrP++;
  566. if (tmp < 0) tmp = -tmp;
  567. if (tmp >= 4) *pStrength = 1;
  568. tmp = *ptrQ-- - *ptrP--;
  569. if (tmp < 0) tmp = -tmp;
  570. if (tmp >= 4) *pStrength = 1;
  571. }
  572. pStrength++;
  573. ptrQ += 2;
  574. ptrP += 2;
  575. // 2nd blk
  576. if (*pStrength == 0)
  577. {
  578. // check |mv difference| >= 4
  579. tmp = *ptrQ++ - *ptrP++;
  580. if (tmp < 0) tmp = -tmp;
  581. if (tmp >= 4) *pStrength = 1;
  582. tmp = *ptrQ-- - *ptrP--;
  583. if (tmp < 0) tmp = -tmp;
  584. if (tmp >= 4) *pStrength = 1;
  585. }
  586. pStrength++;
  587. ptrQ += 2;
  588. ptrP += 2;
  589. // 3rd blk
  590. if (*pStrength == 0)
  591. {
  592. // check |mv difference| >= 4
  593. tmp = *ptrQ++ - *ptrP++;
  594. if (tmp < 0) tmp = -tmp;
  595. if (tmp >= 4) *pStrength = 1;
  596. tmp = *ptrQ-- - *ptrP--;
  597. if (tmp < 0) tmp = -tmp;
  598. if (tmp >= 4) *pStrength = 1;
  599. }
  600. pStrength++;
  601. ptrQ += 2;
  602. ptrP += 2;
  603. // 4th blk
  604. if (*pStrength == 0)
  605. {
  606. // check |mv difference| >= 4
  607. tmp = *ptrQ++ - *ptrP++;
  608. if (tmp < 0) tmp = -tmp;
  609. if (tmp >= 4) *pStrength = 1;
  610. tmp = *ptrQ-- - *ptrP--;
  611. if (tmp < 0) tmp = -tmp;
  612. if (tmp >= 4) *pStrength = 1;
  613. }
  614. } /* end of: else if(dir == 0) */
  615. } /* end of: if( !(MbP->mbMode == AVC_I4 ...) */
  616. }
  617. void GetStrength_VerticalEdges(uint8 *Strength, AVCMacroblock* MbQ)
  618. {
  619. int idx, tmp;
  620. int16 *ptr, *pmvx, *pmvy;
  621. uint8 *pnz;
  622. uint8 *pStrength, *pStr;
  623. void* refIdx;
  624. if (MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
  625. {
  626. *((int*)Strength) = ININT_STRENGTH[1]; // Start with Strength=3. or Strength=4 for Mb-edge
  627. *((int*)(Strength + 4)) = ININT_STRENGTH[2];
  628. *((int*)(Strength + 8)) = ININT_STRENGTH[3];
  629. }
  630. else // Not intra or SP-frame
  631. {
  632. *((int*)Strength) = 0; // for non-intra MB, strength = 0, 1 or 2.
  633. *((int*)(Strength + 4)) = 0;
  634. *((int*)(Strength + 8)) = 0;
  635. //1. Check the ref_frame_id
  636. refIdx = (void*)MbQ->RefIdx; //de-ref type-punned pointer fix
  637. ptr = (int16*)refIdx;
  638. pStrength = Strength;
  639. if (ptr[0] != ptr[1]) pStrength[4] = 1;
  640. if (ptr[2] != ptr[3]) pStrength[6] = 1;
  641. pStrength[5] = pStrength[4];
  642. pStrength[7] = pStrength[6];
  643. //2. Check the nz_coeff block and mv difference
  644. pmvx = (int16*)(MbQ->mvL0 + 1); // points to 4x4 block #1,not #0
  645. pmvy = pmvx + 1;
  646. for (idx = 0; idx < 4; idx += 2) // unroll the loop, make 4 iterations to 2
  647. {
  648. // first/third row : 1,2,3 or 9,10,12
  649. // Strength = 2 for a whole row
  650. pnz = MbQ->nz_coeff + (idx << 2);
  651. if (*pnz++ != 0) *pStrength = 2;
  652. if (*pnz++ != 0)
  653. {
  654. *pStrength = 2;
  655. *(pStrength + 4) = 2;
  656. }
  657. if (*pnz++ != 0)
  658. {
  659. *(pStrength + 4) = 2;
  660. *(pStrength + 8) = 2;
  661. }
  662. if (*pnz != 0) *(pStrength + 8) = 2;
  663. // Then Strength = 1
  664. if (*pStrength == 0)
  665. {
  666. //within the same 8x8 block, no need to check the reference id
  667. //only need to check the |mv difference| >= 4
  668. tmp = *pmvx - *(pmvx - 2);
  669. if (tmp < 0) tmp = -tmp;
  670. if (tmp >= 4) *pStrength = 1;
  671. tmp = *pmvy - *(pmvy - 2);
  672. if (tmp < 0) tmp = -tmp;
  673. if (tmp >= 4) *pStrength = 1;
  674. }
  675. pmvx += 2;
  676. pmvy += 2;
  677. pStr = pStrength + 4;
  678. if (*pStr == 0)
  679. {
  680. //check the |mv difference| >= 4
  681. tmp = *pmvx - *(pmvx - 2);
  682. if (tmp < 0) tmp = -tmp;
  683. if (tmp >= 4) *pStr = 1;
  684. tmp = *pmvy - *(pmvy - 2);
  685. if (tmp < 0) tmp = -tmp;
  686. if (tmp >= 4) *pStr = 1;
  687. }
  688. pmvx += 2;
  689. pmvy += 2;
  690. pStr = pStrength + 8;
  691. if (*pStr == 0)
  692. {
  693. //within the same 8x8 block, no need to check the reference id
  694. //only need to check the |mv difference| >= 4
  695. tmp = *pmvx - *(pmvx - 2);
  696. if (tmp < 0) tmp = -tmp;
  697. if (tmp >= 4) *pStr = 1;
  698. tmp = *pmvy - *(pmvy - 2);
  699. if (tmp < 0) tmp = -tmp;
  700. if (tmp >= 4) *pStr = 1;
  701. }
  702. // Second/fourth row: 5,6,7 or 14,15,16
  703. // Strength = 2 for a whole row
  704. pnz = MbQ->nz_coeff + ((idx + 1) << 2);
  705. if (*pnz++ != 0) *(pStrength + 1) = 2;
  706. if (*pnz++ != 0)
  707. {
  708. *(pStrength + 1) = 2;
  709. *(pStrength + 5) = 2;
  710. }
  711. if (*pnz++ != 0)
  712. {
  713. *(pStrength + 5) = 2;
  714. *(pStrength + 9) = 2;
  715. }
  716. if (*pnz != 0) *(pStrength + 9) = 2;
  717. // Then Strength = 1
  718. pmvx += 4;
  719. pmvy += 4;
  720. pStr = pStrength + 1;
  721. if (*pStr == 0)
  722. {
  723. //within the same 8x8 block, no need to check the reference id
  724. //only need to check the |mv difference| >= 4
  725. tmp = *pmvx - *(pmvx - 2);
  726. if (tmp < 0) tmp = -tmp;
  727. if (tmp >= 4) *pStr = 1;
  728. tmp = *pmvy - *(pmvy - 2);
  729. if (tmp < 0) tmp = -tmp;
  730. if (tmp >= 4) *pStr = 1;
  731. }
  732. pmvx += 2;
  733. pmvy += 2;
  734. pStr = pStrength + 5;
  735. if (*pStr == 0)
  736. {
  737. //check the |mv difference| >= 4
  738. tmp = *pmvx - *(pmvx - 2);
  739. if (tmp < 0) tmp = -tmp;
  740. if (tmp >= 4) *pStr = 1;
  741. tmp = *pmvy - *(pmvy - 2);
  742. if (tmp < 0) tmp = -tmp;
  743. if (tmp >= 4) *pStr = 1;
  744. }
  745. pmvx += 2;
  746. pmvy += 2;
  747. pStr = pStrength + 9;
  748. if (*pStr == 0)
  749. {
  750. //within the same 8x8 block, no need to check the reference id
  751. //only need to check the |mv difference| >= 4
  752. tmp = *pmvx - *(pmvx - 2);
  753. if (tmp < 0) tmp = -tmp;
  754. if (tmp >= 4) *pStr = 1;
  755. tmp = *pmvy - *(pmvy - 2);
  756. if (tmp < 0) tmp = -tmp;
  757. if (tmp >= 4) *pStr = 1;
  758. }
  759. // update some variables for the next two rows
  760. pmvx += 4;
  761. pmvy += 4;
  762. pStrength += 2;
  763. } /* end of: for(idx=0; idx<2; idx++) */
  764. } /* end of: else if( MbQ->mbMode == AVC_I4 ...) */
  765. }
  766. void GetStrength_HorizontalEdges(uint8 Strength[12], AVCMacroblock* MbQ)
  767. {
  768. int idx, tmp;
  769. int16 *ptr, *pmvx, *pmvy;
  770. uint8 *pStrength, *pStr;
  771. void* refIdx;
  772. if (MbQ->mbMode == AVC_I4 || MbQ->mbMode == AVC_I16)
  773. {
  774. *((int*)Strength) = ININT_STRENGTH[1]; // Start with Strength=3. or Strength=4 for Mb-edge
  775. *((int*)(Strength + 4)) = ININT_STRENGTH[2];
  776. *((int*)(Strength + 8)) = ININT_STRENGTH[3];
  777. }
  778. else // Not intra or SP-frame
  779. {
  780. *((int*)Strength) = 0; // for non-intra MB, strength = 0, 1 or 2.
  781. *((int*)(Strength + 4)) = 0; // for non-intra MB, strength = 0, 1 or 2.
  782. *((int*)(Strength + 8)) = 0; // for non-intra MB, strength = 0, 1 or 2.
  783. //1. Check the ref_frame_id
  784. refIdx = (void*) MbQ->RefIdx; // de-ref type-punned fix
  785. ptr = (int16*) refIdx;
  786. pStrength = Strength;
  787. if (ptr[0] != ptr[2]) pStrength[4] = 1;
  788. if (ptr[1] != ptr[3]) pStrength[6] = 1;
  789. pStrength[5] = pStrength[4];
  790. pStrength[7] = pStrength[6];
  791. //2. Check the nz_coeff block and mv difference
  792. pmvx = (int16*)(MbQ->mvL0 + 4); // points to 4x4 block #4,not #0
  793. pmvy = pmvx + 1;
  794. for (idx = 0; idx < 4; idx += 2) // unroll the loop, make 4 iterations to 2
  795. {
  796. // first/third row : 1,2,3 or 9,10,12
  797. // Strength = 2 for a whole row
  798. if (MbQ->nz_coeff[idx] != 0) *pStrength = 2;
  799. if (MbQ->nz_coeff[4+idx] != 0)
  800. {
  801. *pStrength = 2;
  802. *(pStrength + 4) = 2;
  803. }
  804. if (MbQ->nz_coeff[8+idx] != 0)
  805. {
  806. *(pStrength + 4) = 2;
  807. *(pStrength + 8) = 2;
  808. }
  809. if (MbQ->nz_coeff[12+idx] != 0) *(pStrength + 8) = 2;
  810. // Then Strength = 1
  811. if (*pStrength == 0)
  812. {
  813. //within the same 8x8 block, no need to check the reference id
  814. //only need to check the |mv difference| >= 4
  815. tmp = *pmvx - *(pmvx - 8);
  816. if (tmp < 0) tmp = -tmp;
  817. if (tmp >= 4) *pStrength = 1;
  818. tmp = *pmvy - *(pmvy - 8);
  819. if (tmp < 0) tmp = -tmp;
  820. if (tmp >= 4) *pStrength = 1;
  821. }
  822. pmvx += 8;
  823. pmvy += 8;
  824. pStr = pStrength + 4;
  825. if (*pStr == 0)
  826. {
  827. //check the |mv difference| >= 4
  828. tmp = *pmvx - *(pmvx - 8);
  829. if (tmp < 0) tmp = -tmp;
  830. if (tmp >= 4) *pStr = 1;
  831. tmp = *pmvy - *(pmvy - 8);
  832. if (tmp < 0) tmp = -tmp;
  833. if (tmp >= 4) *pStr = 1;
  834. }
  835. pmvx += 8;
  836. pmvy += 8;
  837. pStr = pStrength + 8;
  838. if (*pStr == 0)
  839. {
  840. //within the same 8x8 block, no need to check the reference id
  841. //only need to check the |mv difference| >= 4
  842. tmp = *pmvx - *(pmvx - 8);
  843. if (tmp < 0) tmp = -tmp;
  844. if (tmp >= 4) *pStr = 1;
  845. tmp = *pmvy - *(pmvy - 8);
  846. if (tmp < 0) tmp = -tmp;
  847. if (tmp >= 4) *pStr = 1;
  848. }
  849. // Second/fourth row: 5,6,7 or 14,15,16
  850. // Strength = 2 for a whole row
  851. if (MbQ->nz_coeff[idx+1] != 0) *(pStrength + 1) = 2;
  852. if (MbQ->nz_coeff[4+idx+1] != 0)
  853. {
  854. *(pStrength + 1) = 2;
  855. *(pStrength + 5) = 2;
  856. }
  857. if (MbQ->nz_coeff[8+idx+1] != 0)
  858. {
  859. *(pStrength + 5) = 2;
  860. *(pStrength + 9) = 2;
  861. }
  862. if (MbQ->nz_coeff[12+idx+1] != 0) *(pStrength + 9) = 2;
  863. // Then Strength = 1
  864. pmvx -= 14;
  865. pmvy -= 14; // -14 = -16 + 2
  866. pStr = pStrength + 1;
  867. if (*pStr == 0)
  868. {
  869. //within the same 8x8 block, no need to check the reference id
  870. //only need to check the |mv difference| >= 4
  871. tmp = *pmvx - *(pmvx - 8);
  872. if (tmp < 0) tmp = -tmp;
  873. if (tmp >= 4) *pStr = 1;
  874. tmp = *pmvy - *(pmvy - 8);
  875. if (tmp < 0) tmp = -tmp;
  876. if (tmp >= 4) *pStr = 1;
  877. }
  878. pmvx += 8;
  879. pmvy += 8;
  880. pStr = pStrength + 5;
  881. if (*pStr == 0)
  882. {
  883. //check the |mv difference| >= 4
  884. tmp = *pmvx - *(pmvx - 8);
  885. if (tmp < 0) tmp = -tmp;
  886. if (tmp >= 4) *pStr = 1;
  887. tmp = *pmvy - *(pmvy - 8);
  888. if (tmp < 0) tmp = -tmp;
  889. if (tmp >= 4) *pStr = 1;
  890. }
  891. pmvx += 8;
  892. pmvy += 8;
  893. pStr = pStrength + 9;
  894. if (*pStr == 0)
  895. {
  896. //within the same 8x8 block, no need to check the reference id
  897. //only need to check the |mv difference| >= 4
  898. tmp = *pmvx - *(pmvx - 8);
  899. if (tmp < 0) tmp = -tmp;
  900. if (tmp >= 4) *pStr = 1;
  901. tmp = *pmvy - *(pmvy - 8);
  902. if (tmp < 0) tmp = -tmp;
  903. if (tmp >= 4) *pStr = 1;
  904. }
  905. // update some variables for the next two rows
  906. pmvx -= 14;
  907. pmvy -= 14; // -14 = -16 + 2
  908. pStrength += 2;
  909. } /* end of: for(idx=0; idx<2; idx++) */
  910. } /* end of: else if( MbQ->mbMode == AVC_I4 ...) */
  911. }
  912. /*
  913. *****************************************************************************************
  914. * \brief Filters one edge of 16 (luma) or 8 (chroma) pel
  915. *****************************************************************************************
  916. */
  917. void EdgeLoop_Luma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
  918. {
  919. int pel, ap = 0, aq = 0, Strng;
  920. int C0, c0, dif, AbsDelta, tmp, tmp1;
  921. int L2 = 0, L1, L0, R0, R1, R2 = 0, RL0;
  922. if (Strength[0] == 4) /* INTRA strong filtering */
  923. {
  924. for (pel = 0; pel < 16; pel++)
  925. {
  926. R0 = SrcPtr[0];
  927. R1 = SrcPtr[pitch];
  928. L0 = SrcPtr[-pitch];
  929. L1 = SrcPtr[-(pitch<<1)];
  930. // |R0 - R1| < Beta
  931. tmp1 = R0 - R1;
  932. if (tmp1 < 0) tmp1 = -tmp1;
  933. tmp = (tmp1 - Beta);
  934. //|L0 - L1| < Beta
  935. tmp1 = L0 - L1;
  936. if (tmp1 < 0) tmp1 = -tmp1;
  937. tmp &= (tmp1 - Beta);
  938. //|R0 - L0| < Alpha
  939. AbsDelta = R0 - L0;
  940. if (AbsDelta < 0) AbsDelta = -AbsDelta;
  941. tmp &= (AbsDelta - Alpha);
  942. if (tmp < 0)
  943. {
  944. AbsDelta -= ((Alpha >> 2) + 2);
  945. R2 = SrcPtr[pitch<<1]; //inc2
  946. L2 = SrcPtr[-(pitch+(pitch<<1))]; // -inc3
  947. // |R0 - R2| < Beta && |R0 - L0| < (Alpha/4 + 2)
  948. tmp = R0 - R2;
  949. if (tmp < 0) tmp = -tmp;
  950. aq = AbsDelta & (tmp - Beta);
  951. // |L0 - L2| < Beta && |R0 - L0| < (Alpha/4 + 2)
  952. tmp = L0 - L2;
  953. if (tmp < 0) tmp = -tmp;
  954. ap = AbsDelta & (tmp - Beta);
  955. if (aq < 0)
  956. {
  957. tmp = R1 + R0 + L0;
  958. SrcPtr[0] = (L1 + (tmp << 1) + R2 + 4) >> 3;
  959. tmp += R2;
  960. SrcPtr[pitch] = (tmp + 2) >> 2;
  961. SrcPtr[pitch<<1] = (((SrcPtr[(pitch+(pitch<<1))] + R2) << 1) + tmp + 4) >> 3;
  962. }
  963. else
  964. SrcPtr[0] = ((R1 << 1) + R0 + L1 + 2) >> 2;
  965. if (ap < 0)
  966. {
  967. tmp = L1 + R0 + L0;
  968. SrcPtr[-pitch] = (R1 + (tmp << 1) + L2 + 4) >> 3;
  969. tmp += L2;
  970. SrcPtr[-(pitch<<1)] = (tmp + 2) >> 2;
  971. SrcPtr[-(pitch+(pitch<<1))] = (((SrcPtr[-(pitch<<2)] + L2) << 1) + tmp + 4) >> 3;
  972. }
  973. else
  974. SrcPtr[-pitch] = ((L1 << 1) + L0 + R1 + 2) >> 2;
  975. } /* if(tmp < 0) */
  976. SrcPtr ++; // Increment to next set of pixel
  977. } /* end of: for(pel=0; pel<16; pel++) */
  978. } /* if(Strength[0] == 4) */
  979. else /* Normal filtering */
  980. {
  981. for (pel = 0; pel < 16; pel++)
  982. {
  983. Strng = Strength[pel >> 2];
  984. if (Strng)
  985. {
  986. R0 = SrcPtr[0];
  987. R1 = SrcPtr[pitch];
  988. L0 = SrcPtr[-pitch];
  989. L1 = SrcPtr[-(pitch<<1)]; // inc2
  990. //|R0 - L0| < Alpha
  991. tmp1 = R0 - L0;
  992. if (tmp1 < 0) tmp1 = -tmp1;
  993. tmp = (tmp1 - Alpha);
  994. // |R0 - R1| < Beta
  995. tmp1 = R0 - R1;
  996. if (tmp1 < 0) tmp1 = -tmp1;
  997. tmp &= (tmp1 - Beta);
  998. //|L0 - L1| < Beta
  999. tmp1 = L0 - L1;
  1000. if (tmp1 < 0) tmp1 = -tmp1;
  1001. tmp &= (tmp1 - Beta);
  1002. if (tmp < 0)
  1003. {
  1004. R2 = SrcPtr[pitch<<1]; //inc2
  1005. L2 = SrcPtr[-(pitch+(pitch<<1))]; // -inc3
  1006. // |R0 - R2| < Beta
  1007. tmp = R0 - R2;
  1008. if (tmp < 0) tmp = -tmp;
  1009. aq = tmp - Beta;
  1010. // |L0 - L2| < Beta
  1011. tmp = L0 - L2;
  1012. if (tmp < 0) tmp = -tmp;
  1013. ap = tmp - Beta;
  1014. c0 = C0 = clipTable[Strng];
  1015. if (ap < 0) c0++;
  1016. if (aq < 0) c0++;
  1017. //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
  1018. dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
  1019. tmp = dif + c0;
  1020. if ((uint)tmp > (uint)c0 << 1)
  1021. {
  1022. tmp = ~(tmp >> 31);
  1023. dif = (tmp & (c0 << 1)) - c0;
  1024. }
  1025. //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif);
  1026. //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
  1027. RL0 = R0 + L0;
  1028. R0 -= dif;
  1029. L0 += dif;
  1030. if ((uint)R0 > 255)
  1031. {
  1032. tmp = ~(R0 >> 31);
  1033. R0 = tmp & 255;
  1034. }
  1035. if ((uint)L0 > 255)
  1036. {
  1037. tmp = ~(L0 >> 31);
  1038. L0 = tmp & 255;
  1039. }
  1040. SrcPtr[-pitch] = L0;
  1041. SrcPtr[0] = R0;
  1042. if (C0 != 0) /* Multiple zeros in the clip tables */
  1043. {
  1044. if (aq < 0) // SrcPtr[inc] += IClip(-C0, C0,(R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1);
  1045. {
  1046. R2 = (R2 + ((RL0 + 1) >> 1) - (R1 << 1)) >> 1;
  1047. tmp = R2 + C0;
  1048. if ((uint)tmp > (uint)C0 << 1)
  1049. {
  1050. tmp = ~(tmp >> 31);
  1051. R2 = (tmp & (C0 << 1)) - C0;
  1052. }
  1053. SrcPtr[pitch] += R2;
  1054. }
  1055. if (ap < 0) //SrcPtr[-inc2] += IClip(-C0, C0,(L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1);
  1056. {
  1057. L2 = (L2 + ((RL0 + 1) >> 1) - (L1 << 1)) >> 1;
  1058. tmp = L2 + C0;
  1059. if ((uint)tmp > (uint)C0 << 1)
  1060. {
  1061. tmp = ~(tmp >> 31);
  1062. L2 = (tmp & (C0 << 1)) - C0;
  1063. }
  1064. SrcPtr[-(pitch<<1)] += L2;
  1065. }
  1066. }
  1067. } /* if(tmp < 0) */
  1068. } /* end of: if((Strng = Strength[pel >> 2])) */
  1069. SrcPtr ++; // Increment to next set of pixel
  1070. } /* for(pel=0; pel<16; pel++) */
  1071. } /* else if(Strength[0] == 4) */
  1072. }
  1073. void EdgeLoop_Luma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
  1074. {
  1075. int pel, ap = 1, aq = 1;
  1076. int C0, c0, dif, AbsDelta, Strng, tmp, tmp1;
  1077. int L2 = 0, L1, L0, R0, R1, R2 = 0;
  1078. uint8 *ptr, *ptr1;
  1079. register uint R_in, L_in;
  1080. uint R_out, L_out;
  1081. if (Strength[0] == 4) /* INTRA strong filtering */
  1082. {
  1083. for (pel = 0; pel < 16; pel++)
  1084. {
  1085. // Read 8 pels
  1086. R_in = *((uint *)SrcPtr); // R_in = {R3, R2, R1, R0}
  1087. L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
  1088. R1 = (R_in >> 8) & 0xff;
  1089. R0 = R_in & 0xff;
  1090. L0 = L_in >> 24;
  1091. L1 = (L_in >> 16) & 0xff;
  1092. // |R0 - R1| < Beta
  1093. tmp1 = (R_in & 0xff) - R1;
  1094. if (tmp1 < 0) tmp1 = -tmp1;
  1095. tmp = (tmp1 - Beta);
  1096. //|L0 - L1| < Beta
  1097. tmp1 = (L_in >> 24) - L1;
  1098. if (tmp1 < 0) tmp1 = -tmp1;
  1099. tmp &= (tmp1 - Beta);
  1100. //|R0 - L0| < Alpha
  1101. AbsDelta = (R_in & 0xff) - (L_in >> 24);
  1102. if (AbsDelta < 0) AbsDelta = -AbsDelta;
  1103. tmp &= (AbsDelta - Alpha);
  1104. if (tmp < 0)
  1105. {
  1106. AbsDelta -= ((Alpha >> 2) + 2);
  1107. R2 = (R_in >> 16) & 0xff;
  1108. L2 = (L_in >> 8) & 0xff;
  1109. // |R0 - R2| < Beta && |R0 - L0| < (Alpha/4 + 2)
  1110. tmp1 = (R_in & 0xff) - R2;
  1111. if (tmp1 < 0) tmp1 = -tmp1;
  1112. aq = AbsDelta & (tmp1 - Beta);
  1113. // |L0 - L2| < Beta && |R0 - L0| < (Alpha/4 + 2)
  1114. tmp1 = (L_in >> 24) - L2;
  1115. if (tmp1 < 0) tmp1 = -tmp1;
  1116. ap = AbsDelta & (tmp1 - Beta);
  1117. ptr = SrcPtr;
  1118. if (aq < 0)
  1119. {
  1120. R_out = (R_in >> 24) << 24; // Keep R3 at the fourth byte
  1121. tmp = R0 + L0 + R1;
  1122. R_out |= (((tmp << 1) + L1 + R2 + 4) >> 3);
  1123. tmp += R2;
  1124. R_out |= (((tmp + 2) >> 2) << 8);
  1125. tmp1 = ((R_in >> 24) + R2) << 1;
  1126. R_out |= (((tmp1 + tmp + 4) >> 3) << 16);
  1127. *((uint *)SrcPtr) = R_out;
  1128. }
  1129. else
  1130. *ptr = ((R1 << 1) + R0 + L1 + 2) >> 2;
  1131. if (ap < 0)
  1132. {
  1133. L_out = (L_in << 24) >> 24; // Keep L3 at the first byte
  1134. tmp = R0 + L0 + L1;
  1135. L_out |= ((((tmp << 1) + R1 + L2 + 4) >> 3) << 24);
  1136. tmp += L2;
  1137. L_out |= (((tmp + 2) >> 2) << 16);
  1138. tmp1 = ((L_in & 0xff) + L2) << 1;
  1139. L_out |= (((tmp1 + tmp + 4) >> 3) << 8);
  1140. *((uint *)(SrcPtr - 4)) = L_out;
  1141. }
  1142. else
  1143. *(--ptr) = ((L1 << 1) + L0 + R1 + 2) >> 2;
  1144. } /* if(tmp < 0) */
  1145. SrcPtr += pitch; // Increment to next set of pixel
  1146. } /* end of: for(pel=0; pel<16; pel++) */
  1147. } /* if(Strength[0] == 4) */
  1148. else /* Normal filtering */
  1149. {
  1150. for (pel = 0; pel < 16; pel++)
  1151. {
  1152. Strng = Strength[pel >> 2];
  1153. if (Strng)
  1154. {
  1155. // Read 8 pels
  1156. R_in = *((uint *)SrcPtr); // R_in = {R3, R2, R1, R0}
  1157. L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
  1158. R1 = (R_in >> 8) & 0xff;
  1159. R0 = R_in & 0xff;
  1160. L0 = L_in >> 24;
  1161. L1 = (L_in >> 16) & 0xff;
  1162. //|R0 - L0| < Alpha
  1163. tmp = R0 - L0;
  1164. if (tmp < 0) tmp = -tmp;
  1165. tmp -= Alpha;
  1166. // |R0 - R1| < Beta
  1167. tmp1 = R0 - R1;
  1168. if (tmp1 < 0) tmp1 = -tmp1;
  1169. tmp &= (tmp1 - Beta);
  1170. //|L0 - L1| < Beta
  1171. tmp1 = L0 - L1;
  1172. if (tmp1 < 0) tmp1 = -tmp1;
  1173. tmp &= (tmp1 - Beta);
  1174. if (tmp < 0)
  1175. {
  1176. L2 = SrcPtr[-3];
  1177. R2 = SrcPtr[2];
  1178. // |R0 - R2| < Beta
  1179. tmp = R0 - R2;
  1180. if (tmp < 0) tmp = -tmp;
  1181. aq = tmp - Beta;
  1182. // |L0 - L2| < Beta
  1183. tmp = L0 - L2;
  1184. if (tmp < 0) tmp = -tmp;
  1185. ap = tmp - Beta;
  1186. c0 = C0 = clipTable[Strng];
  1187. if (ap < 0) c0++;
  1188. if (aq < 0) c0++;
  1189. //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
  1190. dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
  1191. tmp = dif + c0;
  1192. if ((uint)tmp > (uint)c0 << 1)
  1193. {
  1194. tmp = ~(tmp >> 31);
  1195. dif = (tmp & (c0 << 1)) - c0;
  1196. }
  1197. ptr = SrcPtr;
  1198. ptr1 = SrcPtr - 1;
  1199. //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif);
  1200. //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
  1201. R_in = R0 - dif;
  1202. L_in = L0 + dif; /* cannot re-use R0 and L0 here */
  1203. if ((uint)R_in > 255)
  1204. {
  1205. tmp = ~((int)R_in >> 31);
  1206. R_in = tmp & 255;
  1207. }
  1208. if ((uint)L_in > 255)
  1209. {
  1210. tmp = ~((int)L_in >> 31);
  1211. L_in = tmp & 255;
  1212. }
  1213. *ptr1-- = L_in;
  1214. *ptr++ = R_in;
  1215. if (C0 != 0) // Multiple zeros in the clip tables
  1216. {
  1217. if (ap < 0) //SrcPtr[-inc2] += IClip(-C0, C0,(L2 + ((RL0 + 1) >> 1) - (L1<<1)) >> 1);
  1218. {
  1219. L2 = (L2 + ((R0 + L0 + 1) >> 1) - (L1 << 1)) >> 1;
  1220. tmp = L2 + C0;
  1221. if ((uint)tmp > (uint)C0 << 1)
  1222. {
  1223. tmp = ~(tmp >> 31);
  1224. L2 = (tmp & (C0 << 1)) - C0;
  1225. }
  1226. *ptr1 += L2;
  1227. }
  1228. if (aq < 0) // SrcPtr[inc] += IClip(-C0, C0,(R2 + ((RL0 + 1) >> 1) - (R1<<1)) >> 1);
  1229. {
  1230. R2 = (R2 + ((R0 + L0 + 1) >> 1) - (R1 << 1)) >> 1;
  1231. tmp = R2 + C0;
  1232. if ((uint)tmp > (uint)C0 << 1)
  1233. {
  1234. tmp = ~(tmp >> 31);
  1235. R2 = (tmp & (C0 << 1)) - C0;
  1236. }
  1237. *ptr += R2;
  1238. }
  1239. }
  1240. } /* if(tmp < 0) */
  1241. } /* end of: if((Strng = Strength[pel >> 2])) */
  1242. SrcPtr += pitch; // Increment to next set of pixel
  1243. } /* for(pel=0; pel<16; pel++) */
  1244. } /* else if(Strength[0] == 4) */
  1245. }
  1246. void EdgeLoop_Chroma_vertical(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
  1247. {
  1248. int pel, Strng;
  1249. int c0, dif;
  1250. int L1, L0, R0, R1, tmp, tmp1;
  1251. uint8 *ptr;
  1252. uint R_in, L_in;
  1253. for (pel = 0; pel < 16; pel++)
  1254. {
  1255. Strng = Strength[pel>>2];
  1256. if (Strng)
  1257. {
  1258. // Read 8 pels
  1259. R_in = *((uint *)SrcPtr); // R_in = {R3, R2, R1, R0}
  1260. L_in = *((uint *)(SrcPtr - 4)); // L_in = {L0, L1, L2, L3}
  1261. R1 = (R_in >> 8) & 0xff;
  1262. R0 = R_in & 0xff;
  1263. L0 = L_in >> 24;
  1264. L1 = (L_in >> 16) & 0xff;
  1265. // |R0 - R1| < Beta
  1266. tmp1 = R0 - R1;
  1267. if (tmp1 < 0) tmp1 = -tmp1;
  1268. tmp = (tmp1 - Beta);
  1269. //|L0 - L1| < Beta
  1270. tmp1 = L0 - L1;
  1271. if (tmp1 < 0) tmp1 = -tmp1;
  1272. tmp &= (tmp1 - Beta);
  1273. //|R0 - L0| < Alpha
  1274. tmp1 = R0 - L0;
  1275. if (tmp1 < 0) tmp1 = -tmp1;
  1276. tmp &= (tmp1 - Alpha);
  1277. if (tmp < 0)
  1278. {
  1279. ptr = SrcPtr;
  1280. if (Strng == 4) /* INTRA strong filtering */
  1281. {
  1282. *ptr-- = ((R1 << 1) + R0 + L1 + 2) >> 2;
  1283. *ptr = ((L1 << 1) + L0 + R1 + 2) >> 2;
  1284. }
  1285. else /* normal filtering */
  1286. {
  1287. c0 = clipTable[Strng] + 1;
  1288. //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
  1289. dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
  1290. tmp = dif + c0;
  1291. if ((uint)tmp > (uint)c0 << 1)
  1292. {
  1293. tmp = ~(tmp >> 31);
  1294. dif = (tmp & (c0 << 1)) - c0;
  1295. }
  1296. //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif);
  1297. //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
  1298. L0 += dif;
  1299. R0 -= dif;
  1300. if ((uint)L0 > 255)
  1301. {
  1302. tmp = ~(L0 >> 31);
  1303. L0 = tmp & 255;
  1304. }
  1305. if ((uint)R0 > 255)
  1306. {
  1307. tmp = ~(R0 >> 31);
  1308. R0 = tmp & 255;
  1309. }
  1310. *ptr-- = R0;
  1311. *ptr = L0;
  1312. }
  1313. }
  1314. pel ++;
  1315. SrcPtr += pitch; // Increment to next set of pixel
  1316. } /* end of: if((Strng = Strength[pel >> 2])) */
  1317. else
  1318. {
  1319. pel += 3;
  1320. SrcPtr += (pitch << 1); //PtrInc << 1;
  1321. }
  1322. } /* end of: for(pel=0; pel<16; pel++) */
  1323. }
  1324. void EdgeLoop_Chroma_horizontal(uint8* SrcPtr, uint8 *Strength, int Alpha, int Beta, int *clipTable, int pitch)
  1325. {
  1326. int pel, Strng;
  1327. int c0, dif;
  1328. int L1, L0, R0, R1, tmp, tmp1;
  1329. for (pel = 0; pel < 16; pel++)
  1330. {
  1331. Strng = Strength[pel>>2];
  1332. if (Strng)
  1333. {
  1334. R0 = SrcPtr[0];
  1335. L0 = SrcPtr[-pitch];
  1336. L1 = SrcPtr[-(pitch<<1)]; //inc2
  1337. R1 = SrcPtr[pitch];
  1338. // |R0 - R1| < Beta
  1339. tmp1 = R0 - R1;
  1340. if (tmp1 < 0) tmp1 = -tmp1;
  1341. tmp = (tmp1 - Beta);
  1342. //|L0 - L1| < Beta
  1343. tmp1 = L0 - L1;
  1344. if (tmp1 < 0) tmp1 = -tmp1;
  1345. tmp &= (tmp1 - Beta);
  1346. //|R0 - L0| < Alpha
  1347. tmp1 = R0 - L0;
  1348. if (tmp1 < 0) tmp1 = -tmp1;
  1349. tmp &= (tmp1 - Alpha);
  1350. if (tmp < 0)
  1351. {
  1352. if (Strng == 4) /* INTRA strong filtering */
  1353. {
  1354. SrcPtr[0] = ((R1 << 1) + R0 + L1 + 2) >> 2;
  1355. SrcPtr[-pitch] = ((L1 << 1) + L0 + R1 + 2) >> 2;
  1356. }
  1357. else /* normal filtering */
  1358. {
  1359. c0 = clipTable[Strng] + 1;
  1360. //dif = IClip(-c0, c0, ((Delta << 2) + (L1 - R1) + 4) >> 3);
  1361. dif = (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3;
  1362. tmp = dif + c0;
  1363. if ((uint)tmp > (uint)c0 << 1)
  1364. {
  1365. tmp = ~(tmp >> 31);
  1366. dif = (tmp & (c0 << 1)) - c0;
  1367. }
  1368. //SrcPtr[-inc] = (uint8)IClip(0, 255, L0 + dif);
  1369. //SrcPtr[0] = (uint8)IClip(0, 255, R0 - dif);
  1370. L0 += dif;
  1371. R0 -= dif;
  1372. if ((uint)L0 > 255)
  1373. {
  1374. tmp = ~(L0 >> 31);
  1375. L0 = tmp & 255;
  1376. }
  1377. if ((uint)R0 > 255)
  1378. {
  1379. tmp = ~(R0 >> 31);
  1380. R0 = tmp & 255;
  1381. }
  1382. SrcPtr[0] = R0;
  1383. SrcPtr[-pitch] = L0;
  1384. }
  1385. }
  1386. pel ++;
  1387. SrcPtr ++; // Increment to next set of pixel
  1388. } /* end of: if((Strng = Strength[pel >> 2])) */
  1389. else
  1390. {
  1391. pel += 3;
  1392. SrcPtr += 2;
  1393. }
  1394. } /* end of: for(pel=0; pel<16; pel++) */
  1395. }