www.pudn.com > avs-m3.rar > 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  
//#include  
#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;jbuf[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;jbuf[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<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<streamBuffer[bitstream_length-1] & (0x01<<(bitoffset)); 
  } 
   
  trailingbits = (0x01 << bitoffset); 
 
 
#if TRACE 
  tracebits2("Byte Stream Trailing Bits",(bitoffset+1),trailingbits); 
#endif 
 
}