simpledeblocker.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. /****************************************************************************
  2. *
  3. * Module Title : simpledeblock.c
  4. *
  5. * Description : Simple deblocking filter.
  6. *
  7. ***************************************************************************/
  8. #define STRICT /* Strict type checking */
  9. /****************************************************************************
  10. * Header Files
  11. ****************************************************************************/
  12. #include "postp.h"
  13. /****************************************************************************
  14. * Macros
  15. ****************************************************************************/
  16. #if ( defined(_MSC_VER) || defined(MAPCA) )
  17. #define abs(x) ( (x>0) ? (x) : (-(x)) )
  18. #endif
  19. /****************************************************************************
  20. * Imports
  21. ****************************************************************************/
  22. extern UINT32 *DeblockLimitValuesV2;
  23. /****************************************************************************
  24. * Module Statics
  25. ****************************************************************************/
  26. static const UINT32 DeblockLimitValuesV1[Q_TABLE_SIZE] =
  27. {
  28. 30, 25, 20, 20, 15, 15, 14, 14,
  29. 13, 13, 12, 12, 11, 11, 10, 10,
  30. 9, 9, 8, 8, 7, 7, 7, 7,
  31. 6, 6, 6, 6, 5, 5, 5, 5,
  32. 4, 4, 4, 4, 3, 3, 3, 3,
  33. 2, 2, 2, 2, 2, 2, 2, 2,
  34. 0, 0, 0, 0, 0, 0, 0, 0,
  35. 0, 0, 0, 0, 0, 0, 0, 0
  36. };
  37. /****************************************************************************
  38. *
  39. * ROUTINE : FilterHoriz_Simple2_C
  40. *
  41. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processing instance (NOT USED).
  42. * UINT8 *PixelPtr : Pointer to four pixels that straddle the edge.
  43. * INT32 LineLength : Stride of the image being filtered.
  44. * INT32 *BoundingValuePtr : Pointer to array of bounding values.
  45. *
  46. * OUTPUTS : None.
  47. *
  48. * RETURNS : void
  49. *
  50. * FUNCTION : Applies a loop filter to the vertical edge by applying
  51. * the filter horizontally to each of the 8-rows of the
  52. * block edge.
  53. *
  54. * SPECIAL NOTES : None.
  55. *
  56. ****************************************************************************/
  57. void FilterHoriz_Simple2_C
  58. (
  59. POSTPROC_INSTANCE *ppi,
  60. UINT8 *PixelPtr,
  61. INT32 LineLength,
  62. INT32 *BoundingValuePtr
  63. )
  64. {
  65. INT32 j;
  66. INT32 x,y,z;
  67. INT32 FiltVal;
  68. UINT8 *LimitTable = &LimitVal_VP31[VAL_RANGE];
  69. (void) ppi;
  70. for ( j=0; j<8; j++ )
  71. {
  72. y = PixelPtr[2]-PixelPtr[1];
  73. if ( !y ) continue;
  74. x = PixelPtr[1]-PixelPtr[0];
  75. z = PixelPtr[3]-PixelPtr[2];
  76. FiltVal = 2 * y + z - x;
  77. FiltVal = BoundingValuePtr[(FiltVal + 4) >> 3];
  78. PixelPtr[1] = LimitTable[(INT32)PixelPtr[1] + FiltVal];
  79. PixelPtr[2] = LimitTable[(INT32)PixelPtr[2] - FiltVal];
  80. FiltVal >>= 1;
  81. FiltVal *= ((x|z)==0);
  82. PixelPtr[0] = LimitTable[(INT32)PixelPtr[0] + FiltVal];
  83. PixelPtr[3] = LimitTable[(INT32)PixelPtr[3] - FiltVal];
  84. PixelPtr += LineLength;
  85. }
  86. }
  87. /****************************************************************************
  88. *
  89. * ROUTINE : FilterVert_Simple2_C
  90. *
  91. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processing instance (NOT USED).
  92. * UINT8 *PixelPtr : Pointer to four pixels that straddle the edge.
  93. * INT32 LineLength : Stride of the image being filtered.
  94. * INT32 *BoundingValuePtr : Pointer to array of bounding values.
  95. *
  96. * OUTPUTS : None.
  97. *
  98. * RETURNS : void
  99. *
  100. * FUNCTION : Applies a loop filter to the horizontal edge by applying
  101. * the filter vertically to each of the 8-columns of the
  102. * block edge.
  103. *
  104. * SPECIAL NOTES : None.
  105. *
  106. ****************************************************************************/
  107. void FilterVert_Simple2_C
  108. (
  109. POSTPROC_INSTANCE *ppi,
  110. UINT8 *PixelPtr,
  111. INT32 LineLength,
  112. INT32 *BoundingValuePtr
  113. )
  114. {
  115. INT32 j;
  116. INT32 FiltVal;
  117. UINT8 *LimitTable = &LimitVal_VP31[VAL_RANGE];
  118. (void) ppi;
  119. for ( j=0; j<8; j++ )
  120. {
  121. INT32 UseHighVariance;
  122. FiltVal = ( ((INT32)PixelPtr[0]*3) - ((INT32)PixelPtr[-LineLength]*3) );
  123. UseHighVariance = abs ( PixelPtr[-(2*LineLength)] - PixelPtr[-LineLength] ) > 1 ||
  124. abs ( PixelPtr[0] - PixelPtr[LineLength]) > 1;
  125. if ( UseHighVariance )
  126. FiltVal += ((INT32)PixelPtr[-(2*LineLength)]) - ((INT32)PixelPtr[LineLength]);
  127. FiltVal = BoundingValuePtr[(FiltVal + 4) >> 3];
  128. PixelPtr[-LineLength] = LimitTable[(INT32)PixelPtr[-LineLength] + FiltVal];
  129. PixelPtr[ 0] = LimitTable[(INT32)PixelPtr[ 0] - FiltVal];
  130. if ( !UseHighVariance )
  131. {
  132. FiltVal >>=1;
  133. PixelPtr[-2*LineLength] = LimitTable[(INT32)PixelPtr[-2*LineLength] + FiltVal];
  134. PixelPtr[ LineLength] = LimitTable[(INT32)PixelPtr[ LineLength] - FiltVal];
  135. }
  136. PixelPtr++;
  137. }
  138. }
  139. /****************************************************************************
  140. *
  141. * ROUTINE : FilterHoriz_Simple_C
  142. *
  143. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processing instance (NOT USED).
  144. * UINT8 *PixelPtr : Pointer to four pixels that straddle the edge.
  145. * INT32 LineLength : Stride of the image being filtered.
  146. * INT32 *BoundingValuePtr : Pointer to array of bounding values.
  147. *
  148. * OUTPUTS : None.
  149. *
  150. * RETURNS : void
  151. *
  152. * FUNCTION : Applies a loop filter to the vertical edge by applying
  153. * the filter horizontally to each of the 8-rows of the
  154. * block edge.
  155. *
  156. * SPECIAL NOTES : None.
  157. *
  158. ****************************************************************************/
  159. void FilterHoriz_Simple_C
  160. (
  161. POSTPROC_INSTANCE *ppi,
  162. UINT8 *PixelPtr,
  163. INT32 LineLength,
  164. INT32 *BoundingValuePtr
  165. )
  166. {
  167. INT32 j;
  168. INT32 FiltVal;
  169. UINT8 *LimitTable = &LimitVal_VP31[VAL_RANGE];
  170. (void) ppi;
  171. for ( j=0; j<8; j++ )
  172. {
  173. INT32 UseHighVariance;
  174. FiltVal = (PixelPtr[2]*3) - (PixelPtr[1]*3);
  175. UseHighVariance = abs(PixelPtr[0] - PixelPtr[1]) > 1 ||
  176. abs(PixelPtr[2] - PixelPtr[3]) > 1;
  177. if ( UseHighVariance )
  178. FiltVal += PixelPtr[0] - PixelPtr[3];
  179. FiltVal = BoundingValuePtr[(FiltVal + 4) >> 3];
  180. PixelPtr[1] = LimitTable[(INT32)PixelPtr[1] + FiltVal];
  181. PixelPtr[2] = LimitTable[(INT32)PixelPtr[2] - FiltVal];
  182. if ( !UseHighVariance )
  183. {
  184. FiltVal >>= 1;
  185. PixelPtr[0] = LimitTable[(INT32)PixelPtr[0] + FiltVal];
  186. PixelPtr[3] = LimitTable[(INT32)PixelPtr[3] - FiltVal];
  187. }
  188. PixelPtr += LineLength;
  189. }
  190. }
  191. /****************************************************************************
  192. *
  193. * ROUTINE : FilterVert_Simple_C
  194. *
  195. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processing instance (NOT USED).
  196. * UINT8 *PixelPtr : Pointer to four pixels that straddle the edge.
  197. * INT32 LineLength : Stride of the image being filtered.
  198. * INT32 *BoundingValuePtr : Pointer to array of bounding values.
  199. *
  200. * OUTPUTS : None.
  201. *
  202. * RETURNS : void
  203. *
  204. * FUNCTION : Applies a loop filter to the horizontal edge by applying
  205. * the filter vertically to each of the 8-columns of the
  206. * block edge.
  207. *
  208. * SPECIAL NOTES : None.
  209. *
  210. ****************************************************************************/
  211. void FilterVert_Simple_C
  212. (
  213. POSTPROC_INSTANCE *ppi,
  214. UINT8 *PixelPtr,
  215. INT32 LineLength,
  216. INT32 *BoundingValuePtr
  217. )
  218. {
  219. INT32 j;
  220. INT32 FiltVal;
  221. UINT8 *LimitTable = &LimitVal_VP31[VAL_RANGE];
  222. (void) ppi;
  223. for ( j=0; j<8; j++ )
  224. {
  225. INT32 UseHighVariance;
  226. FiltVal = ( ((INT32)PixelPtr[0]*3) - ((INT32)PixelPtr[-LineLength]*3) );
  227. UseHighVariance = abs(PixelPtr[-(2*LineLength)] - PixelPtr[-LineLength]) > 1 ||
  228. abs(PixelPtr[0] - PixelPtr[LineLength]) > 1;
  229. if ( UseHighVariance )
  230. FiltVal += ((INT32)PixelPtr[-(2*LineLength)]) - ((INT32)PixelPtr[LineLength]);
  231. FiltVal = BoundingValuePtr[(FiltVal + 4) >> 3];
  232. PixelPtr[-LineLength] = LimitTable[(INT32)PixelPtr[-LineLength] + FiltVal];
  233. PixelPtr[ 0] = LimitTable[(INT32)PixelPtr[ 0] - FiltVal];
  234. if ( !UseHighVariance )
  235. {
  236. FiltVal >>=1;
  237. PixelPtr[-2*LineLength] = LimitTable[(INT32)PixelPtr[-2*LineLength] + FiltVal];
  238. PixelPtr[ LineLength] = LimitTable[(INT32)PixelPtr[ LineLength] - FiltVal];
  239. }
  240. PixelPtr++;
  241. }
  242. }
  243. /****************************************************************************
  244. *
  245. * ROUTINE : SimpleDeblockFrame
  246. *
  247. * INPUTS : POSTPROC_INSTANCE *ppi : Pointer to post-processing instance.
  248. * UINT8 *SrcBuffer : Pointer to image to be deblocked.
  249. * UINT8 *DestBuffer : Pointer to image to hold deblocked image.
  250. *
  251. * OUTPUTS : None.
  252. *
  253. * RETURNS : void
  254. *
  255. * FUNCTION : Simple deblocker.
  256. *
  257. * SPECIAL NOTES : None.
  258. *
  259. ****************************************************************************/
  260. void SimpleDeblockFrame ( POSTPROC_INSTANCE *ppi, UINT8 *SrcBuffer, UINT8 *DestBuffer )
  261. {
  262. INT32 j, m, n;
  263. INT32 RowStart;
  264. INT32 NextRow;
  265. INT32 FLimit;
  266. INT32 QIndex;
  267. INT32 *BoundingValuePtr;
  268. INT32 LineLength = 0;
  269. INT32 FragsAcross = ppi->HFragments;
  270. INT32 FragsDown = ppi->VFragments;
  271. QIndex = ppi->FrameQIndex;
  272. // Encoder version specific clause
  273. if ( ppi->Vp3VersionNo >= 2 )
  274. FLimit = DeblockLimitValuesV2[QIndex];
  275. else
  276. FLimit = DeblockLimitValuesV1[QIndex];
  277. BoundingValuePtr = SetupDeblockValueArray ( ppi, FLimit );
  278. for ( j=0; j<3; j++ )
  279. {
  280. switch ( j )
  281. {
  282. case 0: // Y
  283. FragsAcross = ppi->HFragments;
  284. FragsDown = ppi->VFragments;
  285. LineLength = ppi->YStride;
  286. RowStart = ppi->ReconYDataOffset;
  287. break;
  288. case 1: // U
  289. FragsAcross = ppi->HFragments >> 1;
  290. FragsDown = ppi->VFragments >> 1;
  291. LineLength = ppi->UVStride;
  292. RowStart = ppi->ReconUDataOffset;
  293. break;
  294. case 2: // V
  295. FragsAcross = ppi->HFragments >> 1;
  296. FragsDown = ppi->VFragments >> 1;
  297. LineLength = ppi->UVStride;
  298. RowStart = ppi->ReconVDataOffset;
  299. break;
  300. }
  301. NextRow = LineLength * 8;
  302. /*************/
  303. /* First Row */
  304. /*************/
  305. memcpy ( &DestBuffer[RowStart], &SrcBuffer[RowStart], 8*LineLength );
  306. /* First Column -- Skip */
  307. /* Remaining Columns */
  308. for ( n=1; n<FragsAcross; n++ ) // Filter Left edge always
  309. FilterHoriz_Simple ( ppi, &DestBuffer[RowStart+n*8-2], LineLength, BoundingValuePtr );
  310. RowStart += NextRow;
  311. //**************/
  312. // Middle Rows */
  313. //**************/
  314. for ( m=1; m<FragsDown; m++ )
  315. {
  316. n = 0;
  317. memcpy ( &DestBuffer[RowStart], &SrcBuffer[RowStart], 8*LineLength );
  318. /* First column */
  319. FilterVert_Simple ( ppi, &DestBuffer[RowStart+n*8], LineLength, BoundingValuePtr );
  320. /* Middle columns */
  321. for ( n=1; n<FragsAcross; n++ )
  322. {
  323. // Filter Left edge always
  324. FilterHoriz_Simple ( ppi, &DestBuffer[RowStart+n*8-2], LineLength, BoundingValuePtr );
  325. // TopRow is always done
  326. FilterVert_Simple ( ppi, &DestBuffer[RowStart+n*8], LineLength, BoundingValuePtr );
  327. }
  328. RowStart += NextRow;
  329. }
  330. }
  331. }