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

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