⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pred.cpp

📁 AVS是中国自己推出的视频图像音频编解码标准。包中是AVS 源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*************************************************************************
 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
*************************************************************************/
/*************************************************************************
  文件名称:	pred.cpp
  描    述: mv 预测
*************************************************************************/
/*************************************************************************
  Revision History
  data          Modification                                    Author
  2005-3-2      Created                                          jthou
 *************************************************************************/
#include "pred.h"
#include "define.h"
#include "global.h"
#include "block.h"

AVS_HRESULT IntraPredLuma(MBINFO* pMbInfo, const AVS_BYTE* pbCurrY, AVS_DWORD dwMbIndex, AVS_DWORD dwImgWidth, AVS_DWORD dwImgHeight, AVS_DWORD dwBlockNo, AVS_BYTE* pPred, AVS_DWORD dwImgX, AVS_DWORD dwImgY)
{
  AVS_BOOL LeftBlockAvailable = FALSE;
  AVS_BOOL UpBlockAvailable = FALSE;
  AVS_BOOL LeftDownBlockAvailable = FALSE;
  AVS_BOOL UpRightBlockAvailable = FALSE;
  AVS_INT  intraPredModeA = -1, intraPredModeB = -1;
  AVS_INT  predIntraPredMode = -1;
  AVS_INT  IntraLumaPredMode = -1;
  AVS_INT  mostpredIntraPredMode = -1;
  
  AVS_INT BlockX = dwImgX >> 3;
  AVS_INT BlockY = dwImgY >> 3;
  AVS_INT dwMb8Width = dwImgWidth>>3;
  AVS_INT dwMb8Height = dwImgHeight>>3;
  
  AVS_DWORD dwMbWidth = dwImgWidth >> 4;
  dwImgWidth = dwImgWidth;
  

  
  //判断相邻块是否已“可用”
  if(BlockY > 0)
    UpBlockAvailable = TRUE;
  if(BlockY>0 && BlockX<dwMb8Width-1)
    UpRightBlockAvailable = TRUE;
  if(BlockX > 0)
    LeftBlockAvailable = TRUE;
  if(BlockX>0 && BlockY<dwMb8Height-1 )
    LeftDownBlockAvailable = TRUE;
  
  if(dwBlockNo == 3)
    UpRightBlockAvailable = FALSE; 
  if(dwBlockNo != 0)
    LeftDownBlockAvailable = FALSE;
    
  //求预测模式
  if(LeftBlockAvailable)
  {
    if(dwBlockNo == 0 || dwBlockNo == 2)
    {
      if(pMbInfo[dwMbIndex-1].dwMbType == I_8x8)
        intraPredModeA = pMbInfo[dwMbIndex-1].iIntraLumaPredModeNew[dwBlockNo+1];
      else 
        intraPredModeA = 2;
    }
    else
      intraPredModeA = pMbInfo[dwMbIndex].iIntraLumaPredModeNew[dwBlockNo-1];
  }
   
   if(UpBlockAvailable)
   {
     if(dwBlockNo == 0 || dwBlockNo == 1)
     {
       if(pMbInfo[dwMbIndex-dwMbWidth].dwMbType == I_8x8)
         intraPredModeB = pMbInfo[dwMbIndex-dwMbWidth].iIntraLumaPredModeNew[dwBlockNo+2];
       else
         intraPredModeB = 2;
     }
     else
       intraPredModeB = pMbInfo[dwMbIndex].iIntraLumaPredModeNew[dwBlockNo-2];
   }
   
   if (intraPredModeA == -1 || intraPredModeB == -1) 
   {
     predIntraPredMode = 2;
   }
   else
   {
     predIntraPredMode = min(intraPredModeA, intraPredModeB);
   }
  
   if(pMbInfo[dwMbIndex].bPredModeFlag[dwBlockNo])
   {
     IntraLumaPredMode = predIntraPredMode;
   }
   else
   {
     if(pMbInfo[dwMbIndex].iIntraLumaPredMode[dwBlockNo] < predIntraPredMode)
       IntraLumaPredMode = pMbInfo[dwMbIndex].iIntraLumaPredMode[dwBlockNo];
     else
       IntraLumaPredMode = pMbInfo[dwMbIndex].iIntraLumaPredMode[dwBlockNo]+1;
   }

   pMbInfo[dwMbIndex].iIntraLumaPredModeNew[dwBlockNo] = IntraLumaPredMode; 

    
   AVS_BYTE c[18], r[18];
   AVS_INT i, j;
   if(LeftBlockAvailable)
   {
     for(i=0; i<8; i++)
       c[i+1] = *(pbCurrY + (dwImgY+i)*dwImgWidth + dwImgX-1);
     c[0] = c[1];
    
     for(i=0; i<9; i++)
     {
       c[i+9] = c[8];
     }
   }
   if(UpBlockAvailable)
   {
     for(i=0; i<8; i++)
       r[i+1] = *(pbCurrY+(dwImgY-1)*dwImgWidth + dwImgX+i);
     r[0] = r[1];

     for(i=0; i<9; i++)
     {
       r[i+9] = r[8];
     }
   }
   if(LeftDownBlockAvailable)
   {
     for(i=0; i<8; i++)
       c[i+9] = *(pbCurrY+(dwImgY+8+i)*dwImgWidth + dwImgX-1);
     c[17] = c[16];
   }
   if(UpRightBlockAvailable)
   {
     for(i=0; i<8; i++)
       r[i+9] = *(pbCurrY+(dwImgY-1)*dwImgWidth + dwImgX+8+i);
     r[17] =r[16];
   }

   if(UpBlockAvailable && LeftBlockAvailable)
   {
     r[0] = c[0] = *(pbCurrY+(dwImgY-1)*dwImgWidth + dwImgX-1);
   }

   switch(IntraLumaPredMode) 
   {
   case Intra_8x8_Vertical:
       for(i=0; i<8; i++)
         for(j=0; j<8; j++)
           pPred[i*8+j]=r[j+1];
     break;
   case Intra_8x8_Horizontal:
       for(i=0; i<8; i++)
         for(j=0; j<8; j++)
           pPred[i*8+j]=c[i+1];
     break;
   case Intra_8x8_DC:
     if(!UpBlockAvailable && !LeftBlockAvailable)
     {       
       for(i=0;i<8;i++)
         for(j=0;j<8;j++)
           pPred[i*8+j] = 128;
     }
     else if(UpBlockAvailable && !LeftBlockAvailable)
     {
       for(i=0;i<8;i++)
         for(j=0;j<8;j++)
           //pPred[j*8+i] = (r[i]+2*r[i+1]+r[i+2]+2)>>2;  
           pPred[i*8+j] = (r[j]+2*r[j+1]+r[j+2]+2)>>2;  
     }
     else if(!UpBlockAvailable && LeftBlockAvailable)
     {
        for(i=0; i<8; i++)
           for(j=0; j<8; j++)
             //pPred[j*8+i] = (c[j]+2*c[j+1]+c[j+2]+2)>>2;  
             pPred[i*8+j] = (c[i]+2*c[i+1]+c[i+2]+2)>>2;  
     }
     else if(UpBlockAvailable && LeftBlockAvailable)
     {
        for(i=0; i<8; i++)
           for(j=0; j<8; j++)
             //pPred[j*8+i] = (((r[i]+2*r[i+1]+r[i+2]+2)>>2)+((c[j]+2*c[j+1]+c[j+2]+2)>>2))>>1;
             pPred[i*8+j] = (((r[j]+2*r[j+1]+r[j+2]+2)>>2)+((c[i]+2*c[i+1]+c[i+2]+2)>>2))>>1;
       
     }
     break;
   case Intra_8x8_Down_Left:
       for(i=0; i<8; i++)
       {
         for(j=0; j<8; j++)
          //pPred[j*8+i] = (((r[i+j+1]+2*r[i+j+2]+r[i+j+3]+2)>>2)+((c[i+j+1]+2*c[i+j+2]+c[i+j+3]+2)>>2))>>1;
          pPred[i*8+j] = (((r[i+j+1]+2*r[i+j+2]+r[i+j+3]+2)>>2)+((c[i+j+1]+2*c[i+j+2]+c[i+j+3]+2)>>2))>>1;
       }
   
     break;
   case Intra_8x8_Down_Right:
       for(i=0; i<8; i++)
       {
         for(j=0; j<8; j++)
         {
           if(i==j)
             pPred[i*8+j] = (c[1]+2*r[0]+r[1]+2)>>2;
           if(j>i)
             pPred[i*8+j] = (r[j-i+1]+2*r[j-i]+r[j-i-1]+2)>>2;
           if(j<i)
             pPred[i*8+j] = (c[i-j+1]+2*c[i-j]+c[i-j-1]+2)>>2;
         }
       }   
     break;
   default:
     break;
     //erro!
   }
   return AVS_NOERROR;
}

AVS_HRESULT IntraPredChroma(MBINFO* pMbInfo, const AVS_BYTE* pbCurrUV, AVS_DWORD dwMbIndex, AVS_DWORD dwMbWidth, AVS_DWORD dwMbHeight, AVS_BYTE* pPred, AVS_DWORD dwUVX, AVS_DWORD dwUVY)
{
  AVS_INT i, j;
  AVS_BOOL UpBlockAvailable = FALSE;
  AVS_BOOL LeftBlockAvailable = FALSE;

  AVS_INT BlockX = dwMbIndex%dwMbWidth;
  AVS_INT BlockY = dwMbIndex/dwMbWidth;
  
  AVS_INT dwUVWidth = dwMbWidth*8;
  
  if(BlockX > 0)
    LeftBlockAvailable = TRUE;
  if(BlockY > 0)
    UpBlockAvailable = TRUE;

  AVS_INT r[10], c[10];
  if(LeftBlockAvailable)
  {
    for(i=0; i<8; i++)
      c[i+1] = *(pbCurrUV+(dwUVY+i)*dwUVWidth+dwUVX-1);
    c[0] = c[1];
    c[9] = c[8];
  }
  if(UpBlockAvailable)
  {
    for(i=0; i<8; i++)
      r[i+1] = *(pbCurrUV+(dwUVY-1)*dwUVWidth+dwUVX+i);
    r[0] = r[1];
    r[9] = r[8];
  }
  if(LeftBlockAvailable && UpBlockAvailable)
  {
    c[0] = r[0] = *(pbCurrUV+(dwUVY-1)*dwUVWidth+dwUVX-1);
  }

  AVS_INT intraChromaPreMode = pMbInfo[dwMbIndex].dwintraChromaPredMode;
  AVS_INT ih=0, iv=0, ia=0, ib=0, ic=0;

  switch(intraChromaPreMode) 
  {
  case Intra_Chroma_DC:
    if(LeftBlockAvailable && UpBlockAvailable)
    {
      for(i=0; i<8; i++)
        for(j=0; j<8; j++)
          pPred[j*8+i] = (((r[i]+2*r[i+1]+r[i+2]+2)>>2)+((c[j]+2*c[j+1]+c[j+2]+2)>>2))>>1;
    }
    if(!LeftBlockAvailable && UpBlockAvailable)
    {
       for(i=0; i<8; i++)
        for(j=0; j<8; j++)
          pPred[j*8+i] = (r[i]+2*r[i+1]+r[i+2]+2)>>2; 
    }
    if(LeftBlockAvailable && !UpBlockAvailable)
    {
       for(i=0; i<8; i++)
        for(j=0; j<8; j++)
          pPred[j*8+i] = (c[j]+2*c[j+1]+c[j+2]+2)>>2;
    }
    if(!LeftBlockAvailable && !UpBlockAvailable)
    {
       for(i=0; i<8; i++)
        for(j=0; j<8; j++)
          pPred[j*8+i] = 128;
    }
  	break;
  case Intra_Chroma_Horizontal:
    for(i=0; i<8; i++)
      for(j=0; j<8; j++)
        pPred[j*8+i] = c[j+1];
  	break;
  case Intra_Chroma_Vertical:
    for(i=0; i<8; i++)
      for(j=0; j<8; j++)
        pPred[j*8+i] = r[i+1];
    break;
  case Intra_Chroma_Plane:
    for(i=0; i<=3; i++)
    {
      ih += (i+1)*(r[5+i]-r[3-i]);
      iv += (i+1)*(c[5+i]-c[3-i]);
    }
    ia = (r[8]+c[8])<<4; 
    ib = (17*ih+16)>>5;
    ic = (17*iv+16)>>5;
    for(i=0; i<8; i++)
      for(j=0; j<8; j++)
        pPred[i*8+j] = Clip((ia+(j-3)*ib+(i-3)*ic+16)>>5); 
    break;
  default:
    // error!
    break;
  }
  return AVS_NOERROR;
}

