www.pudn.com > AVS.rar > loopfilter.cpp


/************************************************************************* 
 AVS1-P2视频解码器源码 
 版权所有:联合信源数字音视频技术(北京)有限公司, (c) 2005-2006  
 
 AVS1-P2 Video Decoder Source Code 
 (c) Copyright, NSCC All Rights Reserved, 2005-2006 
 ************************************************************************* 
 Distributed under the terms of the GNU General Public License as 
 published by the Free Software Foundation; either version 2 of the 
 License, or (at your option) any later version. 
 
 This program is distributed in the hope that it will be useful, 
 but WITHOUT ANY WARRANTY; without even the implied warranty of 
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 GNU General Public License for more details. 
 
 You should have received a copy of the GNU General Public License 
 along with this program; if not, write to the Free Software 
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
*************************************************************************/ 
/************************************************************************* 
  文件名称:	loopfilter.cpp 
  描    述: 环路滤波相关的一些函数 
*************************************************************************/ 
/************************************************************************* 
  Revision History 
  data          Modification                                    Author 
  2005-4-6      Created                                          jthou 
 *************************************************************************/ 
 
#include "loopfilter.h" 
 
//  BsH00    BsH01 
//--------------------- 
//|        |          | 
//|BsV00   |BsV01     | 
//|        |          | 
//| BsH10  | BsH11    | 
//--------------------- 
//|        |          | 
//|BsV10   |BsV11     | 
//|        |          | 
//|        |          | 
//--------------------- 
void DeblockVBs2_Luma(AVS_BYTE* pStart, AVS_INT Alpha, AVS_INT Beta, AVS_INT iStride) 
{ 
  AVS_INT i; 
  AVS_BYTE* p = pStart; 
  for(i=0; i<8; i++) 
  { 
    AVS_BYTE p2 = *(p-3); 
    AVS_BYTE p1 = *(p-2); 
    AVS_BYTE p0 = *(p-1); 
     
    AVS_BYTE q0 = *p; 
    AVS_BYTE q1 = *(p+1); 
    AVS_BYTE q2 = *(p+2); 
    if(abs(p0-q0)>2)+2)) 
      { 
        *(p-1) = (p1 + 2*p0 + q0 + 2) >> 2; 
        *(p-2) = (2*p1 + p0 + q0 + 2) >> 2; 
      } 
      else 
      { 
        *(p-1) = (2*p1 + p0 + q0 + 2) >> 2; 
      } 
      if(aq>2)+2)) 
      { 
        *(p  ) = (q1 + 2*q0 + p0 + 2) >> 2; 
        *(p+1) = (2*q1 + q0 + p0 + 2) >> 2; 
      } 
      else 
      { 
        *(p  ) = (2*q1 + q0 + p0 + 2) >> 2; 
      } 
    } 
     
    p += iStride; 
  }  
} 
 
 
void DeblockVBs1_Luma(AVS_BYTE* pStart,AVS_INT C, AVS_INT Alpha, AVS_INT Beta, AVS_INT iStride) 
{ 
  AVS_INT i; 
  AVS_BYTE* p = pStart; 
   
  for(i=0; i<8; i++) 
  { 
    AVS_BYTE p2 = *(p-3); 
    AVS_BYTE p1 = *(p-2); 
    AVS_BYTE p0 = *(p-1); 
     
    AVS_BYTE q0 = *p; 
    AVS_BYTE q1 = *(p+1); 
    AVS_BYTE q2 = *(p+2); 
 
    if(abs(p0-q0)>3)); 
       
      *(p-1) = Clip(p0+delta); 
      *(p  ) = Clip(q0+delta); 
       
      AVS_INT ap = abs(p2-p0); 
      AVS_INT aq = abs(q2-q0); 
       
      if(ap>3))); 
      if(aq>3))); 
    } 
     
    p += iStride; 
  }   
} 
 
