📄 bitstrm.c
字号:
/*************************************************************************This software module was originally developed by Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation Bruce Lin (blin@microsoft.com), Microsoft Corporation Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation (date: March, 1996)and edited by Yoshihiro Kikuchi (TOSHIBA CORPORATION) Takeshi Nagai (TOSHIBA CORPORATION) Toshiaki Watanabe (TOSHIBA CORPORATION) Noboru Yamaguchi (TOSHIBA CORPORATION)in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). This software module is an implementation of a part of one or more MPEG-4 Video tools as specified by the MPEG-4 Video. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. The original developer of this software module and his/her company, the subsequent editors and their companies, and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. Copyright is not released for non MPEG-4 Video conforming products. Microsoft retains full right to use the code for his/her own purpose, assign or donate the code to a third party and to inhibit third parties from using the code for non MPEG-4 Video conforming products. This copyright notice must be included in all copies or derivative works. Copyright (c) 1996, 1997.Module Name: bitstrm.cAbstract: Classes for bitstream I/O.Revision History:*************************************************************************/#include "typeapi.h"#include "codehead.h"#include "mode.h"#include "global.h"#include "bitstrm.h"#include "huffman.h"#include "vopses.h"#include "vopsedec.h"#ifdef USE_MAI#include "mai_component.h"#include "mai_compbase.h" /* for MAICompBase_BufferProcessed */#else /* STANDALONE */#include "mae_pass_thru.h"#endif#ifdef TRACE_BUILD#define DPRINTF(_args_) MAIOSDebugPrint _args_ #define DPRINTF2(_args_) MAIOSDebugPrint _args_#else#define DPRINTF(_args_) #define DPRINTF2(_args_) #endifunsigned int m_uiReadCount=0;unsigned int g_bEOFReached=0;int nBytesAvailable = 0, nTotalBytes = MAX_BUFFER_SIZE;unsigned char MyBuffer[MAX_BUFFER_SIZE];#ifdef USE_MAIextern MAICompBufferPool_t g_hInBufferPool;extern MAICompHandle_t g_hComp;extern Int g_MP4VDecodeMode;extern m_u32 g_uiWaitForIFrame;#endifInt m_lCounter=0;UInt m_uNumOfBitsInBuffer=0;int m_chDecBuffer=0;int g_nMP4VPTS = 0;void MP4V_ResetBitStream(){ /* reset all bitstream related vaiables */ m_uiReadCount=0; g_bEOFReached=0; nBytesAvailable = 0; nTotalBytes = MAX_BUFFER_SIZE; m_lCounter=0; m_uNumOfBitsInBuffer=0; m_chDecBuffer=0; g_nMP4VPTS=0;}// Get the num-bit field of x starting from position p#define getbit(num) ((unsigned int)m_chDecBuffer >> (32 - num))//#define getbit(num) ((m_chDecBuffer >> (32 - num)) & ~(0xFFFFFFFF << num))#define MP4V_PEEKHELPER(nBitsToPeek, nlocalBytes, iBitsToRet)\{\ Int chNext, iNext;\\ for (; nBitsToPeek > 0; nBitsToPeek -= 8)\ {\ chNext = MyBuffer[nTotalBytes-nlocalBytes];\ iNext = chNext & 0x000000FF;\ nlocalBytes--;\\ if (nBitsToPeek < 8)\ {\ iNext = iNext >> (8 - nBitsToPeek);\ *iBitsToRet = iNext | (*iBitsToRet << nBitsToPeek);\ }\\ else\ {\ *iBitsToRet = *iBitsToRet << 8;\ *iBitsToRet |= iNext;\ }\ }\}#ifndef USE_MAI /* STANDALONE */INLINE Void ReadFileMP4(){ unsigned int uiDataOffset=(nTotalBytes-nBytesAvailable); int iDataRead; DPRINTF((M_TEXT("ReadFileMP4() nTotalBytes=%d nBytesAvail=%d Offset=%d\n"), nTotalBytes, nBytesAvailable, uiDataOffset)); if (nBytesAvailable) /* are there still bytes left in buffer */ { /* move left over bytes to start of MyBuffer */ memmove(MyBuffer, MyBuffer+uiDataOffset, nBytesAvailable); } /* append new data to MyBuffer */ iDataRead = fread(MyBuffer+nBytesAvailable, 1, MAX_BUFFER_SIZE-nBytesAvailable, g_InFile); if (iDataRead>0) nBytesAvailable += iDataRead; // To accomodate the last buffer of the stream if (nBytesAvailable < MAX_BUFFER_SIZE) g_bEOFReached = 1; nTotalBytes = nBytesAvailable;}#else /* USE_MAI */Void ReadFileMP4(){ MAIStatus_e eStatus=MAI_STATUS_OK; MAICompBuffer_t BufferInfo; int eEOS=0; unsigned int timeout = g_bEOFReached?0:MAI_TIMEOUT_INFINITE; unsigned int uiDataOffset=(nTotalBytes-nBytesAvailable); m_bool bIsStreaming=MAICompBase_IsStreaming(g_hComp); DPRINTF((M_TEXT("MPV4: ReadFileMP4() nTotalBytes=%d nBytesAvail=%d Offset=%d\n"), nTotalBytes, nBytesAvailable, uiDataOffset)); if(nBytesAvailable <0) // Bug fix 5694. nBytesAvailable=0; if (nBytesAvailable) /* are there still bytes left in buffer */ { DPRINTF((M_TEXT("MPV4: ReadFileMP4() memmove (nBytesAvail=%d)\n"), nBytesAvailable)); /* move left over bytes to start of MyBuffer */ memmove(MyBuffer, MyBuffer+uiDataOffset, nBytesAvailable); } /* append new data after left over data */ BufferInfo.pBuffer = MyBuffer+nBytesAvailable; BufferInfo.uiBufSize = MAX_BUFFER_SIZE-nBytesAvailable; while (eStatus==MAI_STATUS_OK) /* retrieve MAI input buffers until we have an error or actual data */ { if (!bIsStreaming) timeout = 0; /* no thread running, so don't do infinite wait */ eStatus = MAICompBufferPoolRead(g_hInBufferPool,&BufferInfo, timeout); if (eStatus!=MAI_STATUS_OK) { /* nBytesAvailable should be zero when we finish last bytes */ /* nBytesAvailable = 0; */ DPRINTF2((M_TEXT("MPV4: ReadFileMP4() Setting EOS: PoolRead(%p) eStatus %d\n"), g_hInBufferPool, eStatus)); g_bEOFReached = 1; break; } else { m_uiReadCount++; DPRINTF2((M_TEXT("MPV4: ReadFileMP4() DataSize=%d PTS=%d Flags=0x%X Avail=%d Data=%02X %02X %02X %02X\n"), BufferInfo.uiDataSize, MAITIME_LO32(BufferInfo.tTimeStamp), BufferInfo.dwFlags, nBytesAvailable, BufferInfo.pBuffer[0], BufferInfo.pBuffer[1], BufferInfo.pBuffer[2], BufferInfo.pBuffer[3]));#if 0 if ((BufferInfo.dwFlags&MAICOMPBUF_FLAG_FRAMEEND) && (nBytesAvailable&3)) { /* not a multiple of 32 bits, add 0 padding */ MyBuffer[nBytesAvailable]=0; MyBuffer[nBytesAvailable+1]=0; MyBuffer[nBytesAvailable+2]=0; nBytesAvailable=(nBytesAvailable+3)&~3; DPRINTF((M_TEXT("MPV4: ReadFileMP4() Padded Avail: %d\n"), nBytesAvailable)); }#endif if ((BufferInfo.dwFlags&(MAICOMPBUF_FLAG_DATADISCON|MAICOMPBUF_FLAG_NEWFORMAT|MAICOMPBUF_FLAG_SOS))!=0) { DPRINTF2((M_TEXT("MPV4: ReadFileMP4() DATADISCON|NEWFORMAT|SOS\n"))); /* Check for stream discontinuity */ if ((BufferInfo.dwFlags&(MAICOMPBUF_FLAG_DATADISCON|MAICOMPBUF_FLAG_SOS))!=0) /* send out DATADISCON/SOS buffer */ { MAICompBuffer_t *pOutBufferInfo=M_NULL; if (MAI_STATUS_OK==MAICompBase_OutputGetBuf(g_hComp, 0, &pOutBufferInfo)) { DPRINTF2((M_TEXT("MPV4: ReadFileMP4() OutputPutBuf(datasize=0) SOS/DATADISCON pts=%d\n"), MAITIME_LO32(pOutBufferInfo->tTimeStamp))); pOutBufferInfo->dwFlags = MAICOMPBUF_FLAG_VIDEO; pOutBufferInfo->dwFlags |= BufferInfo.dwFlags&(MAICOMPBUF_FLAG_DATADISCON|MAICOMPBUF_FLAG_SOS); if ((BufferInfo.dwFlags&MAICOMPBUF_FLAG_PTS)!=0) { pOutBufferInfo->dwFlags |= MAICOMPBUF_FLAG_PTS; MAITIME_ASSIGN(BufferInfo.tTimeStamp, BufferInfo.tTimeStamp); } pOutBufferInfo->uiDataSize = 0; MAICompBase_OutputPutBuf(g_hComp, 0, pOutBufferInfo); } } if (bIsStreaming) { /* start of new point in stream or got a new buffer, report SOS to compbase */ MAICompBase_NewFrame(g_hComp, 0, MAI_FRAMETYPE_NONE, COMPBASE_NEWFRAME_FLAG_SOS); } g_uiWaitForIFrame = TRUE; //if (g_MP4VDecodeMode==DECODE_NORMAL) // g_MP4VDecodeMode=DECODE_WAITFORI; if ((BufferInfo.dwFlags&(MAICOMPBUF_FLAG_NEWFORMAT|MAICOMPBUF_FLAG_VIDEO))==(MAICOMPBUF_FLAG_NEWFORMAT|MAICOMPBUF_FLAG_VIDEO)) { DPRINTF((M_TEXT("MPV4: ReadFileMP4() NEWFORMAT: MediaType received\n"))); /* got a Video MediaType structure, don't actually pass this to the decoder */ /* MAIMediaTypeVideo_t *pMT=(MAIMediaTypeVideo_t *)BufferInfo.pBuffer; */ BufferInfo.uiDataSize=0; /* ignore this data */ } } if ((BufferInfo.dwFlags&MAICOMPBUF_FLAG_EOS)!=0) { DPRINTF((M_TEXT("MPV4: ReadFileMP4() Setting EOS: eEOS %d nBytesAvailable %d nTotalBytes %d eStatus %d\n"),eEOS,nBytesAvailable, nTotalBytes, eStatus)); eEOS=1; timeout = 0; /* we don't want to timeout on any more reads, just let decoder process EOS first */ g_bEOFReached = 1; } else g_bEOFReached=0; /* we've read data, so clear EOS */ if (BufferInfo.uiDataSize) /* we've got actual MPEG4 bitstream data */ {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -