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

📄 macroblock.cpp

📁 AVS是中国自己推出的视频图像音频编解码标准。包中是AVS 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************
 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
*************************************************************************/
/*************************************************************************
  文件名称:	macroblock.cpp
  描    述: 包含三个函数:ParseOnMacroBlock完成宏块码流Parse
                          McIdctRecOneMarcroBlock完成运动补偿和重构
                          InitOneMacroBlock完成在求预测mv之前的一些准备工作
            详细情况见函数具体实现
*************************************************************************/
/*************************************************************************
  Revision History
  data          Modification                                    Author
  2005-2-21      Created                                          jthou
 *************************************************************************/

#include "macroblock.h"
#include "vlc.h"
#include "global.h"
#include "pred.h"
#include "block.h"
#include "define.h"

/************************************************************************/
/* 函数功能:解码过程,从压缩码流中解出宏块信息及亮度色度系数           */
/*         - Parse码流                                                  */
/*         - VLD                                                        */
/*         - 反量化                                                     */
/************************************************************************/
AVS_HRESULT ParseOneMacroBlock(AVS_BYTE** ppData, 
                               AVS_DWORD dwDataLen, 
                               AVS_DWORD* pdwBitOffset, 
                               STREAMINFO* StrmInfo, 
                               MBINFO* pMbInfo, 
                               AVS_DWORD dwMbIndex, 
                               AVS_INT* pCodCounter, 
                               AVS_SHORT* pLumaResidual, 
                               AVS_SHORT* pChromaResidual)
{
  const AVS_BYTE* pbCurrent = *ppData; 
  AVS_DWORD MbWidth = StrmInfo->SeqInfo.dwMbWidth;
  AVS_DWORD MbHeight = StrmInfo->SeqInfo.dwHeight;
  AVS_DWORD PictureType = StrmInfo->ImgInfo.dwImageType; 
  AVS_BOOL  PictureStructure = StrmInfo->ImgInfo.bPictureStructure;
  AVS_BOOL  SkipModeFlag = StrmInfo->ImgInfo.bSkipModeFlag;
  AVS_DWORD MbTypeIndex = 0;
  MBINFO* pCurrMb = &pMbInfo[dwMbIndex];
  AVS_INT   mb_type = 0;
  AVS_INT i;
  AVS_INT cod_counter = *pCodCounter;

  //应该初始化宏块信息
  pCurrMb->bHasCbp = FALSE;
  pCurrMb->dwMbQp = StrmInfo->ImgInfo.dwPictureQp;
  


  if(PictureType == I_IMG)   //这部分与标准不符,从参考软件52b中摘出来的
  {
    mb_type = 0;
  }
  else if(StrmInfo->ImgInfo.bSkipModeFlag)
  {
    if(cod_counter == -1)
    {
      cod_counter = ue(pbCurrent, pdwBitOffset, dwDataLen);
    }
    if(cod_counter == 0)
    {
      mb_type = ue(pbCurrent, pdwBitOffset, dwDataLen);
      if(PictureType == P_IMG)
        mb_type ++;
      cod_counter --;
    }
    else
    {
      cod_counter --;
      mb_type = 0;
    }
  }
  else
  {
    //好像运行不到
  }
  
  *pCodCounter = cod_counter;


  if(mb_type==0 && PictureType != I_IMG && cod_counter >=0)  //跳过模式 skip mode  
  {
    if(PictureType == P_IMG) 
      pCurrMb->dwMbType = P_Skip;
    else
      pCurrMb->dwMbType = B_Skip;
    return AVS_NOERROR;
  }
 
  if(PictureType == I_IMG)
  //if(StrmInfo->ImgInfo.dwImageType1 == I_IMG)
  {
    if(PictureStructure == 1)
    {
      MbTypeIndex = 0;
      pCurrMb->dwMbType = I_8x8;
      pCurrMb->dwMvNum = 0;
    }
    if(PictureStructure == 0)
    {
      MbTypeIndex = 0;
      pCurrMb->dwMbType = I_8x8;
      pCurrMb->dwMvNum = 0;
    }
  }
  
  if(PictureType == P_IMG)
  {
      MbTypeIndex = mb_type;
    if(MbTypeIndex >= 5)  //含CBP
    {
      pCurrMb->bHasCbp = TRUE;
      pCurrMb->dwCBPCodeNum = MbTypeIndex - 5;
      MbTypeIndex = 5;
    }
    if(MbTypeIndex == 5)
      pCurrMb->dwMbType = I_8x8;
    else 
      pCurrMb->dwMbType = MbTypeIndex + 1;
  }

  if(PictureType == B_IMG)
  {
    if(SkipModeFlag)            
      MbTypeIndex = mb_type + 1;
    else
      MbTypeIndex = mb_type;

    if(MbTypeIndex >= 24)
    {
      pCurrMb->bHasCbp = TRUE;
      pCurrMb->dwCBPCodeNum = MbTypeIndex - 24;
      MbTypeIndex = 24;
    }
    if(MbTypeIndex == 24)
      pCurrMb->dwMbType = I_8x8;
    else if(MbTypeIndex == 23) //B_8x8
    {
      pCurrMb->dwMbType = B_8x8;
    }
    else
      pCurrMb->dwMbType = MbTypeIndex + 6; 
  }

  if(pCurrMb->dwMbType != P_Skip && pCurrMb->dwMbType != B_Skip)
  {
    if(pCurrMb->dwMbType == B_8x8)
    {
      for(i=0; i<4; i++)
      {
        AVS_INT mb_part_type = read_bits(pbCurrent, pdwBitOffset, 2);//u(pbCurrent, pdwBitOffset, dwDataLen, 2);
        pCurrMb->dwMbPartType[i] = mb_part_type + 30;  
      }
    }

    if(pCurrMb->dwMbType == I_8x8)
    {
      for(i=0; i<4; i++)
      {
        pCurrMb->bPredModeFlag[i] = read_bits(pbCurrent, pdwBitOffset, 1);//u(pbCurrent, pdwBitOffset, dwDataLen, 1);
        if(!pCurrMb->bPredModeFlag[i])
          pCurrMb->iIntraLumaPredMode[i] = read_bits(pbCurrent, pdwBitOffset, 2);//u(pbCurrent, pdwBitOffset, dwDataLen, 2);
        else
          pCurrMb->iIntraLumaPredMode[i] = -1;
      }
      pCurrMb->dwintraChromaPredMode = ue(pbCurrent, pdwBitOffset, dwDataLen);
      
      if(StrmInfo->SeqInfo.dwChromaFormat == CHROMA422)
        pCurrMb->dwintraChromaPredMode422 = ue(pbCurrent, pdwBitOffset, dwDataLen);
    }
    
    if(pCurrMb->dwMbType == B_8x8)
    {
      for(i=0; i<4; i++)
        pCurrMb->dwMvNum += MvNum[pCurrMb->dwMbPartType[i]];
    }
    else
      pCurrMb->dwMvNum = MvNum[pCurrMb->dwMbType];

    AVS_INT mvBwNum = 0;
    if(pCurrMb->dwMbType == B_8x8)
    {
      for(i=0; i<4; i++)
      {
        if(pCurrMb->dwMbPartType[i] == SB_Bck_8x8)
        {
          mvBwNum ++;
        }
      }
    }  
    AVS_INT mvFwNum = pCurrMb->dwMvNum - mvBwNum;
    AVS_INT tmpRefIdxFw[4], tmpRefIdxBw[4];

    AVS_INT x = 0;
    AVS_INT y = 0;
    
    if ((!StrmInfo->ImgInfo.bPictureReferenceFlag && PictureType==P_IMG && StrmInfo->ImgInfo.bPictureStructure) || 
     (!StrmInfo->ImgInfo.bPictureReferenceFlag && !StrmInfo->ImgInfo.bPictureStructure && StrmInfo->ImgInfo.dwImageType1 !=I_IMG)) 
    {
    for(i=0; i<pCurrMb->dwMvNum; i++)
    {
      if(pCurrMb->dwMbType == B_8x8)
      {
       if(i<mvFwNum)
        {
        if(!PictureStructure && PictureType==P_IMG)
          tmpRefIdxFw[x] = read_bits(pbCurrent, pdwBitOffset, 2);
        else
          tmpRefIdxFw[x] = read_bits(pbCurrent, pdwBitOffset, 1);
          x++;
        }
        else
        {
        if(!PictureStructure && PictureType==P_IMG)
          tmpRefIdxBw[y] = read_bits(pbCurrent, pdwBitOffset, 2);
        else
          tmpRefIdxBw[y] = read_bits(pbCurrent, pdwBitOffset, 1);
          y++;
        }
      }
      else
      {
        if(!PictureStructure && PictureType==P_IMG)
          pCurrMb->dwMbReferenceIndex[i] = read_bits(pbCurrent, pdwBitOffset, 2);
        else
          pCurrMb->dwMbReferenceIndex[i] = read_bits(pbCurrent, pdwBitOffset, 1);
      }
    }

    x = 0;
    y = 0;
    if(pCurrMb->dwMbType == B_8x8)
    {
      for(i=0; i<4; i++)
      {
        if(pCurrMb->dwMbPartType[i] == SB_Bck_8x8)
        {
          pCurrMb->dwMbReferenceIndex[i] = tmpRefIdxBw[x];
          x++;
        }
        else if(pCurrMb->dwMbPartType[i] == SB_Direct_8x8)
        {
          pCurrMb->dwMbReferenceIndex[i] = 0;
        }
        else
        { 
          pCurrMb->dwMbReferenceIndex[i] = tmpRefIdxFw[y];
          y++;
        }
      }
    }
    }
    
    AVS_INT tmpmvdFwx[4], tmpmvdFwy[4];
    AVS_INT tmpmvdBwx[4], tmpmvdBwy[4];

    x=y=0;

    for(i=0; i<pCurrMb->dwMvNum; i++)
    {
      if(pCurrMb->dwMbType == B_8x8)
      {
       if(i<mvFwNum)
        {
          tmpmvdFwx[x] = se(pbCurrent, pdwBitOffset, dwDataLen);
          tmpmvdFwy[x] = se(pbCurrent, pdwBitOffset, dwDataLen);
          x++;
        }
        else
        {
          tmpmvdBwx[y] = se(pbCurrent, pdwBitOffset, dwDataLen);
          tmpmvdBwy[y] = se(pbCurrent, pdwBitOffset, dwDataLen);
          y++;
        }
      }
      else
      {
        pCurrMb->iMvDiffX[i] = se(pbCurrent, pdwBitOffset, dwDataLen);
        pCurrMb->iMvDiffY[i] = se(pbCurrent, pdwBitOffset, dwDataLen);   
      }
    }

    x = 0;
    y = 0;
    if(pCurrMb->dwMbType == B_8x8)
    {
      for(i=0; i<4; i++)
      {
        if(pCurrMb->dwMbPartType[i] == SB_Bck_8x8)
        {
          pCurrMb->iMvDiffX[i] = tmpmvdBwx[x];
          pCurrMb->iMvDiffY[i] = tmpmvdBwy[x];
          x++;
        }
        else if(pCurrMb->dwMbPartType[i] == SB_Direct_8x8)
        {
          pCurrMb->iMvDiffX[i] = 0;
          pCurrMb->iMvDiffY[i] = 0;      
        }
        else
        {
          pCurrMb->iMvDiffX[i] = tmpmvdFwx[y];
          pCurrMb->iMvDiffY[i] = tmpmvdFwy[y];
          y++;
        }
      }
    }


    if(pCurrMb->bHasCbp)
    {
        pCurrMb->dwCbp = NCBP[pCurrMb->dwCBPCodeNum][0];
    }
    else
    {
        pCurrMb->dwCbp = me(pbCurrent, pdwBitOffset, dwDataLen, pCurrMb->dwMbType);
    }

    if(StrmInfo->SeqInfo.dwChromaFormat == CHROMA422)
    {
      pCurrMb->dwCbp422 = me_chroma422(pbCurrent, pdwBitOffset, dwDataLen, pCurrMb->dwMbType);
    }
    
    if((pCurrMb->dwCbp>0 || (pCurrMb->dwCbp422>0 && StrmInfo->SeqInfo.dwChromaFormat == CHROMA422)) && 
      !StrmInfo->ImgInfo.bFixedPictureQp) //??
    {
      pCurrMb->iMbQpDelta = se(pbCurrent, pdwBitOffset, dwDataLen);
      pCurrMb->dwMbQp += pCurrMb->iMbQpDelta; //??
    }

    for(i=0; i<4; i++)
    {
      if (pCurrMb->dwCbp&(1<<i))
        ReadLumaCoeff(pbCurrent,dwDataLen, pdwBitOffset, pCurrMb, StrmInfo->ImgInfo.bPictureStructure, pLumaResidual+i*64);
    }
      
    for(i=0; i<2; i++)
    {
      if ((pCurrMb->dwCbp>>4)&(i+1))
        ReadChromaCoeff(pbCurrent, dwDataLen, pdwBitOffset, pCurrMb, StrmInfo->ImgInfo.bPictureStructure, pChromaResidual+i*64);
    }
    
    if(StrmInfo->SeqInfo.dwChromaFormat == CHROMA422)
    {
      for(i=6; i<8; i++)
      {
        // ReadChromaCoff422();
      }
    }
  }
  
  return AVS_NOERROR;
}

/************************************************************************/
/* 函数功能:运动补偿、反变换、重构                                     */
/*         - 运动矢量预测                                               */
/*         - 计算预测值                                                 */
/*         - 对系数进行反变化得到残差数据                               */
/*         - 残差数据和预测数据相加,得到重构图像                       */
/************************************************************************/
AVS_HRESULT McIdctRecOneMarcroBlock(MBINFO* pMbInfo,
                                    AVS_DWORD dwMbIndex, 
                                    STREAMINFO* pStrmInfo, 
                                    const VIDEODATA** ppRefFrame, 
                                    VIDEODATA* pCurrFrame,
                                    AVS_DWORD  dwRefNum,
                                    AVS_DWORD MbWidth,
                                    AVS_DWORD MbHeight,
                                    AVS_DWORD dwCurrDistanceIndex,
                                    BWREFINFO* pBwRefInfo,
                                    AVS_SHORT* pLumaResidual,
                                    AVS_SHORT* pChromaResidual)
{
  AVS_INT block;
  
  AVS_INT MbX = dwMbIndex%MbWidth;
  AVS_INT MbY = dwMbIndex/MbWidth;
  AVS_DWORD imgWidth = pStrmInfo->SeqInfo.dwWidth;

⌨️ 快捷键说明

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