void DeblockHBs2_Luma(AVS_BYTE* pStart, AVS_INT Alpha, AVS_INT Beta, AVS_INT iStride) 
{ 
  AVS_INT i; 
  AVS_BYTE* p = pStart; 
  for(i=0; i<8; i++) 
  { 
    AVS_BYTE p2 = *(p-3*iStride); 
    AVS_BYTE p1 = *(p-2*iStride); 
    AVS_BYTE p0 = *(p-iStride); 
     
    AVS_BYTE q0 = *p; 
    AVS_BYTE q1 = *(p+iStride); 
    AVS_BYTE q2 = *(p+2*iStride); 
    if(abs(p0-q0)>2)+2)) 
      { 
        *(p-iStride) = (p1 + 2*p0 + q0 + 2) >> 2; 
        *(p-2*iStride) = (2*p1 + p0 + q0 + 2) >> 2; 
      } 
      else 
      { 
        *(p-iStride) = (2*p1 + p0 + q0 + 2) >> 2; 
      } 
      if(aq>2)+2)) 
      { 
        *(p  ) = (q1 + 2*q0 + p0 + 2) >> 2; 
        *(p+iStride) = (2*q1 + q0 + p0 + 2) >> 2; 
      } 
      else 
      { 
        *(p  ) = (2*q1 + q0 + p0 + 2) >> 2; 
      } 
    } 
    p++; 
  } 
} 
 
void DeblockHBs1_Luma(AVS_BYTE* pStart,AVS_INT C, AVS_INT Alpha, AVS_INT Beta, AVS_INT iStride) 
{ 
  AVS_INT i; 
  AVS_BYTE* p = pStart; 
  for(i=0; i<8; i++) 
  { 
    AVS_BYTE p2 = *(p-3*iStride); 
    AVS_BYTE p1 = *(p-2*iStride); 
    AVS_BYTE p0 = *(p-iStride); 
     
    AVS_BYTE q0 = *p; 
    AVS_BYTE q1 = *(p+iStride); 
    AVS_BYTE q2 = *(p+2*iStride); 
     
    if(abs(p0-q0)>3)); 
       
      *(p-iStride) = Clip(p0+delta); 
      *(p  ) = Clip(q0+delta); 
       
      AVS_INT ap = abs(p2-p0); 
      AVS_INT aq = abs(q2-q0); 
       
      if(ap>3))); 
      if(aq>3))); 
    } 
    p++; 
  } 
} 
 
void DeblockVBs2_Chroma(AVS_BYTE* pStart, AVS_INT Alpha, AVS_INT Beta, AVS_INT iStride) 
{ 
  AVS_INT i; 
  AVS_BYTE* p = pStart; 
   
  for(i=0; i<4; i++) 
  { 
    AVS_BYTE p2 = *(p-3); 
    AVS_BYTE p1 = *(p-2); 
    AVS_BYTE p0 = *(p-1); 
     
    AVS_BYTE q0 = *p; 
    AVS_BYTE q1 = *(p+1); 
    AVS_BYTE q2 = *(p+2); 
    if(abs(p0-q0)>2)+2)) 
      { 
        *(p-1) = (p1 + 2*p0 + q0 + 2) >> 2; 
      } 
      else 
      { 
        *(p-1) = (2*p1 + p0 + q0 + 2) >> 2; 
      } 
      if(aq>2)+2)) 
      { 
        *(p  ) = (q1 + 2*q0 + p0 + 2) >> 2; 
      } 
      else 
      { 
        *(p  ) = (2*q1 + q0 + p0 + 2) >> 2; 
      } 
    } 
     
    p += iStride; 
  } 
} 
 
void DeblockVBs1_Chroma(AVS_BYTE* pStart, AVS_INT Alpha, AVS_INT Beta, AVS_INT C, AVS_INT iStride) 
{ 
  AVS_INT i; 
  AVS_BYTE* p = pStart; 
  for(i=0; i<4; i++) 
  { 
    AVS_BYTE p2 = *(p-3); 
    AVS_BYTE p1 = *(p-2); 
    AVS_BYTE p0 = *(p-1); 
     
    AVS_BYTE q0 = *p; 
    AVS_BYTE q1 = *(p+1); 
    AVS_BYTE q2 = *(p+2); 
 
    if(abs(p0-q0)>3)); 
       
      *(p-1) = Clip(p0+delta); 
      *(p  ) = Clip(q0+delta); 
    }     
     
    p += iStride; 
  } 
} 
 
