📄 bitstream.c
字号:
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2003, Advanced Audio Video Coding Standard, Part II
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the users without any
* license fee or royalty on an "as is" basis. The AVS disclaims
* any and all warranties, whether express, implied, or statutory,
* including any implied warranties of merchantability or of fitness
* for a particular purpose. In no event shall the contributors or
* the AVS be liable for any incidental, punitive, or consequential
* damages of any kind whatsoever arising from the use of this program.
*
* This disclaimer of warranty extends to the user of this program
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The AVS does not represent or warrant that the program furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy is available from the AVS Web site at
* http://www.avs.org.cn
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
************************************************************************
*/
/*
*************************************************************************************
* File name: bitstream.c
* Function: decode bitstream
*
*************************************************************************************
*/
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "global.h"
#include "annexb.h"
#include "memalloc.h"
#define SVA_STREAM_BUF_SIZE 1024
FILE *bitsfile = NULL; //!< the bit stream file
unsigned char bit[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
typedef struct {
FILE *f;
unsigned char buf[SVA_STREAM_BUF_SIZE]; //流缓冲区,size must be large than 3 bytes
unsigned int uClearBits;//不含填充位的位缓冲,32位,初始值是0xFFFFFFFF
unsigned int uPre3Bytes;// 含填充位的位缓冲,32位,初始值是0x00000000
int iBytePosition; //当前字节位置
int iBufBytesNum; //最近一次读入缓冲区的字节数
int iClearBitsNum; //不含填充位的位的个数
int iStuffBitsNum; //已剔除的填充位的个数,遇到开始码时置0
int iBitsCount; //码流总位数
} InputStream;
InputStream IRABS;
InputStream *pIRABS = &IRABS;
void OpenIRABS(InputStream *p, char *fname)
{
p->f = fopen(fname,"rb");
if(p->f==NULL){printf ("\nCan't open file %s",fname);exit(-1);}
p->uClearBits = 0xffffffff;
p->iBytePosition = 0;
p->iBufBytesNum = 0;
p->iClearBitsNum = 0;
p->iStuffBitsNum = 0;
p->iBitsCount = 0;
p->uPre3Bytes = 0;
}
void CloseIRABS(InputStream *p)
{
fclose(p->f);
}
//------------------------------------------------------------------------
// move iBytePosition to the next byte of start code prefix
//return
// 0 : OK
// -1 : arrive at stream end and start code is not found
// -2 : p->iBytePosition error
//-------------------------------------------------------------------------
int NextStartCode(InputStream *p)
{
int i, m;
unsigned char a,b; // a b 0 1 2 3 4 ... M-3 M-2 M-1
m=0; // cjw 20060323 for linux envi
while(1)
{
if(p->iBytePosition >= p->iBufBytesNum - 2) //if all bytes in buffer has been searched
{
m = p->iBufBytesNum - p->iBytePosition;
if(m <0) return -2; // p->iBytePosition error
if(m==1) b=p->buf[p->iBytePosition+1];
if(m==2){ b=p->buf[p->iBytePosition+1]; a=p->buf[p->iBytePosition];}
p->iBufBytesNum = fread(p->buf,1,SVA_STREAM_BUF_SIZE,p->f);
p->iBytePosition = 0;
}
if(p->iBufBytesNum + m < 3)
return -1; //arrive at stream end and start code is not found
if(m==1 && b==0 && p->buf[0]==0 && p->buf[1]==1)
{
p->iBytePosition = 2;
p->iClearBitsNum = 0;
p->iStuffBitsNum = 0;
p->iBitsCount += 24;
p->uPre3Bytes = 1;
return 0;
}
if(m==2 && b==0 && a==0 && p->buf[0]==1)
{
p->iBytePosition = 1;
p->iClearBitsNum = 0;
p->iStuffBitsNum = 0;
p->iBitsCount += 24;
p->uPre3Bytes = 1;
return 0;
}
if(m==2 && b==0 && p->buf[0]==0 && p->buf[1]==1)
{
p->iBytePosition = 2;
p->iClearBitsNum = 0;
p->iStuffBitsNum = 0;
p->iBitsCount += 24;
p->uPre3Bytes = 1;
return 0;
}
for(i = p->iBytePosition; i < p->iBufBytesNum - 2; i++)
{
if(p->buf[i]==0 && p->buf[i+1]==0 && p->buf[i+2]==1)
{
p->iBytePosition = i+3;
p->iClearBitsNum = 0;
p->iStuffBitsNum = 0;
p->iBitsCount += 24;
p->uPre3Bytes = 1;
return 0;
}
p->iBitsCount += 8;
}
p->iBytePosition = i;
}
}
//----------------------------------------------------------------------
//return
// 0 : OK
// -1 : arrive at stream end
// -2 : meet another start code
//----------------------------------------------------------------------
int ClearNextByte(InputStream *p)
{
int i,k,j;
unsigned char temp[3];
i = p->iBytePosition;
k = p->iBufBytesNum - i;
if(k < 3)
{
for(j=0;j<k;j++) temp[j] = p->buf[i+j];
p->iBufBytesNum = fread(p->buf+k,1,SVA_STREAM_BUF_SIZE-k,p->f);
if(p->iBufBytesNum == 0)
{
if(k>0)
{
p->uPre3Bytes = ((p->uPre3Bytes<<8) | p->buf[i]) & 0x00ffffff;
if(p->uPre3Bytes < 4)
{
p->uClearBits = (p->uClearBits << 6) | (p->buf[i] >> 2);
p->iClearBitsNum += 6;
}
else
{
p->uClearBits = (p->uClearBits << 8) | p->buf[i];
p->iClearBitsNum += 8;
}
p->iBytePosition++;
return 0;
}
else
{
return -1;//arrive at stream end
}
}
else
{
for(j=0;j<k;j++) p->buf[j] = temp[j];
p->iBufBytesNum += k;
i = p->iBytePosition = 0;
}
}
if(p->buf[i]==0 && p->buf[i+1]==0 && p->buf[i+2]==1) return -2;// meet another start code
p->uPre3Bytes = ((p->uPre3Bytes<<8) | p->buf[i]) & 0x00ffffff;
if(p->uPre3Bytes < 4)
{
p->uClearBits = (p->uClearBits << 6) | (p->buf[i] >> 2);
p->iClearBitsNum += 6;
}
else
{
p->uClearBits = (p->uClearBits << 8) | p->buf[i];
p->iClearBitsNum += 8;
}
p->iBytePosition++;
return 0;
}
//----------------------------------------------------------
//return
// 0 : OK
// -1 : arrive at stream end
// -2 : meet another start code
//----------------------------------------------------------
int read_n_bit(InputStream *p,int n,int *v)
{
int r;
unsigned int t;
while(n > p->iClearBitsNum)
{
r = ClearNextByte( p );
if(r)
{
if(r==-1)
{
if(p->iBufBytesNum - p->iBytePosition > 0)
break;
}
return r;
}
}
t = p->uClearBits;
r = 32 - p->iClearBitsNum;
*v = (t << r) >> (32 - n);
p->iClearBitsNum -= n;
return 0;
}
//==================================================================================
void OpenBitstreamFile (char *fn)
{
OpenIRABS(pIRABS, fn);
}
void CloseBitstreamFile()
{
CloseIRABS(pIRABS);
}
static int FindStartCode (unsigned char *Buf, int i)
{
if(Buf[i]==0 && Buf[i+1]==0 && Buf[i+2]==1)
return 1;
else
return 0;
}
////////////////////////////////////////////////////////////////////////////
//check slice start code jlzheng 6.30
////////////////////////////////////////////////////////////////////////////
int checkstartcode() //check slice start code jlzheng 6.30
{
int temp_i, temp_val;
if (currStream->bitstream_length*8 - currStream->frame_bitoffset == 0)
return 1;
if(img->current_mb_nr == 0)
{
//--- added by Yulj 2004.07.15
if ( currStream->bitstream_length*8 - currStream->frame_bitoffset <=8
&& currStream->bitstream_length*8 - currStream->frame_bitoffset > 0 ){
temp_i = currStream->bitstream_length*8 - currStream->frame_bitoffset;
assert( temp_i > 0 );
temp_val = get_uv(temp_i, "filling data") ;
}
}
// if(img->current_mb_nr == 0) //commented by cjw AVS 20070204
// {
// if(StartCodePosition>6 && StartCodePosition<20)
// return 1;
// else
// {
// currStream->frame_bitoffset = currentbitoffset;
// return 0;
// }
// }
if(img->current_mb_nr == 0) //added by cjw AVS 20070327
{
if(StartCodePosition>6 && StartCodePosition<0x000fffff)//zhangji 2007 01 30
return 1;
else
{
currStream->frame_bitoffset = currentbitoffset;
return 0;
}
}
if(img->current_mb_nr != 0)
{
//--- added by Yulj 2004.07.15
if (currStream->bitstream_length*8 - currStream->frame_bitoffset <= 8
&& currStream->bitstream_length*8 - currStream->frame_bitoffset >0){
temp_i = currStream->bitstream_length*8 - currStream->frame_bitoffset;
assert( temp_i > 0 );
temp_val = get_uv(temp_i, "filling data") ;
if ( temp_val == (1 << (temp_i -1)) && img->cod_counter <= 0 )
return 1; // last MB in current slice
}
return 0; // not last MB in current slice
//---end
}
return 1;
}
//------------------------------------------------------------
// buf : buffer
// startcodepos :
// length :
int GetOneUnit (char *buf,int *startcodepos,int *length)
{
int i,j,k;
i = NextStartCode(pIRABS);
if(i!=0)
{
if(i==-1) printf("\narrive at stream end and start code is not found!");
if(i==-2) printf("\np->iBytePosition error!");
exit(i);
}
buf[0] = 0;
buf[1] = 0;
buf[2] = 1;
*startcodepos = 3;
i = read_n_bit(pIRABS,8,&j);
buf[3] = (char)j;
if(buf[3]==SEQUENCE_END_CODE)
{
*length = 4;
return -1;
}
k = 4;
while(1)
{
i = read_n_bit(pIRABS,8,&j);
if(i<0) break;
buf[k++] = (char)j;
}
if(pIRABS->iClearBitsNum>0)
{
int shift;
shift = 8 - pIRABS->iClearBitsNum;
i = read_n_bit(pIRABS,pIRABS->iClearBitsNum,&j);
if(j!=0) //qhg 20060327 for de-emulation.
buf[k++] = (char)(j<<shift);
}
*length = k;
return k;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -