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

📄 pred.cpp

📁 AVS是中国自己推出的视频图像音频编解码标准。包中是AVS 源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
  AVS_INT  RefIdxC = -1;
  AVS_INT  RefIdxD = -1;

  AVS_INT idxBw = 0;
  AVS_INT idxFw = 1;
  AVS_INT dirBw = 1;

  AVS_INT iBlockDistance = ((dwCurrDistanceIndex - ppRefFrame[idxFw]->dwDistanceIndex)+512)%512;
  AVS_INT iBlockDistanceBw = ((ppRefFrame[idxBw]->dwDistanceIndex - dwCurrDistanceIndex)+512)%512;


  MOTIONVECTOR mvA={0,0}, mvB={0,0}, mvC={0,0}, mvD={0,0}, mvFw={0,0}, mvBw={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] == PREDDIRBWD)
  {
    mvA.x = mvA.y = 0;
    BlockDistanceA = 1;
    RefIdxA = -1;
  }
  else
  {
    mvA = pMbInfo[dwMbIndex-1].mv[1];
    BlockDistanceA = pMbInfo[dwMbIndex-1].iBlockDistance[1];
    RefIdxA = pMbInfo[dwMbIndex-1].dwMbReferenceIndex[1];
  }

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

  if(!D_BlockAvailable || pMbInfo[dwMbIndex-dwMbWidth-1].dwMbType == I_8x8 ||
    pMbInfo[dwMbIndex-dwMbWidth-1].predDir[3] == PREDDIRBWD)
  {
    mvD.x = mvD.y = 0;
    BlockDistanceD = 1;
    RefIdxD = -1;
  }
  else
  {
    mvD = pMbInfo[dwMbIndex-dwMbWidth-1].mv[3];
    BlockDistanceD = pMbInfo[dwMbIndex-dwMbWidth-1].iBlockDistance[3];
    RefIdxD = pMbInfo[dwMbIndex-dwMbWidth-1].dwMbReferenceIndex[3];
  }
  if(!C_BlockAvailable)
  {
    mvC = mvD;
    BlockDistanceC = BlockDistanceD;
    RefIdxC = RefIdxD;
  }
  else if(pMbInfo[dwMbIndex-dwMbWidth+1].dwMbType==I_8x8 ||
    pMbInfo[dwMbIndex-dwMbWidth+1].predDir[2]== PREDDIRBWD)
  {
    mvC.x = mvC.y = 0;
    BlockDistanceC = 1;  
    RefIdxC = -1;
  }
  else
  {
    mvC = pMbInfo[dwMbIndex-dwMbWidth+1].mv[2];
    BlockDistanceC = pMbInfo[dwMbIndex-dwMbWidth+1].iBlockDistance[2];
    RefIdxC = pMbInfo[dwMbIndex-dwMbWidth+1].dwMbReferenceIndex[2];
  }

  if(RefIdxA !=-1 && RefIdxB == -1 && RefIdxC == -1)
  {
    MVEPred = mvA;
  }
  else if(RefIdxA == -1 && RefIdxB != -1 && RefIdxC == -1)
  {
    MVEPred = mvB;
  }
  else if(RefIdxA ==-1 && RefIdxB == -1 && RefIdxC != -1)
  {
    MVEPred = mvC;
  }
  else
  {
    MVEPred = ScalePredMv(&mvA, &mvB, &mvC, iBlockDistance, BlockDistanceA, BlockDistanceB, BlockDistanceC);
  }
  
  mvE.x = MVEPred.x + pMbInfo[dwMbIndex].iMvDiffX[0];
  mvE.y = MVEPred.y + pMbInfo[dwMbIndex].iMvDiffY[0];
  
  mvBw.x = -((mvE.x * iBlockDistanceBw * (512/iBlockDistance)+256) >> 9);
  mvBw.y = -((mvE.y * iBlockDistanceBw * (512/iBlockDistance)+256) >> 9);

  AVS_BYTE pPredBw[4][8][8];
  
  for(AVS_INT block=0; block<4; block++)
  {
    pMbInfo[dwMbIndex].mv[block] = mvE;
    pMbInfo[dwMbIndex].iBlockDistance[block] = iBlockDistance;
    pMbInfo[dwMbIndex].mvBw[block] = mvBw;
    pMbInfo[dwMbIndex].iBlockDistanceBw[block] = iBlockDistanceBw;

    AVS_INT iImgWidth = dwMbWidth*16;
    AVS_INT iImgHeight = dwMbHeight*16;
    AVS_INT iImgX = (dwMbIndex%dwMbWidth)*16 + (block%2)*8;
    AVS_INT iImgY = (dwMbIndex/dwMbWidth)*16 + (block/2)*8;

    //插值,得到4个8x8预测块
    GetBlock(&(pMbInfo[dwMbIndex].mv[block]),iImgX, iImgY, iImgWidth, iImgHeight, ppRefFrame[idxFw]->y, pPred+block*64);
    GetBlock(&(pMbInfo[dwMbIndex].mvBw[block]),iImgX, iImgY, iImgWidth, iImgHeight, ppRefFrame[idxBw]->y, &(pPredBw[block][0][0]));
  } 

  // average
  AVS_BYTE* pDst = pPred;
  AVS_BYTE* pSrc = &(pPredBw[0][0][0]);
  AverageB8x(pDst, pSrc, 32, 8);

  return AVS_NOERROR;
}

AVS_HRESULT InterPredLuma16x8(MBINFO* pMbInfo, AVS_INT dwMbIndex, const AVS_BYTE* pbRefY, AVS_INT dwMbWidth, AVS_INT dwMbHeight, AVS_INT iBlockDistance, AVS_INT dwSubMb, 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, mvB, mvC, mvD, mvE;
  MOTIONVECTOR MVEPred;

  AVS_INT MbX = dwMbIndex%dwMbWidth;
  AVS_INT MbY = dwMbIndex/dwMbWidth;
  
  if(dwSubMb == 0)
  {//上块
    if(MbX > 0)
      A_BlockAvailable = TRUE;
    if(MbY>0 && MbX<dwMbWidth-1)
      C_BlockAvailable = TRUE;
    if(MbY>0)
      B_BlockAvailable = TRUE;
    if(MbX>0 && MbY>0)
      D_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];
      }
      else
      {
        mvB = pMbInfo[dwMbIndex-dwMbWidth].mvBw[2];
        BlockDistanceB = pMbInfo[dwMbIndex-dwMbWidth].iBlockDistanceBw[2];
        RefIdxB = pMbInfo[dwMbIndex-dwMbWidth].dwMbReferenceIndexBw[2];
      }
    }

    if(!D_BlockAvailable || pMbInfo[dwMbIndex-dwMbWidth-1].dwMbType == I_8x8 ||
      (pMbInfo[dwMbIndex-dwMbWidth-1].predDir[3] != pMbInfo[dwMbIndex].predDir[0] &&
      pMbInfo[dwMbIndex-dwMbWidth-1].predDir[3] != PREDDIRSYM))
    {
      mvD.x = mvD.y = 0;
      BlockDistanceD = 1;
      RefIdxD = -1;
    }
    else
    {
      if(!dirBw)
      {
        mvD = pMbInfo[dwMbIndex-dwMbWidth-1].mv[3];
        BlockDistanceD = pMbInfo[dwMbIndex-dwMbWidth-1].iBlockDistance[3];
        RefIdxD = pMbInfo[dwMbIndex-dwMbWidth-1].dwMbReferenceIndex[3];
      }
      else
      {
        mvD = pMbInfo[dwMbIndex-dwMbWidth-1].mvBw[3];
        BlockDistanceD = pMbInfo[dwMbIndex-dwMbWidth-1].iBlockDistanceBw[3];
        RefIdxD = pMbInfo[dwMbIndex-dwMbWidth-1].dwMbReferenceIndexBw[3];
      }
    }
    if(!C_BlockAvailable)
    {
      mvC = mvD;
      BlockDistanceC = BlockDistanceD;
      RefIdxC = RefIdxD;
    }
    else if(pMbInfo[dwMbIndex-dwMbWidth+1].dwMbType==I_8x8 ||
      (pMbInfo[dwMbIndex-dwMbWidth+1].predDir[2]!=pMbInfo[dwMbIndex].predDir[0] &&
      pMbInfo[dwMbIndex-dwMbWidth+1].predDir[2]!= PREDDIRSYM))
    {
      mvC.x = mvC.y = 0;
      BlockDistanceC = 1;
      RefIdxC = -1;
    }
    else
    {
      if(!dirBw)
      {
        mvC = pMbInfo[dwMbIndex-dwMbWidth+1].mv[2];
        BlockDistanceC = pMbInfo[dwMbIndex-dwMbWidth+1].iBlockDistance[2];
        RefIdxC = pMbInfo[dwMbIndex-dwMbWidth+1].dwMbReferenceIndex[2];
      }
      else
      {
        mvC = pMbInfo[dwMbIndex-dwMbWidth+1].mvBw[2];
        BlockDistanceC = pMbInfo[dwMbIndex-dwMbWidth+1].iBlockDistanceBw[2];
        RefIdxC = pMbInfo[dwMbIndex-dwMbWidth+1].dwMbReferenceIndexBw[2];
      }    
    }
    
    if(RefIdxA !=-1 && RefIdxB == -1 && RefIdxC == -1)
    {
      MVEPred = mvA;
    }
    else if(RefIdxA == -1 && RefIdxB != -1 && RefIdxC == -1)
    {
      MVEPred = mvB;
    }
    else if(RefIdxA ==-1 && RefIdxB == -1 && RefIdxC != -1)
    {
      MVEPred = mvC;
    }
    else
    {
      if((!dirBw && RefIdxB == pMbInfo[dwMbIndex].dwMbReferenceIndex[0])
        ||(dirBw && RefIdxB == pMbInfo[dwMbIndex].dwMbReferenceIndexBw[0]))  
      {
        MVEPred = mvB;
      }
      else
      {
        MVEPred = ScalePredMv(&mvA, &mvB, &mvC, iBlockDistance, BlockDistanceA, BlockDistanceB, BlockDistanceC);
      }
    }    
  }
  else
  {//下块
    if(MbX > 0)
      A_BlockAvailable = TRUE;
    B_BlockAvailable = TRUE;
    if(MbX>0)
      D_BlockAvailable = TRUE;
    
    if(!A_BlockAvailable || pMbInfo[dwMbIndex-1].dwMbType == I_8x8 ||
      (pMbInfo[dwMbIndex-1].predDir[3] != pMbInfo[dwMbIndex].predDir[2] &&
      pMbInfo[dwMbIndex-1].predDir[3] != PREDDIRSYM))
    {
      mvA.x = mvA.y = 0;
      BlockDistanceA = 1;
      RefIdxA = -1;
    }
    else
    {
      if(!dirBw)
      {
        mvA = pMbInfo[dwMbIndex-1].mv[3];
        BlockDistanceA = pMbInfo[dwMbIndex-1].iBlockDistance[3];
        RefIdxA = pMbInfo[dwMbIndex-1].dwMbReferenceIndex[3];
      }
      else
      {
        mvA = pMbInfo[dwMbIndex-1].mvBw[3];
        BlockDistanceA = pMbInfo[dwMbIndex-1].iBlockDistanceBw[3];
        RefIdxA = pMbInfo[dwMbIndex-1].dwMbReferenceIndexBw[3];
      }
    }
    
    if(!B_BlockAvailable || 
      (pMbInfo[dwMbIndex].predDir[0] != pMbInfo[dwMbIndex].predDir[2] &&
      pMbInfo[dwMbIndex].predDir[0]!= PREDDIRSYM))
    {
      mvB.x = mvB.y = 0;
      BlockDistanceB = 1;
      RefIdxB = -1;
    }
    else
    {
      if(!dirBw)
      {
        mvB = pMbInfo[dwMbIndex].mv[0];
        BlockDistanceB = pMbInfo[dwMbIndex].iBlockDistance[0];
        RefIdxB = pMbInfo[dwMbIndex].dwMbReferenceIndex[0]; 
      }
      else
      {
        mvB = pMbInfo[dwMbIndex].mvBw[0];
        BlockDistanceB = pMbInfo[dwMbIndex].iBlockDistanceBw[0];
        RefIdxB = pMbInfo[dwMbIndex].dwMbReferenceIndexBw[0]; 
      }
    }

    if(!D_BlockAvailable || pMbInfo[dwMbIndex-1].dwMbType == I_8x8 ||
      (pMbInfo[dwMbIndex-1].predDir[1] != pMbInfo[dwMbIndex].predDir[2] &&
      pMbInfo[dwMbIndex-1].predDir[1] != PREDDIRSYM))
    {
      mvD.x = mvD.y = 0;
      BlockDistanceD = 1;
      RefIdxD = -1;
    }
    else
    {
      if(!dirBw)
      {
        mvD = pMbInfo[dwMbIndex-1].mv[1];
        BlockDistanceD = pMbInfo[dwMbIndex-1].iBlockDistance[1];
        RefIdxD = pMbInfo[dwMbIndex-1].dwMbReferenceIndex[1];
      }
      else
      {
        mvD = pMbInfo[dwMbIndex-1].mvBw[1];
        BlockDistanceD = pMbInfo[dwMbIndex-1].iBlockDistanceBw[1];
        RefIdxD = pMbInfo[dwMbIndex-1].dwMbReferenceIndexBw[1];
      }
    }

    mvC = mvD;
    BlockDistanceC = BlockDistanceD;
    RefIdxC = RefIdxD;
    

    if(RefIdxA !=-1 && RefIdxB == -1 && RefIdxC == -1)
    {
      MVEPred = mvA;
    }
    else if(RefIdxA == -1 && RefIdxB != -1 && RefIdxC == -1)
    {
      MVEPred = mvB;
    }
    else if(RefIdxA ==-1 && RefIdxB == -1 && RefIdxC != -1)
    {
      MVEPred = mvC;
    }
    else
    {
      if(!dirBw && RefIdxA == pMbInfo[dwMbIndex].dwMbReferenceIndex[2])
      {
        MVEPred = mvA;
      }
      else if(dirBw && RefIdxA == pMbInfo[dwMbIndex].dwMbReferenceIndexBw[2])
      {
        MVEPred = mvA;
      }
      else
      {
        MVEPred = ScalePredMv(&mvA, &mvB, &mvC, iBlockDistance, BlockDistanceA, BlockDistanceB, BlockDistanceC);
      }
    }        
  }

  mvE.x = MVEPred.x + pMbInfo[dwMbIndex].iMvDiffX[dwSubMb]; 
  mvE.y = MVEPred.y + pMbInfo[dwMbIndex].iMvDiffY[dwSubMb];
  

  for(AVS_INT block=0; block<2; block++)
  {
    //预测补偿
    if(!dirBw)
      pMbInfo[dwMbIndex].mv[block+dwSubMb*2] = mvE;
    else
      pMbInfo[dwMbIndex].mvBw[block+dwSubMb*2] = mvE;
    pMbInfo[dwMbIndex].iBlockDistance[block+dwSubMb*2] = iBlockDistance;
    if(dirBw)
    {
      pMbInfo[dwMbIndex].mvBw[block+dwSubMb*2] = mvE;
      pMbInfo[dwMbIndex].iBlockDistanceBw[block+dwSubMb*2] = iBlockDistance;
    }
    
    AVS_INT iImgWidth = dwMbWidth*16;
    AVS_INT iImgHeight = dwMbHeight*16;
    AVS_INT iImgX = (dwMbIndex%dwMbWidth)*16 + ((block+dwSubMb*2)%2)*8;
    AVS_INT iImgY = (dwMbIndex/dwMbWidth)*16 + ((block+dwSubMb*2)/2)*8;
    if(!dirBw)
    {
      GetBlock(&(pMbInfo[dwMbIndex].mv[block+dwSubMb*2]),iImgX, iImgY, iImgWidth, iImgHeight, pbRefY, pPred+block*64);

⌨️ 快捷键说明

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