void DeblockHBs2_Chroma(AVS_BYTE* pStart, AVS_INT Alpha, AVS_INT Beta, AVS_INT iStride) 
{ 
  AVS_INT i; 
  AVS_BYTE* p = pStart; 
  for(i=0; i<4; i++) 
  { 
    AVS_BYTE p2 = *(p-3*iStride); 
    AVS_BYTE p1 = *(p-2*iStride); 
    AVS_BYTE p0 = *(p-iStride); 
     
    AVS_BYTE q0 = *p; 
    AVS_BYTE q1 = *(p+iStride); 
    AVS_BYTE q2 = *(p+2*iStride); 
    if(abs(p0-q0)>2)+2)) 
        *(p-iStride) = (p1 + 2*p0 + q0 + 2) >> 2; 
      else 
        *(p-iStride) = (2*p1 + p0 + q0 + 2) >> 2; 
  
      if(aq>2)+2)) 
        *(p  ) = (q1 + 2*q0 + p0 + 2) >> 2; 
      else 
        *(p  ) = (2*q1 + q0 + p0 + 2) >> 2; 
    }       
    p ++; 
  } 
} 
 
void DeblockHBs1_Chroma(AVS_BYTE* pStart, AVS_INT Alpha, AVS_INT Beta, AVS_INT C, AVS_INT iStride) 
{ 
  AVS_INT i; 
  AVS_BYTE* p = pStart; 
  for(i=0; i<4; i++) 
  { 
    AVS_BYTE p1 = *(p-2*iStride); 
    AVS_BYTE p0 = *(p-iStride); 
     
    AVS_BYTE q0 = *p; 
    AVS_BYTE q1 = *(p+iStride); 
    if(abs(p0-q0)>3)); 
     
      *(p-iStride) = Clip(p0+delta); 
      *(p  ) = Clip(q0+delta); 
    } 
    p++; 
  } 
} 
 
AVS_INT GetStrengthP(AVS_DWORD dwRefIdxP, AVS_DWORD dwRefIdxQ, MOTIONVECTOR* pMvP, MOTIONVECTOR* pMvQ) 
{ 
  if(dwRefIdxP != dwRefIdxQ || 
    abs(pMvP->x - pMvQ->x) >= 4 || 
    abs(pMvP->y - pMvQ->y) >= 4) 
    return 1; 
  else 
    return 0; 
} 
 
AVS_INT GetStrengthB(MOTIONVECTOR* pMvP, MOTIONVECTOR* pMvQ, MOTIONVECTOR* pMvBwP, MOTIONVECTOR* pMvBwQ) 
{ 
  if(abs(pMvP->x - pMvQ->x) >= 4 || 
    abs(pMvP->y - pMvQ->y) >= 4 || 
    abs(pMvBwP->x - pMvBwQ->x) >= 4 || 
    abs(pMvBwP->y - pMvBwQ->y) >= 4) 
    return 1; 
  else 
    return 0; 
} 
/************************************************************************/ 
/* 函数功能:滤波亮度BsV00边                                            */ 
/*         - 位置参见标准文档                                           */ 
/*         - 调用时先判断该边是否在边界处                               */ 
/************************************************************************/ 
void DeblockMb_BsV00_Luma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
  MBINFO* pMbP = &(pMbInfo[dwMbIndex-1]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
 
  AVS_INT QPav = (pMbP->dwMbQp + pMbQ->dwMbQp + 1)/2; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<4; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<4; 
 
  AVS_BYTE* p = pImgData + imgY*iStride + imgX; 
  AVS_INT C = CLIP_TABLE[IndexA]; 
   
  if(Bs == 2) 
    DeblockVBs2_Luma(p, Alpha, Beta, iStride); 
  else if(Bs == 1) 
    DeblockVBs1_Luma(p, C, Alpha, Beta, iStride); 
} 
 
/************************************************************************/ 
/* 函数功能:滤波亮度BsV10边                                            */ 
/*         - 位置参见标准文档                                           */ 
/*         - 调用时先判断该边是否在边界处                               */ 
/************************************************************************/ 
void DeblockMb_BsV10_Luma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
  MBINFO* pMbP = &(pMbInfo[dwMbIndex-1]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
 
  AVS_INT QPav = (pMbP->dwMbQp + pMbQ->dwMbQp + 1)/2; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<4; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<4; 
 
  AVS_BYTE* p = pImgData + (imgY+8)*iStride + imgX; 
  AVS_INT C = CLIP_TABLE[IndexA]; 
   
  if(Bs == 2) 
    DeblockVBs2_Luma(p, Alpha, Beta, iStride); 
  else if(Bs == 1) 
    DeblockVBs1_Luma(p, C, Alpha, Beta, iStride); 
} 
 
/************************************************************************/ 
/* 函数功能:滤波亮度BsV01边                                            */ 
/*         - 位置参见标准文档                                           */ 
/************************************************************************/ 
void DeblockMb_BsV01_Luma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
  MBINFO* pMbP = &(pMbInfo[dwMbIndex]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
  
  AVS_INT QPav =  pMbP->dwMbQp; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<4; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<4; 
 
  AVS_BYTE* p = pImgData + imgY*iStride + (imgX+8); 
 
  AVS_INT C = CLIP_TABLE[IndexA]; 
   
  if(Bs == 2) 
    DeblockVBs2_Luma(p, Alpha, Beta, iStride); 
  else if(Bs == 1) 
    DeblockVBs1_Luma(p, C, Alpha, Beta, iStride); 
 
} 
 
/************************************************************************/ 
/* 函数功能:滤波亮度BsV11边                                            */ 
/*         - 位置参见标准文档                                           */ 
/*         - 调用时先判断该边是否在边界处                               */ 
/************************************************************************/ 
void DeblockMb_BsV11_Luma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
  MBINFO* pMbP = &(pMbInfo[dwMbIndex]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
     
  AVS_INT QPav = pMbP->dwMbQp; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<4; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<4; 
 
  AVS_BYTE* p = pImgData + (imgY+8)*iStride + (imgX+8); 
 
   
  AVS_INT C = CLIP_TABLE[IndexA]; 
   
  if(Bs == 2) 
    DeblockVBs2_Luma(p, Alpha, Beta, iStride); 
  else if(Bs == 1) 
    DeblockVBs1_Luma(p, C, Alpha, Beta, iStride); 
 
} 
 
/************************************************************************/ 
/* 函数功能:滤波亮度BsH00边                                            */ 
/*         - 位置参见标准文档                                           */ 
/*         - 调用时先判断该边是否在边界处                               */ 
/************************************************************************/ 
void DeblockMb_BsH00_Luma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
  MBINFO* pMbP = &(pMbInfo[dwMbIndex-dwMbWidth]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
   
  AVS_INT QPav = (pMbP->dwMbQp + pMbQ->dwMbQp + 1)/2; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<4; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<4; 
 
  AVS_BYTE* p = pImgData + imgY*iStride + imgX; 
  AVS_INT C = CLIP_TABLE[IndexA]; 
 
  if(Bs == 2) 
    DeblockHBs2_Luma(p, Alpha, Beta, iStride); 
  else if(Bs == 1) 
    DeblockHBs1_Luma(p, C, Alpha, Beta, iStride); 
} 
 
/************************************************************************/ 
/* 函数功能:滤波亮度BsH01边                                            */ 
/*         - 位置参见标准文档                                           */ 
/*         - 调用时先判断该边是否在边界处                               */ 
/************************************************************************/ 
void DeblockMb_BsH01_Luma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
  MBINFO* pMbP = &(pMbInfo[dwMbIndex-dwMbWidth]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
   
  AVS_INT QPav = (pMbP->dwMbQp + pMbQ->dwMbQp + 1)/2; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<4; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<4; 
 
  AVS_BYTE* p = pImgData + imgY*iStride + (imgX+8); 
  AVS_INT C = CLIP_TABLE[IndexA]; 
 
  if(Bs == 2) 
    DeblockHBs2_Luma(p, Alpha, Beta, iStride); 
  else if(Bs == 1) 
    DeblockHBs1_Luma(p, C, Alpha, Beta, iStride); 
} 
 
/************************************************************************/ 
/* 函数功能:滤波亮度BsH00边                                            */ 
/*         - 位置参见标准文档                                           */ 
/*         - 调用时先判断该边是否在边界处                               */ 
/************************************************************************/ 
void DeblockMb_BsH10_Luma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
  MBINFO* pMbP = &(pMbInfo[dwMbIndex]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
     
  AVS_INT QPav = pMbP->dwMbQp; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<4; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<4; 
 
  AVS_BYTE* p = pImgData + (imgY+8)*iStride + imgX; 
 
  AVS_INT C = CLIP_TABLE[IndexA]; 
 
  if(Bs == 2) 
    DeblockHBs2_Luma(p, Alpha, Beta, iStride); 
  else if(Bs == 1) 
    DeblockHBs1_Luma(p, C, Alpha, Beta, iStride); 
} 
 
/************************************************************************/ 
/* 函数功能:滤波亮度BsH11边                                            */ 
/*         - 位置参见标准文档                                           */ 
/*         - 调用时先判断该边是否在边界处                               */ 
/************************************************************************/ 
void DeblockMb_BsH11_Luma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
  MBINFO* pMbP = &(pMbInfo[dwMbIndex]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
   
  AVS_INT QPav = pMbP->dwMbQp; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<4; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<4; 
 
  AVS_BYTE* p = pImgData + (imgY+8)*iStride + (imgX+8); 
 
  AVS_INT C = CLIP_TABLE[IndexA]; 
 
  if(Bs == 2) 
    DeblockHBs2_Luma(p, Alpha, Beta, iStride); 
  else if(Bs == 1) 
    DeblockHBs1_Luma(p, C, Alpha, Beta, iStride); 
} 
 
 
/************************************************************************/ 
/* 函数功能:滤波色度BsV00边                                            */ 
/*         - 位置参见标准文档                                           */ 
/*         - 调用时先判断该边是否在边界处                               */ 
/************************************************************************/ 
void DeblockMb_BsV00_Chroma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
  MBINFO* pMbP = &(pMbInfo[dwMbIndex-1]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
 
  AVS_INT QPav = (pMbP->dwMbQp + pMbQ->dwMbQp + 1)/2; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<3; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<3; 
 
  AVS_BYTE* p = pImgData + imgY*iStride + imgX; 
 
  AVS_INT C = CLIP_TABLE[IndexA]; 
  
  if(Bs == 2) 
    DeblockVBs2_Chroma(p, Alpha, Beta, iStride); 
  else if(Bs == 1) 
    DeblockVBs1_Chroma(p, Alpha, Beta, C, iStride); 
} 
 
/************************************************************************/ 
/* 函数功能:滤波色度BsV10边                                            */ 
/*         - 位置参见标准文档                                           */ 
/*         - 调用时先判断该边是否在边界处                               */ 
/************************************************************************/ 
void DeblockMb_BsV10_Chroma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
  MBINFO* pMbP = &(pMbInfo[dwMbIndex-1]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
 
  AVS_INT QPav = (pMbP->dwMbQp + pMbQ->dwMbQp + 1)/2; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<3; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<3; 
 
  AVS_BYTE* p = pImgData + (imgY+4)*iStride + imgX; 
 
  AVS_INT C = CLIP_TABLE[IndexA]; 
  
  if(Bs == 2) 
    DeblockVBs2_Chroma(p, Alpha, Beta, iStride); 
  else if(Bs == 1) 
    DeblockVBs1_Chroma(p, Alpha, Beta, C, iStride); 
} 
 
/************************************************************************/ 
/* 函数功能:滤波色度BsH00边                                            */ 
/*         - 位置参见标准文档                                           */ 
/*         - 调用时先判断该边是否在边界处                               */ 
/************************************************************************/ 
void DeblockMb_BsH00_Chroma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
  MBINFO* pMbP = &(pMbInfo[dwMbIndex-dwMbWidth]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
     
  AVS_INT QPav = (pMbP->dwMbQp + pMbQ->dwMbQp + 1)/2; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<3; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<3; 
 
  AVS_BYTE* p = pImgData + imgY*iStride + imgX; 
  AVS_INT C = CLIP_TABLE[IndexA]; 
  if(Bs == 2) 
    DeblockHBs2_Chroma(p, Alpha, Beta,iStride); 
  else if(Bs == 1) 
    DeblockHBs1_Chroma(p, Alpha, Beta, C, iStride); 
} 
 
