Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

765 lines
18 KiB

  1. /* *************************************************************************
  2. ** INTEL Corporation Proprietary Information
  3. **
  4. ** This listing is supplied under the terms of a license
  5. ** agreement with INTEL Corporation and may not be copied
  6. ** nor disclosed except in accordance with the terms of
  7. ** that agreement.
  8. **
  9. ** Copyright (c) 1995 Intel Corporation.
  10. ** Copyright (c) 1996 Intel Corporation.
  11. ** All Rights Reserved.
  12. **
  13. ** *************************************************************************
  14. */
  15. #include "precomp.h"
  16. /* map of coded and not-coded blocks */
  17. extern char coded_map[][22+1];
  18. /* QP map */
  19. extern char QP_map[][22];
  20. #if defined(H263P) // { if defined(H263P)
  21. /* table for de-blocking filter */
  22. /* currently requires 2048 bytes */
  23. signed char dxQP[64][32];
  24. #if 0 // { 0
  25. static void HorizEdgeFilter(unsigned char *rec,
  26. int width,
  27. int height,
  28. int pitch,
  29. int shift) {
  30. int i, j, k;
  31. int d, delta;
  32. int mbc;
  33. int mod_div = 1 << shift;
  34. unsigned char *r = rec + (pitch << 3);
  35. unsigned char *r_2 = r - (pitch << 1);
  36. unsigned char *r_1 = r - pitch;
  37. unsigned char *r1 = r + pitch;
  38. char *pcoded_row0 = &coded_map[8>>shift][0];
  39. char *pcoded_row1 = pcoded_row0 + sizeof(coded_map[0]);
  40. char *pQP_map = &QP_map[0][0];
  41. for (j = 8; j < height; ) {
  42. for (i = 0; i < width; i += 8) {
  43. mbc = i >> shift;
  44. if (pcoded_row0[mbc+1] || pcoded_row1[mbc+1]) {
  45. for (k = i; k < i+8; k++) {
  46. d = (r_2[k]+(r_2[k]<<1)-(r_1[k]<<3)+(r[k]<<3)-(r1[k]+(r1[k]<<1)))>>4;
  47. if (d && (d >= -32) && (d < 32)) {
  48. delta = dxQP[d+32][pQP_map[mbc]];
  49. r[k] = ClampTbl[r[k]-delta+CLAMP_BIAS];
  50. r_1[k] = ClampTbl[r_1[k]+delta+CLAMP_BIAS];
  51. }
  52. }
  53. }
  54. }
  55. r_2 += (pitch<<3);
  56. r_1 += (pitch<<3);
  57. r += (pitch<<3);
  58. r1 += (pitch<<3);
  59. if (0 == ((j+=8)%mod_div)) {
  60. pcoded_row0 += sizeof(coded_map[0]);
  61. pcoded_row1 += sizeof(coded_map[0]);
  62. pQP_map += sizeof(QP_map[0]);
  63. }
  64. }
  65. }
  66. static void VertEdgeFilter(unsigned char *rec,
  67. int width,
  68. int height,
  69. int pitch,
  70. int shift) {
  71. unsigned char *r = rec;
  72. int i, j, k;
  73. int mbc;
  74. int d, delta;
  75. int mod_div = 1 << shift;
  76. char *pcoded_row1 = &coded_map[1][0];
  77. char *pQP_map = &QP_map[0][0];
  78. for (j = 0; j < height; ) {
  79. for (i = 8; i < width; i += 8) {
  80. mbc = i >> shift;
  81. if (pcoded_row1[mbc] || pcoded_row1[mbc+1]) {
  82. for (k = 0; k < 8; k++) {
  83. d = (r[i-2]+(r[i-2]<<1)-(r[i-1]<<3)+(r[i]<<3)-(r[i+1]+(r[i+1]<<1)))>>4;
  84. if (d && (d > -32) && (d < 32)) {
  85. delta = dxQP[d+32][pQP_map[mbc]];
  86. r[i] = ClampTbl[r[i]-delta+CLAMP_BIAS];
  87. r[i-1] = ClampTbl[r[i-1]+delta+CLAMP_BIAS];
  88. }
  89. r += pitch;
  90. }
  91. r -= pitch<<3;
  92. }
  93. }
  94. r += pitch<<3;
  95. if (0 == ((j+=8)%mod_div)) {
  96. pcoded_row1 += sizeof(coded_map[0]);
  97. pQP_map += sizeof(QP_map[0]);
  98. }
  99. }
  100. }
  101. #else // }{ 0
  102. __declspec(naked)
  103. static void HorizEdgeFilter(unsigned char *rec,
  104. int width,
  105. int height,
  106. int pitch,
  107. int shift) {
  108. // Permanent (callee-save) registers - ebx, esi, edi, ebp
  109. // Temporary (caller-save) registers - eax, ecx, edx
  110. //
  111. // Stack frame layout
  112. // | shift | + 68
  113. // | pitch | + 64
  114. // | height | + 60
  115. // | width | + 56
  116. // | rec | + 52
  117. // -----------------------------
  118. // | return addr | + 48
  119. // | saved ebp | + 44
  120. // | saved ebx | + 40
  121. // | saved esi | + 36
  122. // | saved edi | + 32
  123. #define LOCALSIZE 32
  124. #define SHIFT 68
  125. #define PITCH_PARM 64
  126. #define HEIGHT 60
  127. #define WIDTH 56
  128. #define REC 52
  129. #define LOOP_I 28
  130. #define LOOP_J 24
  131. #define LOOP_K 20
  132. #define PCODED_ROW0 16
  133. #define PCODED_ROW1 12
  134. #define PQP_MAP 8
  135. #define MBC 4
  136. #define LOOP_K_LIMIT 0
  137. _asm {
  138. push ebp
  139. push ebx
  140. push esi
  141. push edi
  142. sub esp, LOCALSIZE
  143. // r = rec + (pitch << 3)
  144. // r_2 = r - (pitch << 1)
  145. // r_1 = r - pitch
  146. // r1 = r + pitch
  147. // assign(esi, r_2)
  148. // assign(edi, r1)
  149. // assign(ebp, pitch)
  150. mov ebp, [esp + PITCH_PARM]
  151. mov esi, [esp + REC]
  152. lea esi, [esi + ebp*4]
  153. lea esi, [esi + ebp*2]
  154. lea edi, [esi + ebp*2]
  155. lea edi, [edi + ebp]
  156. // pcoded_row0 = &coded_map[8>>shift][0]
  157. // pcoded_row1 = pcoded_row0 + sizeof(coded_map[0])
  158. // pQP_map = &QP_map[0][0]
  159. mov eax, 8
  160. mov ecx, [esp + SHIFT]
  161. shr eax, cl
  162. mov ebx, TYPE coded_map[0]
  163. imul eax, ebx
  164. lea eax, [coded_map + eax]
  165. mov [esp + PCODED_ROW0], eax
  166. add eax, ebx
  167. mov [esp + PCODED_ROW1], eax
  168. lea eax, [QP_map]
  169. mov [esp + PQP_MAP], eax
  170. // for (j = 8; j < height; )
  171. mov DWORD PTR [esp + LOOP_J], 8
  172. L1:
  173. // for (i = 0; i < width; i += 8)
  174. mov DWORD PTR [esp + LOOP_I], 0
  175. L2:
  176. // mbc = i >> shift
  177. // if (pcoded_row0[mbc+1] || pcoded_row1[mbc+1])
  178. mov eax, [esp + LOOP_I]
  179. mov ecx, [esp + SHIFT]
  180. shr eax, cl
  181. mov ebx, [esp + PCODED_ROW0]
  182. mov [esp + MBC], eax
  183. mov cl, [ebx+eax+1]
  184. mov ebx, [esp + PCODED_ROW1]
  185. test ecx, ecx
  186. jnz L3
  187. mov cl, [ebx+eax+1]
  188. test ecx, ecx
  189. jz L4
  190. L3:
  191. // for (k = i; k < i+8; k++)
  192. mov eax, [esp + LOOP_I]
  193. xor ebx, ebx
  194. add eax, 8
  195. // read r_1[k]
  196. mov bl, [esi+ebp]
  197. mov [esp + LOOP_K_LIMIT], eax
  198. xor eax, eax
  199. L5:
  200. // d = (r_2[k]+(r_2[k]<<1)-(r_1[k]<<3)+(r[k]<<3)-(r1[k]+(r1[k]<<1)))>>4
  201. // read r_2[k]
  202. mov al, [esi]
  203. xor ecx, ecx
  204. // read r[k]
  205. mov cl, [esi+ebp*2]
  206. xor edx, edx
  207. // read r1[k] and compute r_2[k]*3
  208. mov dl, [edi]
  209. lea eax,[eax+eax*2]
  210. // compute r_1[k]*8 and r[k]*8
  211. lea ebx, [ebx*8]
  212. lea ecx, [ecx*8]
  213. // compute r1[k]*3 and (r_2[k]*3 - r_1[k]*8)
  214. lea edx, [edx+edx*2]
  215. sub eax, ebx
  216. // compute (r_2[k]*3 - r_1[k]*8 + r[k]*8)
  217. add eax, ecx
  218. xor ecx, ecx
  219. // compute (r_2[k]*3 - r_1[k]*8 + r[k]*8 - r1[k]*3)
  220. sub eax, edx
  221. xor edx, edx
  222. // compute (r_2[k]*3 - r_1[k]*8 + r[k]*8 - r1[k]*3) >> 4
  223. sar eax, 4
  224. mov ebx, [esp + PQP_MAP]
  225. // if (d && (d >= -32) && (d < 32))
  226. add ebx, [esp + MBC]
  227. test eax, eax
  228. jz L6
  229. cmp eax, -32
  230. jl L6
  231. cmp eax, 32
  232. jge L6
  233. // delta = dxQP[d+32][pQP_map[mbc]]
  234. // r[k] = ClampTbl[r[k]-delta+CLAMP_BIAS]
  235. // r_1[k] = ClampTbl[r_1[k]+delta+CLAMP_BIAS]
  236. lea eax, [eax + 32]
  237. mov cl, [ebx]
  238. shl eax, 5
  239. mov dl, [esi+ebp]
  240. mov al, dxQP[eax+ecx]
  241. mov cl, [esi+ebp*2]
  242. movsx eax, al
  243. sub ecx, eax
  244. mov dl, ClampTbl[edx + eax + CLAMP_BIAS]
  245. mov cl, ClampTbl[ecx + CLAMP_BIAS]
  246. mov [esi+ebp], dl
  247. mov [esi+ebp*2], cl
  248. nop
  249. L6:
  250. mov edx, [esp + LOOP_I]
  251. inc esi
  252. inc edx
  253. inc edi
  254. xor eax, eax
  255. xor ebx, ebx
  256. mov [esp + LOOP_I], edx
  257. mov bl, [esi+ebp]
  258. cmp edx, [esp + LOOP_K_LIMIT]
  259. jl L5
  260. jmp L4a
  261. L4:
  262. mov eax, [esp + LOOP_I]
  263. lea esi, [esi+8]
  264. add eax, 8
  265. lea edi, [edi+8]
  266. mov [esp + LOOP_I],eax
  267. nop
  268. L4a:
  269. mov eax, [esp + LOOP_I]
  270. cmp eax, [esp + WIDTH]
  271. jl L2
  272. // r_2 += (pitch<<3)
  273. // r_1 += (pitch<<3)
  274. // r += (pitch<<3)
  275. // r1 += (pitch<<3)
  276. mov eax, ebp
  277. shl eax, 3
  278. sub eax, [esp + WIDTH]
  279. lea esi, [esi + eax]
  280. lea edi, [edi + eax]
  281. // if (0 == ((j+=8)%mod_div))
  282. mov eax, [esp + LOOP_J]
  283. add eax, 8
  284. mov [esp + LOOP_J], eax
  285. mov ebx, eax
  286. mov ecx, [esp + SHIFT]
  287. shr eax, cl
  288. shl eax, cl
  289. sub ebx, eax
  290. jnz L7
  291. // pcoded_row0 += sizeof(coded_map[0])
  292. // pcoded_row1 += sizeof(coded_map[0])
  293. // pQP_map += sizeof(QP_map[0])
  294. mov eax, [esp + PCODED_ROW0]
  295. mov ebx, [esp + PCODED_ROW1]
  296. mov ecx, [esp + PQP_MAP]
  297. add eax, TYPE coded_map[0]
  298. add ebx, TYPE coded_map[0]
  299. add ecx, TYPE QP_map[0]
  300. mov [esp + PCODED_ROW0], eax
  301. mov [esp + PCODED_ROW1], ebx
  302. mov [esp + PQP_MAP], ecx
  303. L7:
  304. mov eax, [esp + LOOP_J]
  305. cmp eax, [esp + HEIGHT]
  306. jl L1
  307. add esp, LOCALSIZE
  308. pop edi
  309. pop esi
  310. pop ebx
  311. pop ebp
  312. ret
  313. }
  314. }
  315. #undef LOCALSIZE
  316. #undef SHIFT
  317. #undef PITCH_PARM
  318. #undef HEIGHT
  319. #undef WIDTH
  320. #undef REC
  321. #undef LOOP_I
  322. #undef LOOP_J
  323. #undef LOOP_K
  324. #undef PCODED_ROW0
  325. #undef PCODED_ROW1
  326. #undef PQP_MAP
  327. #undef MBC
  328. #undef LOOP_K_LIMIT
  329. __declspec(naked)
  330. static void VertEdgeFilter(unsigned char *rec,
  331. int width,
  332. int height,
  333. int pitch,
  334. int shift) {
  335. // Permanent (callee-save) registers - ebx, esi, edi, ebp
  336. // Temporary (caller-save) registers - eax, ecx, edx
  337. //
  338. // Stack frame layout
  339. // | shift | + 56
  340. // | pitch | + 52
  341. // | height | + 48
  342. // | width | + 44
  343. // | rec | + 40
  344. // -----------------------------
  345. // | return addr | + 36
  346. // | saved ebp | + 32
  347. // | saved ebx | + 28
  348. // | saved esi | + 24
  349. // | saved edi | + 20
  350. #define LOCALSIZE 20
  351. #define SHIFT 56
  352. #define PITCH_PARM 52
  353. #define HEIGHT 48
  354. #define WIDTH 44
  355. #define REC 40
  356. #define LOOP_K 16
  357. #define LOOP_J 12
  358. #define PCODED_ROW1 8
  359. #define PQP_MAP 4
  360. #define MBC 0
  361. _asm {
  362. push ebp
  363. push ebx
  364. push esi
  365. push edi
  366. sub esp, LOCALSIZE
  367. // assign(esi, r)
  368. mov esi, [esp + REC]
  369. // assign(edi, pitch)
  370. mov edi, [esp + PITCH_PARM]
  371. // pcoded_row1 = &coded_map[1][0]
  372. mov eax, TYPE coded_map[0]
  373. lea eax, [coded_map + eax]
  374. mov [esp + PCODED_ROW1], eax
  375. // pQP_map = &QP_map[0][0]
  376. lea eax, [QP_map]
  377. mov [esp + PQP_MAP], eax
  378. // for (j = 0; j < height; )
  379. xor eax, eax
  380. mov [esp + LOOP_J], eax
  381. L1:
  382. // for (i = 8; i < width; i += 8)
  383. // assign(ebp,i)
  384. mov ebp, 8
  385. // mbc = i >> shift
  386. L2:
  387. mov eax, ebp
  388. mov ecx, [esp + SHIFT]
  389. shr eax, cl
  390. mov [esp + MBC], eax
  391. // if (pcoded_row1[mbc] || pcoded_row1[mbc+1])
  392. xor ecx, ecx
  393. mov ebx, [esp + PCODED_ROW1]
  394. mov cl, [ebx+eax]
  395. test ecx, ecx
  396. jnz L3
  397. mov cl, [ebx+eax+1]
  398. test ecx, ecx
  399. jz L4
  400. L3:
  401. // for (k = 0; k < 8; k++)
  402. mov DWORD PTR [esp + LOOP_K], 8
  403. xor eax, eax
  404. xor ebx, ebx
  405. xor ecx, ecx
  406. xor edx, edx
  407. L5:
  408. // d = (r[i-2]+(r[i-2]<<1)-(r[i-1]<<3)+(r[i]<<3)-(r[i+1]+(r[i+1]<<1)))>>4
  409. // read r[i-2] and r[i]
  410. mov al, [esi+ebp-2]
  411. mov bl, [esi+ebp]
  412. // read r[i-1] and r[i+1]
  413. mov cl, [esi+ebp-1]
  414. mov dl, [esi+ebp+1]
  415. // compute r[i-2]*3 and r[i]*8
  416. lea eax, [eax+eax*2]
  417. lea ebx, [ebx*8]
  418. // compute r[i-1]*8 and r[i+1]*3
  419. lea ecx, [ecx*8]
  420. lea edx, [edx+edx*2]
  421. // compute (r[i-2]*3 + r[i]*8) and (r[i-1]*8 + r[i+1]*3)
  422. add eax, ebx
  423. add ecx, edx
  424. // compute (r[i-2]*3 - r[i-1]*8 + r[i]*8 - r[i+1]*3)
  425. sub eax, ecx
  426. xor ecx, ecx
  427. // compute ((r[i-2]*3 - r[i-1]*8 + r[i]*8 - r[i+1]*3) >> 4)
  428. sar eax, 4
  429. xor edx, edx
  430. // if (d && (d >= -32) && (d < 32))
  431. test eax, eax
  432. jz L6
  433. cmp eax, -32
  434. jl L6
  435. cmp eax, 32
  436. jge L6
  437. // delta = dxQP[d+32][pQP_map[mbc]]
  438. // r[i] = ClampTbl[r[i]-delta+CLAMP_BIAS]
  439. // r[i-1] = ClampTbl[r[i-1]+delta+CLAMP_BIAS]
  440. lea eax, [eax + 32]
  441. mov ebx, [esp + PQP_MAP]
  442. shl eax, 5
  443. add ebx, [esp + MBC]
  444. mov cl, [ebx]
  445. xor ebx, ebx
  446. mov al, dxQP[eax+ecx]
  447. mov bl, [esi+ebp]
  448. movsx eax, al
  449. sub ebx, eax
  450. mov cl, [esi+ebp-1]
  451. mov bl, ClampTbl[ebx + CLAMP_BIAS]
  452. mov cl, ClampTbl[ecx + eax + CLAMP_BIAS]
  453. mov [esi+ebp], bl
  454. mov [esi+ebp-1], cl
  455. L6:
  456. add esi, edi
  457. mov eax, [esp + LOOP_K]
  458. xor ebx, ebx
  459. dec eax
  460. mov [esp + LOOP_K], eax
  461. jnz L5
  462. // r -= (pitch<<3)
  463. mov eax, edi
  464. shl eax, 3
  465. sub esi, eax
  466. L4:
  467. add ebp, 8
  468. cmp ebp, [esp + WIDTH]
  469. jl L2
  470. // r += (pitch<<3)
  471. mov eax, edi
  472. shl eax, 3
  473. lea esi, [esi + eax]
  474. // if (0 == ((j+=8)%mod_div))
  475. mov eax, [esp + LOOP_J]
  476. add eax, 8
  477. mov [esp + LOOP_J], eax
  478. mov ebx, eax
  479. mov ecx, [esp + SHIFT]
  480. shr eax, cl
  481. shl eax, cl
  482. sub ebx, eax
  483. jnz L7
  484. // pcoded_row1 += sizeof(coded_map[0])
  485. // pQP_map += sizeof(QP_map[0])
  486. mov eax, [esp + PCODED_ROW1]
  487. mov ebx, [esp + PQP_MAP]
  488. add eax, TYPE coded_map[0]
  489. add ebx, TYPE QP_map[0]
  490. mov [esp + PCODED_ROW1], eax
  491. mov [esp + PQP_MAP], ebx
  492. L7:
  493. mov eax, [esp + LOOP_J]
  494. cmp eax, [esp + HEIGHT]
  495. jl L1
  496. add esp, LOCALSIZE
  497. pop edi
  498. pop esi
  499. pop ebx
  500. pop ebp
  501. ret
  502. }
  503. }
  504. #undef LOCALSIZE
  505. #undef SHIFT
  506. #undef PITCH_PARM
  507. #undef HEIGHT
  508. #undef WIDTH
  509. #undef REC
  510. #undef LOOP_K
  511. #undef LOOP_J
  512. #undef PCODED_ROW1
  513. #undef PQP_MAP
  514. #undef MBC
  515. #endif // } 0
  516. #define abs(x) (((x)>0)?(x):(-(x)))
  517. #define sign(x) (((x)<0)?(-1):(1))
  518. void InitEdgeFilterTab()
  519. {
  520. int d,QP;
  521. for (d = 0; d < 64; d++) { // -32 <= d < 32
  522. for (QP = 0; QP < 32; QP++) { // 0 <= QP < 32
  523. dxQP[d][QP] = sign(d-32)*(max(0,(abs(d-32)-max(0,((2*abs(d-32))-QP)))));
  524. }
  525. }
  526. }
  527. /**********************************************************************
  528. *
  529. * Name: EdgeFilter
  530. * Description: performs deblocking filtering on
  531. * reconstructed frames
  532. *
  533. * Input: pointers to reconstructed frame and difference
  534. * image
  535. * Returns:
  536. * Side effects:
  537. *
  538. * Date: 951129 Author: Gisle.Bjontegaard@fou.telenor.no
  539. * Karl.Lillevold@nta.no
  540. * Modified for annex J in H.263+: 961120 Karl O. Lillevold
  541. *
  542. ***********************************************************************/
  543. // C version of block edge filter functions
  544. // takes about 3 ms for QCIF and 12 ms for CIF on a Pentium 120.
  545. void EdgeFilter(unsigned char *lum,
  546. unsigned char *Cb,
  547. unsigned char *Cr,
  548. int width, int height, int pitch) {
  549. /* Luma */
  550. HorizEdgeFilter(lum, width, height, pitch, 4);
  551. VertEdgeFilter (lum, width, height, pitch, 4);
  552. /* Chroma */
  553. HorizEdgeFilter(Cb, width>>1, height>>1, pitch, 3);
  554. VertEdgeFilter (Cb, width>>1, height>>1, pitch, 3);
  555. HorizEdgeFilter(Cr, width>>1, height>>1, pitch, 3);
  556. VertEdgeFilter (Cr, width>>1, height>>1, pitch, 3);
  557. return;
  558. }
  559. #else // Karl's original version }{
  560. /* currently requires 11232 bytes */
  561. signed char dtab[352*32];
  562. /***********************************************************************/
  563. static void HorizEdgeFilter(unsigned char *rec,
  564. int width, int height, int pitch, int chr)
  565. {
  566. int i,j,k;
  567. int delta;
  568. int mbc, mbr, do_filter;
  569. unsigned char *r_2, *r_1, *r, *r1;
  570. signed char *deltatab;
  571. /* horizontal edges */
  572. r = rec + 8*pitch;
  573. r_2 = r - 2*pitch;
  574. r_1 = r - pitch;
  575. r1 = r + pitch;
  576. for (j = 8; j < height; j += 8) {
  577. for (i = 0; i < width; i += 8) {
  578. if (!chr) {
  579. mbr = (j >> 4);
  580. mbc = (i >> 4);
  581. }
  582. else {
  583. mbr = (j >> 3);
  584. mbc = (i >> 3);
  585. }
  586. deltatab = dtab + 176 + 351 * (QP_map[mbr][mbc] - 1);
  587. do_filter = coded_map[mbr+1][mbc+1] || coded_map[mbr][mbc+1];
  588. if (do_filter) {
  589. for (k = i; k < i+8; k++) {
  590. delta = (int)deltatab[ (( (int)(*(r_2 + k) * 3) -
  591. (int)(*(r_1 + k) * 8) +
  592. (int)(*(r + k) * 8) -
  593. (int)(*(r1 + k) * 3)) >>4)];
  594. *(r + k) = ClampTbl[ (int)(*(r + k)) - delta + CLAMP_BIAS];
  595. *(r_1 + k) = ClampTbl[ (int)(*(r_1 + k)) + delta + CLAMP_BIAS];
  596. }
  597. }
  598. }
  599. r += (pitch<<3);
  600. r1 += (pitch<<3);
  601. r_1 += (pitch<<3);
  602. r_2 += (pitch<<3);
  603. }
  604. return;
  605. }
  606. static void VertEdgeFilter(unsigned char *rec,
  607. int width, int height, int pitch, int chr)
  608. {
  609. int i,j,k;
  610. int delta;
  611. int mbc, mbr;
  612. int do_filter;
  613. signed char *deltatab;
  614. unsigned char *r;
  615. /* vertical edges */
  616. for (i = 8; i < width; i += 8)
  617. {
  618. r = rec;
  619. for (j = 0; j < height; j +=8)
  620. {
  621. if (!chr) {
  622. mbr = (j >> 4);
  623. mbc = (i >> 4);
  624. }
  625. else {
  626. mbr = (j >> 3);
  627. mbc = (i >> 3);
  628. }
  629. deltatab = dtab + 176 + 351 * (QP_map[mbr][mbc] - 1);
  630. do_filter = coded_map[mbr+1][mbc+1] || coded_map[mbr+1][mbc];
  631. if (do_filter) {
  632. for (k = 0; k < 8; k++) {
  633. delta = (int)deltatab[(( (int)(*(r + i-2 ) * 3) -
  634. (int)(*(r + i-1 ) * 8) +
  635. (int)(*(r + i ) * 8) -
  636. (int)(*(r + i+1 ) * 3) ) >>4)];
  637. *(r + i ) = ClampTbl[ (int)(*(r + i )) - delta + CLAMP_BIAS];
  638. *(r + i-1 ) = ClampTbl[ (int)(*(r + i-1)) + delta + CLAMP_BIAS];
  639. r += pitch;
  640. }
  641. }
  642. else {
  643. r += (pitch<<3);
  644. }
  645. }
  646. }
  647. return;
  648. }
  649. /**********************************************************************
  650. *
  651. * Name: EdgeFilter
  652. * Description: performs deblocking filtering on
  653. * reconstructed frames
  654. *
  655. * Input: pointers to reconstructed frame and difference
  656. * image
  657. * Returns:
  658. * Side effects:
  659. *
  660. * Date: 951129 Author: Gisle.Bjontegaard@fou.telenor.no
  661. * Karl.Lillevold@nta.no
  662. * Modified for annex J in H.263+: 961120 Karl O. Lillevold
  663. *
  664. ***********************************************************************/
  665. void EdgeFilter(unsigned char *lum,
  666. unsigned char *Cb,
  667. unsigned char *Cr,
  668. int width, int height, int pitch)
  669. {
  670. /* Luma */
  671. HorizEdgeFilter(lum, width, height, pitch, 0);
  672. VertEdgeFilter (lum, width, height, pitch, 0);
  673. /* Chroma */
  674. HorizEdgeFilter(Cb, width>>1, height>>1, pitch, 1);
  675. VertEdgeFilter (Cb, width>>1, height>>1, pitch, 1);
  676. HorizEdgeFilter(Cr, width>>1, height>>1, pitch, 1);
  677. VertEdgeFilter (Cr, width>>1, height>>1, pitch, 1);
  678. return;
  679. }
  680. #define sign(a) ((a) < 0 ? -1 : 1)
  681. void InitEdgeFilterTab()
  682. {
  683. int i,QP;
  684. for (QP = 1; QP <= 31; QP++) {
  685. for (i = -176; i <= 175; i++) {
  686. dtab[i+176 +(QP-1)*351] = sign(i) * (max(0,abs(i)-max(0,2*abs(i) - QP)));
  687. }
  688. }
  689. }
  690. #endif // } if defined(H263P)