www.pudn.com > VC_Standalone.rar > avsdeclib.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) 场编码(field coding) 
  2) 多Slice结构 
  3) 加权预测 
  4) 去伪起始码 
 *************************************************************************/ 
/************************************************************************* 
  Revision History 
  data          Modification                                    Author 
  2006-3-12     Created                                          jthou 
 *************************************************************************/ 
#include "define.h" 
#include "avsdeclib.h" 
#include "global.h" 
#include "decode.h" 
#include "stream.h" 
 
////////////////////////////////////////////////////////////////////////// 
// global variables 
 
  STREAMINFO strmInfo; 
  AVS_BYTE* pbBuf = (AVS_BYTE*)calloc(INBUFLEN*2, sizeof(AVS_BYTE)); 
 
  VIDEODATA* videoBuf[3]; 
  VIDEODATA* pRefFrame[2]; 
  VIDEODATA* pCurrFrame; 
  VIDEODATA* videoFieldBuf[5]; 
  VIDEODATA* pRefField[4]; 
  MBINFO* pMbInfo; 
  BWREFINFO* pBwRefInfo; 
  bool firstFrame; 
 
int OpenAVSDec(BYTE* pbData, int len, SEQ_INFO* pInfo) 
{ 
  if(DWORD_SWAP(*(AVS_DWORD*)pbData)!= SEQENCE_START_CODE) 
    return AVS_FALSE; 
  if(len < 20) 
    return AVS_NOT_ENOUGH_DATA; 
 
  pBwRefInfo =  new BWREFINFO[MAX_MB_NUM]; 
  pMbInfo = new MBINFO[MAX_MB_NUM]; 
  firstFrame = 1; 
 
  GetMem(videoBuf, 3); 
  GetMem(videoFieldBuf, 5); 
 
  // Init reference frame buffer 
  pRefFrame[0] = videoBuf[0]; 
  pRefFrame[1] = videoBuf[1]; 
  pCurrFrame = videoBuf[2]; 
 
  InitDecode(pbData, len, &strmInfo); 
 
  pInfo->image_width = strmInfo.SeqInfo.dwWidth; 
  pInfo->image_height = strmInfo.SeqInfo.dwHeight; 
  pInfo->frame_rate = strmInfo.SeqInfo.fFrameRate; 
} 
 
int GetOneFrameBitsFromBuffer(unsigned char *pFrameBuf, int iBufLen, int *pFrameLen, int* pNoUseDataLen) 
{ 
  AVS_BYTE* pbData = pFrameBuf; 
  AVS_INT iLeft = iBufLen; 
  AVS_INT iNoUseDatalen = 0; 
   
  *pFrameLen = 0; 
  *pNoUseDataLen = 0; 
   
  while (pbData[0] != 0x00 || 
    pbData[1] != 0x00 || 
    pbData[2] != 0x01) 
  { 
    pbData ++; 
    iLeft --; 
    (*pNoUseDataLen) ++; 
    if(iLeft < 4) 
      return 0; 
  } 
 
  while(1) 
  { 
    switch(pbData[(*pNoUseDataLen)+3]) 
    { 
    case 0xB0:    // Sequence Header  
     if(!FindNextPicOrEndStartCode(pbData, iBufLen, (AVS_DWORD*)&iLeft)) 
       return AVS_NOT_ENOUGH_DATA; 
      SeqenceHeader(pbData, iBufLen, &(strmInfo.SeqInfo)); 
       
      *pNoUseDataLen += iBufLen-iLeft; 
      break; 
    case 0xB5:    // Extension  
     if(!FindNextPicOrEndStartCode(pbData+*pNoUseDataLen, iBufLen, (AVS_DWORD*)&iLeft)) 
       return AVS_NOT_ENOUGH_DATA; 
      *pNoUseDataLen += iBufLen-iLeft; 
      break; 
    case 0xB2:    // User Data 
     if(!FindNextPicOrEndStartCode(pbData+*pNoUseDataLen, iBufLen, (AVS_DWORD*)&iLeft)) 
       return AVS_NOT_ENOUGH_DATA; 
      *pNoUseDataLen = iBufLen-iLeft; 
      break; 
    case 0xB3:    // I frame 
     if(!FindNextPicOrEndStartCode(pbData+*pNoUseDataLen, iBufLen, (AVS_DWORD*)&iLeft)) 
       return AVS_NOT_ENOUGH_DATA; 
      *pFrameLen = iBufLen-iLeft+*pNoUseDataLen; 
      return 1; 
    case 0xB6:    // PB frame 
     if(!FindNextPicOrEndStartCode(pbData+*pNoUseDataLen, iBufLen, (AVS_DWORD*)&iLeft)) 
       return AVS_NOT_ENOUGH_DATA; 
      *pFrameLen = iBufLen-iLeft+*pNoUseDataLen; 
      return 1; 
    case 0xB1:    // Sequence End 
      return 0; 
    } 
  } 
} 
 
int DecOneFrameFromBuffer(unsigned char *pbData, int iFrameLen, BYTE** ppOutY, BYTE** ppOutU, BYTE** ppOutV) 
{ 
  if(DWORD_SWAP(*(AVS_DWORD*)pbData)==I_FRAME_START_CODE || DWORD_SWAP(*(AVS_DWORD*)pbData) == PB_FRAME_START_CODE) 
  { 
    DecodeOneFrame(pbData, iFrameLen, &strmInfo, pRefFrame, &pCurrFrame, pMbInfo, pBwRefInfo); 
  } 
  if(firstFrame) 
  { 
    *ppOutY = pRefFrame[0]->y; 
    *ppOutU = pRefFrame[0]->u; 
    *ppOutV = pRefFrame[0]->v;  
    firstFrame = FALSE; 
  } 
  else if((strmInfo.ImgInfo.dwImageType != B_IMG )) 
  { 
    *ppOutY = pRefFrame[1]->y; 
    *ppOutU = pRefFrame[1]->u; 
    *ppOutV = pRefFrame[1]->v;  
  } 
  else 
  { 
    *ppOutY = pCurrFrame->y; 
    *ppOutU = pCurrFrame->u; 
    *ppOutV = pCurrFrame->v;  
  } 
 
  return AVS_NOERROR; 
} 
 
void CloseAVSDec() 
{ 
  delete []pBwRefInfo; 
  delete []pMbInfo; 
  ReleaseMem(videoBuf, 3); 
  ReleaseMem(videoFieldBuf, 5); 
}