www.pudn.com > wm2.5.zip > bitstream.c


/*! 
 ************************************************************************************* 
 * \file bitstream.c 
 * 
 * \brief 
 *     
 * 
 * \date: updating  
 *      
 * \author     
 *     
 ************************************************************************************* 
 */ 
 
#include  
#include  
#include  
 
#include "global.h" 
#include "bitstream.h" 
#include "memalloc.h" 
#include "nalu.h"//WJP FOR NAL 
 
//////////////////////////////////////////////////////////////////////////////// 
 
FILE *bits = NULL;                //!< the bit stream file 
//WJP FOR SLICE 
//extern int Position_of_Slice_in_Picbuff[176]; 
//extern int Slice_Enable; 
#define SVA_STREAM_BUF_SIZE 1024 
 
//unsigned char bit[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; 
 
typedef struct { 
	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 IRABS , *pIRABS = &IRABS; 
/* 
************************************************************************* 
* Function:get the current nalu_header. 
* Input: 
* Output: 
* Return:  
		  code	:	OK 
		  -1	:	arrive at stream end and start code is not found 
		  -2	:	Pop->iBytesition error 
* Author: Jianpeng Wang 
************************************************************************* 
*/ 
int GetNaluHeader(InputStream *p) 
{ 
	int i, m; 
	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; 
	} 
} 
/* 
************************************************************************* 
* Function:read one byte of the nalu payload 
* Input: 
* Output: 
* Return:  
		  code	:	meet the nalu header 
		  -1	:	arrive at stream end 
		  -2	:	OK 
* Author: Jianpeng Wang 
************************************************************************* 
*/ 
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;	 
} 
 
/* 
************************************************************************* 
* Function:get the a unit start with a start code. 
* Input: 
* Output: 
* Return:  
* Attention:	Modified by Jianpeng Wang 
************************************************************************* 
*/ 
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; 
 
	//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; 
}