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


/* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2004, 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. 
************************************************************************ 
*/   
 
#include "stdio.h" 
#include "stdlib.h" 
#include "string.h" 
#include "malloc.h" 
 
#include "types.h" 
#include "global.h" 
#include "define.h" 
#include "bitstream.h" 
#include  "vlc.h" 
 
#include "nalu.h" //WJP FOR NAL 
//WJP FOR SLICE 
unsigned char bit[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; 
OutputStream  ORABS; 
OutputStream *pORABS = &ORABS; 
//WJP END 
/* 
************************************************************************* 
* Function:allocate memory for the coded picture data 
* Input: 
* Output: 
* Return:  
************************************************************************* 
*/ 
void AllocateBitstream(void) 
{ 
	//added by MAZHAN 
	//const int buffer_size = (pgImage->img_width * pgImage->img_width * 4);  
	//bugs fixed....zhan ma 12.23 
	const int buffer_size = (pgImage->img_width * pgImage->img_height * 4);  
		 
	if ((pgcurrBitStream->streamBuffer = (Byte *) calloc(buffer_size, sizeof(Byte))) == NULL) 
		no_mem_exit ("malloc_slice: StreamBuffer"); 
	 
	pgcurrBitStream->bits_to_go = 8; 
} 
 
/* 
************************************************************************* 
* Function:free the allocated memory for the coded picture data 
* Input: 
* Output: 
* Return:  
************************************************************************* 
*/ 
void FreeBitstream(void) 
{ 
	if (pgcurrBitStream->streamBuffer) 
		free(pgcurrBitStream->streamBuffer); 
} 
 
/* 
************************************************************************* 
* Function:initialize the coded picture buffer 
* Input: 
* Output: 
* Return:  
************************************************************************* 
*/ 
void Init_Bitstream(void) 
{ 
	pgcurrBitStream->bits_to_go        = 8; 
	pgcurrBitStream->byte_buf          = 0; 
	pgcurrBitStream->byte_pos          = 0; 
} 
 
 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
************************************************************************* 
*/ 
int write_1_bit(OutputStream *p,int b) 
{ 
	int i; 
	 
	if(p->iBitOffset==6) 
	{ 
		i = p->uPreBytes & 0x003fffff; 
		if(i == 0) 
		{ 
			p->buf[p->iBytePosition] = 0x02; 
			p->iBytePosition++; 
			p->iBitOffset		= 0; 
			p->uPreBytes		= 0x00000002; 
			p->iNumOfStuffBits	+= 2; 
			p->iBitsCount		+= 2; 
			printf("emulation\n");//²âÊÔ 
		} 
	} 
 
	if(p->iBytePosition == SVA_STREAM_BUF_SIZE) 
	{ 
		i = fwrite(p->buf,1,SVA_STREAM_BUF_SIZE,pgcurrBitStream->f); 
		if(i!=SVA_STREAM_BUF_SIZE) 
		{ 
			printf ("Fatal: write file error, exit (-1)\n"); 
			exit (-1); 
		} 
		p->iBytePosition	= 0; 
		p->iBitOffset		= 0; 
	} 
 
	p->uPreBytes <<= 1; 
 
	if(b) 
	{ 
		p->buf[p->iBytePosition] |= bit[p->iBitOffset]; 
		p->uPreBytes |= 1; 
	} 
	else 
	{ 
		p->buf[p->iBytePosition] &= (~bit[p->iBitOffset]); 
	} 
 
	p->iBitOffset++; 
 
	if(p->iBitOffset==8) 
	{ 
		p->iBitOffset = 0; 
		p->iBytePosition++; 
	} 
 
	p->iBitsCount++; 
 
	return 0; 
} 
/* 
 *	 
 */ 
int write_n_bit(OutputStream *p,int b,int n) 
{ 
	if(n>30) 
		return 1; 
 
	while(n>0) 
	{ 
		write_1_bit(p,b&(0x01<<(n-1))); 
		n--; 
	} 
 
	return 0; 
} 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
************************************************************************* 
*/ 
int write_align_stuff(OutputStream *p) 
{ 
	unsigned char c; 
 
	if(p->iBitOffset == 0) 
		return 0; 
 
	c = 0xff << ( 7 - p->iBitOffset ); 
	p->buf[p->iBytePosition] = (c & p->buf[p->iBytePosition])|(0x80>>(p->iBitOffset)); 
	p->iBitsCount += 8 - p->iBitOffset; 
	p->uPreBytes	= (p->uPreBytes << (8 - p->iBitOffset)) & c; 
	p->iNumOfStuffBits	+= 8 - p->iBitOffset; 
	p->iBitOffset = 0; 
	p->iBytePosition++; 
 
	return 0; 
} 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
************************************************************************* 
*/ 
int write_start_code(OutputStream *p,unsigned char code) 
{ 
	int i; 
 
	if(p->iBitOffset) 
		write_align_stuff(p); 
 
	if(p->iBytePosition >= SVA_STREAM_BUF_SIZE-4 && p->iBytePosition >0 ) 
	{ 
		i = fwrite(p->buf,1,p->iBytePosition,pgcurrBitStream->f); 
		if(i != p->iBytePosition) 
		{ 
			printf ("\nWrite file error"); 
			exit (-1); 
		} 
		p->iBytePosition	= 0; 
		p->iBitOffset		= 0; 
	} 
 
	p->buf[p->iBytePosition  ] = 0; 
	p->buf[p->iBytePosition+1] = 0; 
	p->buf[p->iBytePosition+2] = 1; 
	p->buf[p->iBytePosition+3] = code; 
	//printf("this start code is %x \n",code); 
	p->iBytePosition += 4; 
	p->iBitsCount += 32; 
	p->uPreBytes	= (unsigned int)code + 256; 
 
	return 0; 
} 
 
/* 
************************************************************************* 
* Function:Write bit steam to file 
* Input: 
* Output: 
* Return: none 
* Attention:Modified by Jianpeng Wang 
************************************************************************* 
*/ 
void WriteBitstreamtoFile(void) 
{ 
	int i,j=0; 
	int nal_payload_len; 
	NALU_t *nalu;//WJP FOR NAL 
 
	//Form_RBSP(pgcurrBitStream);//WJP FOR NAL 
	//WJP FOR NAL 
	for(i=0;Position_of_Slice_in_PicBuf[i]>=0;i++) 
	{ 
		if(Position_of_Slice_in_PicBuf[i+1]<0) 
			nal_payload_len = pgcurrBitStream->byte_pos - Position_of_Slice_in_PicBuf[i]; 
		else 
			nal_payload_len = Position_of_Slice_in_PicBuf[i+1]-Position_of_Slice_in_PicBuf[i]; 
		nalu = AllocNALU(nal_payload_len+1);		 
		Form_NALU(nalu, NALU_TYPE_SLICE, NAL_REF_IDC_REF, pgcurrBitStream->streamBuffer+Position_of_Slice_in_PicBuf[i], nal_payload_len); 
		gTotalBits += 8*Write_NALU2File(nalu,pgcurrBitStream->f); 
		FreeNALU(nalu);		 
	} 
	//END 
 
} 
//WJP END 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
void error(char *text, int code) 
{ 
	fprintf(stderr, "%s\n", text); 
	exit(code); 
} 
 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
void no_mem_exit(char *where) 
{ 
	printf("Could not allocate memory: %s",where); 
	error ("Could not allocate memory", 100); 
} 
 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention:Mainly flushing of everything Add termination symbol, etc. 
************************************************************************* 
*/ 
//void terminate_sequence(void)//WJP FOR SLICE 
//{ 
	//write_start_code(pORABS, 0xb1); WJP FOR NAL 
	/* 
	if(pORABS->iBitOffset) 
		fwrite(pORABS->buf,1,pORABS->iBytePosition+1,pgcurrBitStream->f); 
	else 
		fwrite(pORABS->buf,1,pORABS->iBytePosition  ,pgcurrBitStream->f); 
 
	return;  
	*/ 
//} 
 
/* 
************************************************************************* 
* Function: write rbsp_trailing_bits 
* Input: 
* Output: 
* Return:  
* Attention:Mainly flushing of everything Add termination symbol, etc. 
************************************************************************* 
*/ 
void Form_RBSP(Bitstream *currBitStream)//WJP FOR NAL 
{ 
	currBitStream->byte_buf <<= 1; 
	currBitStream->byte_buf |= 1;   
	currBitStream->bits_to_go--;   
	currBitStream->byte_buf <<= currBitStream->bits_to_go; 
	currBitStream->streamBuffer[currBitStream->byte_pos++] = currBitStream->byte_buf; 
	currBitStream->bits_to_go = 8;   
	currBitStream->byte_buf = 0; 
	return ;      
}