MOTIONVECTOR ScaleMv(MOTIONVECTOR* pMv, AVS_INT iDistance1, AVS_INT iDistance2)
{
  MOTIONVECTOR mv={0,0};
  if(pMv->x != 0)
    mv.x = sign1(pMv->x)*((abs(pMv->x)*iDistance1*(512/iDistance2)+256) >>9);
  if(pMv->y != 0)
    mv.y = sign1(pMv->y)*((abs(pMv->y)*iDistance1*(512/iDistance2)+256) >>9);
  
  return mv;
}

MOTIONVECTOR ScalePredMv(MOTIONVECTOR* pMvA, MOTIONVECTOR* pMvB, MOTIONVECTOR* pMvC, AVS_INT iDistance1, AVS_INT iDistanceA, AVS_INT iDistanceB, AVS_INT iDistanceC)
{
  MOTIONVECTOR MVA, MVB, MVC;

  MVA = ScaleMv(pMvA, iDistance1, iDistanceA);
  MVB = ScaleMv(pMvB, iDistance1, iDistanceB);
  MVC = ScaleMv(pMvC, iDistance1, iDistanceC);

  AVS_INT VAB = abs(MVA.x - MVB.x) + abs(MVA.y - MVB.y);
  AVS_INT VBC = abs(MVB.x - MVC.x) + abs(MVB.y - MVC.y);
  AVS_INT VCA = abs(MVC.x - MVA.x) + abs(MVC.y - MVA.y);
  
  AVS_INT FMV = Median(VAB, VBC, VCA);
  if(FMV == VAB)
    return MVC;
  else if(FMV == VBC)
    return MVA;
  else
    return MVB;
}


AVS_HRESULT InterPredLuma16x16(MBINFO* pMbInfo, AVS_INT dwMbIndex, const AVS_BYTE* pbRefY, AVS_INT dwMbWidth, AVS_INT dwMbHeight, AVS_INT iBlockDistance, AVS_INT dirBw, AVS_BYTE* pPred)
{
  AVS_BOOL A_BlockAvailable = FALSE;
  AVS_BOOL B_BlockAvailable = FALSE;
  AVS_BOOL C_BlockAvailable = FALSE;
  AVS_BOOL D_BlockAvailable = FALSE;

  AVS_INT  BlockDistanceA=1;
  AVS_INT  BlockDistanceB=1;
  AVS_INT  BlockDistanceC=1;
  AVS_INT  BlockDistanceD=1;

  AVS_INT  RefIdxA = -1;
  AVS_INT  RefIdxB = -1;
  AVS_INT  RefIdxC = -1;
  AVS_INT  RefIdxD = -1;


  MOTIONVECTOR mvA={0,0}, mvB={0,0}, mvC={0,0}, mvD={0,0}, mvE={0,0};
  MOTIONVECTOR MVEPred={0,0};

  AVS_INT MbX = dwMbIndex%dwMbWidth;
  AVS_INT MbY = dwMbIndex/dwMbWidth;

  if(MbX>0)
    A_BlockAvailable = TRUE;
  if(MbY>0)
    B_BlockAvailable = TRUE;
  if(MbX>0 && MbY>0)
    D_BlockAvailable = TRUE;
  if(MbY>0 && MbX<dwMbWidth-1)
    C_BlockAvailable = TRUE; 

  if(!A_BlockAvailable || pMbInfo[dwMbIndex-1].dwMbType == I_8x8 ||
    (pMbInfo[dwMbIndex-1].predDir[1] != pMbInfo[dwMbIndex].predDir[0] && 
    pMbInfo[dwMbIndex-1].predDir[1] != PREDDIRSYM))
  {
    mvA.x = mvA.y = 0;
    BlockDistanceA = 1;
    RefIdxA = -1;
  }
  else
  {
    if(!dirBw)
    {
      mvA = pMbInfo[dwMbIndex-1].mv[1];
      BlockDistanceA = pMbInfo[dwMbIndex-1].iBlockDistance[1];
      RefIdxA = pMbInfo[dwMbIndex-1].dwMbReferenceIndex[1];
    }
    else
    {
      mvA = pMbInfo[dwMbIndex-1].mvBw[1];
      BlockDistanceA = pMbInfo[dwMbIndex-1].iBlockDistanceBw[1];
      RefIdxA = pMbInfo[dwMbIndex-1].dwMbReferenceIndexBw[1];
    }
  }

  if(!B_BlockAvailable || pMbInfo[dwMbIndex-dwMbWidth].dwMbType == I_8x8 ||
    (pMbInfo[dwMbIndex-dwMbWidth].predDir[2] != pMbInfo[dwMbIndex].predDir[0] && 
    pMbInfo[dwMbIndex-dwMbWidth].predDir[2] != PREDDIRSYM))
  {
    mvB.x = mvB.y = 0;
    BlockDistanceB = 1;
    RefIdxB = -1;
  }
  else
  {
    if(!dirBw)
    {
      mvB = pMbInfo[dwMbIndex-dwMbWidth].mv[2];
      BlockDistanceB = pMbInfo[dwMbIndex-dwMbWidth].iBlockDistance[2];
      RefIdxB = pMbInfo[dwMbIndex-dwMbWidth].dwMbReferenceIndex[2];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -