loopFilter.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:43k
源码类别:

Audio

开发平台:

Visual C++

  1. /*!
  2.  *************************************************************************************
  3.  * file loopFilter.c
  4.  *
  5.  * brief
  6.  *    Filter to reduce blocking artifacts on a macroblock level.
  7.  *    The filter strength is QP dependent.
  8.  *
  9.  * author
  10.  *    Contributors:
  11.  *    - Peter List       Peter.List@t-systems.de:  Original code                                 (13-Aug-2001)
  12.  *    - Jani Lainema     Jani.Lainema@nokia.com:   Some bug fixing, removal of recursiveness     (16-Aug-2001)
  13.  *    - Peter List       Peter.List@t-systems.de:  inplace filtering and various simplifications (10-Jan-2002)
  14.  *    - Anthony Joch     anthony@ubvideo.com:      Simplified switching between filters and
  15.  *                                                 non-recursive default filter.                 (08-Jul-2002)
  16.  *    - Cristina Gomila  cristina.gomila@thomson.net: Simplification of the chroma deblocking
  17.  *                                                    from JVT-E089                              (21-Nov-2002)
  18.  *    - Alexis Michael Tourapis atour@dolby.com:   Speed/Architecture improvements               (08-Feb-2007)
  19.  *************************************************************************************
  20.  */
  21. #include "global.h"
  22. #include "image.h"
  23. #include "mb_access.h"
  24. #include "loopfilter.h"
  25. byte mixedModeEdgeFlag, fieldModeFilteringFlag;
  26. static int64  **list0_refPicIdArr, **list1_refPicIdArr;
  27. static short  ***list0_mv, ***list1_mv;
  28. static char   **list0_refIdxArr, **list1_refIdxArr;
  29. static Macroblock *MbP, *MbQ;
  30. static imgpel   *SrcPtrP, *SrcPtrQ;
  31. /*********************************************************************************************************/
  32. // NOTE: In principle, the alpha and beta tables are calculated with the formulas below
  33. //       Alpha( qp ) = 0.8 * (2^(qp/6)  -  1)
  34. //       Beta ( qp ) = 0.5 * qp  -  7
  35. // The tables actually used have been "hand optimized" though (by Anthony Joch). So, the
  36. // table values might be a little different to formula-generated values. Also, the first
  37. // few values of both tables is set to zero to force the filter off at low qp抯
  38. static const byte ALPHA_TABLE[52]  = {0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,4,4,5,6,  7,8,9,10,12,13,15,17,  20,22,25,28,32,36,40,45,  50,56,63,71,80,90,101,113,  127,144,162,182,203,226,255,255} ;
  39. static const byte  BETA_TABLE[52]  = {0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,2,2,2,3,  3,3,3, 4, 4, 4, 6, 6,   7, 7, 8, 8, 9, 9,10,10,  11,11,12,12,13,13, 14, 14,   15, 15, 16, 16, 17, 17, 18, 18} ;
  40. static const byte CLIP_TAB[52][5]  =
  41. {
  42.   { 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},
  43.   { 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},{ 0, 0, 0, 0, 0},
  44.   { 0, 0, 0, 0, 0},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 0, 1, 1},{ 0, 0, 1, 1, 1},{ 0, 0, 1, 1, 1},{ 0, 1, 1, 1, 1},
  45.   { 0, 1, 1, 1, 1},{ 0, 1, 1, 1, 1},{ 0, 1, 1, 1, 1},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 1, 2, 2},{ 0, 1, 2, 3, 3},
  46.   { 0, 1, 2, 3, 3},{ 0, 2, 2, 3, 3},{ 0, 2, 2, 4, 4},{ 0, 2, 3, 4, 4},{ 0, 2, 3, 4, 4},{ 0, 3, 3, 5, 5},{ 0, 3, 4, 6, 6},{ 0, 3, 4, 6, 6},
  47.   { 0, 4, 5, 7, 7},{ 0, 4, 5, 8, 8},{ 0, 4, 6, 9, 9},{ 0, 5, 7,10,10},{ 0, 6, 8,11,11},{ 0, 6, 8,13,13},{ 0, 7,10,14,14},{ 0, 8,11,16,16},
  48.   { 0, 9,12,18,18},{ 0,10,13,20,20},{ 0,11,15,23,23},{ 0,13,17,25,25}
  49. } ;
  50. static const char chroma_edge[2][4][4] = //[dir][edge][yuv_format]
  51. { { {-4, 0, 0, 0},
  52.     {-4,-4,-4, 4},
  53.     {-4, 4, 4, 8},
  54.     {-4,-4,-4, 12}},
  55.   { {-4, 0,  0,  0},
  56.     {-4,-4,  4,  4},
  57.     {-4, 4,  8,  8},
  58.     {-4,-4, 12, 12}}};
  59. static const int pelnum_cr[2][4] =  {{0,8,16,16}, {0,8, 8,16}};  //[dir:0=vert, 1=hor.][yuv_format]
  60. void (*GetStrength)(byte Strength[16],ImageParameters *img,int MbQAddr,int dir,int edge, int mvlimit,StorablePicture *p);
  61. void GetStrengthNormal(byte Strength[16],ImageParameters *img,int MbQAddr,int dir,int edge, int mvlimit,StorablePicture *p);
  62. void GetStrengthMBAff(byte Strength[16],ImageParameters *img,int MbQAddr,int dir,int edge, int mvlimit,StorablePicture *p);
  63. void (*EdgeLoopLuma)(ColorPlane pl, imgpel** Img, byte Strength[16],ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset, int dir, int edge, int width, StorablePicture *p);
  64. void EdgeLoopLumaNormal(ColorPlane pl, imgpel** Img, byte Strength[16],ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset, int dir, int edge, int width, StorablePicture *p);
  65. void EdgeLoopLumaMBAff(ColorPlane pl, imgpel** Img, byte Strength[16],ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset, int dir, int edge, int width, StorablePicture *p);
  66. void (*EdgeLoopChroma)(imgpel** Img, byte Strength[16],ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset, int dir, int edge, int width, int uv, StorablePicture *p);
  67. void EdgeLoopChromaNormal(imgpel** Img, byte Strength[16],ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset, int dir, int edge, int width, int uv, StorablePicture *p);
  68. void EdgeLoopChromaMBAff(imgpel** Img, byte Strength[16],ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset, int dir, int edge, int width, int uv, StorablePicture *p);
  69. void DeblockMb(ImageParameters *img, StorablePicture *p, int MbQAddr);
  70. int compute_deblock_strength(char **list0_refIdxArr, char **list1_refIdxArr, int64 **list0_refPicIdArr, int64 **list1_refPicIdArr, 
  71.                              short  ***list0_mv, short  ***list1_mv, int blk_y, int blk_x, int blk_y2, int blk_x2, int mvlimit);
  72. /*!
  73.  *****************************************************************************************
  74.  * brief
  75.  *    Filter all macroblocks in order of increasing macroblock address.
  76.  *****************************************************************************************
  77.  */
  78. void DeblockPicture(ImageParameters *img, StorablePicture *p)
  79. {
  80.   unsigned i;
  81.   if (p->MbaffFrameFlag == 1) 
  82.   {
  83.     GetStrength    = GetStrengthMBAff;
  84.     EdgeLoopLuma   = EdgeLoopLumaMBAff;
  85.     EdgeLoopChroma = EdgeLoopChromaMBAff;
  86.   }
  87.   else
  88.   {
  89.     GetStrength    = GetStrengthNormal;
  90.     EdgeLoopLuma   = EdgeLoopLumaNormal;
  91.     EdgeLoopChroma = EdgeLoopChromaNormal;
  92.   }
  93.   for (i = 0; i < p->PicSizeInMbs; i++)
  94.   {
  95.     DeblockMb( img, p, i ) ;
  96.   }
  97. }
  98. /*!
  99.  *****************************************************************************************
  100.  * brief
  101.  *    Deblocking filter for one macroblock.
  102.  *****************************************************************************************
  103.  */
  104. void DeblockMb(ImageParameters *img, StorablePicture *p, int MbQAddr)
  105. {
  106.   int           EdgeCondition;
  107.   int           dir, edge;
  108.   byte          Strength[16];
  109.   int           mb_x, mb_y;
  110.   
  111.   int           filterNon8x8LumaEdgesFlag[4] = {1,1,1,1};
  112.   int           filterLeftMbEdgeFlag;
  113.   int           filterTopMbEdgeFlag;
  114.   int           fieldModeMbFlag;
  115.   int           mvlimit = 4;
  116.   int           i, StrengthSum;
  117.   Macroblock    *MbQ;
  118.   imgpel **imgY   = p->imgY;
  119.   imgpel ***imgUV = p->imgUV;
  120.   
  121.   int           edge_cr;
  122.   
  123.   img->DeblockCall = 1;
  124.   get_mb_pos (MbQAddr, img->mb_size[IS_LUMA], &mb_x, &mb_y);
  125.   
  126.   filterLeftMbEdgeFlag = (mb_x != 0);
  127.   filterTopMbEdgeFlag  = (mb_y != 0);
  128.   
  129.   MbQ = &(img->mb_data[MbQAddr]) ; // current Mb
  130.   
  131.   if (MbQ->mb_type == I8MB)
  132.     assert(MbQ->luma_transform_size_8x8_flag);
  133.   
  134.   filterNon8x8LumaEdgesFlag[1] =
  135.     filterNon8x8LumaEdgesFlag[3] = !(MbQ->luma_transform_size_8x8_flag);
  136.   
  137.   if (p->MbaffFrameFlag && mb_y == MB_BLOCK_SIZE && MbQ->mb_field)
  138.     filterTopMbEdgeFlag = 0;
  139.   
  140.   fieldModeMbFlag = (p->structure!=FRAME) || (p->MbaffFrameFlag && MbQ->mb_field);
  141.   if (fieldModeMbFlag)
  142.     mvlimit = 2;
  143.   
  144.   // return, if filter is disabled
  145.   if (MbQ->DFDisableIdc==1) 
  146.   {
  147.     img->DeblockCall = 0;
  148.     return;
  149.   }
  150.   
  151.   if (MbQ->DFDisableIdc==2)
  152.   {
  153.     // don't filter at slice boundaries
  154.     filterLeftMbEdgeFlag = MbQ->mbAvailA;
  155.     // if this the bottom of a frame macroblock pair then always filter the top edge
  156.     filterTopMbEdgeFlag  = (p->MbaffFrameFlag && !MbQ->mb_field && (MbQAddr & 0x01)) ? 1 : MbQ->mbAvailB;
  157.   }
  158.   img->current_mb_nr = MbQAddr;
  159.   CheckAvailabilityOfNeighbors(&img->mb_data[MbQAddr]);
  160.   for( dir = 0 ; dir < 2 ; dir++ )                                                      // filter first vertical edges, followed by horizontal 
  161.   {
  162.     EdgeCondition = (dir && filterTopMbEdgeFlag) || (!dir && filterLeftMbEdgeFlag); // can not filter beyond picture boundaries
  163.     for( edge=0; edge<4 ; edge++ )                                            // first 4 vertical strips of 16 pel
  164.     {                                                                               // then  4 horizontal
  165.       if( edge || EdgeCondition )
  166.       {
  167.         edge_cr = chroma_edge[dir][edge][p->chroma_format_idc];
  168.         GetStrength(Strength, img, MbQAddr, dir, edge << 2, mvlimit, p); // Strength for 4 blks in 1 stripe
  169.         StrengthSum = Strength[0];
  170.         for (i = 1; i < MB_BLOCK_SIZE && StrengthSum == 0 ; i++)
  171.         {
  172.           StrengthSum += Strength[i];
  173.         }
  174.         
  175.         
  176.         if( StrengthSum )                      // only if one of the 16 Strength bytes is != 0
  177.         {
  178.           if (filterNon8x8LumaEdgesFlag[edge])
  179.           {
  180.             EdgeLoopLuma( PLANE_Y, imgY, Strength, img, MbQAddr, MbQ->DFAlphaC0Offset, MbQ->DFBetaOffset, dir, edge << 2, p->size_x, p) ;
  181.             if( active_sps->chroma_format_idc==YUV444 && !IS_INDEPENDENT(img) )
  182.             {
  183.               EdgeLoopLuma(PLANE_U, imgUV[0], Strength, img, MbQAddr, MbQ->DFAlphaC0Offset, MbQ->DFBetaOffset, dir, edge << 2, p->size_x, p);
  184.               EdgeLoopLuma(PLANE_V, imgUV[1], Strength, img, MbQAddr, MbQ->DFAlphaC0Offset, MbQ->DFBetaOffset, dir, edge << 2, p->size_x, p);
  185.             }
  186.           }
  187.           if (active_sps->chroma_format_idc==YUV420 || active_sps->chroma_format_idc==YUV422)
  188.           {
  189.             if( (imgUV != NULL) && (edge_cr >= 0))
  190.             {
  191.               EdgeLoopChroma( imgUV[0], Strength, img, MbQAddr, MbQ->DFAlphaC0Offset, MbQ->DFBetaOffset, dir, edge_cr, p->size_x_cr, 0, p);
  192.               EdgeLoopChroma( imgUV[1], Strength, img, MbQAddr, MbQ->DFAlphaC0Offset, MbQ->DFBetaOffset, dir, edge_cr, p->size_x_cr, 1, p);
  193.             }
  194.           }
  195.         }
  196.         
  197.         if (dir && !edge && !MbQ->mb_field && mixedModeEdgeFlag) 
  198.         {
  199.           // this is the extra horizontal edge between a frame macroblock pair and a field above it
  200.           img->DeblockCall = 2;
  201.           GetStrength(Strength,img,MbQAddr,dir, MB_BLOCK_SIZE, mvlimit, p); // Strength for 4 blks in 1 stripe
  202.           //if( *((int*)Strength) )                           // only if one of the 4 Strength bytes is != 0
  203.           {
  204.             if (filterNon8x8LumaEdgesFlag[edge])
  205.             {
  206.               EdgeLoopLuma(PLANE_Y, imgY, Strength, img, MbQAddr, MbQ->DFAlphaC0Offset, MbQ->DFBetaOffset, dir, 16, p->size_x, p) ;
  207.               if( active_sps->chroma_format_idc==YUV444 && !IS_INDEPENDENT(img) )
  208.               {
  209.                 EdgeLoopLuma(PLANE_U, imgUV[0], Strength, img, MbQAddr, MbQ->DFAlphaC0Offset, MbQ->DFBetaOffset, dir, edge << 2, p->size_x, p) ;
  210.                 EdgeLoopLuma(PLANE_V, imgUV[1], Strength, img, MbQAddr, MbQ->DFAlphaC0Offset, MbQ->DFBetaOffset, dir, edge << 2, p->size_x, p) ;
  211.               }
  212.             }
  213.             if (active_sps->chroma_format_idc==YUV420 || active_sps->chroma_format_idc==YUV422) 
  214.             {
  215.               if( (imgUV != NULL) && (edge_cr >= 0))
  216.               {
  217.                 EdgeLoopChroma( imgUV[0], Strength, img, MbQAddr, MbQ->DFAlphaC0Offset, MbQ->DFBetaOffset, dir, MB_BLOCK_SIZE, p->size_x_cr, 0, p) ;
  218.                 EdgeLoopChroma( imgUV[1], Strength, img, MbQAddr, MbQ->DFAlphaC0Offset, MbQ->DFBetaOffset, dir, MB_BLOCK_SIZE, p->size_x_cr, 1, p) ;
  219.               }
  220.             }
  221.           }
  222.           img->DeblockCall = 1;
  223.         }
  224.       }
  225.     }//end edge
  226.   }//end loop dir
  227.   
  228.   img->DeblockCall = 0;
  229. }
  230.   /*!
  231.  *********************************************************************************************
  232.  * brief
  233.  *    returns a buffer of 16 Strength values for one stripe in a mb (for different Frame or Field types)
  234.  *********************************************************************************************
  235.  */
  236. #define ANY_INTRA (MbP->mb_type==I4MB||MbP->mb_type==I8MB||MbP->mb_type==I16MB||MbP->mb_type==IPCM||MbQ->mb_type==I4MB||MbQ->mb_type==I8MB||MbQ->mb_type==I16MB||MbQ->mb_type==IPCM)
  237. void GetStrengthNormal(byte Strength[MB_BLOCK_SIZE], ImageParameters *img, int MbQAddr, int dir, int edge, int mvlimit, StorablePicture *p)
  238. {
  239.   static int64  ref_p0,ref_p1,ref_q0,ref_q1;
  240.   static int    blkP, blkQ, idx;
  241.   static int    blk_x, blk_x2, blk_y, blk_y2 ;  
  242.   static int    xQ, yQ;
  243.   static int    mb_x, mb_y;  
  244.   static PixelPos pixP, pixMB;
  245.   static byte StrValue;
  246.   if ((p->slice_type==SP_SLICE)||(p->slice_type==SI_SLICE) )
  247.   { 
  248.     // Set strength to either 3 or 4 regardless of pixel position
  249.     StrValue = (edge == 0 && (((p->structure==FRAME)) || ((p->structure != FRAME) && !dir))) ? 4 : 3;
  250.     memset(&Strength[0], (byte) StrValue, MB_BLOCK_SIZE * sizeof(byte));
  251.   }
  252.   else
  253.   {    
  254.     xQ = dir ? 0 : edge - 1;
  255.     yQ = dir ? (edge < 16 ? edge - 1: 0) : 0;
  256.     MbQ = &(img->mb_data[MbQAddr]);
  257.     getNeighbour(MbQ, xQ, yQ, img->mb_size[IS_LUMA], &pixMB);
  258.     pixP = pixMB;
  259.     MbP = &(img->mb_data[pixP.mb_addr]);
  260.     if (!ANY_INTRA)
  261.     {
  262.       list0_refPicIdArr = p->motion.ref_pic_id[LIST_0];
  263.       list1_refPicIdArr = p->motion.ref_pic_id[LIST_1];
  264.       list0_mv = p->motion.mv[LIST_0];
  265.       list1_mv = p->motion.mv[LIST_1];
  266.       list0_refIdxArr = p->motion.ref_idx[LIST_0];
  267.       list1_refIdxArr = p->motion.ref_idx[LIST_1];
  268.       get_mb_block_pos (MbQAddr, &mb_x, &mb_y);
  269.       mb_x <<= 2;
  270.       mb_y <<= 2;
  271.       yQ += dir;
  272.       xQ += (1 - dir);
  273.       for( idx = 0 ; idx < MB_BLOCK_SIZE ; idx += BLOCK_SIZE )
  274.       {
  275.         if (dir)
  276.         {
  277.           xQ = idx;
  278.           pixP.x = pixMB.x + idx;
  279.           pixP.pos_x = pixMB.pos_x + idx;
  280.         }
  281.         else
  282.         {
  283.           yQ = idx;
  284.           pixP.y = pixMB.y + idx;
  285.           pixP.pos_y = pixMB.pos_y + idx;
  286.         }
  287.         blkQ = ((yQ >> 2) << 2) + (xQ >> 2);
  288.         blkP = ((pixP.y >> 2) << 2) + (pixP.x >> 2);
  289.         if( ((MbQ->cbp_blk & ((int64)1 << blkQ )) != 0) || ((MbP->cbp_blk & ((int64)1 << blkP)) != 0) )
  290.           StrValue = 2;
  291.         else
  292.         {
  293.           // if no coefs, but vector difference >= 1 set Strength=1
  294.           // if this is a mixed mode edge then one set of reference pictures will be frame and the
  295.           // other will be field          
  296.           blk_y  = mb_y + (blkQ >> 2);
  297.           blk_x  = mb_x + (blkQ  & 3);
  298.           blk_y2 = pixP.pos_y >> 2;
  299.           blk_x2 = pixP.pos_x >> 2;
  300.           ref_p0 = list0_refIdxArr[blk_y ][blk_x ]< 0 ? INT64_MIN : list0_refPicIdArr[blk_y ][blk_x ];
  301.           ref_q0 = list0_refIdxArr[blk_y2][blk_x2]< 0 ? INT64_MIN : list0_refPicIdArr[blk_y2][blk_x2];
  302.           ref_p1 = list1_refIdxArr[blk_y ][blk_x ]< 0 ? INT64_MIN : list1_refPicIdArr[blk_y ][blk_x ];
  303.           ref_q1 = list1_refIdxArr[blk_y2][blk_x2]< 0 ? INT64_MIN : list1_refPicIdArr[blk_y2][blk_x2];
  304.           if ( ((ref_p0==ref_q0) && (ref_p1==ref_q1)) || ((ref_p0==ref_q1) && (ref_p1==ref_q0)))
  305.           {
  306.             // L0 and L1 reference pictures of p0 are different; q0 as well
  307.             if (ref_p0 != ref_p1)
  308.             {
  309.               // compare MV for the same reference picture
  310.               if (ref_p0 == ref_q0)
  311.               {
  312.                 if (ref_p0 == INT64_MIN)
  313.                 {
  314.                   StrValue =  (byte) (
  315.                     (iabs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  316.                     (iabs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit));
  317.                 }
  318.                 else if (ref_p1 == INT64_MIN)
  319.                 {
  320.                   StrValue =  (byte) (
  321.                     (iabs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  322.                     (iabs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit));
  323.                 }
  324.                 else
  325.                 {
  326.                   StrValue =  (byte) (
  327.                     (iabs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  328.                     (iabs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit) |
  329.                     (iabs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  330.                     (iabs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit));
  331.                 }
  332.               }
  333.               else
  334.               {
  335.                 StrValue =  (byte) ( 
  336.                   (iabs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  337.                   (iabs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit) |
  338.                   (iabs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  339.                   (iabs( list1_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit));
  340.               }
  341.             }
  342.             else
  343.             { // L0 and L1 reference pictures of p0 are the same; q0 as well
  344.               StrValue = (byte) (
  345.                 ((iabs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  346.                 (iabs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit ) |
  347.                 (iabs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  348.                 (iabs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit))
  349.                 &&
  350.                 ((iabs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  351.                 (iabs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit) |
  352.                 (iabs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  353.                 (iabs( list1_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit)));
  354.             }
  355.           }
  356.           else
  357.           {
  358.             StrValue = 1;
  359.           }                  
  360.         }
  361.         memset(&Strength[idx], (byte) StrValue, BLOCK_SIZE * sizeof(byte));
  362.       }
  363.     }
  364.     else
  365.     {
  366.       // Start with Strength=3. or Strength=4 for Mb-edge
  367.       StrValue = (edge == 0 && ((((p->structure==FRAME))) || ((p->structure != FRAME) && !dir))) ? 4 : 3;
  368.       memset(&Strength[0], (byte) StrValue, MB_BLOCK_SIZE * sizeof(byte));
  369.     }      
  370.   }
  371. }
  372. /*!
  373.  *********************************************************************************************
  374.  * brief
  375.  *    returns a buffer of 16 Strength values for one stripe in a mb (for MBAFF)
  376.  *********************************************************************************************
  377.  */
  378. void GetStrengthMBAff(byte Strength[16], ImageParameters *img, int MbQAddr, int dir, int edge, int mvlimit, StorablePicture *p)
  379. {
  380.   int    blkP, blkQ, idx;
  381.   int    blk_x, blk_x2, blk_y, blk_y2 ;
  382.   int64    ref_p0,ref_p1,ref_q0,ref_q1;
  383.   int      xQ, yQ;
  384.   int      mb_x, mb_y;
  385.   PixelPos pixP;
  386.   int dir_m1 = (1 - dir);
  387.   MbQ = &(img->mb_data[MbQAddr]);
  388.   list0_mv = p->motion.mv[LIST_0];
  389.   list1_mv = p->motion.mv[LIST_1];
  390.   list0_refIdxArr = p->motion.ref_idx[LIST_0];
  391.   list1_refIdxArr = p->motion.ref_idx[LIST_1];
  392.   list0_refPicIdArr = p->motion.ref_pic_id[LIST_0];
  393.   list1_refPicIdArr = p->motion.ref_pic_id[LIST_1];
  394.   for( idx=0 ; idx<16 ; idx++ )
  395.   {
  396.     xQ = dir ? idx : edge;
  397.     yQ = dir ? (edge < MB_BLOCK_SIZE ? edge : 1) : idx;
  398.     getNeighbour(MbQ, xQ - dir_m1, yQ - dir, img->mb_size[IS_LUMA], &pixP);
  399.     blkQ = ((yQ >> 2) << 2) + (xQ >> 2);
  400.     blkP = ((pixP.y >> 2)<<2) + (pixP.x >> 2);
  401.     MbP = &(img->mb_data[pixP.mb_addr]);
  402.     mixedModeEdgeFlag = (byte) (MbQ->mb_field != MbP->mb_field);   
  403.     if ((p->slice_type==SP_SLICE)||(p->slice_type==SI_SLICE) )
  404.     {
  405.       Strength[idx] = (edge == 0 && (((!p->MbaffFrameFlag && (p->structure==FRAME)) ||
  406.       (p->MbaffFrameFlag && !MbP->mb_field && !MbQ->mb_field)) ||
  407.       ((p->MbaffFrameFlag || (p->structure != FRAME)) && !dir))) ? 4 : 3;
  408.     }
  409.     else
  410.     {
  411.       // Start with Strength=3. or Strength=4 for Mb-edge
  412.       Strength[idx] = (edge == 0 && (((!p->MbaffFrameFlag && (p->structure==FRAME)) ||
  413.         (p->MbaffFrameFlag && !MbP->mb_field && !MbQ->mb_field)) ||
  414.         ((p->MbaffFrameFlag || (p->structure!=FRAME)) && !dir))) ? 4 : 3;
  415.       if(  !(MbP->mb_type==I4MB || MbP->mb_type==I16MB || MbP->mb_type==I8MB || MbP->mb_type==IPCM)
  416.         && !(MbQ->mb_type==I4MB || MbQ->mb_type==I16MB || MbQ->mb_type==I8MB || MbQ->mb_type==IPCM) )
  417.       {
  418.         if( ((MbQ->cbp_blk &  ((int64)1 << blkQ )) != 0) || ((MbP->cbp_blk &  ((int64)1 << blkP)) != 0) )
  419.           Strength[idx] = 2 ;
  420.         else
  421.         {
  422.           // if no coefs, but vector difference >= 1 set Strength=1
  423.           // if this is a mixed mode edge then one set of reference pictures will be frame and the
  424.           // other will be field
  425.           if (mixedModeEdgeFlag)
  426.           {
  427.             (Strength[idx] = 1);
  428.           }
  429.           else
  430.           {
  431.             get_mb_block_pos (MbQAddr, &mb_x, &mb_y);
  432.             blk_y  = (mb_y<<2) + (blkQ >> 2) ;
  433.             blk_x  = (mb_x<<2) + (blkQ  & 3) ;
  434.             blk_y2 = pixP.pos_y >> 2;
  435.             blk_x2 = pixP.pos_x >> 2;
  436.             {
  437.               ref_p0 = list0_refIdxArr[blk_y ][blk_x ] < 0 ? INT64_MIN : list0_refPicIdArr[blk_y ][blk_x];
  438.               ref_q0 = list0_refIdxArr[blk_y2][blk_x2] < 0 ? INT64_MIN : list0_refPicIdArr[blk_y2][blk_x2];
  439.               ref_p1 = list1_refIdxArr[blk_y ][blk_x ] < 0 ? INT64_MIN : list1_refPicIdArr[blk_y ][blk_x];
  440.               ref_q1 = list1_refIdxArr[blk_y2][blk_x2]<0 ? INT64_MIN : list1_refPicIdArr[blk_y2][blk_x2];
  441.               if ( ((ref_p0==ref_q0) && (ref_p1==ref_q1)) ||
  442.                 ((ref_p0==ref_q1) && (ref_p1==ref_q0)))
  443.               {
  444.                 Strength[idx]=0;
  445.                 // L0 and L1 reference pictures of p0 are different; q0 as well
  446.                 if (ref_p0 != ref_p1)
  447.                 {
  448.                   // compare MV for the same reference picture
  449.                   if (ref_p0==ref_q0)
  450.                   {
  451.                     Strength[idx] =  (byte) (
  452.                       (iabs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  453.                       (iabs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit) |
  454.                       (iabs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  455.                       (iabs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit));
  456.                   }
  457.                   else
  458.                   {
  459.                     Strength[idx] =  (byte) (
  460.                       (iabs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  461.                       (iabs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit) |
  462.                       (iabs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  463.                       (iabs( list1_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit));
  464.                   }
  465.                 }
  466.                 else
  467.                 { // L0 and L1 reference pictures of p0 are the same; q0 as well
  468.                   Strength[idx] = (byte) (
  469.                     ((iabs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  470.                     (iabs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit ) |
  471.                     (iabs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  472.                     (iabs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit))
  473.                     &&
  474.                     ((iabs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  475.                     (iabs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit) |
  476.                     (iabs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  477.                     (iabs( list1_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit)));
  478.                 }
  479.               }
  480.               else
  481.               {
  482.                 Strength[idx] = 1;
  483.               }
  484.             }
  485.           }
  486.         }
  487.       }
  488.     }
  489.   }
  490. }
  491. /*!
  492.  *****************************************************************************************
  493.  * brief
  494.  *    Filters 16 pel block edge of Frame or Field coded MBs 
  495.  *****************************************************************************************
  496.  */
  497. void EdgeLoopLumaNormal(ColorPlane pl, imgpel** Img, byte Strength[16], ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset,
  498.               int dir, int edge, int width, StorablePicture *p)
  499. {
  500.   static imgpel   L2, L1, L0, R0, R1, R2, L3, R3;
  501.   static PixelPos pixP, pixQ, pixMB1, pixMB2;
  502.   static int      C0, tc0, dif, RL0;
  503.   static int      pel, ap, aq, Strng;
  504.   static int      Alpha, Beta, small_gap;
  505.   static int      indexA, indexB;
  506.   static int      QP;
  507.   static const byte* ClipTab;
  508.   static int incQ, incP;
  509.   int      xQ = dir ? 0 : edge - 1;
  510.   int      yQ = dir ? (edge < MB_BLOCK_SIZE ? edge - 1: 0) : 0; 
  511.   MbQ = &(img->mb_data[MbQAddr]);
  512.   getNeighbour(MbQ, xQ, yQ, img->mb_size[IS_LUMA], &pixMB1); 
  513.   if (pixMB1.available || (MbQ->DFDisableIdc== 0))
  514.   {      
  515.     int  bitdepth_scale   = pl? img->bitdepth_scale[IS_CHROMA] : img->bitdepth_scale[IS_LUMA];
  516.     int  max_imgpel_value = img->max_imgpel_value_comp[pl];
  517.     pixP = pixMB1;
  518.     MbP  = &(img->mb_data[pixP.mb_addr]);
  519.     incQ = dir ? width : 1;
  520.     incP = incQ;
  521.     yQ += dir;
  522.     xQ += (1 - dir);
  523.     getNeighbour(MbQ, xQ, yQ, img->mb_size[IS_LUMA], &pixMB2);
  524.     pixQ = pixMB2;
  525.     // Average QP of the two blocks
  526.     QP = pl? ((MbP->qpc[pl-1] + MbQ->qpc[pl-1] + 1) >> 1) : (MbP->qp + MbQ->qp + 1) >> 1;
  527.     indexA = iClip3(0, MAX_QP, QP + AlphaC0Offset);
  528.     indexB = iClip3(0, MAX_QP, QP + BetaOffset);
  529.     Alpha   = ALPHA_TABLE[indexA] * bitdepth_scale;
  530.     Beta    = BETA_TABLE [indexB] * bitdepth_scale;
  531.     ClipTab = CLIP_TAB[indexA];
  532.     for( pel = 0 ; pel < MB_BLOCK_SIZE ; pel++ )
  533.     {
  534.       if( (Strng = Strength[pel]) != 0)
  535.       {
  536.         if (dir)
  537.         {
  538.           xQ         = pel;
  539.           pixP.x     = pixMB1.x + pel;
  540.           pixP.pos_x = pixMB1.pos_x + pel;
  541.           pixQ.x     = pixMB2.x + pel;
  542.           pixQ.pos_x = pixMB2.pos_x + pel;
  543.         }
  544.         else
  545.         {
  546.           yQ         = pel;
  547.           pixP.y     = pixMB1.y + pel;
  548.           pixP.pos_y = pixMB1.pos_y + pel;
  549.           pixQ.y     = pixMB2.y + pel;
  550.           pixQ.pos_y = pixMB2.pos_y + pel;
  551.         }
  552.         SrcPtrQ = &(Img[pixQ.pos_y][pixQ.pos_x]);
  553.         SrcPtrP = &(Img[pixP.pos_y][pixP.pos_x]);
  554.         L3 = *(SrcPtrP - incP * 3);
  555.         L2 = *(SrcPtrP - incP * 2);
  556.         L1 = *(SrcPtrP - incP);
  557.         L0 = *SrcPtrP;
  558.         R0 = *SrcPtrQ;
  559.         R1 = *(SrcPtrQ + incQ);
  560.         R2 = *(SrcPtrQ + incQ * 2);
  561.         R3 = *(SrcPtrQ + incQ * 3);
  562.         if( iabs( R0 - L0 ) < Alpha )
  563.         {
  564.           if ((iabs( R0 - R1) < Beta)  && (iabs(L0 - L1)  < Beta))
  565.           {
  566.             if(Strng == 4 )    // INTRA strong filtering
  567.             {
  568.               RL0 = L0 + R0;
  569.               small_gap = (iabs( R0 - L0 ) < ((Alpha >> 2) + 2));
  570.               aq  = ( iabs( R0 - R2) < Beta ) & small_gap;
  571.               ap  = ( iabs( L0 - L2) < Beta ) & small_gap;
  572.               if (ap)
  573.               {
  574.                 *(SrcPtrP - incP*2) = (imgpel) ((((L3 + L2) <<1) + L2 + L1 + RL0 + 4) >> 3);
  575.                 *(SrcPtrP - incP)   = (imgpel)  (( L2 + L1 + RL0 + 2) >> 2);
  576.                 *SrcPtrP            = (imgpel)  (( R1 + ((L1 + RL0) << 1) +  L2 + 4) >> 3);
  577.               }
  578.               else
  579.               {
  580.                 *SrcPtrP = (imgpel) (((L1 << 1) + L0 + R1 + 2) >> 2) ;                
  581.               }
  582.               if (aq)
  583.               {
  584.                 *SrcPtrQ              = (imgpel) (( L1 + ((R1 + RL0) << 1) +  R2 + 4) >> 3);
  585.                 *(SrcPtrQ + incQ    ) = (imgpel) (( R2 + R0 + L0 + R1 + 2) >> 2);
  586.                 *(SrcPtrQ + incQ * 2) = (imgpel) ((((R3 + R2) <<1) + R2 + R1 + RL0 + 4) >> 3);
  587.               }
  588.               else
  589.               {
  590.                 *SrcPtrQ = (imgpel) (((R1 << 1) + R0 + L1 + 2) >> 2);
  591.               }
  592.             }
  593.             else   // normal filtering
  594.             {              
  595.               RL0 = (L0 + R0 + 1) >> 1;
  596.               aq  = (iabs(R0 - R2) < Beta);
  597.               ap  = (iabs(L0 - L2) < Beta);
  598.               C0  = ClipTab[ Strng ] * bitdepth_scale;
  599.               tc0  = (C0 + ap + aq) ;
  600.               dif = iClip3( -tc0, tc0, (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3 );
  601.               if( ap )
  602.                 *(SrcPtrP - incP) += iClip3( -C0,  C0, (L2 + RL0 - (L1<<1)) >> 1 );
  603.               *SrcPtrP = (imgpel) iClip1(max_imgpel_value, L0 + dif);
  604.               *SrcPtrQ = (imgpel) iClip1(max_imgpel_value, R0 - dif);
  605.               if( aq  )
  606.                 *(SrcPtrQ + incQ) += iClip3( -C0,  C0, (R2 + RL0 - (R1<<1)) >> 1 );
  607.             }            
  608.           }
  609.         }
  610.       }
  611.     }
  612.   }
  613. }
  614. /*!
  615.  *****************************************************************************************
  616.  * brief
  617.  *    Filters 16 pel block edge of Super MB Frame coded MBs
  618.  *****************************************************************************************
  619.  */
  620. void EdgeLoopLumaMBAff(ColorPlane pl, imgpel** Img, byte Strength[16],ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset,
  621.               int dir, int edge, int width, StorablePicture *p)
  622. {
  623.   int      pel, ap = 0, aq = 0, Strng ;
  624.   int      incP, incQ;
  625.   int      C0, tc0, dif;
  626.   imgpel   L2 = 0, L1, L0, R0, R1, R2 = 0, L3, R3;
  627.   int      RL0;
  628.   int      Alpha = 0, Beta = 0 ;
  629.   const byte* ClipTab = NULL;
  630.   int      small_gap;
  631.   int      indexA, indexB;
  632.   int      PelNum = pl? pelnum_cr[dir][p->chroma_format_idc] : MB_BLOCK_SIZE;
  633.   imgpel   *SrcPtrP, *SrcPtrQ;
  634.   int      QP;
  635.   int      xQ, yQ;
  636.   PixelPos pixP, pixQ;
  637.   int      dir_m1 = (1 - dir);
  638.   int      bitdepth_scale = pl? img->bitdepth_scale[IS_CHROMA] : img->bitdepth_scale[IS_LUMA];
  639.   int      max_imgpel_value = img->max_imgpel_value_comp[pl];
  640.   MbQ = &(img->mb_data[MbQAddr]);
  641.   
  642.   for( pel = 0 ; pel < PelNum ; pel++ )
  643.   {
  644.     xQ = dir ? pel : edge;
  645.     yQ = dir ? (edge < 16 ? edge : 1) : pel;
  646.     getNeighbour(MbQ, xQ - (dir_m1), yQ - dir, img->mb_size[IS_LUMA], &pixP);     
  647.     if (pixP.available || (MbQ->DFDisableIdc== 0))
  648.     {
  649.       if( (Strng = Strength[pel]) != 0)
  650.       {
  651.         getNeighbour(MbQ, xQ, yQ, img->mb_size[IS_LUMA], &pixQ);
  652.         MbP = &(img->mb_data[pixP.mb_addr]);
  653.         fieldModeFilteringFlag = (byte) (MbQ->mb_field || MbP->mb_field);
  654.         incQ    = dir ? ((fieldModeFilteringFlag && !MbQ->mb_field) ? 2 * width : width) : 1;
  655.         incP    = dir ? ((fieldModeFilteringFlag && !MbP->mb_field) ? 2 * width : width) : 1;
  656.         SrcPtrQ = &(Img[pixQ.pos_y][pixQ.pos_x]);
  657.         SrcPtrP = &(Img[pixP.pos_y][pixP.pos_x]);
  658.         // Average QP of the two blocks
  659.         QP = pl? ((MbP->qpc[pl-1] + MbQ->qpc[pl-1] + 1) >> 1) : (MbP->qp + MbQ->qp + 1) >> 1;
  660.         indexA = iClip3(0, MAX_QP, QP + AlphaC0Offset);
  661.         indexB = iClip3(0, MAX_QP, QP + BetaOffset);
  662.         Alpha   = ALPHA_TABLE[indexA] * bitdepth_scale;
  663.         Beta    = BETA_TABLE [indexB] * bitdepth_scale;
  664.         ClipTab = CLIP_TAB[indexA];
  665.         L3  = SrcPtrP[-incP*3];
  666.         L2  = SrcPtrP[-incP*2];
  667.         L1  = SrcPtrP[-incP];
  668.         L0  = SrcPtrP[0] ;
  669.         R0  = SrcPtrQ[0] ;      
  670.         R1  = SrcPtrQ[ incQ];      
  671.         R2  = SrcPtrQ[ incQ*2];
  672.         R3  = SrcPtrQ[ incQ*3];
  673.         if( iabs( R0 - L0 ) < Alpha )
  674.         {          
  675.           if ((iabs( R0 - R1) < Beta )   && (iabs(L0 - L1) < Beta ))
  676.           {
  677.             if(Strng == 4 )    // INTRA strong filtering
  678.             {
  679.               RL0 = L0 + R0;
  680.               small_gap = (iabs( R0 - L0 ) < ((Alpha >> 2) + 2));
  681.               aq  = ( iabs( R0 - R2) < Beta ) & small_gap;               
  682.               ap  = ( iabs( L0 - L2) < Beta ) & small_gap;
  683.               if (ap)
  684.               {
  685.                 SrcPtrP[-incP * 2] = (imgpel) ((((L3 + L2) << 1) + L2 + L1 + RL0 + 4) >> 3);
  686.                 SrcPtrP[-incP    ] = (imgpel) (( L2 + L1 + L0 + R0 + 2) >> 2);
  687.                 SrcPtrP[    0    ] = (imgpel) (( R1 + ((L1 + RL0) << 1) +  L2 + 4) >> 3);
  688.               }
  689.               else
  690.               {
  691.                 SrcPtrP[     0     ] = (imgpel) (((L1 << 1) + L0 + R1 + 2) >> 2) ;
  692.               }
  693.               if (aq)
  694.               {
  695.                 SrcPtrQ[    0     ] = (imgpel) (( L1 + ((R1 + RL0) << 1) +  R2 + 4) >> 3);
  696.                 SrcPtrQ[ incQ     ] = (imgpel) (( R2 + R0 + R1 + L0 + 2) >> 2);
  697.                 SrcPtrQ[ incQ * 2 ] = (imgpel) ((((R3 + R2) << 1) + R2 + R1 + RL0 + 4) >> 3);
  698.               }
  699.               else
  700.               {
  701.                 SrcPtrQ[    0     ] = (imgpel) (((R1 << 1) + R0 + L1 + 2) >> 2);
  702.               }
  703.             }
  704.             else   // normal filtering
  705.             {              
  706.               RL0 = (L0 + R0 + 1) >> 1;
  707.               aq  = (iabs( R0 - R2) < Beta);
  708.               ap  = (iabs( L0 - L2) < Beta);
  709.               C0  = ClipTab[ Strng ] * bitdepth_scale;
  710.               tc0  = (C0 + ap + aq) ;
  711.               dif = iClip3( -tc0, tc0, (((R0 - L0) << 2) + (L1 - R1) + 4) >> 3) ;
  712.               if( ap )
  713.                 SrcPtrP[-incP] += iClip3( -C0,  C0, ( L2 + RL0 - (L1 << 1)) >> 1 ) ;
  714.               *SrcPtrP  = (imgpel) iClip1(max_imgpel_value, L0 + dif);
  715.               *SrcPtrQ  = (imgpel) iClip1(max_imgpel_value, R0 - dif);
  716.               if( aq  )
  717.                 SrcPtrQ[ incQ] += iClip3( -C0,  C0, ( R2 + RL0 - (R1 << 1)) >> 1 ) ;
  718.             }            
  719.           }
  720.         }
  721.       }
  722.     }
  723.   }
  724. }
  725. /*!
  726.  *****************************************************************************************
  727.  * brief
  728.  *    Filters chroma block edge for Frame or Field coded pictures
  729.  *****************************************************************************************
  730.  */
  731. void EdgeLoopChromaNormal(imgpel** Img, byte Strength[16],ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset,
  732.               int dir, int edge, int width, int uv, StorablePicture *p)
  733. {
  734.   static int      pel, Strng ;
  735.   static int      incP, incQ;
  736.   static int      tc0, dif;
  737.   static imgpel   L1, L0, R0, R1;
  738.   static int      Alpha, Beta;
  739.   static const byte* ClipTab;
  740.   static int      indexA, indexB;
  741.   int      PelNum = pelnum_cr[dir][p->chroma_format_idc];
  742.   int      StrengthIdx;
  743.   static imgpel   *SrcPtrP, *SrcPtrQ;
  744.   static PixelPos pixP, pixQ, pixMB1, pixMB2;
  745.   static int      QP;
  746.   
  747.   int      bitdepth_scale = img->bitdepth_scale[IS_CHROMA];
  748.   int      max_imgpel_value = img->max_imgpel_value_comp[uv + 1];
  749.   int xQ = dir ? 0 : edge - 1;
  750.   int yQ = dir ? (edge < 16 ? edge - 1: 0) : 0;
  751.   MbQ = &(img->mb_data[MbQAddr]);
  752.   getNeighbour(MbQ, xQ, yQ, img->mb_size[IS_CHROMA], &pixMB1);
  753.   if (pixMB1.available || (MbQ->DFDisableIdc == 0))
  754.   {
  755.     pixP = pixMB1;
  756.     MbP = &(img->mb_data[pixP.mb_addr]);
  757.     yQ += dir;
  758.     xQ += (1 - dir);
  759.     incQ = dir ? width : 1;
  760.     incP = incQ;
  761.     getNeighbour(MbQ, xQ, yQ, img->mb_size[IS_CHROMA], &pixMB2);
  762.     pixQ = pixMB2;
  763.     // Average QP of the two blocks
  764.     QP = (MbP->qpc[uv] + MbQ->qpc[uv] + 1) >> 1;
  765.     indexA = iClip3(0, MAX_QP, QP + AlphaC0Offset);
  766.     indexB = iClip3(0, MAX_QP, QP + BetaOffset);
  767.     Alpha   = ALPHA_TABLE[indexA] * bitdepth_scale;
  768.     Beta    = BETA_TABLE [indexB] * bitdepth_scale;
  769.     ClipTab = CLIP_TAB[indexA];
  770.     for( pel = 0 ; pel < PelNum ; pel++ )
  771.     {
  772.       StrengthIdx = (PelNum == 8) ? (((pel >> 1) << 2) + (pel & 0x01)) : pel;
  773.       if( (Strng = Strength[StrengthIdx]) != 0)
  774.       {
  775.         if (dir)
  776.         {
  777.           xQ         = pel;
  778.           pixP.x     = pixMB1.x + pel;
  779.           pixP.pos_x = pixMB1.pos_x + pel;
  780.           pixQ.x     = pixMB2.x + pel;
  781.           pixQ.pos_x = pixMB2.pos_x + pel;
  782.         }
  783.         else
  784.         {
  785.           yQ         = pel;
  786.           pixP.y     = pixMB1.y + pel;
  787.           pixP.pos_y = pixMB1.pos_y + pel;
  788.           pixQ.y     = pixMB2.y + pel;
  789.           pixQ.pos_y = pixMB2.pos_y + pel;
  790.         }
  791.         SrcPtrP = &(Img[pixP.pos_y][pixP.pos_x]);
  792.         L1  = *(SrcPtrP - incP);
  793.         L0  = *SrcPtrP;
  794.         SrcPtrQ = &(Img[pixQ.pos_y][pixQ.pos_x]);
  795.         R0  = *SrcPtrQ;
  796.         R1  = *(SrcPtrQ + incQ);
  797.         if (( iabs( R0 - L0 ) < Alpha ) && ( iabs(R0 - R1) < Beta )  && ( iabs(L0 - L1) < Beta )  )
  798.         {
  799.           if( Strng == 4 )    // INTRA strong filtering
  800.           {
  801.             *SrcPtrP = (imgpel) ( ((L1 << 1) + L0 + R1 + 2) >> 2 );
  802.             *SrcPtrQ = (imgpel) ( ((R1 << 1) + R0 + L1 + 2) >> 2 );              
  803.           }
  804.           else
  805.           {
  806.             tc0  = ClipTab[ Strng ] * bitdepth_scale + 1;
  807.             dif = iClip3( -tc0, tc0, ( ((R0 - L0) << 2) + (L1 - R1) + 4) >> 3 );
  808.             *SrcPtrP = (imgpel) iClip1 ( max_imgpel_value, L0 + dif) ;
  809.             *SrcPtrQ = (imgpel) iClip1 ( max_imgpel_value, R0 - dif) ;
  810.           }
  811.         }
  812.       }
  813.     }
  814.   }
  815. }
  816. /*!
  817. *****************************************************************************************
  818. * brief
  819. *    Filters chroma block edge for MBAFF types
  820. *****************************************************************************************
  821.  */
  822. void EdgeLoopChromaMBAff(imgpel** Img, byte Strength[16],ImageParameters *img, int MbQAddr, int AlphaC0Offset, int BetaOffset,
  823.                          int dir, int edge, int width, int uv, StorablePicture *p)
  824. {
  825.   int      pel, Strng ;
  826.   int      incP, incQ;
  827.   int      C0, tc0, dif;
  828.   imgpel   L1, L0, R0, R1;
  829.   int      Alpha = 0, Beta = 0;
  830.   const byte* ClipTab = NULL;
  831.   int      indexA, indexB;
  832.   int      PelNum = pelnum_cr[dir][p->chroma_format_idc];
  833.   int      StrengthIdx;
  834.   imgpel   *SrcPtrP, *SrcPtrQ;
  835.   int      QP;
  836.   int      xQ, yQ;
  837.   PixelPos pixP, pixQ;
  838.   int      dir_m1 = 1 - dir;
  839.   int      bitdepth_scale = img->bitdepth_scale[IS_CHROMA];
  840.   int      max_imgpel_value = img->max_imgpel_value_comp[uv + 1];
  841.   MbQ = &(img->mb_data[MbQAddr]);
  842.   for( pel = 0 ; pel < PelNum ; pel++ )
  843.   {
  844.     xQ = dir ? pel : edge;
  845.     yQ = dir ? (edge < 16? edge : 1) : pel;
  846.     getNeighbour(MbQ, xQ, yQ, img->mb_size[IS_CHROMA], &pixQ);
  847.     getNeighbour(MbQ, xQ - (dir_m1), yQ - dir, img->mb_size[IS_CHROMA], &pixP);    
  848.     MbP = &(img->mb_data[pixP.mb_addr]);    
  849.     StrengthIdx = (PelNum == 8) ? ((MbQ->mb_field && !MbP->mb_field) ? pel << 1 :((pel >> 1) << 2) + (pel & 0x01)) : pel;
  850.     if (pixP.available || (MbQ->DFDisableIdc == 0))
  851.     {
  852.       if( (Strng = Strength[StrengthIdx]) != 0)
  853.       {
  854.         fieldModeFilteringFlag = (byte) (MbQ->mb_field || MbP->mb_field);
  855.         incQ = dir ? ((fieldModeFilteringFlag && !MbQ->mb_field) ? 2 * width : width) : 1;
  856.         incP = dir ? ((fieldModeFilteringFlag && !MbP->mb_field) ? 2 * width : width) : 1;
  857.         SrcPtrQ = &(Img[pixQ.pos_y][pixQ.pos_x]);
  858.         SrcPtrP = &(Img[pixP.pos_y][pixP.pos_x]);
  859.         // Average QP of the two blocks
  860.         QP = (MbP->qpc[uv] + MbQ->qpc[uv] + 1) >> 1;
  861.         indexA = iClip3(0, MAX_QP, QP + AlphaC0Offset);
  862.         indexB = iClip3(0, MAX_QP, QP + BetaOffset);
  863.         Alpha   = ALPHA_TABLE[indexA] * bitdepth_scale;
  864.         Beta    = BETA_TABLE [indexB] * bitdepth_scale;
  865.         ClipTab = CLIP_TAB[indexA];
  866.         L1  = SrcPtrP[-incP];
  867.         L0  = SrcPtrP[0] ;
  868.         R0  = SrcPtrQ[0] ;      
  869.         R1  = SrcPtrQ[ incQ];      
  870.         if( iabs( R0 - L0 ) < Alpha )
  871.         {          
  872.           if( ((iabs( R0 - R1) - Beta )  & (iabs(L0 - L1) - Beta )) < 0  )
  873.           {
  874.             if( Strng == 4 )    // INTRA strong filtering
  875.             {
  876.               SrcPtrQ[0] = (imgpel) ( ((R1 << 1) + R0 + L1 + 2) >> 2 );
  877.               SrcPtrP[0] = (imgpel) ( ((L1 << 1) + L0 + R1 + 2) >> 2 );
  878.             }
  879.             else
  880.             {
  881.               C0  = ClipTab[ Strng ] * bitdepth_scale;
  882.               tc0  = (C0 + 1);
  883.               dif = iClip3( -tc0, tc0, ( ((R0 - L0) << 2) + (L1 - R1) + 4) >> 3 );
  884.               SrcPtrP[0] = (imgpel) iClip1 ( max_imgpel_value, L0 + dif );
  885.               SrcPtrQ[0] = (imgpel) iClip1 ( max_imgpel_value, R0 - dif );
  886.             }
  887.           }
  888.         }
  889.       }
  890.     }
  891.   }
  892. }
  893. int compute_deblock_strength(char **list0_refIdxArr, 
  894.                              char **list1_refIdxArr, 
  895.                              int64 **list0_refPicIdArr, 
  896.                              int64 **list1_refPicIdArr, 
  897.                              short  ***list0_mv,
  898.                              short  ***list1_mv,
  899.                              int blk_y, int blk_x, 
  900.                              int blk_y2, int blk_x2, 
  901.                              int mvlimit)
  902. {
  903.   static int64 ref_p0, ref_q0, ref_p1, ref_q1;
  904.   static byte StrValue;
  905.   ref_p0 = list0_refIdxArr[blk_y] [blk_x] <0 ? INT64_MIN : list0_refPicIdArr[blk_y] [blk_x];
  906.   ref_q0 = list0_refIdxArr[blk_y2][blk_x2]<0 ? INT64_MIN : list0_refPicIdArr[blk_y2][blk_x2];
  907.   ref_p1 = list1_refIdxArr[blk_y] [blk_x] <0 ? INT64_MIN : list1_refPicIdArr[blk_y] [blk_x];
  908.   ref_q1 = list1_refIdxArr[blk_y2][blk_x2]<0 ? INT64_MIN : list1_refPicIdArr[blk_y2][blk_x2];
  909.   if ( ((ref_p0==ref_q0) && (ref_p1==ref_q1)) || ((ref_p0==ref_q1) && (ref_p1==ref_q0)))
  910.   {
  911.     // L0 and L1 reference pictures of p0 are different; q0 as well
  912.     if (ref_p0 != ref_p1)
  913.     {
  914.       // compare MV for the same reference picture
  915.       if (ref_p0 == ref_q0)
  916.       {
  917.         StrValue =  (byte) (
  918.           (iabs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  919.           (iabs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit) |
  920.           (iabs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  921.           (iabs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit));                  
  922.       }
  923.       else
  924.       {
  925.         StrValue =  (byte) (
  926.           (iabs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  927.           (iabs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit) |
  928.           (iabs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  929.           (iabs( list1_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit));
  930.       }
  931.     }
  932.     else
  933.     { // L0 and L1 reference pictures of p0 are the same; q0 as well
  934.       StrValue = (byte) (
  935.         ((iabs( list0_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  936.         (iabs( list0_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit ) |
  937.         (iabs( list1_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  938.         (iabs( list1_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit))
  939.         &&
  940.         ((iabs( list0_mv[blk_y][blk_x][0] - list1_mv[blk_y2][blk_x2][0]) >= 4) |
  941.         (iabs( list0_mv[blk_y][blk_x][1] - list1_mv[blk_y2][blk_x2][1]) >= mvlimit) |
  942.         (iabs( list1_mv[blk_y][blk_x][0] - list0_mv[blk_y2][blk_x2][0]) >= 4) |
  943.         (iabs( list1_mv[blk_y][blk_x][1] - list0_mv[blk_y2][blk_x2][1]) >= mvlimit)));
  944.     }
  945.   }
  946.   else
  947.   {
  948.     StrValue = 1;
  949.   }
  950.  return StrValue;
  951. }