/************************************************************************/ 
/* 函数功能:滤波色度BsH01边                                            */ 
/*         - 位置参见标准文档                                           */ 
/*         - 调用时先判断该边是否在边界处                               */ 
/************************************************************************/ 
void DeblockMb_BsH01_Chroma(AVS_INT Bs, MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_INT iImgType, AVS_INT iAlphaOffset, AVS_INT iBetaOffset, AVS_BYTE* pImgData, AVS_INT iStride) 
{ 
   
  MBINFO* pMbP = &(pMbInfo[dwMbIndex-dwMbWidth]); 
  MBINFO* pMbQ = &(pMbInfo[dwMbIndex]); 
   
  
  AVS_INT QPav = (pMbInfo[dwMbIndex-dwMbWidth].dwMbQp + pMbInfo[dwMbIndex].dwMbQp + 1)/2; 
  AVS_INT IndexA = Clip3(0, 63, QPav+iAlphaOffset); 
  AVS_INT IndexB = Clip3(0, 63, QPav+iBetaOffset); 
  AVS_INT Alpha = ALPHA_TABLE[IndexA]; 
  AVS_INT Beta = BETA_TABLE[IndexB]; 
   
  AVS_INT imgX = (dwMbIndex%dwMbWidth)<<3; 
  AVS_INT imgY = (dwMbIndex/dwMbWidth)<<3; 
 
  AVS_BYTE* p = pImgData + imgY*iStride + (imgX+4); 
 
  AVS_INT C = CLIP_TABLE[IndexA]; 
  if(Bs == 2) 
    DeblockHBs2_Chroma(p, Alpha, Beta, iStride); 
  else if(Bs == 1) 
    DeblockHBs1_Chroma(p, Alpha, Beta, C, iStride); 
} 
 
AVS_INT GetBsH00(MBINFO* pMbP, MBINFO* pMbQ, AVS_INT iImgType) 
{ 
  AVS_INT Bs; 
   
  if(pMbP->dwMbType == I_8x8 || pMbQ->dwMbType == I_8x8) 
    Bs = 2; 
  else  
  { 
    if(iImgType == P_IMG ) 
      Bs = GetStrengthP(pMbP->dwMbReferenceIndex[2], pMbQ->dwMbReferenceIndex[0], &(pMbP->mv[2]), &(pMbQ->mv[0])); 
    else   // B frame 
      Bs = GetStrengthB(&(pMbP->mv[2]), &(pMbQ->mv[0]), &(pMbP->mvBw[2]), &(pMbQ->mvBw[0])); 
  } 
  return Bs; 
} 
 
AVS_INT GetBsH01(MBINFO* pMbP, MBINFO* pMbQ, AVS_INT iImgType) 
{ 
  int Bs = 0; 
  if(pMbP->dwMbType == I_8x8 || pMbQ->dwMbType == I_8x8) 
    Bs = 2; 
  else  
  { 
    if(iImgType == P_IMG ) 
      Bs = GetStrengthP(pMbP->dwMbReferenceIndex[3], pMbQ->dwMbReferenceIndex[1], &(pMbP->mv[3]), &(pMbQ->mv[1])); 
    else   // B frame 
      Bs = GetStrengthB(&(pMbP->mv[3]), &(pMbQ->mv[1]), &(pMbP->mvBw[3]), &(pMbQ->mvBw[1])); 
  } 
  return Bs; 
} 
 
AVS_INT GetBsH10(MBINFO* pMbP, MBINFO* pMbQ, AVS_INT iImgType) 
{ 
  AVS_INT Bs; 
  if(pMbP->dwMbType == I_8x8) 
    Bs = 2; 
  else  
  { 
    if(iImgType == P_IMG ) 
      Bs = GetStrengthP(pMbP->dwMbReferenceIndex[0], pMbQ->dwMbReferenceIndex[2], &(pMbP->mv[0]), &(pMbQ->mv[2])); 
    else   // B frame 
      Bs = GetStrengthB(&(pMbP->mv[0]), &(pMbQ->mv[2]), &(pMbP->mvBw[0]), &(pMbQ->mvBw[2])); 
  } 
  return Bs; 
} 
 
AVS_INT GetBsH11(MBINFO* pMbP, MBINFO* pMbQ, AVS_INT iImgType) 
{ 
  AVS_INT Bs; 
  if(pMbP->dwMbType == I_8x8) 
    Bs = 2; 
  else  
  { 
    if(iImgType == P_IMG ) 
      Bs = GetStrengthP(pMbP->dwMbReferenceIndex[1], pMbQ->dwMbReferenceIndex[3], &(pMbP->mv[1]), &(pMbQ->mv[3])); 
    else   // B frame 
      Bs = GetStrengthB(&(pMbP->mv[1]), &(pMbQ->mv[3]), &(pMbP->mvBw[1]), &(pMbQ->mvBw[3])); 
  } 
  return Bs; 
 
} 
 
AVS_INT GetBsV00(MBINFO* pMbP, MBINFO* pMbQ, AVS_INT iImgType) 
{ 
  AVS_INT Bs; 
 
  if(pMbP->dwMbType == I_8x8 || pMbQ->dwMbType == I_8x8) 
    Bs = 2; 
  else  
  { 
    if(iImgType == P_IMG ) 
      Bs = GetStrengthP(pMbP->dwMbReferenceIndex[1], pMbQ->dwMbReferenceIndex[0], &(pMbP->mv[1]), &(pMbQ->mv[0])); 
    else   // B frame 
      Bs = GetStrengthB(&(pMbP->mv[1]), &(pMbQ->mv[0]), &(pMbP->mvBw[1]), &(pMbQ->mvBw[0])); 
  } 
  return Bs; 
} 
 
AVS_INT GetBsV01(MBINFO* pMbP, MBINFO* pMbQ, AVS_INT iImgType) 
{ 
  AVS_INT Bs; 
  if(pMbP->dwMbType == I_8x8) 
    Bs = 2; 
  else  
  { 
    if(iImgType == P_IMG ) 
      Bs = GetStrengthP(pMbP->dwMbReferenceIndex[0], pMbQ->dwMbReferenceIndex[1], &(pMbP->mv[0]), &(pMbQ->mv[1])); 
    else   // B frame 
      Bs = GetStrengthB(&(pMbP->mv[0]), &(pMbP->mv[1]), &(pMbQ->mvBw[0]), &(pMbQ->mvBw[1])); 
  } 
  return Bs; 
} 
 
AVS_INT GetBsV10(MBINFO* pMbP, MBINFO* pMbQ, AVS_INT iImgType) 
{ 
  AVS_INT Bs; 
 
  if(pMbP->dwMbType == I_8x8 || pMbQ->dwMbType == I_8x8) 
    Bs = 2; 
  else  
  { 
    if(iImgType == P_IMG ) 
      Bs = GetStrengthP(pMbP->dwMbReferenceIndex[3], pMbQ->dwMbReferenceIndex[2], &(pMbP->mv[3]), &(pMbQ->mv[2])); 
    else   // B frame 
      Bs = GetStrengthB(&(pMbP->mv[1]), &(pMbQ->mv[2]), &(pMbP->mvBw[1]), &(pMbQ->mvBw[2])); 
  } 
  return Bs; 
} 
 
AVS_INT GetBsV11(MBINFO* pMbP, MBINFO* pMbQ, AVS_INT iImgType) 
{ 
  AVS_INT Bs; 
  if(pMbP->dwMbType == I_8x8) 
    Bs = 2; 
  else  
  { 
    if(iImgType == P_IMG ) 
      Bs = GetStrengthP(pMbP->dwMbReferenceIndex[2], pMbQ->dwMbReferenceIndex[3], &(pMbP->mv[2]), &(pMbQ->mv[3])); 
    else   // B frame 
      Bs = GetStrengthB(&(pMbP->mv[2]), &(pMbQ->mv[3]), &(pMbP->mvBw[2]), &(pMbQ->mvBw[3])); 
  } 
  return Bs; 
} 
 
