📄 annexb.c
字号:
/*!
*************************************************************************************
* \file
* bitstream.c
* \brief
* bitstream handling including high-level syntax parset and NAL de-compression etc.
* \notes:
* upadated @ June 14th 2005 according to the FCD
*************************************************************************************
*/
#include <stdlib.h>
//#include <memory.h>
#include "global.h"
#include "annexb.h"
#include "memalloc.h"
#include "nalu.h"
FILE *bits = NULL; //!< the bit stream file
InputStream IRABS , *pIRABS = &IRABS;
/*!
*************************************************************************************
* \brief :
* Open the Byte Stream
*************************************************************************************
*/
void OpenAnnexbFile(char *fn)
{
if ( NULL == (bits=fopen(fn, "rb")) ) //!< open bitstream file in bit format
{
snprintf (errortext, ET_SIZE, "Cannot open Annex B ByteStream file '%s'", input->infile);
error(errortext,500);
}
}
/*!
*************************************************************************************
* \brief :
* Close the Byte Stream
*************************************************************************************
*/
void CloseAnnexbFile()
{
fclose(bits);
}
/*!
*************************************************************************************
* \brief :
* get the current nalu_header
* \notes :
* code : OK
* -1 : arrive at stream end and start code is not found
* -2 : Pop->iBytesition error
*************************************************************************************
*/
int GetNaluHeader(InputStream *p)
{
int i, m=0;//change m=0 by stephen for debug
unsigned char a,b,c; // a b c 0 1 2 3 4 ... M-3 M-2 M-1
while(1)
{
if(p->iBytePosition >= p->iBufBytesNum - 3) //if all bytes in buffer has been searched
{
m = p->iBufBytesNum - p->iBytePosition;
if(m <0)
return -2; // p->iBytePosition error
if(m==1) c=p->buf[p->iBytePosition];
if(m==2){ c=p->buf[p->iBytePosition+1]; b=p->buf[p->iBytePosition];}
if(m==3){ c=p->buf[p->iBytePosition+2]; b=p->buf[p->iBytePosition+1];a=p->buf[p->iBytePosition];}
p->iBufBytesNum = fread(p->buf,1,SVA_STREAM_BUF_SIZE,bits);
p->iBytePosition = 0;
}
if(p->iBufBytesNum + m < 4) return -1; //arrive at stream end and start code is not found
if(m==1 && c==0 && p->buf[0]==0 && p->buf[1]==1)
{
p->iBytePosition = 3;
p->iClearBitsNum = 0;
p->iStuffBitsNum = 0;
p->iBitsCount += 32;
p->uPre3Bytes = p->buf[2]+256;
//printf("p->uPre3Bytes is %x n1\n",p->uPre3Bytes);
return p->buf[2];
}
if(m==2 && b==0 && c==0 && p->buf[0]==1)
{
p->iBytePosition = 2;
p->iClearBitsNum = 0;
p->iStuffBitsNum = 0;
p->iBitsCount += 32;
p->uPre3Bytes = p->buf[1]+256;
//printf("p->uPre3Bytes is %x n2\n",p->uPre3Bytes);
return p->buf[1];
}
if(m==3 && a==0 && b==0 && c==1)
{
p->iBytePosition = 1;
p->iClearBitsNum = 0;
p->iStuffBitsNum = 0;
p->iBitsCount += 32;
p->uPre3Bytes = p->buf[0]+256;
//printf("p->uPre3Bytes is %x n3\n",p->uPre3Bytes);
return p->buf[0];
}
for(i = p->iBytePosition; i < p->iBufBytesNum - 3; i++)
{
if(p->buf[i]==0 && p->buf[i+1]==0 && p->buf[i+2]==1)
{
p->iBytePosition = i+4;
p->iClearBitsNum = 0;
p->iStuffBitsNum = 0;
p->iBitsCount += 24;
p->uPre3Bytes = p->buf[i+3]+256;
//printf("p->uPre3Bytes is %x n0\n",p->uPre3Bytes);
return p->buf[i+3];
}
p->iBitsCount += 8;
}
p->iBytePosition = i;
}
}
/*!
*************************************************************************************
* \brief :
* read one byte of the nalu payload
* \notes :
* code : meet the nalu header
* -1 : arrive at stream end
* -2 : OK
*************************************************************************************
*/
int read_1_byte(InputStream *p, int *value)
{
int i,k,j;
unsigned char temp[4];
int read_len=0;//WJP FOR NAL ADD
i = p->iBytePosition;
k = p->iBufBytesNum - i;
if(k < 4)
{
for(j=0;j<k;j++)
temp[j] = p->buf[i+j];
read_len/*p->iBufBytesNum*/ = fread(p->buf+k,1,SVA_STREAM_BUF_SIZE-k,bits);//WJP FOR NAL ADD
if(read_len == 0)//WJP FOR NAL ADD
{
if(k>0)
{
p->uClearBits = (p->uClearBits << 8) | p->buf[i];
p->iClearBitsNum += 8;
p->iBytePosition++;
*value = p->buf[i];
return -2;
}
else
{
return -1;//arrive at stream end
}
}
else
{
for(j=0;j<k;j++)
p->buf[j] = temp[j];
p->iBufBytesNum = read_len + k;//WJP FOR NAL ADD
i = p->iBytePosition = 0;
}
}
if(p->buf[i]==0 && p->buf[i+1]==0 && p->buf[i+2]==1)
{
//printf("The next code is %x c\n",p->buf[i+3]);
return p->buf[i+3];// meet another start code
}
p->uPre3Bytes = ((p->uPre3Bytes<<8) | p->buf[i]) & 0x00ffffff;
p->uClearBits = (p->uClearBits << 8) | p->buf[i];
p->iClearBitsNum += 8;
p->iBytePosition++;
*value = p->buf[i];
return -2;
}
/*!
*************************************************************************************
* \brief :
* get the a unit start with a start code.
* \notes :
* code : meet the nalu header
* -1 : arrive at stream end
* -2 : OK
*************************************************************************************
*/
int GetOneUnit (NALU_t *nalu, int *next_nalu_type)
{
int i,j,k;
int nalu_over=0;
i = GetNaluHeader(pIRABS);
nalu->buf[0] = i;
nalu->nal_unit_type = i & 31;
i >>= 5;
nalu->nal_reference_idc = i & 3;
i >>= 2;
nalu->forbidden_bit = i & 1;
#if ERR_REPORT
CheckNALUValid(nalu->buf[0],p_err);
#endif
//GET the nalu payload and find the next nalu type
k=1;
while(!nalu_over)
{
i = read_1_byte(pIRABS,&j);
//code : meet the nalu header
// -1 : arrive at stream end
// -2 : OK
if(i == -2)
nalu->buf[k++] = (char)j;
else if(i == -1)
{
*next_nalu_type = -1;
break;
}
else
{
nalu_over = 1;
*next_nalu_type = i & 31;
}
}
nalu->len = k;
return 1;
}
void DecodeTrailingBits(Bitstream *bitstream)
{
int ctr_bit, bitoffset, trailingbits;
bitoffset = 0;
//find trailing 1
ctr_bit = (bitstream->streamBuffer[currStream->bitstream_length-1] & (0x01<<bitoffset)); // set up control bit
while (ctr_bit==0)
{ // find trailing 1 bit
bitoffset++;
//if(bitoffset == 8)
//{
// if(last_byte_pos == 0)
// printf(" Panic: All zero data sequence in RBSP \n");
// assert(last_byte_pos != 0);
// last_byte_pos -= 1;
// bitoffset = 0;
// }
ctr_bit= bitstream->streamBuffer[currStream->bitstream_length-1] & (0x01<<(bitoffset));
}
trailingbits = (0x01 << bitoffset);
#if TRACE
tracebits2("Byte Stream Trailing Bits",(bitoffset+1),trailingbits);
#endif
}
void DecodeTrailingBits1(Bitstream *bitstream,int bitstream_length)
{
int ctr_bit, bitoffset, trailingbits;
bitoffset = 0;
//find trailing 1
ctr_bit = (bitstream->streamBuffer[bitstream_length-1] & (0x01<<bitoffset)); // set up control bit
while (ctr_bit==0)
{ // find trailing 1 bit
bitoffset++;
//if(bitoffset == 8)
//{
// if(last_byte_pos == 0)
// printf(" Panic: All zero data sequence in RBSP \n");
// assert(last_byte_pos != 0);
// last_byte_pos -= 1;
// bitoffset = 0;
// }
ctr_bit= bitstream->streamBuffer[bitstream_length-1] & (0x01<<(bitoffset));
}
trailingbits = (0x01 << bitoffset);
#if TRACE
tracebits2("Byte Stream Trailing Bits",(bitoffset+1),trailingbits);
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -