www.pudn.com > AVS.rar > decode.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 
*************************************************************************/ 
/************************************************************************* 
  本代码为AVS1-P2标准视频解码器的源代码,实现了AVS1-P2标准文本中所规定的 
  绝大部分功能,但不包括: 
  1) 多Slice结构 
  2) 加权预测 
  3) 去伪起始码 
 *************************************************************************/ 
/************************************************************************* 
  Revision History 
  data          Modification                                    Author 
  2005-2-8      Created                                          jthou 
 *************************************************************************/ 
 
/************************************************************************* 
  文件名称:	decode.cpp 
  描    述: 包含main函数, 
*************************************************************************/ 
#include  
#include  
#include "define.h" 
#include "global.h" 
#include "decode.h" 
#include "stream.h" 
#include "memory.h" 
#include "malloc.h" 
#include "vlc.h" 
#include "block.h" 
#include "macroblock.h" 
#include "loopfilter.h" 
#include "image.h" 
#include  
#include  
 
/************************************************************************/ 
/* main函数                                                             */ 
/*		argv[1] 被解码压缩流路径                                        */ 
/*		argv[2] 解后YUV数据存放路径                                     */ 
/*		argv[3] 要解码的帧数                                            */ 
/*		argv[4] WriteFlag,是否将解码结果写入文件                        */ 
/************************************************************************/ 
 
 
AVS_HRESULT DecodeOneFrame(AVS_BYTE* pbData, 
                     AVS_DWORD dwFrameLen, 
                     STREAMINFO* StrmInfo,  
                     VIDEODATA** ppRefFrame, 
                     VIDEODATA** pCurrFrame,  
                     MBINFO* pMbInfo, 
                     BWREFINFO* pBwRefInfo) 
{ 
  AVS_BYTE* pbCurrent = pbData;  
  AVS_DWORD dwCode = *(AVS_DWORD*)pbCurrent; 
  AVS_DWORD dwBitOffset = 0; 
 
  if(DWORD_SWAP(dwCode)!=I_FRAME_START_CODE && DWORD_SWAP(dwCode)!=PB_FRAME_START_CODE) 
    return AVS_NOT_VALID_PIC_DATA; 
 
  GetImgHeaderInfo(pbCurrent, dwFrameLen, &dwBitOffset, StrmInfo); 
 
  AVS_DWORD imgWid = StrmInfo->SeqInfo.dwWidth; 
  AVS_DWORD imgHei = StrmInfo->SeqInfo.dwHeight; 
 
  StrmInfo->ImgInfo.dwImageType1 = StrmInfo->ImgInfo.dwImageType; 
 
  if(StrmInfo->ImgInfo.bPictureStructure) 
  { 
    // frame type decoding... 
    (*pCurrFrame)->dwDistanceIndex = StrmInfo->ImgInfo.dwPictureDistance * 2; 
    PictureData(pbCurrent,  
      dwFrameLen, 
      &dwBitOffset, 
      StrmInfo,  
      ppRefFrame, 
      *pCurrFrame,  
      pMbInfo,  
      pBwRefInfo); 
  } 
  else 
  { 
    return THIS_VERSION_NOT_SUPPORT; 
  } 
   
  if(StrmInfo->ImgInfo.dwImageType != B_IMG) 
  { 
    UpdateRefBuffer(&ppRefFrame, &pCurrFrame, 2); 
  } 
 
  return AVS_NOERROR;    
} 
 
/************************************************************************/ 
/* 函数功能:初始化解码器                                               */ 
/*         - 初始化VLC表                                                */ 
/*         - 初始化Clip表                                               */ 
/*         - 初始化TabBuf(替代解码过程中的取绝对值)                     */  
/*         - 分析序列头                                                 */ 
/************************************************************************/ 
AVS_HRESULT InitDecode(const AVS_BYTE* pbData, AVS_DWORD dwDataLen, STREAMINFO* strmInfo) 
{ 
  const AVS_BYTE* pbCurrent = pbData; 
  AVS_DWORD dwLeft = dwDataLen; 
 
  MakeVlcTable(); 
  MakeClipTable(); 
  MakeTabNoBuf(); 
 
  while(dwLeft > 18) 
  { 
    AVS_DWORD dwCode = *(AVS_DWORD*)pbCurrent; 
    if((dwCode & 0x00FFFFFF) == 0x00010000) 
    { 
      dwCode = DWORD_SWAP(dwCode);   
      if(dwCode == SEQENCE_START_CODE) 
      { 
        AVS_DWORD dwHeadLen = SeqenceHeader(pbCurrent, dwLeft, &(strmInfo->SeqInfo)); 
        pbCurrent += dwHeadLen; 
        dwLeft -= dwHeadLen; 
        break; 
      } 
    } 
    pbCurrent++; 
    dwLeft--; 
  } 
  return dwLeft; 
} 
 
AVS_DWORD PictureData(AVS_BYTE*   pbData, 
                  AVS_DWORD         dwFrameLen, 
                  AVS_DWORD*        pdwBitOffset, 
                  STREAMINFO*   StrmInfo, 
                  VIDEODATA**   ppRefFrame,  
                  VIDEODATA*    pCurrFrame,  
                  MBINFO*       pMbInfo, 
                  BWREFINFO*    pBwRefInfo) 
{ 
  AVS_BYTE* pbCurrent = pbData; 
  AVS_DWORD dwLeft = dwFrameLen; 
  AVS_DWORD MbIndex = 0; 
  AVS_DWORD MbWidth = StrmInfo->SeqInfo.dwMbWidth; 
  AVS_DWORD MbHeight = StrmInfo->SeqInfo.dwMbHeight; 
  AVS_DWORD MbNum = MbHeight * MbWidth; 
  AVS_INT   cod_counter = -1; 
 
  AVS_DWORD dwImgWidth = StrmInfo->SeqInfo.dwWidth; 
  AVS_SHORT LumaCoef[256]; 
  AVS_SHORT ChromaCoef[256]; 
 
  AVS_DWORD dwCurrDistanceIndex = pCurrFrame->dwDistanceIndex; 
 
  for(MbIndex=0; MbIndex>3)<<3); 
      while(!IsSliceHeader(pbCurrent, offset)) 
      { 
        offset += 8; 
        if(offset > 20*8) 
          break; 
      } 
      if(IsSliceHeader(pbCurrent, offset)) 
      {  
        *pdwBitOffset = offset;                           
        *pdwBitOffset += 32; 
        SliceHeader(pbCurrent, dwLeft, MbIndex, pdwBitOffset, StrmInfo); 
      } 
    } 
 
    ParseOneMacroBlock( 
      &pbCurrent,  
      dwLeft,  
      pdwBitOffset, 
      StrmInfo,  
      pMbInfo,  
      MbIndex, 
      &cod_counter, 
      LumaCoef, 
      ChromaCoef);   
 
 
    McIdctRecOneMarcroBlock( 
      pMbInfo,  
      MbIndex,  
      StrmInfo,  
      (const VIDEODATA**)ppRefFrame,  
      pCurrFrame,  
      2, 
      MbWidth, 
      MbHeight, 
      dwCurrDistanceIndex, 
      pBwRefInfo, 
      LumaCoef, 
      ChromaCoef);   
  } 
  for(MbIndex=0; MbIndex>4, 
        StrmInfo, 
        pCurrFrame 
        ); 
    }    
     
  return AVS_NOERROR; 
}