deblock.c 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491
  1. /****************************************************************************
  2. *
  3. * Module Title : deblock.c
  4. *
  5. * Description : Post-processing deblocker functions.
  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. * Exports
  21. ****************************************************************************/
  22. UINT32 DeblockLimitValuesVp4[Q_TABLE_SIZE] =
  23. {
  24. 30, 25, 20, 20, 15, 15, 14, 14,
  25. 13, 13, 12, 12, 11, 11, 10, 10,
  26. 9, 9, 8, 8, 7, 7, 7, 7,
  27. 6, 6, 6, 6, 5, 5, 5, 5,
  28. 4, 4, 4, 4, 3, 3, 3, 3,
  29. 2, 2, 2, 2, 2, 2, 2, 2,
  30. 2, 2, 2, 2, 2, 2, 2, 2,
  31. 1, 1, 1, 1, 1, 1, 1, 1
  32. };
  33. UINT32 DeblockLimitValuesVp5[Q_TABLE_SIZE] =
  34. {
  35. 15, 15, 15, 15, 10, 10, 10, 10,
  36. 10, 10, 10, 10, 10, 9, 8, 8,
  37. 8, 8, 8, 8, 8, 8, 8, 8,
  38. 8, 7, 7, 7, 7, 7, 7, 7,
  39. 6, 6, 6, 6, 5, 5, 5, 5,
  40. 5, 4, 4, 4, 4, 4, 4, 3,
  41. 3, 3, 3, 3, 3, 2, 2, 2,
  42. 2, 2, 1, 1, 1, 0, 0, 0
  43. };
  44. UINT32 DeblockLimitValuesVp6[Q_TABLE_SIZE] =
  45. {
  46. 15, 15, 15, 15, 10, 10, 10, 10,
  47. 10, 10, 10, 10, 10, 9, 8, 8,
  48. 8, 8, 8, 8, 8, 8, 8, 8,
  49. 8, 7, 7, 7, 7, 7, 7, 7,
  50. 6, 6, 6, 6, 5, 5, 5, 5,
  51. 5, 4, 4, 4, 4, 4, 4, 3,
  52. 3, 3, 3, 3, 3, 2, 2, 2,
  53. 2, 2, 1, 1, 1, 0, 0, 0
  54. };
  55. UINT32 *DCQuantScaleV2;
  56. UINT32 *DCQuantScaleUV;
  57. UINT32 *DCQuantScaleV1;
  58. UINT32 *DeblockLimitValuesV2;
  59. /****************************************************************************
  60. *
  61. * ROUTINE : SetupDeblockValueArray_Generic
  62. *
  63. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  64. * INT32 FLimit : Deblocking limit value.
  65. *
  66. * OUTPUTS : None
  67. *
  68. * RETURNS : UINT32 *: Pointer to deblocker LUT.
  69. *
  70. * FUNCTION : Sets up the bounding value array.
  71. *
  72. * SPECIAL NOTES : None.
  73. *
  74. ****************************************************************************/
  75. INT32 *SetupDeblockValueArray_Generic ( POSTPROC_INSTANCE *pbi, INT32 FLimit )
  76. {
  77. INT32 i;
  78. INT32 *DeblockValuePtr;
  79. DeblockValuePtr = &pbi->DeblockBoundingValue[256];
  80. // Set up the bounding value array.
  81. memset ( pbi->DeblockBoundingValue, 0, (512*sizeof(*pbi->DeblockBoundingValue)) );
  82. for ( i=0; i<FLimit; i++ )
  83. {
  84. DeblockValuePtr[-i-FLimit] = (-FLimit+i);
  85. DeblockValuePtr[-i] = -i;
  86. DeblockValuePtr[i] = i;
  87. DeblockValuePtr[i+FLimit] = FLimit-i;
  88. }
  89. return DeblockValuePtr;
  90. }
  91. /****************************************************************************
  92. *
  93. * ROUTINE : SetupDeblocker
  94. *
  95. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  96. *
  97. * OUTPUTS : None.
  98. *
  99. * RETURNS : void
  100. *
  101. * FUNCTION : Prepares LUT ready to apply a loop filter.
  102. *
  103. * SPECIAL NOTES : None.
  104. *
  105. ****************************************************************************/
  106. void SetupDeblocker ( POSTPROC_INSTANCE *pbi )
  107. {
  108. INT32 FLimit;
  109. if ( pbi->Vp3VersionNo >= 2 )
  110. {
  111. FLimit = DeblockLimitValuesV2[pbi->FrameQIndex];
  112. pbi->DeblockValuePtr = SetupDeblockValueArray_Generic ( pbi, FLimit );
  113. }
  114. else
  115. {
  116. FLimit = DeblockLimitValuesV2[pbi->FrameQIndex];
  117. pbi->DeblockValuePtr = SetupDeblockValueArray ( pbi, FLimit );
  118. }
  119. }
  120. /****************************************************************************
  121. *
  122. * ROUTINE : DeblockVerticalEdgesInLoopFilteredBand
  123. *
  124. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  125. * UINT8 *SrcPtr : Pointer to input image.
  126. * UINT8 *DesPtr : Pointer to output image.
  127. * UINT32 PlaneLineStep : Stride of SrcPtr & DesPtr.
  128. * UINT32 FragsAcross : Number of blocks across.
  129. * UINT32 StartFrag : Number of first block.
  130. * UINT32 *QuantScale :
  131. *
  132. * OUTPUTS : None.
  133. *
  134. * RETURNS : void
  135. *
  136. * FUNCTION : Filters the vertical edges in a band.
  137. *
  138. * SPECIAL NOTES : Variance values for each block are stored in
  139. * pbi->FragmentVariances for later use.
  140. *
  141. ****************************************************************************/
  142. void DeblockVerticalEdgesInLoopFilteredBand
  143. (
  144. POSTPROC_INSTANCE *pbi,
  145. UINT8 *SrcPtr,
  146. UINT8 *DesPtr,
  147. UINT32 PlaneLineStep,
  148. UINT32 FragsAcross,
  149. UINT32 StartFrag,
  150. UINT32 *QuantScale
  151. )
  152. {
  153. UINT32 j, k;
  154. INT32 QStep;
  155. INT32 FLimit;
  156. INT32 p1,p2;
  157. INT32 psum;
  158. INT32 v[10];
  159. INT32 Sum1, Sum2;
  160. INT32 Variance1, Variance2;
  161. UINT8 *Src, *Des;
  162. UINT32 CurrentFrag = StartFrag;
  163. while ( CurrentFrag < (StartFrag+FragsAcross-1) )
  164. {
  165. Src = SrcPtr + 8*(CurrentFrag-StartFrag+1);
  166. Des = DesPtr + 8*(CurrentFrag-StartFrag+1);
  167. QStep = QuantScale[pbi->FragQIndex[CurrentFrag+1]];
  168. FLimit = (QStep * QStep * 3)>>5 ;
  169. for( j=0; j<8 ; j++)
  170. {
  171. v[1] = Src[-4];
  172. v[2] = Src[-3];
  173. v[3] = Src[-2];
  174. v[4] = Src[-1];
  175. v[5] = Src[0];
  176. v[6] = Src[+1];
  177. v[7] = Src[+2];
  178. v[8] = Src[+3];
  179. Variance1 = Variance2 = 0;
  180. Sum1 = Sum2 = 0;
  181. for ( k=1; k<=4; k++ )
  182. {
  183. Sum1 += v[k];
  184. Variance1 += v[k]*v[k];
  185. }
  186. for ( k=5; k<=8; k++ )
  187. {
  188. Sum2 += v[k];
  189. Variance2 += v[k]*v[k];
  190. }
  191. Variance1 -= ((Sum1>>1)*((Sum1+1)>>1));
  192. Variance2 -= ((Sum2>>1)*((Sum2+1)>>1));
  193. pbi->FragmentVariances[CurrentFrag] += Variance1;
  194. pbi->FragmentVariances[CurrentFrag + 1] += Variance2;
  195. if( (Variance1 < FLimit) && (Variance2 < FLimit) &&
  196. ((v[5] - v[4]) < QStep) && ((v[4] - v[5]) < QStep) )
  197. {
  198. p1 = (abs(Src[-4] - Src[-5]) < QStep ) ? Src[-5] : Src[-4];
  199. p2 = (abs(Src[+3] - Src[+4]) < QStep ) ? Src[+4] : Src[+3];
  200. /* low pass filtering (LPF9: 1 1 2 2 4 2 2 1 1) */
  201. psum = p1 + p1 + p1 + v[1] + v[2] + v[3] + v[4] + 4;
  202. Des[-4] = (INT8) ((((psum + v[1]) << 1) - (v[4] - v[5])) >> 4);
  203. psum += v[5] - p1;
  204. Des[-3] = (INT8) ((((psum + v[2]) << 1) - (v[5] - v[6])) >> 4);
  205. psum += v[6] - p1;
  206. Des[-2] = (INT8) ((((psum + v[3]) << 1) - (v[6] - v[7])) >> 4);
  207. psum += v[7] - p1;
  208. Des[-1] = (INT8) ((((psum + v[4]) << 1) + p1 - v[1] - (v[7] - v[8])) >> 4);
  209. psum += v[8] - v[1];
  210. Des[0] = (INT8) ((((psum + v[5]) << 1) + (v[1] - v[2]) - v[8] + p2) >> 4);
  211. psum += p2 - v[2];
  212. Des[+1] =(INT8) ((((psum + v[6]) << 1) + (v[2] - v[3])) >> 4);
  213. psum += p2 - v[3];
  214. Des[+2] = (INT8) ((((psum + v[7]) << 1) + (v[3] - v[4])) >> 4);
  215. psum += p2 - v[4];
  216. Des[+3] = (INT8) ((((psum + v[8]) << 1) + (v[4] - v[5])) >> 4);
  217. }
  218. Src += PlaneLineStep;
  219. Des += PlaneLineStep;
  220. }
  221. CurrentFrag++;
  222. }
  223. }
  224. /****************************************************************************
  225. *
  226. * ROUTINE : DeblockLoopFilteredBand_C
  227. *
  228. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  229. * UINT8 *SrcPtr : Pointer to input image.
  230. * UINT8 *DesPtr : Pointer to output image.
  231. * UINT32 PlaneLineStep : Stride of SrcPtr & DesPtr.
  232. * UINT32 FragsAcross : Number of blocks across.
  233. * UINT32 StartFrag : Number of first block.
  234. * UINT32 *QuantScale :
  235. *
  236. * OUTPUTS : None.
  237. *
  238. * RETURNS : void
  239. *
  240. * FUNCTION : Filters both horizontal and vertical edge in a band.
  241. *
  242. * SPECIAL NOTES : Variance values for each block are stored in
  243. * pbi->FragmentVariances for later use.
  244. *
  245. ****************************************************************************/
  246. void DeblockLoopFilteredBand_C
  247. (
  248. POSTPROC_INSTANCE *pbi,
  249. UINT8 *SrcPtr,
  250. UINT8 *DesPtr,
  251. UINT32 PlaneLineStep,
  252. UINT32 FragsAcross,
  253. UINT32 StartFrag,
  254. UINT32 *QuantScale
  255. )
  256. {
  257. UINT32 j,k;
  258. UINT32 CurrentFrag=StartFrag;
  259. INT32 QStep;
  260. INT32 FLimit;
  261. UINT8 *Src, *Des;
  262. INT32 psum;
  263. INT32 v[10];
  264. INT32 p1,p2;
  265. INT32 w1, w2, w3, w4, w5;
  266. INT32 Variance1, Variance2;
  267. INT32 Sum1, Sum2;
  268. w1 = PlaneLineStep;
  269. w2 = PlaneLineStep * 2;
  270. w3 = PlaneLineStep * 3;
  271. w4 = PlaneLineStep * 4;
  272. w5 = PlaneLineStep * 5;
  273. while ( CurrentFrag < StartFrag+FragsAcross )
  274. {
  275. Src = SrcPtr + 8*(CurrentFrag-StartFrag);
  276. Des = DesPtr + 8*(CurrentFrag-StartFrag);
  277. QStep = QuantScale[pbi->FragQIndex[CurrentFrag+FragsAcross]];
  278. FLimit = (QStep * QStep * 3)>>5 ;
  279. for ( j=0; j<8; j++ )
  280. {
  281. v[1] = Src[-w4];
  282. v[2] = Src[-w3];
  283. v[3] = Src[-w2];
  284. v[4] = Src[-w1];
  285. v[5] = Src[0];
  286. v[6] = Src[+w1];
  287. v[7] = Src[+w2];
  288. v[8] = Src[+w3];
  289. Variance1 = Variance2 = 0;
  290. Sum1 = Sum2 = 0;
  291. for ( k=1; k<=4; k++ )
  292. {
  293. Sum1 += v[k];
  294. Variance1 += v[k]*v[k];
  295. }
  296. for ( k=5; k<=8; k++ )
  297. {
  298. Sum2 += v[k];
  299. Variance2 += v[k]*v[k];
  300. }
  301. Variance1 -= ((Sum1>>1)*((Sum1+1)>>1));
  302. Variance2 -= ((Sum2>>1)*((Sum2+1)>>1));
  303. pbi->FragmentVariances[CurrentFrag] += Variance1;
  304. pbi->FragmentVariances[CurrentFrag + FragsAcross] += Variance2;
  305. if( (Variance1 < FLimit) && (Variance2 < FLimit) &&
  306. ((v[5] - v[4]) < QStep) && ((v[4] - v[5]) < QStep) )
  307. {
  308. p1 = (abs(Src[-w4] - Src[-w5]) < QStep ) ? Src[-w5] : Src[-w4];
  309. p2 = (abs(Src[+w3] - Src[+w4]) < QStep ) ? Src[+w4] : Src[+w3];
  310. /* low pass filtering (LPF9: 1 1 2 2 4 2 2 1 1) */
  311. psum = p1 + p1 + p1 + v[1] + v[2] + v[3] + v[4] + 4;
  312. Des[-w4] = (INT8)((((psum + v[1]) << 1) - (v[4] - v[5])) >> 4);
  313. psum += v[5] - p1;
  314. Des[-w3] = (INT8)((((psum + v[2]) << 1) - (v[5] - v[6])) >> 4);
  315. psum += v[6] - p1;
  316. Des[-w2] = (INT8)((((psum + v[3]) << 1) - (v[6] - v[7])) >> 4);
  317. psum += v[7] - p1;
  318. Des[-w1] = (INT8)((((psum + v[4]) << 1) + p1 - v[1] - (v[7] - v[8])) >> 4);
  319. psum += v[8] - v[1];
  320. Des[0] = (INT8)((((psum + v[5]) << 1) + (v[1] - v[2]) - v[8] + p2) >> 4);
  321. psum += p2 - v[2];
  322. Des[+w1] = (INT8)((((psum + v[6]) << 1) + (v[2] - v[3])) >> 4);
  323. psum += p2 - v[3];
  324. Des[+w2] = (INT8)((((psum + v[7]) << 1) + (v[3] - v[4])) >> 4);
  325. psum += p2 - v[4];
  326. Des[+w3] = (INT8)((((psum + v[8]) << 1) + (v[4] - v[5])) >> 4);
  327. }
  328. else
  329. {
  330. Des[-w4] = Src[-w4];
  331. Des[-w3] = Src[-w3];
  332. Des[-w2] = Src[-w2];
  333. Des[-w1] = Src[-w1];
  334. Des[0] = Src[0];
  335. Des[+w1] = Src[+w1];
  336. Des[+w2] = Src[+w2];
  337. Des[+w3] = Src[+w3];
  338. }
  339. Src++;
  340. Des++;
  341. }
  342. CurrentFrag++;
  343. }
  344. CurrentFrag = StartFrag;
  345. while ( CurrentFrag < (StartFrag+FragsAcross-1) )
  346. {
  347. Des = DesPtr - 8*PlaneLineStep + 8*(CurrentFrag-StartFrag+1);
  348. Src = Des;
  349. QStep = QuantScale[pbi->FragQIndex[CurrentFrag+1]];
  350. FLimit = (QStep * QStep * 3)>>5 ;
  351. for ( j=0; j<8 ; j++ )
  352. {
  353. v[1] = Src[-4];
  354. v[2] = Src[-3];
  355. v[3] = Src[-2];
  356. v[4] = Src[-1];
  357. v[5] = Src[0];
  358. v[6] = Src[+1];
  359. v[7] = Src[+2];
  360. v[8] = Src[+3];
  361. Variance1 = Variance2 = 0;
  362. Sum1 = Sum2 = 0;
  363. for ( k=1; k<=4; k++ )
  364. {
  365. Sum1 += v[k];
  366. Variance1 += v[k]*v[k];
  367. }
  368. for ( k=5; k<=8; k++ )
  369. {
  370. Sum2 += v[k];
  371. Variance2 += v[k]*v[k];
  372. }
  373. Variance1 -= ((Sum1>>1)*((Sum1+1)>>1));
  374. Variance2 -= ((Sum2>>1)*((Sum2+1)>>1));
  375. pbi->FragmentVariances[CurrentFrag] += Variance1;
  376. pbi->FragmentVariances[CurrentFrag + 1] += Variance2;
  377. if ( (Variance1 < FLimit) && (Variance2 < FLimit) &&
  378. ((v[5] - v[4]) < QStep) && ((v[4] - v[5]) < QStep) )
  379. {
  380. p1 = (abs(Src[-4] - Src[-5]) < QStep ) ? Src[-5] : Src[-4];
  381. p2 = (abs(Src[+3] - Src[+4]) < QStep ) ? Src[+4] : Src[+3];
  382. /* lo pass filtering (LPF9: 1 1 2 2 4 2 2 1 1) */
  383. psum = p1 + p1 + p1 + v[1] + v[2] + v[3] + v[4] + 4;
  384. Des[-4] = (INT8)((((psum + v[1]) << 1) - (v[4] - v[5])) >> 4);
  385. psum += v[5] - p1;
  386. Des[-3] = (INT8)((((psum + v[2]) << 1) - (v[5] - v[6])) >> 4);
  387. psum += v[6] - p1;
  388. Des[-2] = (INT8)((((psum + v[3]) << 1) - (v[6] - v[7])) >> 4);
  389. psum += v[7] - p1;
  390. Des[-1] = (INT8)((((psum + v[4]) << 1) + p1 - v[1] - (v[7] - v[8])) >> 4);
  391. psum += v[8] - v[1];
  392. Des[0] = (INT8)((((psum + v[5]) << 1) + (v[1] - v[2]) - v[8] + p2) >> 4);
  393. psum += p2 - v[2];
  394. Des[+1] = (INT8)((((psum + v[6]) << 1) + (v[2] - v[3])) >> 4);
  395. psum += p2 - v[3];
  396. Des[+2] =(INT8)((((psum + v[7]) << 1) + (v[3] - v[4])) >> 4);
  397. psum += p2 - v[4];
  398. Des[+3] = (INT8)((((psum + v[8]) << 1) + (v[4] - v[5])) >> 4);
  399. }
  400. Src += PlaneLineStep;
  401. Des += PlaneLineStep;
  402. }
  403. CurrentFrag++;
  404. }
  405. }
  406. /****************************************************************************
  407. *
  408. * ROUTINE : DeblockVerticalEdgesInNonFilteredBand
  409. *
  410. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  411. * UINT8 *SrcPtr : Pointer to input image.
  412. * UINT8 *DesPtr : Pointer to output image.
  413. * UINT32 PlaneLineStep : Stride of SrcPtr & DesPtr.
  414. * UINT32 FragsAcross : Number of blocks across.
  415. * UINT32 StartFrag : Number of first block.
  416. * UINT32 *QuantScale :
  417. *
  418. * OUTPUTS : None.
  419. *
  420. * RETURNS : void
  421. *
  422. * FUNCTION : Filter the vertical edges in a band.
  423. *
  424. * SPECIAL NOTES : Variance values for each block are stored in
  425. * pbi->FragmentVariances for later use.
  426. *
  427. ****************************************************************************/
  428. void DeblockVerticalEdgesInNonFilteredBand
  429. (
  430. POSTPROC_INSTANCE *pbi,
  431. UINT8 *SrcPtr,
  432. UINT8 *DesPtr,
  433. UINT32 PlaneLineStep,
  434. UINT32 FragsAcross,
  435. UINT32 StartFrag,
  436. UINT32 *QuantScale
  437. )
  438. {
  439. UINT32 j,k;
  440. INT32 QStep;
  441. INT32 FLimit;
  442. INT32 psum;
  443. INT32 v[10];
  444. INT32 p1,p2;
  445. INT32 Sum1, Sum2;
  446. INT32 Variance1, Variance2;
  447. UINT8 *Src, *Des;
  448. UINT32 CurrentFrag = StartFrag;
  449. while ( CurrentFrag < (StartFrag + FragsAcross-1) )
  450. {
  451. Src = SrcPtr + 8*(CurrentFrag-StartFrag+1);
  452. Des = DesPtr + 8*(CurrentFrag-StartFrag+1);
  453. QStep = QuantScale[pbi->FragQIndex[CurrentFrag+1]];
  454. FLimit = (QStep * QStep * 3)>>5 ;
  455. for ( j=0; j<8 ; j++ )
  456. {
  457. v[1] = Src[-4];
  458. v[2] = Src[-3];
  459. v[3] = Src[-2];
  460. v[4] = Src[-1];
  461. v[5] = Src[0];
  462. v[6] = Src[+1];
  463. v[7] = Src[+2];
  464. v[8] = Src[+3];
  465. Variance1 = Variance2 = 0;
  466. Sum1 = Sum2 = 0;
  467. for ( k=1; k<=4; k++ )
  468. {
  469. Sum1 += v[k];
  470. Variance1 += v[k]*v[k];
  471. }
  472. for ( k=5; k<=8; k++ )
  473. {
  474. Sum2 += v[k];
  475. Variance2 += v[k]*v[k];
  476. }
  477. Variance1 -= ((Sum1>>1)*((Sum1+1)>>1));
  478. Variance2 -= ((Sum2>>1)*((Sum2+1)>>1));
  479. pbi->FragmentVariances[CurrentFrag] += Variance1;
  480. pbi->FragmentVariances[CurrentFrag + 1] += Variance2;
  481. if ( (Variance1 < FLimit) && (Variance2 < FLimit) &&
  482. ((v[5] - v[4]) < QStep) && ((v[4] - v[5]) < QStep) )
  483. {
  484. p1 = (abs(Src[-4] - Src[-5]) < QStep ) ? Src[-5] : Src[-4];
  485. p2 = (abs(Src[+3] - Src[+4]) < QStep ) ? Src[+4] : Src[+3];
  486. // low pass filtering (LPF9: 1 1 2 2 4 2 2 1 1)
  487. psum = p1 + p1 + p1 + v[1] + v[2] + v[3] + v[4] + 4;
  488. Des[-4] = (INT8)((((psum + v[1]) << 1) - (v[4] - v[5])) >> 4);
  489. psum += v[5] - p1;
  490. Des[-3] = (INT8)((((psum + v[2]) << 1) - (v[5] - v[6])) >> 4);
  491. psum += v[6] - p1;
  492. Des[-2] = (INT8)((((psum + v[3]) << 1) - (v[6] - v[7])) >> 4);
  493. psum += v[7] - p1;
  494. Des[-1] = (INT8)((((psum + v[4]) << 1) + p1 - v[1] - (v[7] - v[8])) >> 4);
  495. psum += v[8] - v[1];
  496. Des[0] = (INT8)((((psum + v[5]) << 1) + (v[1] - v[2]) - v[8] + p2) >> 4);
  497. psum += p2 - v[2];
  498. Des[+1] =(INT8)((((psum + v[6]) << 1) + (v[2] - v[3])) >> 4);
  499. psum += p2 - v[3];
  500. Des[+2] = (INT8)((((psum + v[7]) << 1) + (v[3] - v[4])) >> 4);
  501. psum += p2 - v[4];
  502. Des[+3] = (INT8)((((psum + v[8]) << 1) + (v[4] - v[5])) >> 4);
  503. }
  504. else
  505. {
  506. // Old loop filter
  507. INT32 FiltVal;
  508. UINT8 *LimitTable = &LimitVal_VP31[VAL_RANGE];
  509. FiltVal = v[3] - v[4] * 3 + v[5] * 3 - v[6] ;
  510. FiltVal = pbi->DeblockValuePtr[(FiltVal + 4) >> 3];
  511. Des[-1] = LimitTable[(INT32)v[4] + FiltVal];
  512. Des[ 0] = LimitTable[(INT32)v[5] - FiltVal];
  513. }
  514. Src += PlaneLineStep;
  515. Des += PlaneLineStep;
  516. }
  517. CurrentFrag++;
  518. }
  519. }
  520. /****************************************************************************
  521. *
  522. * ROUTINE : DeblockVerticalEdgesInNonFilteredBandNewFilter
  523. *
  524. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  525. * UINT8 *SrcPtr : Pointer to input image.
  526. * UINT8 *DesPtr : Pointer to output image.
  527. * UINT32 PlaneLineStep : Stride of SrcPtr & DesPtr.
  528. * UINT32 FragsAcross : Number of blocks across.
  529. * UINT32 StartFrag : Number of first block.
  530. * UINT32 *QuantScale :
  531. *
  532. * OUTPUTS : None.
  533. *
  534. * RETURNS : void
  535. *
  536. * FUNCTION : Filter the vertical edges in a band.
  537. *
  538. * SPECIAL NOTES : None.
  539. *
  540. ****************************************************************************/
  541. void DeblockVerticalEdgesInNonFilteredBandNewFilter
  542. (
  543. POSTPROC_INSTANCE *pbi,
  544. UINT8 *SrcPtr,
  545. UINT8 *DesPtr,
  546. UINT32 PlaneLineStep,
  547. UINT32 FragsAcross,
  548. UINT32 StartFrag,
  549. UINT32 *QuantScale
  550. )
  551. {
  552. UINT32 j,k;
  553. INT32 QStep;
  554. INT32 FLimit;
  555. INT32 psum;
  556. INT32 v[10];
  557. INT32 p1,p2;
  558. INT32 Sum1, Sum2;
  559. UINT8 *Src, *Des;
  560. UINT32 CurrentFrag = StartFrag;
  561. QStep = QuantScale[pbi->FrameQIndex];
  562. for (CurrentFrag = StartFrag; CurrentFrag < (StartFrag + FragsAcross); CurrentFrag++)
  563. {
  564. Src = SrcPtr + 8*(CurrentFrag-StartFrag+1);
  565. Des = DesPtr + 8*(CurrentFrag-StartFrag+1);
  566. FLimit = (QStep * QStep * 3)>>5;
  567. for ( j=0; j<8; j++ )
  568. {
  569. v[0] = Src[-5];
  570. v[1] = Src[-4];
  571. v[2] = Src[-3];
  572. v[3] = Src[-2];
  573. v[4] = Src[-1];
  574. v[5] = Src[0];
  575. v[6] = Src[+1];
  576. v[7] = Src[+2];
  577. v[8] = Src[+3];
  578. v[9] = Src[+4];
  579. Sum1 = Sum2 = 0;
  580. for ( k=1; k<=4; k++ )
  581. Sum1 += abs ( v[k]-v[k-1] );
  582. for ( k=5; k<=8; k++ )
  583. Sum2 += abs ( v[k]-v[k+1] );
  584. if ( (Sum1 < FLimit) && (Sum2 < FLimit) &&
  585. ((v[5] - v[4]) < QStep) && ((v[4] - v[5]) < QStep) )
  586. {
  587. p1 = v[0];
  588. p2 = v[9];
  589. // low pass filtering (LPF7: 1 1 1 2 1 1 1)
  590. psum = p1 + p1 + p1 + v[1] + v[2] + v[3] + v[4] + 4;
  591. Des[-4] = (INT8)((psum + v[1]) >> 3);
  592. psum += v[5] - p1;
  593. Des[-3] = (INT8)((psum + v[2]) >> 3);
  594. psum += v[6] - p1;
  595. Des[-2] = (INT8)((psum + v[3]) >> 3);
  596. psum += v[7] - p1;
  597. Des[-1] = (INT8)((psum + v[4]) >> 3);
  598. psum += v[8] - v[1];
  599. Des[0] = (INT8)((psum + v[5]) >> 3);
  600. psum += p2 - v[2];
  601. Des[+1] = (INT8)((psum + v[6]) >> 3);
  602. psum += p2 - v[3];
  603. Des[+2] = (INT8)((psum + v[7]) >> 3);
  604. psum += p2 - v[4];
  605. Des[+3] = (INT8)((psum + v[8]) >> 3);
  606. }
  607. else
  608. {
  609. // Old loopfilter
  610. INT32 FiltVal;
  611. UINT8 * LimitTable = &LimitVal_VP31[VAL_RANGE];
  612. FiltVal = v[3] - v[4] * 3 + v[5] * 3 - v[6] ;
  613. FiltVal = pbi->DeblockValuePtr[(FiltVal + 4) >> 3];
  614. Des[-1] = LimitTable[(INT32)v[4] + FiltVal];
  615. Des[ 0] = LimitTable[(INT32)v[5] - FiltVal];
  616. }
  617. Src += PlaneLineStep;
  618. Des += PlaneLineStep;
  619. }
  620. }
  621. }
  622. /****************************************************************************
  623. *
  624. * ROUTINE : DeblockNonFilteredBand_C
  625. *
  626. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  627. * UINT8 *SrcPtr : Pointer to input image.
  628. * UINT8 *DesPtr : Pointer to output image.
  629. * UINT32 PlaneLineStep : Stride of SrcPtr & DesPtr.
  630. * UINT32 FragsAcross : Number of blocks across.
  631. * UINT32 StartFrag : Number of first block.
  632. * UINT32 *QuantScale :
  633. *
  634. * OUTPUTS : None.
  635. *
  636. * RETURNS : void
  637. *
  638. * FUNCTION : Filter both horizontal and vertical edge in a band.
  639. *
  640. * SPECIAL NOTES : Variance values for each block are stored in
  641. * pbi->FragmentVariances for later use.
  642. *
  643. ****************************************************************************/
  644. void DeblockNonFilteredBand_C
  645. (
  646. POSTPROC_INSTANCE *pbi,
  647. UINT8 *SrcPtr,
  648. UINT8 *DesPtr,
  649. UINT32 PlaneLineStep,
  650. UINT32 FragsAcross,
  651. UINT32 StartFrag,
  652. UINT32 *QuantScale
  653. )
  654. {
  655. UINT32 j,k;
  656. INT32 QStep;
  657. INT32 FLimit;
  658. INT32 psum;
  659. INT32 v[10];
  660. INT32 p1,p2;
  661. INT32 w1, w2, w3, w4, w5;
  662. INT32 Variance1, Variance2;
  663. INT32 Sum1, Sum2;
  664. UINT8 *Src, *Des;
  665. UINT32 CurrentFrag = StartFrag;
  666. w1 = PlaneLineStep;
  667. w2 = PlaneLineStep * 2;
  668. w3 = PlaneLineStep * 3;
  669. w4 = PlaneLineStep * 4;
  670. w5 = PlaneLineStep * 5;
  671. while ( CurrentFrag < StartFrag+FragsAcross )
  672. {
  673. Src = SrcPtr + 8*(CurrentFrag-StartFrag);
  674. Des = DesPtr + 8*(CurrentFrag-StartFrag);
  675. QStep = QuantScale[pbi->FragQIndex[CurrentFrag+FragsAcross]];
  676. FLimit = (QStep * QStep * 3)>>5;
  677. for ( j=0; j<8; j++ )
  678. {
  679. v[1] = Src[-w4];
  680. v[2] = Src[-w3];
  681. v[3] = Src[-w2];
  682. v[4] = Src[-w1];
  683. v[5] = Src[ 0];
  684. v[6] = Src[+w1];
  685. v[7] = Src[+w2];
  686. v[8] = Src[+w3];
  687. Variance1 = Variance2 = 0;
  688. Sum1 = Sum2 = 0;
  689. for ( k=1; k<=4; k++ )
  690. {
  691. Sum1 += v[k];
  692. Variance1 += v[k]*v[k];
  693. }
  694. for ( k=5; k<=8; k++ )
  695. {
  696. Sum2 += v[k];
  697. Variance2 += v[k]*v[k];
  698. }
  699. Variance1 -= ((Sum1>>1)*((Sum1+1)>>1));
  700. Variance2 -= ((Sum2>>1)*((Sum2+1)>>1));
  701. pbi->FragmentVariances[CurrentFrag] += Variance1;
  702. pbi->FragmentVariances[CurrentFrag + FragsAcross] += Variance2;
  703. if ( (Variance1 < FLimit) && (Variance2 < FLimit) &&
  704. ((v[5] - v[4]) < QStep) && ((v[4] - v[5]) < QStep) )
  705. {
  706. p1 = (abs(Src[-w4] - Src[-w5]) < QStep ) ? Src[-w5] : Src[-w4];
  707. p2 = (abs(Src[+w3] - Src[+w4]) < QStep ) ? Src[+w4] : Src[+w3];
  708. // low pass filtering (LPF9: 1 1 2 2 4 2 2 1 1)
  709. psum = p1 + p1 + p1 + v[1] + v[2] + v[3] + v[4] + 4;
  710. Des[-w4] = (INT8)((((psum + v[1]) << 1) - (v[4] - v[5])) >> 4);
  711. psum += v[5] - p1;
  712. Des[-w3] = (INT8)((((psum + v[2]) << 1) - (v[5] - v[6])) >> 4);
  713. psum += v[6] - p1;
  714. Des[-w2] = (INT8)((((psum + v[3]) << 1) - (v[6] - v[7])) >> 4);
  715. psum += v[7] - p1;
  716. Des[-w1] = (INT8)((((psum + v[4]) << 1) + p1 - v[1] - (v[7] - v[8])) >> 4);
  717. psum += v[8] - v[1];
  718. Des[0] = (INT8)((((psum + v[5]) << 1) + (v[1] - v[2]) - v[8] + p2) >> 4);
  719. psum += p2 - v[2];
  720. Des[+w1] = (INT8)((((psum + v[6]) << 1) + (v[2] - v[3])) >> 4);
  721. psum += p2 - v[3];
  722. Des[+w2] = (INT8)((((psum + v[7]) << 1) + (v[3] - v[4])) >> 4);
  723. psum += p2 - v[4];
  724. Des[+w3] = (INT8)((((psum + v[8]) << 1) + (v[4] - v[5])) >> 4);
  725. }
  726. else
  727. {
  728. // Old loopfilter
  729. INT32 FiltVal;
  730. UINT8 *LimitTable = &LimitVal_VP31[VAL_RANGE];
  731. FiltVal = v[3] - v[4] * 3 + v[5] * 3 - v[6] ;
  732. FiltVal = pbi->DeblockValuePtr[(FiltVal + 4) >> 3];
  733. Des[-w1] = LimitTable[(INT32)v[4] + FiltVal];
  734. Des[ 0] = LimitTable[(INT32)v[5] - FiltVal];
  735. Des[-w4]=Src[-w4];
  736. Des[-w3]=Src[-w3];
  737. Des[-w2]=Src[-w2];
  738. Des[+w1]=Src[+w1];
  739. Des[+w2]=Src[+w2];
  740. Des[+w3]=Src[+w3];
  741. }
  742. Src++;
  743. Des++;
  744. }
  745. // Finished filtering horizontal edge, vertical edge next...
  746. // skip the first one
  747. if ( CurrentFrag==StartFrag )
  748. CurrentFrag++;
  749. else
  750. {
  751. Des = DesPtr - 8*PlaneLineStep + 8*(CurrentFrag-StartFrag);
  752. Src = Des;
  753. QStep = QuantScale[pbi->FragQIndex[CurrentFrag]];
  754. FLimit = (QStep * QStep * 3)>>5 ;
  755. for ( j=0; j<8; j++ )
  756. {
  757. v[1] = Src[-4];
  758. v[2] = Src[-3];
  759. v[3] = Src[-2];
  760. v[4] = Src[-1];
  761. v[5] = Src[0];
  762. v[6] = Src[+1];
  763. v[7] = Src[+2];
  764. v[8] = Src[+3];
  765. Variance1 = Variance2 = 0;
  766. Sum1 = Sum2 = 0;
  767. for ( k=1; k<=4; k++ )
  768. {
  769. Sum1 += v[k];
  770. Variance1 += v[k]*v[k];
  771. }
  772. for ( k=5; k<=8; k++ )
  773. {
  774. Sum2 += v[k];
  775. Variance2 += v[k]*v[k];
  776. }
  777. Variance1 -= ((Sum1>>1)*((Sum1+1)>>1));
  778. Variance2 -= ((Sum2>>1)*((Sum2+1)>>1));
  779. pbi->FragmentVariances[CurrentFrag-1] += Variance1;
  780. pbi->FragmentVariances[CurrentFrag] += Variance2;
  781. if ( (Variance1 < FLimit) && (Variance2 < FLimit) &&
  782. ((v[5] - v[4]) < QStep) && ((v[4] - v[5]) < QStep) )
  783. {
  784. p1 = (abs(Src[-4] - Src[-5]) < QStep ) ? Src[-5] : Src[-4];
  785. p2 = (abs(Src[+3] - Src[+4]) < QStep ) ? Src[+4] : Src[+3];
  786. // lo pass filtering (LPF9: 1 1 2 2 4 2 2 1 1)
  787. psum = p1 + p1 + p1 + v[1] + v[2] + v[3] + v[4] + 4;
  788. Des[-4] = (INT8)((((psum + v[1]) << 1) - (v[4] - v[5])) >> 4);
  789. psum += v[5] - p1;
  790. Des[-3] = (INT8)((((psum + v[2]) << 1) - (v[5] - v[6])) >> 4);
  791. psum += v[6] - p1;
  792. Des[-2] = (INT8)((((psum + v[3]) << 1) - (v[6] - v[7])) >> 4);
  793. psum += v[7] - p1;
  794. Des[-1] = (INT8)((((psum + v[4]) << 1) + p1 - v[1] - (v[7] - v[8])) >> 4);
  795. psum += v[8] - v[1];
  796. Des[0] = (INT8)((((psum + v[5]) << 1) + (v[1] - v[2]) - v[8] + p2) >> 4);
  797. psum += p2 - v[2];
  798. Des[+1] = (INT8)((((psum + v[6]) << 1) + (v[2] - v[3])) >> 4);
  799. psum += p2 - v[3];
  800. Des[+2] =(INT8)((((psum + v[7]) << 1) + (v[3] - v[4])) >> 4);
  801. psum += p2 - v[4];
  802. Des[+3] = (INT8)((((psum + v[8]) << 1) + (v[4] - v[5])) >> 4);
  803. }
  804. else
  805. {
  806. // Old loop-filter
  807. INT32 FiltVal;
  808. UINT8 * LimitTable = &LimitVal_VP31[VAL_RANGE];
  809. FiltVal = v[3] - v[4] * 3 + v[5] * 3 - v[6] ;
  810. FiltVal = pbi->DeblockValuePtr[(FiltVal + 4) >> 3];
  811. Des[-1] = LimitTable[(INT32)v[4] + FiltVal];
  812. Des[ 0] = LimitTable[(INT32)v[5] - FiltVal];
  813. }
  814. Src += PlaneLineStep;
  815. Des += PlaneLineStep;
  816. }
  817. }
  818. CurrentFrag++;
  819. }
  820. }
  821. /****************************************************************************
  822. *
  823. * ROUTINE : DeblockNonFilteredBandNewFilter_C
  824. *
  825. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  826. * UINT8 *SrcPtr : Pointer to input image.
  827. * UINT8 *DesPtr : Pointer to output image.
  828. * UINT32 PlaneLineStep : Stride of SrcPtr & DesPtr.
  829. * UINT32 FragsAcross : Number of blocks across.
  830. * UINT32 StartFrag : Number of first block.
  831. * UINT32 *QuantScale :
  832. *
  833. * OUTPUTS : None.
  834. *
  835. * RETURNS : void
  836. *
  837. * FUNCTION : Filter both horizontal and vertical edge in a band.
  838. *
  839. * SPECIAL NOTES : Variance values for each block are stored in
  840. * pbi->FragmentVariances for later use.
  841. * Uses SAD to determine where to apply the new
  842. * 7 tap fiter.
  843. *
  844. ****************************************************************************/
  845. void DeblockNonFilteredBandNewFilter_C
  846. (
  847. POSTPROC_INSTANCE *pbi,
  848. UINT8 *SrcPtr,
  849. UINT8 *DesPtr,
  850. UINT32 PlaneLineStep,
  851. UINT32 FragsAcross,
  852. UINT32 StartFrag,
  853. UINT32 *QuantScale
  854. )
  855. {
  856. UINT32 j,k;
  857. INT32 QStep;
  858. INT32 FLimit;
  859. INT32 psum;
  860. INT32 v[10];
  861. INT32 p1,p2;
  862. INT32 w1, w2, w3, w4, w5;
  863. INT32 Sum1, Sum2;
  864. UINT8 *Src, *Des;
  865. UINT32 CurrentFrag = StartFrag;
  866. w1 = PlaneLineStep;
  867. w2 = PlaneLineStep * 2;
  868. w3 = PlaneLineStep * 3;
  869. w4 = PlaneLineStep * 4;
  870. w5 = PlaneLineStep * 5;
  871. QStep = QuantScale[pbi->FrameQIndex];
  872. while ( CurrentFrag < (StartFrag + FragsAcross) )
  873. {
  874. Src = SrcPtr + 8*(CurrentFrag-StartFrag);
  875. Des = DesPtr + 8*(CurrentFrag-StartFrag);
  876. FLimit = ( QStep * 3 ) >> 2;
  877. for ( j=0; j<8; j++ )
  878. {
  879. v[0] = Src[-w5];
  880. v[1] = Src[-w4];
  881. v[2] = Src[-w3];
  882. v[3] = Src[-w2];
  883. v[4] = Src[-w1];
  884. v[5] = Src[ 0];
  885. v[6] = Src[+w1];
  886. v[7] = Src[+w2];
  887. v[8] = Src[+w3];
  888. v[9] = Src[+w4];
  889. Sum1 = Sum2 = 0;
  890. for ( k=1; k<=4; k++ )
  891. Sum1 += abs ( v[k]-v[k-1] );
  892. for ( k=5; k<=8; k++ )
  893. Sum2 += abs ( v[k]-v[k+1] );
  894. pbi->FragmentVariances[CurrentFrag] +=((Sum1>255)?255:Sum1);
  895. pbi->FragmentVariances[CurrentFrag + FragsAcross] += ((Sum2>255)?255:Sum2);
  896. if ( (Sum1 < FLimit) && (Sum2 < FLimit) &&
  897. ((v[5] - v[4]) < QStep) && ((v[4] - v[5]) < QStep) )
  898. {
  899. p1 = v[0];
  900. p2 = v[9];
  901. // low pass filtering (LPF7: 1 1 1 2 1 1 1)
  902. psum = p1 + p1 + p1 + v[1] + v[2] + v[3] + v[4] + 4;
  903. Des[-w4] = (INT8)((psum + v[1]) >> 3);
  904. psum += v[5] - p1;
  905. Des[-w3] = (INT8)((psum + v[2]) >> 3);
  906. psum += v[6] - p1;
  907. Des[-w2] = (INT8)((psum + v[3]) >> 3);
  908. psum += v[7] - p1;
  909. Des[-w1] = (INT8)((psum + v[4]) >> 3);
  910. psum += v[8] - v[1];
  911. Des[0] = (INT8)((psum + v[5]) >> 3);
  912. psum += p2 - v[2];
  913. Des[+w1] = (INT8)((psum + v[6]) >> 3);
  914. psum += p2 - v[3];
  915. Des[+w2] = (INT8)((psum + v[7]) >> 3);
  916. psum += p2 - v[4];
  917. Des[+w3] = (INT8)((psum + v[8]) >> 3);
  918. }
  919. else
  920. {
  921. //old loopfilter
  922. INT32 FiltVal;
  923. UINT8 * LimitTable = &LimitVal_VP31[VAL_RANGE];
  924. FiltVal = v[3] - v[4] * 3 + v[5] * 3 - v[6] ;
  925. FiltVal = pbi->DeblockValuePtr[(FiltVal + 4) >> 3];
  926. Des[-w1] = LimitTable[(INT32)v[4] + FiltVal];
  927. Des[ 0] = LimitTable[(INT32)v[5] - FiltVal];
  928. Des[-w4]=Src[-w4];
  929. Des[-w3]=Src[-w3];
  930. Des[-w2]=Src[-w2];
  931. Des[+w1]=Src[+w1];
  932. Des[+w2]=Src[+w2];
  933. Des[+w3]=Src[+w3];
  934. }
  935. Src++;
  936. Des++;
  937. }
  938. // Finished filtering horizontal edge, vertical edge next...
  939. // skip the first one
  940. if ( CurrentFrag==StartFrag )
  941. CurrentFrag++;
  942. else
  943. {
  944. Des = DesPtr - 8*PlaneLineStep + 8*(CurrentFrag-StartFrag);
  945. Src = Des;
  946. FLimit = (QStep * 3) >> 2;
  947. for ( j=0; j<8; j++ )
  948. {
  949. v[0] = Src[-5];
  950. v[1] = Src[-4];
  951. v[2] = Src[-3];
  952. v[3] = Src[-2];
  953. v[4] = Src[-1];
  954. v[5] = Src[0];
  955. v[6] = Src[+1];
  956. v[7] = Src[+2];
  957. v[8] = Src[+3];
  958. v[9] = Src[+4];
  959. Sum1 = Sum2 = 0;
  960. for ( k=1; k<=4; k++ )
  961. Sum1 += abs ( v[k]-v[k-1] );
  962. for ( k=5; k<=8; k++ )
  963. Sum2 += abs ( v[k]-v[k+1] );
  964. pbi->FragmentVariances[CurrentFrag-1] += ((Sum1>255)?255:Sum1);
  965. pbi->FragmentVariances[CurrentFrag] += ((Sum2>255)?255:Sum2);
  966. if ( (Sum1 < FLimit) && (Sum2 < FLimit) &&
  967. ((v[5] - v[4]) < QStep) && ((v[4] - v[5]) < QStep) )
  968. {
  969. p1 = v[0];
  970. p2 = v[9];
  971. // low pass filtering (LPF7: 1 1 1 2 1 1 1)
  972. psum = p1 + p1 + p1 + v[1] + v[2] + v[3] + v[4] + 4;
  973. Des[-4] = (INT8)((psum + v[1]) >> 3);
  974. psum += v[5] - p1;
  975. Des[-3] = (INT8)((psum + v[2]) >> 3);
  976. psum += v[6] - p1;
  977. Des[-2] = (INT8)((psum + v[3]) >> 3);
  978. psum += v[7] - p1;
  979. Des[-1] = (INT8)((psum + v[4]) >> 3);
  980. psum += v[8] - v[1];
  981. Des[0] = (INT8)((psum + v[5]) >> 3);
  982. psum += p2 - v[2];
  983. Des[+1] = (INT8)((psum + v[6]) >> 3);
  984. psum += p2 - v[3];
  985. Des[+2] = (INT8)((psum + v[7]) >> 3);
  986. psum += p2 - v[4];
  987. Des[+3] = (INT8)((psum + v[8]) >> 3);
  988. }
  989. else
  990. {
  991. // Old loopfilter
  992. INT32 FiltVal;
  993. UINT8 * LimitTable = &LimitVal_VP31[VAL_RANGE];
  994. FiltVal = v[3] - v[4] * 3 + v[5] * 3 - v[6] ;
  995. FiltVal = pbi->DeblockValuePtr[(FiltVal + 4) >> 3];
  996. Des[-1] = LimitTable[(INT32)v[4] + FiltVal];
  997. Des[ 0] = LimitTable[(INT32)v[5] - FiltVal];
  998. }
  999. Src += PlaneLineStep;
  1000. Des += PlaneLineStep;
  1001. }
  1002. CurrentFrag++;
  1003. }
  1004. }
  1005. }
  1006. /****************************************************************************
  1007. *
  1008. * ROUTINE : DeblockPlane
  1009. *
  1010. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  1011. * UINT8 *SourceBuffer : Pointer to input image.
  1012. * UINT8 *DestinationBuffer : Pointer to output image.
  1013. * UINT32 Channel : Whether the Y, U or V plane.
  1014. *
  1015. * OUTPUTS : None.
  1016. *
  1017. * RETURNS : void
  1018. *
  1019. * FUNCTION : Applies de-blocking filters to an image plane Y, U or V.
  1020. *
  1021. * SPECIAL NOTES : None.
  1022. *
  1023. ****************************************************************************/
  1024. void DeblockPlane
  1025. (
  1026. POSTPROC_INSTANCE *pbi,
  1027. UINT8 *SourceBuffer,
  1028. UINT8 *DestinationBuffer,
  1029. UINT32 Channel
  1030. )
  1031. {
  1032. UINT32 i, j, k;
  1033. UINT32 PixelIndex;
  1034. UINT32 FragsDown = 0;
  1035. UINT32 FragsAcross = 0;
  1036. UINT32 StartFrag = 0;
  1037. UINT32 PlaneLineStep = 0;
  1038. UINT8 *SrcPtr = 0, *DesPtr = 0;
  1039. UINT32 *QuantScale = 0;
  1040. typedef void (*ApplyFilterToBand) (xPB_INST, UINT8 *, UINT8 *, UINT32, UINT32, UINT32, UINT32 *);
  1041. ApplyFilterToBand DeblockBand;
  1042. ApplyFilterToBand DeblockVerticalEdgesInBand;
  1043. if ( pbi->Vp3VersionNo >= 2 )
  1044. {
  1045. DeblockBand = DeblockNonFilteredBand;
  1046. DeblockVerticalEdgesInBand = DeblockVerticalEdgesInNonFilteredBand;
  1047. }
  1048. else
  1049. {
  1050. DeblockBand = DeblockLoopFilteredBand;
  1051. DeblockVerticalEdgesInBand = DeblockVerticalEdgesInLoopFilteredBand;
  1052. }
  1053. switch( Channel )
  1054. {
  1055. case 0:
  1056. // Get the parameters
  1057. PlaneLineStep = pbi->YStride;
  1058. FragsAcross = pbi->HFragments;
  1059. FragsDown = pbi->VFragments;
  1060. StartFrag = 0;
  1061. PixelIndex = pbi->ReconYDataOffset;
  1062. SrcPtr = &SourceBuffer[PixelIndex];
  1063. DesPtr = &DestinationBuffer[PixelIndex];
  1064. break;
  1065. case 1:
  1066. // Get the parameters
  1067. PlaneLineStep = pbi->UVStride;
  1068. FragsAcross = pbi->HFragments / 2;
  1069. FragsDown = pbi->VFragments / 2;
  1070. StartFrag = pbi->YPlaneFragments;
  1071. PixelIndex = pbi->ReconUDataOffset;
  1072. SrcPtr = &SourceBuffer[PixelIndex];
  1073. DesPtr = &DestinationBuffer[PixelIndex];
  1074. break;
  1075. default:
  1076. // Get the parameters
  1077. PlaneLineStep = pbi->UVStride;
  1078. FragsAcross = pbi->HFragments / 2;
  1079. FragsDown = pbi->VFragments / 2;
  1080. StartFrag = pbi->YPlaneFragments + pbi->UVPlaneFragments;
  1081. PixelIndex = pbi->ReconVDataOffset;
  1082. SrcPtr = &SourceBuffer[PixelIndex];
  1083. DesPtr = &DestinationBuffer[PixelIndex];
  1084. break;
  1085. }
  1086. if ( pbi->Vp3VersionNo >= 2 )
  1087. {
  1088. switch ( Channel )
  1089. {
  1090. case 0:
  1091. QuantScale = DCQuantScaleV2;
  1092. break;
  1093. case 1:
  1094. case 2:
  1095. QuantScale = DCQuantScaleUV;
  1096. break;
  1097. }
  1098. }
  1099. else
  1100. {
  1101. QuantScale = DCQuantScaleV1;
  1102. }
  1103. for ( i=0; i<4; i++ )
  1104. for ( j=0; j<PlaneLineStep; j++ )
  1105. DesPtr[i*PlaneLineStep + j] = SrcPtr[i*PlaneLineStep + j];
  1106. // loop to last band
  1107. k = 1;
  1108. while ( k < FragsDown )
  1109. {
  1110. SrcPtr += 8*PlaneLineStep;
  1111. DesPtr += 8*PlaneLineStep;
  1112. // Filter both the horizontal and vertical block edges inside the band
  1113. DeblockBand ( pbi,
  1114. SrcPtr,
  1115. DesPtr,
  1116. PlaneLineStep,
  1117. FragsAcross,
  1118. StartFrag,
  1119. QuantScale );
  1120. // Move on...
  1121. StartFrag += FragsAcross;
  1122. k++;
  1123. }
  1124. // The Last band
  1125. for ( i=0; i<4; i++ )
  1126. for ( j=0; j<PlaneLineStep; j++ )
  1127. DesPtr[(i+4)*PlaneLineStep + j] = SrcPtr[(i+4)*PlaneLineStep + j];
  1128. DeblockVerticalEdgesInBand ( pbi,
  1129. SrcPtr,
  1130. DesPtr,
  1131. PlaneLineStep,
  1132. FragsAcross,
  1133. StartFrag,
  1134. QuantScale );
  1135. }
  1136. /****************************************************************************
  1137. *
  1138. * ROUTINE : DeblockPlaneNew
  1139. *
  1140. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  1141. * UINT32 PlaneLineStep : Stride for the plane.
  1142. * UINT32 StartFrag : Number of first block.
  1143. * UINT32 FragsAcross : Number of blocks horizontally.
  1144. * UINT32 FragsDown : Number of blocks vertically.
  1145. * UINT8 *SrcPtr : Pointer to input image.
  1146. * UINT8 *DesPtr : Pointer to output image.
  1147. * UINT32 *QuantScale :
  1148. *
  1149. * OUTPUTS : None.
  1150. *
  1151. * RETURNS : void
  1152. *
  1153. * FUNCTION : Applies new de-blocking filters to an image plane Y, U or V.
  1154. *
  1155. * SPECIAL NOTES : Uses the new de-blocking filter.
  1156. *
  1157. ****************************************************************************/
  1158. void DeblockPlaneNew
  1159. (
  1160. POSTPROC_INSTANCE *pbi,
  1161. UINT32 PlaneLineStep,
  1162. UINT32 StartFrag,
  1163. UINT32 FragsAcross,
  1164. UINT32 FragsDown,
  1165. UINT8 *SrcPtr,
  1166. UINT8 *DesPtr,
  1167. UINT32 *QuantScale
  1168. )
  1169. {
  1170. UINT32 i, k;
  1171. typedef void (*ApplyFilterToBand) (xPB_INST, UINT8 *, UINT8 *, UINT32, UINT32, UINT32, UINT32 *);
  1172. ApplyFilterToBand DeblockBand;
  1173. ApplyFilterToBand DeblockVerticalEdgesInBand;
  1174. DeblockBand = DeblockNonFilteredBandNewFilter;
  1175. DeblockVerticalEdgesInBand = DeblockVerticalEdgesInNonFilteredBandNewFilter;
  1176. for ( i=0; i<4; i++ )
  1177. memcpy ( DesPtr+i*PlaneLineStep, SrcPtr+i*PlaneLineStep, PlaneLineStep );
  1178. // loop to last band
  1179. k = 1;
  1180. while ( k < FragsDown )
  1181. {
  1182. SrcPtr += 8*PlaneLineStep;
  1183. DesPtr += 8*PlaneLineStep;
  1184. // Filter both the horizontal and vertical block edges inside the band
  1185. DeblockBand ( pbi,
  1186. SrcPtr,
  1187. DesPtr,
  1188. PlaneLineStep,
  1189. FragsAcross,
  1190. StartFrag,
  1191. QuantScale );
  1192. // Move-on...
  1193. StartFrag += FragsAcross;
  1194. k++;
  1195. }
  1196. // The Last band
  1197. for ( i=0; i<4; i++ )
  1198. memcpy ( DesPtr+(i+4)*PlaneLineStep, SrcPtr+(i+4)*PlaneLineStep, PlaneLineStep );
  1199. DeblockVerticalEdgesInBand ( pbi,
  1200. SrcPtr,
  1201. DesPtr,
  1202. PlaneLineStep,
  1203. FragsAcross,
  1204. StartFrag,
  1205. QuantScale );
  1206. }
  1207. /****************************************************************************
  1208. *
  1209. * ROUTINE : DeblockFrame
  1210. *
  1211. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  1212. * UINT8 *SourceBuffer : Pointer to input frame.
  1213. * UINT8 *DestinationBuffer : Pointer to output deblocked frame.
  1214. *
  1215. * OUTPUTS : None.
  1216. *
  1217. * RETURNS : void
  1218. *
  1219. * FUNCTION : Applies loop filter to the edge pixels of coded blocks.
  1220. *
  1221. * SPECIAL NOTES : None.
  1222. *
  1223. ****************************************************************************/
  1224. void DeblockFrame ( POSTPROC_INSTANCE *pbi, UINT8 *SourceBuffer, UINT8 *DestinationBuffer )
  1225. {
  1226. // Initialize the fragment variance accumulators
  1227. memset ( pbi->FragmentVariances, 0 , pbi->UnitFragments*sizeof(INT32) );
  1228. SetupDeblocker(pbi);
  1229. #if defined(_WIN32)
  1230. if ( pbi->Vp3VersionNo >= 5 )
  1231. {
  1232. // Y
  1233. DeblockPlaneNew ( pbi,
  1234. pbi->YStride,
  1235. 0,
  1236. pbi->HFragments,
  1237. pbi->VFragments,
  1238. &SourceBuffer[pbi->ReconYDataOffset],
  1239. &DestinationBuffer[pbi->ReconYDataOffset],
  1240. DCQuantScaleV2 );
  1241. // U
  1242. DeblockPlaneNew ( pbi,
  1243. pbi->UVStride,
  1244. 0,
  1245. pbi->HFragments / 2,
  1246. pbi->VFragments / 2,
  1247. &SourceBuffer[pbi->ReconUDataOffset],
  1248. &DestinationBuffer[pbi->ReconUDataOffset],
  1249. DCQuantScaleUV );
  1250. // V
  1251. DeblockPlaneNew ( pbi,
  1252. pbi->UVStride,
  1253. 0,
  1254. pbi->HFragments / 2,
  1255. pbi->VFragments / 2,
  1256. &SourceBuffer[pbi->ReconVDataOffset],
  1257. &DestinationBuffer[pbi->ReconVDataOffset],
  1258. DCQuantScaleUV );
  1259. }
  1260. else
  1261. #endif
  1262. {
  1263. DeblockPlane ( pbi, SourceBuffer, DestinationBuffer, 0 ); // Y
  1264. DeblockPlane ( pbi, SourceBuffer, DestinationBuffer, 1 ); // U
  1265. DeblockPlane ( pbi, SourceBuffer, DestinationBuffer, 2 ); // V
  1266. }
  1267. }
  1268. /****************************************************************************
  1269. *
  1270. * ROUTINE : DeblockFrameInterlaced
  1271. *
  1272. * INPUTS : POSTPROC_INSTANCE *pbi : Pointer to post-processor instance.
  1273. * UINT8 *SourceBuffer : Pointer to input frame.
  1274. * UINT8 *DestinationBuffer : Pointer to output deblocked frame.
  1275. *
  1276. * OUTPUTS : None.
  1277. *
  1278. * RETURNS : void
  1279. *
  1280. * FUNCTION : Applies a loop filter to the edge pixels of coded blocks.
  1281. *
  1282. * SPECIAL NOTES : None.
  1283. *
  1284. ****************************************************************************/
  1285. void DeblockFrameInterlaced ( POSTPROC_INSTANCE *pbi, UINT8 *SourceBuffer, UINT8 *DestinationBuffer )
  1286. {
  1287. INT32 *FragVarPtr;
  1288. SetupDeblocker ( pbi );
  1289. // Y Plane
  1290. FragVarPtr = pbi->FragmentVariances;
  1291. memset ( FragVarPtr, 0, pbi->UnitFragments*sizeof(INT32) );
  1292. DeblockPlaneNew ( pbi,
  1293. pbi->YStride*2,
  1294. 0,
  1295. pbi->HFragments,
  1296. pbi->VFragments/2,
  1297. &SourceBuffer[pbi->ReconYDataOffset],
  1298. &DestinationBuffer[pbi->ReconYDataOffset],
  1299. DCQuantScaleV2 );
  1300. pbi->FragmentVariances = pbi->FragmentVariances + pbi->HFragments*pbi->VFragments/2;
  1301. DeblockPlaneNew ( pbi,
  1302. pbi->YStride*2,
  1303. 0,
  1304. pbi->HFragments,
  1305. pbi->VFragments/2,
  1306. &SourceBuffer[pbi->ReconYDataOffset+pbi->YStride],
  1307. &DestinationBuffer[pbi->ReconYDataOffset+pbi->YStride],
  1308. DCQuantScaleV2 );
  1309. // Restore the FragmentVariances point in PBI
  1310. pbi->FragmentVariances = FragVarPtr;
  1311. // UV Plane
  1312. DeblockPlaneNew ( pbi,
  1313. pbi->UVStride,
  1314. pbi->YPlaneFragments,
  1315. pbi->HFragments / 2,
  1316. pbi->VFragments / 2,
  1317. &SourceBuffer[pbi->ReconUDataOffset],
  1318. &DestinationBuffer[pbi->ReconUDataOffset],
  1319. DCQuantScaleUV );
  1320. DeblockPlaneNew ( pbi,
  1321. pbi->UVStride,
  1322. pbi->YPlaneFragments + pbi->UVPlaneFragments,
  1323. pbi->HFragments / 2,
  1324. pbi->VFragments / 2,
  1325. &SourceBuffer[pbi->ReconVDataOffset],
  1326. &DestinationBuffer[pbi->ReconVDataOffset],
  1327. DCQuantScaleUV );
  1328. return;
  1329. }