h263pdec.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:28k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. //#include <string.h>
  36. #include "dllindex.h"
  37. #include "h261defs.h"
  38. #include "h261func.h"
  39. #include "h263plus.h"
  40. #include <stdio.h>
  41. #include "assert.h"
  42. #ifdef _MACINTOSH
  43. #include <string.h> // for memset
  44. #endif
  45. #ifdef COMPILE_MMX
  46. #include "mmxcpuid.h"
  47. #endif
  48. //#define VVPROFILER
  49. #define REPLACE_MACROS
  50. extern void ApplyVerticalDeblockingFilter( PIXEL * left, PIXEL * right, int offset);
  51. extern void ApplyVerticalDeblockingFilterMMX( PIXEL * left, PIXEL * right, int offset);
  52. extern void ApplyHorizontalDeblockingFilter( PIXEL * top, PIXEL * bottom, int offset);
  53. extern void ApplyHorizontalDeblockingFilterMMX( PIXEL * top, PIXEL * bottom, int offset);
  54. #ifdef VVPROFILER
  55. #include "hvdebtim.h"
  56. extern struct CVvDebugTimer * pVvProf[];
  57. #endif
  58. void PredBframePlus( MACROBLOCK_DESCR * mb,  // Macroblock to be predicted
  59.                         PICTURE * prevPic,      // Prev. picture (forward pred)
  60.                         PICTURE * nextPic,      // Next P-picture (backward pred)
  61.                         PICTURE * Bpic          // Output picture where pred is placed
  62.                         );
  63. //  PredBframePlus - Form prediction for B-frame a la H.263+
  64. void PredBframePlus( MACROBLOCK_DESCR * mb,  // Macroblock to be predicted
  65.                         PICTURE * prevPic,      // Prev. picture (forward pred)
  66.                         PICTURE * nextPic,      // Next P-picture (backward pred)
  67.                         PICTURE * Bpic          // Output picture where pred is placed
  68.                         )
  69. {
  70.     if(BFRAME_IS_BIDIRECTIONAL(mb))
  71.     {
  72.         PredBframe(mb,prevPic,nextPic,Bpic);
  73.     }
  74.     else
  75.     {
  76.         S8 saveMvX = mb->mv_x; 
  77.         S8 saveMvY = mb->mv_y;
  78.         U8 saveType = mb->mtype;
  79.         mb->mv_x = mb->mvdB_x; 
  80.         mb->mv_y = mb->mvdB_y;
  81.         mb->mtype = MTYPE263_INTER;
  82.         MotionComp263( mb, prevPic, Bpic );
  83.         mb->mv_x = saveMvX;
  84.         mb->mv_y = saveMvY;
  85.         mb->mtype = saveType;
  86.     }
  87. }
  88. //////////////////////////////////////////////////////////////////////////
  89. // Deblocking Filter Mode Functions
  90. //
  91. static U8 ClipTableBase[288];
  92. static U8 * ClipTable=NULL;
  93. static void InitializeClipTable()
  94. {
  95.     int i;
  96.     if(ClipTable) {
  97.         return;
  98.     } else {
  99.         ClipTable = ClipTableBase + 16;
  100.     }
  101.     for(i = -16; i<=0; i++) ClipTable[i] = 0x00;
  102.     for(i=1 ; i<256; i++) ClipTable[i] = (U8) i;
  103.     for(i=256 ; i<272; i++) ClipTable[i] = 0xFF;
  104. }
  105. static S8 DiffCutoffTableBase[351]; // Range [-175, 175]
  106. static S8 * DiffCutoffTable=NULL;
  107. #ifdef COMPILE_MMX
  108. #define SHORTMAX 32767
  109. __int64 g_qp = 0;
  110. // max - qp
  111. __int64 g_max_qp =   ((__int64) SHORTMAX)
  112. | (((__int64) SHORTMAX)<<16) 
  113. | (((__int64) SHORTMAX)<<32) 
  114. | (((__int64) SHORTMAX)<<48);
  115. // max - 2 * (qp)
  116. __int64 g_max_2qp =   ((__int64) SHORTMAX )
  117. | (((__int64) SHORTMAX)<<16) 
  118. | (((__int64) SHORTMAX)<<32) 
  119. | (((__int64) SHORTMAX)<<48);
  120. #endif
  121. static void InitializeDiffCutoffTable(S32 qp)
  122. {
  123.     static DiffTableQuantCache=0;
  124.     int d, d2;
  125.     if(DiffCutoffTable==NULL) {
  126.         memset(DiffCutoffTableBase, 0, 351);
  127.         DiffCutoffTable = DiffCutoffTableBase + 175;
  128.     }
  129.     if(DiffTableQuantCache == qp) return;
  130.     for(d=0, d2=0; d2<=qp; d++, d2+=2) {
  131.         DiffCutoffTable[d] = d;
  132.         DiffCutoffTable[-d] = -d;
  133.     }
  134.     for(;d<=qp;d++) {
  135.         DiffCutoffTable[d] = qp - d;
  136.         DiffCutoffTable[-d] = -qp + d;
  137.     }
  138.     for(;d<=DiffTableQuantCache;d++) {
  139.         DiffCutoffTable[d] = 0;
  140.         DiffCutoffTable[-d] = 0;
  141.     }
  142.     DiffTableQuantCache = qp;
  143. #ifdef COMPILE_MMX
  144. {
  145. short max_qp, max_2pq;
  146. max_qp = (short)SHORTMAX - (short) qp; // max - pq/2
  147. max_2pq = (short)SHORTMAX - 2*(short)qp; // max - 2 * (pq/2)
  148.     
  149. g_qp = (((__int64) qp)) 
  150. | (((__int64) qp)<<16)
  151. | (((__int64) qp)<<32)
  152. | (((__int64) qp)<<48);
  153. g_max_qp = (((__int64) max_qp)) 
  154. | (((__int64) max_qp)<<16)
  155. | (((__int64) max_qp)<<32)
  156. | (((__int64) max_qp)<<48);
  157. g_max_2qp = (((__int64) max_2pq)) 
  158. | (((__int64) max_2pq)<<16) 
  159. | (((__int64) max_2pq)<<32) 
  160. | (((__int64) max_2pq)<<48);
  161. }
  162. #endif
  163. }
  164. #ifdef _DEBUG
  165. static PIXEL * MACROBLOCK_LUMA_PTR(PICTURE * p,MACROBLOCK_DESCR * mb) 
  166. {
  167.     return ((p)->y.ptr + 16*(mb)->x + 16*(mb)->y*(p)->y.hoffset);
  168. }
  169. static PIXEL * BlockLumaPtr(PICTURE * pic, MACROBLOCK_DESCR * mb, int blk)
  170. {
  171.     switch(blk)
  172.     {
  173.     case 0:
  174.         return MACROBLOCK_LUMA_PTR(pic,mb);
  175.     case 1:
  176.         return MACROBLOCK_LUMA_PTR(pic,mb) + 8;
  177.     case 2:
  178.         return MACROBLOCK_LUMA_PTR(pic,mb) + 8*pic->y.hoffset;
  179.     default:
  180.         return MACROBLOCK_LUMA_PTR(pic,mb) + 8*(pic->y.hoffset + 1);
  181.     }
  182. }
  183. static PIXEL * MacroBlockCrPtr(PICTURE * pic, MACROBLOCK_DESCR * mb)
  184. {
  185.     return pic->cr.ptr + 8*mb->x + 8*mb->y*pic->cr.hoffset;
  186. }
  187. static PIXEL * MacroBlockCbPtr(PICTURE * pic, MACROBLOCK_DESCR * mb)
  188. {
  189.     return pic->cb.ptr + 8*mb->x + 8*mb->y*pic->cb.hoffset;
  190. }
  191. #else
  192. #define MACROBLOCK_LUMA_PTR(p, mb) 
  193.     ((p)->y.ptr + 16*(mb)->x + 16*(mb)->y*(p)->y.hoffset)
  194. #define BlockLumaPtr(pic, mb, blk) 
  195.     (MACROBLOCK_LUMA_PTR((pic),(mb)) + 4*((blk)&2)*(pic)->y.hoffset + 8*((blk)&1))
  196. #define MacroBlockCrPtr(pic, mb) 
  197.     ((pic)->cr.ptr + 8*(mb)->x + 8*(mb)->y*(pic)->cr.hoffset)
  198. #define MacroBlockCbPtr(pic, mb) 
  199.     ((pic)->cb.ptr + 8*(mb)->x + 8*(mb)->y*(pic)->cb.hoffset)
  200. #endif
  201. /******************************************************************************************/
  202. void ApplyVerticalDeblockingFilter( PIXEL * left, PIXEL * right, int offset)
  203. {
  204.     int i;
  205.     left += 7;
  206.     for(i=0; i<8; i++) {
  207. //8-bit arithmetic might overflow, changing to 32-bit
  208.         S32 d = DiffCutoffTable[(3*(S32) left[-1] - 8*(S32)left[0] + 8*(S32)right[0] - 3*(S32)right[1])>>4];        
  209.         *left = ClipTable[*left + d];
  210.         *right = ClipTable[*right - d];
  211.         left += offset;
  212.         right += offset;
  213.     }
  214. }
  215. /*
  216. PIXEL *left01, *right01, *left02, *right02;
  217. static void ApplyVerticalDeblockingFilter( PIXEL * left, PIXEL * right, int offset)
  218. {
  219. int result, ii;
  220. left01 = left;
  221. right01 = right;
  222. left02 = ((PIXEL *)calloc((8*offset)+8, sizeof(*left)));
  223. //left02 += 7;
  224. right02 = ((PIXEL *)calloc((8*offset)+8, sizeof(*right)));
  225. if(!left02 || !right02) return;
  226. //left[-1, 0, -1+offset, 0+offset, ..., -1+7*offset, 0+8*offset]
  227. //right[0, +1, 0+offset, +1+offset, ..., 0+7*offset, +1+8*offset]
  228. for(ii=0; ii<8; ii++) {
  229. left02[-1+ii*offset+7] = left[-1+ii*offset+7];
  230. left02[ 0+ii*offset+7] = left[ 0+ii*offset+7];
  231. right02[ 0+ii*offset] = right[ 0+ii*offset];
  232. right02[+1+ii*offset] = right[+1+ii*offset];
  233. }
  234. //call deblocking filter
  235. ApplyVerticalDeblockingFilterMMX(left01, right01, offset);
  236. ApplyVerticalDeblockingFilterInt(left02, right02, offset);
  237. //compare output
  238. for(ii=0; ii<8; ii++) {
  239. if(
  240. (left02[-1+ii*offset+7] != left01[-1+ii*offset+7])
  241. || (left02[ 0+ii*offset+7] != left01[ 0+ii*offset+7])
  242. || (right02[ 0+ii*offset] != right01[ 0+ii*offset])
  243. || (right02[+1+ii*offset] != right01[+1+ii*offset])
  244. ) {
  245. result = ii;
  246. }
  247. }
  248. free(left02);
  249. free(right02);
  250. }
  251. */
  252. /******************************************************************************************/
  253. void ApplyHorizontalDeblockingFilter( PIXEL * top, PIXEL * bottom, int offset)
  254. {
  255. int i;
  256.     PIXEL *next_to_top;
  257.     PIXEL *next_after_bottom;
  258. top += 7*offset;
  259.     next_to_top = top - offset;
  260.     next_after_bottom = bottom + offset;
  261.     for(i=0; i<8; i++) {
  262. //8-bit arithmetic might overflow, changing to 32-bit
  263.         S32 d = DiffCutoffTable[(3*(S32)next_to_top[0] - 8*(S32)top[0] + 8*(S32)bottom[0] - 3*(S32)next_after_bottom[0])>>4];
  264.         
  265.         *top = ClipTable[*top + d];
  266.         *bottom = ClipTable[*bottom - d];
  267.         top += 1;
  268.         next_to_top += 1;
  269.         bottom += 1;
  270.         next_after_bottom += 1;
  271.     }
  272. }
  273. /*
  274. PIXEL *top01=0, *bottom01=0;
  275. PIXEL *top02=0, *bottom02=0;
  276. static void ApplyHorizontalDeblockingFilter( PIXEL * top, PIXEL * bottom, int offset)
  277. {
  278. int result;
  279. top01 = top;
  280. bottom01 = bottom;
  281. top02 = calloc((7*offset)+8, sizeof(*top));
  282. bottom02 = calloc(offset+8, sizeof(*bottom));
  283. if(!top02 || !bottom02) return;
  284. //top+7*offset [0...7]
  285. //top+6*offset [0...7]
  286. memcpy(top02 + (7*offset), top + (7*offset), 8*sizeof(*top));
  287. memcpy(top02 + (6*offset), top + (6*offset), 8*sizeof(*top));
  288. //bottom[0...7]
  289. //bottom+offset[0...7]
  290. memcpy(bottom02, bottom, 8*sizeof(*bottom));
  291. memcpy(bottom02 + offset, bottom + offset, 8*sizeof(*bottom));
  292. //call deblocking filter
  293. ApplyHorizontalDeblockingFilterMMX(top02, bottom02, offset);
  294. ApplyHorizontalDeblockingFilterInt(top, bottom, offset);
  295. //compare output
  296. if((result = memcmp(top02 + (7*offset), top + (7*offset), 8*sizeof(*top))) != 0) {
  297. PIXEL *point =  top + (7*offset);
  298. PIXEL *point02 =  top02 + (7*offset);
  299. }
  300. if((result = memcmp(top02 + (6*offset), top + (6*offset), 8*sizeof(*top))) != 0) {
  301. PIXEL *point =  top + (6*offset);
  302. PIXEL *point02 =  top02 + (6*offset);
  303. }
  304. if((result = memcmp(bottom02, bottom, 8*sizeof(*bottom))) != 0) {
  305. PIXEL *point =  bottom;
  306. PIXEL *point02 =  bottom02;
  307. }
  308. if((result = memcmp(bottom02 + offset, bottom + offset, 8*sizeof(*bottom))) != 0) {
  309. PIXEL *point =  bottom + offset;
  310. PIXEL *point02 =  bottom02 + offset;
  311. }
  312. free(top02);
  313. free(bottom02);
  314. }
  315. */
  316. /******************************************************************************************/
  317. // This routine applies the H.263+ deblocking filter to a decoded picture.  Note
  318. // That this routine is NOT H.263+ compliant because it applies the filter after the
  319. // reconstructed picture has already been clipped to 0,255
  320. void ApplyDeblockingFilter( PICTURE * pic, MACROBLOCK_DESCR * mb, S32 Bframe)
  321. {
  322.     int i,h,v;
  323.     int numhor=pic->y.nhor>>4; // number of mb per row
  324.     int numvert=pic->y.nvert>>4; // number of mb per col
  325.     int nummb = numhor*numvert;
  326.     int off = pic->y.hoffset;
  327. #ifdef REPLACE_MACROS
  328. PIXEL *pLuma, *pCb, *pCr;
  329. #endif
  330. void (*pApplyHorizontalDeblockingFilter)(PIXEL *, PIXEL *, int); 
  331. void (*pApplyVerticalDeblockingFilter)(PIXEL *, PIXEL *, int); 
  332. #if defined(COMPILE_MMX)
  333. #if (_MSC_VER>=1100)
  334. if(cpuid_is_mmx_deblo_on()) {
  335. //do mmx if compiler switch AND initialized AND detected
  336. pApplyHorizontalDeblockingFilter = ApplyHorizontalDeblockingFilterMMX;
  337. pApplyVerticalDeblockingFilter = ApplyVerticalDeblockingFilterMMX;
  338. } else 
  339. #else
  340. #pragma message("need MSVC 5.0 or higher to compile MMX - MMX disabled")
  341. #endif
  342. #endif
  343. {
  344. pApplyHorizontalDeblockingFilter = ApplyHorizontalDeblockingFilter;
  345. pApplyVerticalDeblockingFilter = ApplyVerticalDeblockingFilter;
  346. }
  347. #ifdef VVPROFILER
  348. S32 ret;
  349. S32 nVvProfNb = 6;
  350. if(!pVvProf[nVvProfNb]) pVvProf[nVvProfNb] = newCVvDebugTimer();//memory leak on destruction
  351. StartTime(pVvProf[nVvProfNb]);
  352. #endif
  353. #ifdef REPLACE_MACROS
  354. //aw using pointers instead of macros
  355. pLuma = pic->y.ptr;
  356. pCb = pic->cb.ptr;
  357. pCr = pic->cr.ptr;
  358. assert(off==16*numhor);
  359. #endif
  360.     if(ClipTable==NULL) InitializeClipTable();
  361.     for(i=0,v=0; v<numvert; v++
  362. #ifdef REPLACE_MACROS
  363. , pLuma += 15*off, 
  364.  pCb += 7*pic->cb.hoffset + pic->cb.hoffset/2, 
  365.  pCr += 7*pic->cr.hoffset + pic->cr.hoffset/2
  366. #endif
  367.  ) {
  368.         for(h=0; h<numhor; h++, i++
  369. #ifdef REPLACE_MACROS
  370. , pLuma+=16, pCb+=8, pCr+=8
  371. #endif
  372. ) {
  373.             int qp;
  374.             if(mb[i].mtype == MTYPE_SKIP) {
  375.                 // Here we check to see if the macroblock below us is coded.  If it is then we need to
  376.                 // filter our bottom horizontal edges.   Note that we need to use the quant value of the
  377.                 // block below
  378.                 if(v<numvert-1 && mb[i+numhor].mtype != MTYPE_SKIP) {
  379.                     qp = Bframe ? mb[i+numhor].Bquant : mb[i+numhor].quant;
  380.                     InitializeDiffCutoffTable(qp);
  381. #ifndef REPLACE_MACROS
  382. pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],2), BlockLumaPtr(pic,&mb[i+numhor],0), off);
  383.                     pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],3), BlockLumaPtr(pic,&mb[i+numhor],1), off);
  384.                     pApplyHorizontalDeblockingFilter(MacroBlockCbPtr(pic, &mb[i]), MacroBlockCbPtr(pic,&mb[i+numhor]), pic->cb.hoffset);
  385.                     pApplyHorizontalDeblockingFilter(MacroBlockCrPtr(pic, &mb[i]), MacroBlockCrPtr(pic,&mb[i+numhor]), pic->cr.hoffset);
  386. #else
  387. assert(BlockLumaPtr(pic,&mb[i],2) == pLuma + 8*off);assert(BlockLumaPtr(pic,&mb[i+numhor],0) == pLuma + 16*off);
  388. assert(BlockLumaPtr(pic,&mb[i],3) == pLuma + 8*off +8);assert(BlockLumaPtr(pic,&mb[i+numhor],1) == pLuma + 16*off +8);
  389. assert(MacroBlockCbPtr(pic, &mb[i]) == pCb);assert(MacroBlockCbPtr(pic,&mb[i+numhor]) == pCb + 8*pic->cb.hoffset);
  390. assert(MacroBlockCrPtr(pic, &mb[i]) == pCr);assert(MacroBlockCrPtr(pic,&mb[i+numhor]) == pCr + 8*pic->cr.hoffset);
  391.                     pApplyHorizontalDeblockingFilter(pLuma + 8*off, pLuma + 16*off, off);
  392.                     pApplyHorizontalDeblockingFilter(pLuma + 8*off +8, pLuma + 16*off +8, off);
  393.                     pApplyHorizontalDeblockingFilter(pCb, pCb + 8*pic->cb.hoffset, pic->cb.hoffset);
  394.                     pApplyHorizontalDeblockingFilter(pCr, pCr + 8*pic->cr.hoffset, pic->cr.hoffset);
  395. #endif
  396.                 }
  397.                 // Here we check to see if the macroblock to the left of us is coded. If so do our left vertical
  398.                 // edges
  399.                 if(h && mb[i-1].mtype != MTYPE_SKIP) {
  400.                     qp = Bframe ? mb[i-1].Bquant : mb[i-1].quant;
  401.                     InitializeDiffCutoffTable(qp);
  402. #ifndef REPLACE_MACROS
  403.                     pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i-1],1), BlockLumaPtr(pic,&mb[i],0), off);
  404.                     pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i-1],3), BlockLumaPtr(pic,&mb[i],2), off);
  405.                     pApplyVerticalDeblockingFilter(MacroBlockCbPtr(pic, &mb[i-1]), MacroBlockCbPtr(pic,&mb[i]), pic->cb.hoffset);
  406.                     pApplyVerticalDeblockingFilter(MacroBlockCrPtr(pic, &mb[i-1]), MacroBlockCrPtr(pic,&mb[i]), pic->cr.hoffset);
  407. #else
  408. assert(BlockLumaPtr(pic,&mb[i-1],1) == pLuma -8);assert(BlockLumaPtr(pic,&mb[i],0) == pLuma);
  409. assert(BlockLumaPtr(pic,&mb[i-1],3) == pLuma + 8*off -8);assert(BlockLumaPtr(pic,&mb[i],2) == pLuma + 8*off);
  410. assert(MacroBlockCbPtr(pic, &mb[i-1]) == pCb -8);assert(MacroBlockCbPtr(pic,&mb[i]) == pCb);
  411. assert(MacroBlockCrPtr(pic, &mb[i-1]) == pCr -8);assert(MacroBlockCrPtr(pic,&mb[i]) == pCr);
  412.                     pApplyVerticalDeblockingFilter(pLuma -8, pLuma, off);
  413. pApplyVerticalDeblockingFilter(pLuma + 8*off -8, pLuma + 8*off, off);
  414.                     pApplyVerticalDeblockingFilter(pCb -8, pCb, pic->cb.hoffset);
  415. pApplyVerticalDeblockingFilter(pCr -8, pCr, pic->cr.hoffset);
  416. #endif
  417.                 }
  418.             } else {
  419.                 qp = Bframe ? mb[i].Bquant : mb[i].quant;
  420.                 InitializeDiffCutoffTable(qp);
  421.                 // First do the first two horizontal edges
  422. #ifndef REPLACE_MACROS
  423. pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],0), BlockLumaPtr(pic,&mb[i],2), off);
  424.                 pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],1), BlockLumaPtr(pic,&mb[i],3), off);
  425. #else
  426. assert(BlockLumaPtr(pic,&mb[i],0) == pLuma);assert(BlockLumaPtr(pic,&mb[i],2) == pLuma + 8*off);
  427. assert(BlockLumaPtr(pic,&mb[i],1) == pLuma +8);assert(BlockLumaPtr(pic,&mb[i],3) == pLuma + 8*off +8);
  428.                 pApplyHorizontalDeblockingFilter(pLuma, pLuma + 8*off, off);
  429. pApplyHorizontalDeblockingFilter(pLuma +8, pLuma + 8*off +8, off);
  430. #endif
  431.                 // Now do the first two vertical edges; don't filter if the left edge is a picture edge
  432.                 if(h) {
  433. #ifndef REPLACE_MACROS
  434. pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i-1],1), BlockLumaPtr(pic,&mb[i],0), off);
  435. #else
  436. assert(BlockLumaPtr(pic,&mb[i-1],1) == pLuma -8);assert(BlockLumaPtr(pic,&mb[i],0) == pLuma);
  437. pApplyVerticalDeblockingFilter(pLuma -8, pLuma, off);
  438. #endif
  439.                 }
  440. #ifndef REPLACE_MACROS
  441.                 pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i],0), BlockLumaPtr(pic,&mb[i],1), off);
  442. #else
  443. assert(BlockLumaPtr(pic,&mb[i],0) == pLuma);assert(BlockLumaPtr(pic,&mb[i],1) == pLuma +8);
  444. pApplyVerticalDeblockingFilter(pLuma, pLuma +8, off);
  445. #endif
  446.                 // Now do the bottom two horizontal edges; don't filter if we are at a bottom edge of the picture
  447.                 if(v < numvert-1) {
  448.                     // Use quantization parameter for lower macroblock if it was coded
  449.                     if(mb[i+numhor].mtype != MTYPE_SKIP) {
  450.                         InitializeDiffCutoffTable(Bframe ? mb[i+numhor].Bquant : mb[i+numhor].quant);
  451.                     }
  452. #ifndef REPLACE_MACROS
  453.                     pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],2), BlockLumaPtr(pic,&mb[i+numhor],0), 
  454.                         off);
  455.                     pApplyHorizontalDeblockingFilter(BlockLumaPtr(pic,&mb[i],3), BlockLumaPtr(pic,&mb[i+numhor],1), 
  456.                         off);
  457. #else
  458. assert(BlockLumaPtr(pic,&mb[i],2) == pLuma + 8*off);assert(BlockLumaPtr(pic,&mb[i+numhor],0) == pLuma + 16*off);
  459. assert(BlockLumaPtr(pic,&mb[i],3) == pLuma + 8*off +8);assert(BlockLumaPtr(pic,&mb[i+numhor],1) == pLuma + 16*off +8);
  460.                     pApplyHorizontalDeblockingFilter(pLuma + 8*off, pLuma + 16*off, off);
  461.                     pApplyHorizontalDeblockingFilter(pLuma + 8*off +8, pLuma + 16*off +8, off);
  462. #endif
  463.                     
  464.                     // restore quantization parameter of current macroblock
  465.                     InitializeDiffCutoffTable(qp);
  466.                 }
  467.                 // Lastly do the lower two vertical edges; don't filter if the left edge is a picture edge
  468.                 if(h) {
  469. #ifndef REPLACE_MACROS
  470. pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i-1],3), BlockLumaPtr(pic,&mb[i],2), off);
  471. #else
  472. assert(BlockLumaPtr(pic,&mb[i-1],3) == pLuma + 8*off - 8);assert(BlockLumaPtr(pic,&mb[i],2) == pLuma +8*off);
  473. pApplyVerticalDeblockingFilter(pLuma + 8*off - 8, pLuma +8*off, off);
  474. #endif
  475.                 }
  476. #ifndef REPLACE_MACROS
  477. pApplyVerticalDeblockingFilter(BlockLumaPtr(pic,&mb[i],2), BlockLumaPtr(pic,&mb[i],3), off);
  478. #else
  479. assert(BlockLumaPtr(pic,&mb[i],2) == pLuma + 8*off);assert(BlockLumaPtr(pic,&mb[i],3) == pLuma + 8*off +8);
  480. pApplyVerticalDeblockingFilter(pLuma + 8*off, pLuma + 8*off +8, off);
  481. #endif
  482.                 // Now apply the filters to the chroma
  483.                 if(v < numvert-1) {
  484. #ifndef REPLACE_MACROS
  485.                     pApplyHorizontalDeblockingFilter(MacroBlockCbPtr(pic, &mb[i]), MacroBlockCbPtr(pic,&mb[i+numhor]), pic->cb.hoffset);
  486.                     pApplyHorizontalDeblockingFilter(MacroBlockCrPtr(pic, &mb[i]), MacroBlockCrPtr(pic,&mb[i+numhor]), pic->cr.hoffset);
  487. #else
  488. assert(MacroBlockCbPtr(pic, &mb[i]) == pCb);assert(MacroBlockCbPtr(pic,&mb[i+numhor]) == pCb +8*pic->cb.hoffset);
  489. assert(MacroBlockCrPtr(pic, &mb[i]) == pCr);assert(MacroBlockCrPtr(pic,&mb[i+numhor]) == pCr +8*pic->cr.hoffset);
  490. pApplyHorizontalDeblockingFilter(pCb, pCb +8*pic->cb.hoffset, pic->cb.hoffset);
  491.                     pApplyHorizontalDeblockingFilter(pCr, pCr +8*pic->cr.hoffset, pic->cr.hoffset);
  492. #endif
  493.                 }
  494.                 if(h) {
  495. #ifndef REPLACE_MACROS
  496.                     pApplyVerticalDeblockingFilter(MacroBlockCbPtr(pic, &mb[i-1]), MacroBlockCbPtr(pic,&mb[i]), pic->cb.hoffset);
  497.                     pApplyVerticalDeblockingFilter(MacroBlockCrPtr(pic, &mb[i-1]), MacroBlockCrPtr(pic,&mb[i]), pic->cr.hoffset);
  498. #else
  499. assert(MacroBlockCbPtr(pic, &mb[i-1]) == pCb -8);assert(MacroBlockCbPtr(pic,&mb[i]) == pCb);
  500. assert(MacroBlockCrPtr(pic, &mb[i-1]) == pCr -8);assert(MacroBlockCrPtr(pic,&mb[i]) == pCr);
  501. pApplyVerticalDeblockingFilter(pCb -8, pCb, pic->cb.hoffset);
  502.                     pApplyVerticalDeblockingFilter(pCr -8, pCr, pic->cr.hoffset);
  503. #endif
  504.                 }
  505.             }
  506.         }
  507.     }
  508. //clear the mmx state
  509. #if defined(COMPILE_MMX)
  510. #if (_MSC_VER>=1100)
  511. if(cpuid_is_mmx_deblo_on()) {
  512. __asm emms
  513. }
  514. #endif
  515. #endif
  516. #ifdef VVPROFILER
  517. StopAndAccuTime(pVvProf[nVvProfNb]);
  518. #endif
  519. }
  520. /******************************************************************************************/
  521. //////////////////////////////////////////////////////////////////////////////
  522. //  Deblocking filter for Reduced Resolution Update mode
  523. //
  524. static void vertFilterRRUmode( PIXEL * right, int offset, int len )
  525. {
  526.     int i, valLeft, valRight;
  527.     for(i=0; i < len; i++) {
  528.         valLeft = right[-1];
  529.         valRight = right[0];
  530.         right[-1] = (3 * valLeft + 1 * valRight + 2) >> 2;
  531.         right[0]  = (1 * valLeft + 3 * valRight + 2) >> 2;
  532.         right += offset;
  533.     }
  534. }
  535. static void horFilterRRUmode( PIXEL * bottom, int offset, int len )
  536. {
  537.     int i, valTop, valBottom;
  538.     PIXEL *top;
  539.         
  540.     top = bottom - offset;
  541.     for(i=0; i < len; i++) {
  542.         valTop = top[0];
  543.         valBottom = bottom[0];
  544.         top[0]    = (3 * valTop + 1 * valBottom + 2) >> 2;
  545.         bottom[0] = (1 * valTop + 3 * valBottom + 2) >> 2;
  546.         top += 1;
  547.         bottom += 1;
  548.     }
  549. }
  550. // This routine applies the Reduced-res. Update mode deblocking filter to a decoded picture.
  551. extern void ReducedResDeblockingFilter( PICTURE * pic, MACROBLOCK_DESCR * mb )
  552. {
  553.     int i,h,v;
  554.     int numhor = (pic->y.nhor + 16) >> 5;   // number of mb per row
  555.     int numvert= (pic->y.nvert+ 16) >> 5;   // number of mb per col
  556.     int nummb = numhor*numvert;
  557.     int off = pic->y.hoffset;
  558.     PIXEL   *luma0;
  559.     int     hSize, vSize, cOffset;
  560.    
  561.     for(i=0,v=0; v<numvert; v++) {
  562.         vSize = 32;
  563.         if (32 * v + 16 >= pic->y.nvert)
  564.             vSize = 16;     // MB is truncated at the bottom
  565.         for(h=0; h<numhor; h++, i++) {
  566.             hSize = 32;
  567.             if (32 * h + 16 >= pic->y.nhor)
  568.                 hSize = 16; // MB is truncated at the right
  569.             luma0 = pic->y.ptr + 32 * h + 32 * v * off;
  570.             cOffset = 16 * h + 16 * v * pic->cb.hoffset;
  571.             // Filter horizontal edge inside block
  572.             if (mb[i].mtype != MTYPE_SKIP  &&  vSize == 32) {
  573.                 horFilterRRUmode( luma0 + 16*off, off, hSize );
  574.             }
  575.             // Filter horizontal edge at the bottom of the block
  576.             if (v < numvert-1  &&  
  577.                 (mb[i].mtype != MTYPE_SKIP  ||  mb[i+numhor].mtype != MTYPE_SKIP)) {
  578.                 horFilterRRUmode( luma0 + 32*off, off, hSize );
  579.                 horFilterRRUmode( pic->cb.ptr + cOffset + 16*pic->cb.hoffset,
  580.                                   pic->cb.hoffset, hSize>>1 );
  581.                 horFilterRRUmode( pic->cr.ptr + cOffset + 16*pic->cr.hoffset,
  582.                                   pic->cr.hoffset, hSize>>1 );
  583.             }
  584.             // Filter vertical edge at the left of the block
  585.             if (h > 0  &&
  586.                 (mb[i].mtype != MTYPE_SKIP  ||  mb[i-1].mtype != MTYPE_SKIP)) {
  587.                 vertFilterRRUmode( luma0, off, vSize );
  588.                 vertFilterRRUmode( pic->cb.ptr + cOffset,
  589.                                   pic->cb.hoffset, vSize>>1 );
  590.                 vertFilterRRUmode( pic->cr.ptr + cOffset,
  591.                                   pic->cr.hoffset, vSize>>1 );
  592.             }
  593.             // Filter vertical edge inside block
  594.             if (mb[i].mtype != MTYPE_SKIP  &&  hSize == 32) {
  595.                 vertFilterRRUmode( luma0 + 16, off, vSize );
  596.             }
  597.         }
  598.     }
  599. }
  600. // Alternate Horizontal Scan Order
  601. static int alt_hor_scan[64] = {  0, 1, 2, 3,10,11,12,13,
  602.                                  4, 5, 8, 9,17,16,15,14,
  603.                                  6, 7,19,18,26,27,28,29,
  604.                                 20,21,24,25,30,31,32,33,
  605.                                 22,23,34,35,42,43,44,45,
  606.                                 36,37,40,41,46,47,48,49,
  607.                                 38,39,50,51,56,57,58,59,
  608.                                 52,53,54,55,60,61,62,63};
  609. // Alternate Vertical (MPEG-2) Scan Order
  610. static int alt_ver_scan[64] = {  0, 4, 6,20,22,36,38,52,
  611.                                  1, 5, 7,21,23,37,39,53,
  612.                                  2, 8,19,24,34,40,50,54,
  613.                                  3, 9,18,25,35,41,51,55,
  614.                                 10,17,26,30,42,46,56,60,
  615.                                 11,16,27,31,43,47,57,61,
  616.                                 12,15,28,32,44,48,58,62,
  617.                                 13,14,29,33,45,49,59,63};
  618. static int MyZigZag[64] = {  0,  1,  5,  6,  14, 15, 27, 28,
  619.                             2,  4,  7,  13, 16, 26, 29, 42,
  620.                             3,  8,  12, 17, 25, 30, 41, 43,
  621.                             9,  11, 18, 24, 31, 40, 44, 53,
  622.                             10, 19, 23, 32, 39, 45, 52, 54,
  623.                             20, 22, 33, 38, 46, 51, 55, 60,
  624.                             21, 34, 37, 47, 50, 56, 59, 61,
  625.                             35, 36, 48, 49, 57, 58, 62, 63
  626. };
  627. static int reorder[8] = {0,4,2,7, 1,5,3,6};
  628. int ireorder[8] = {0,4,2,6, 1,5,7,3};
  629. int inv_alt_hor_scan[64];
  630. int inv_alt_hor_scan_no_reorder[64];
  631. int alt_hor_to_zigzag[64];
  632. int inv_alt_ver_scan[64];
  633. int inv_alt_ver_scan_no_reorder[64];
  634. int alt_ver_to_zigzag[64];
  635. int zigzag_to_zigzag[64];
  636. void InitAdvancedIntraTables()
  637. {
  638.     static int initialized=0;
  639.     int index,i,j;
  640.     if(initialized) return;
  641.     initialized = 1;
  642.     // Generate inverse scan order vectors
  643.     for (index = 0; index < 64; index++) {
  644.         i = reorder[index % 8];
  645.         j = reorder[index / 8];
  646.         inv_alt_ver_scan[ alt_ver_scan[index] ] = i*8 + j;
  647.         inv_alt_hor_scan[ alt_hor_scan[index] ] = i*8 + j;
  648.         inv_alt_ver_scan_no_reorder[ alt_ver_scan[index] ] = index;
  649.         inv_alt_hor_scan_no_reorder[ alt_hor_scan[index] ] = index;
  650.     }
  651.     // Now do the scan's from alt hor and alt ver to zigzag.
  652.     // We need to be careful because the above tables take into
  653.     // account the reorderings that come from our DCT.  We don't
  654.     // want to take that into account, so we apply the ireorder
  655.     for(index = 0; index < 64; index++) {
  656.         i = ireorder[ inv_alt_ver_scan[index]&7 ];
  657.         j = ireorder[ inv_alt_ver_scan[index]>>3 ];
  658.         alt_ver_to_zigzag[ index ] = MyZigZag[ i*8 + j ];
  659.         
  660.         i = ireorder[ inv_alt_hor_scan[index]&7 ];
  661.         j = ireorder[ inv_alt_hor_scan[index]>>3 ];
  662.         alt_hor_to_zigzag[ index ] = MyZigZag[ i*8 + j ];
  663.         zigzag_to_zigzag[ index ] = index;
  664.     }
  665. }