void DeblockOneMacroBlock(MBINFO* pMbInfo, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, STREAMINFO* pStrmInfo, VIDEODATA* pCurrVD) 
{ 
  AVS_BOOL bUpMbAvailable = FALSE; 
  AVS_BOOL bLeftMbAvailable = FALSE; 
  AVS_INT iLumaStride = pStrmInfo->SeqInfo.dwWidth; 
  AVS_INT iChromaStride = pStrmInfo->SeqInfo.dwWidth/2; 
  AVS_DWORD dwImgType = pStrmInfo->ImgInfo.dwImageType; 
  AVS_INT iAlphaOffset = pStrmInfo->ImgInfo.iAlphaCOffset; 
  AVS_INT iBetaOffset = pStrmInfo->ImgInfo.iBetaOffset; 
 
  if(dwMbIndex/dwMbWidth != 0) 
    bUpMbAvailable = TRUE; 
  if(dwMbIndex%dwMbWidth != 0) 
    bLeftMbAvailable = TRUE; 
 
  if(bLeftMbAvailable) 
  { 
    AVS_INT Bs00 = GetBsV00(&(pMbInfo[dwMbIndex-1]), &(pMbInfo[dwMbIndex]), dwImgType); 
    AVS_INT Bs01 = GetBsV01(&(pMbInfo[dwMbIndex]), &(pMbInfo[dwMbIndex]), dwImgType); 
    AVS_INT Bs10 = GetBsV10(&(pMbInfo[dwMbIndex-1]), &(pMbInfo[dwMbIndex]), dwImgType); 
    AVS_INT Bs11 = GetBsV11(&(pMbInfo[dwMbIndex]), &(pMbInfo[dwMbIndex]), dwImgType); 
 
    DeblockMb_BsV00_Luma(Bs00, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride); 
    DeblockMb_BsV01_Luma(Bs01, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride); 
    DeblockMb_BsV10_Luma(Bs10, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride); 
    DeblockMb_BsV11_Luma(Bs11, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride); 
 
    DeblockMb_BsV00_Chroma(Bs00, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->u, iChromaStride); 
    DeblockMb_BsV10_Chroma(Bs01, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->u, iChromaStride); 
 
    DeblockMb_BsV00_Chroma(Bs10, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->v, iChromaStride); 
    DeblockMb_BsV10_Chroma(Bs11, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->v, iChromaStride); 
  } 
  else 
  { 
    AVS_INT Bs01 = GetBsV01(&(pMbInfo[dwMbIndex]), &(pMbInfo[dwMbIndex]), dwImgType); 
    AVS_INT Bs11 = GetBsV11(&(pMbInfo[dwMbIndex]), &(pMbInfo[dwMbIndex]), dwImgType); 
 
    DeblockMb_BsV01_Luma(Bs01, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride); 
    DeblockMb_BsV11_Luma(Bs11, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride);     
  } 
  if(bUpMbAvailable) 
  { 
    AVS_INT Bs00 = GetBsH00(&(pMbInfo[dwMbIndex-dwMbWidth]), &(pMbInfo[dwMbIndex]), dwImgType); 
    AVS_INT Bs01 = GetBsH01(&(pMbInfo[dwMbIndex-dwMbWidth]), &(pMbInfo[dwMbIndex]), dwImgType); 
    AVS_INT Bs10 = GetBsH10(&(pMbInfo[dwMbIndex]), &(pMbInfo[dwMbIndex]), dwImgType); 
    AVS_INT Bs11 = GetBsH11(&(pMbInfo[dwMbIndex]), &(pMbInfo[dwMbIndex]), dwImgType); 
    DeblockMb_BsH00_Luma(Bs00, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride); 
    DeblockMb_BsH01_Luma(Bs01, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride); 
    DeblockMb_BsH10_Luma(Bs10, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride); 
    DeblockMb_BsH11_Luma(Bs11, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride); 
 
    DeblockMb_BsH00_Chroma(Bs00, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->u, iChromaStride); 
    DeblockMb_BsH01_Chroma(Bs01, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->u, iChromaStride); 
 
    DeblockMb_BsH00_Chroma(Bs00, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->v, iChromaStride); 
    DeblockMb_BsH01_Chroma(Bs01, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->v, iChromaStride); 
 
  } 
  else 
  { 
    AVS_INT Bs10 = GetBsH10(&(pMbInfo[dwMbIndex]), &(pMbInfo[dwMbIndex]), dwImgType); 
    AVS_INT Bs11 = GetBsH11(&(pMbInfo[dwMbIndex]), &(pMbInfo[dwMbIndex]), dwImgType); 
 
    DeblockMb_BsH10_Luma(Bs10, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride); 
    DeblockMb_BsH11_Luma(Bs11, pMbInfo, dwMbIndex, dwMbWidth, dwImgType, iAlphaOffset, iBetaOffset, pCurrVD->y, iLumaStride);     
  } 
 
 
}