h263pdec.c
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:29k
源码类别:

Symbian

开发平台:

Visual C++

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