www.pudn.com > lencod.rar > 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:  
* Function:  Annex B Byte Stream format NAL Unit writing routines 
* 
************************************************************************************* 
*/ 
 
 
#include  
#include  
#include  
#include  
 
#include "global.h" 
#include "bitstream.h" 
#define MAXHEADERSIZE 100 
#include "vlc.h" 
 
static FILE *f = NULL;    // the output file 
 
CopyRight CopyRights, *cp = &CopyRights; 
CameraParamters CameraParameter, *camera = &CameraParameter; 
 
 
//////////////////////////////////////////////////////////////////////////////// 
#ifdef SVA_START_CODE_EMULATION 
 
unsigned char bit[8] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; 
OutputStream  ORABS; 
OutputStream *pORABS = &ORABS; 
 
void OpenORABS(OutputStream *p,char *fname) 
{ 
	p->f = fopen(fname,"wb"); 
	if(p->f==NULL){printf ("\nCan't open file %s",fname);exit(-1);} 
 
	p->uPreBytes			= 0xffffffff; 
	p->iBytePosition		= 0; 
	p->iBitOffset			= 0; 
	p->iNumOfStuffBits		= 0; 
	p->iBitsCount			= 0; 
} 
void CloseORABS(OutputStream *p) 
{ 
	if(p->iBitOffset)	fwrite(p->buf,1,p->iBytePosition+1,p->f); 
	else				fwrite(p->buf,1,p->iBytePosition  ,p->f); 
	fclose(p->f); 
} 
void FlushORABS(OutputStream *p) 
{ 
	fflush(p->f); 
} 
 
 
int write_1_bit(OutputStream *p,int b) 
{ 
	int i; 
	 
       //qhg 20060327 delete  
	   //demo needed.  Because de-emulation is used in startslice, it is unecessary to do it here 
//	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; 
//		} 
//	} 
 
	if(p->iBytePosition == SVA_STREAM_BUF_SIZE) 
	{ 
		i = fwrite(p->buf,1,SVA_STREAM_BUF_SIZE,p->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; 
} 
// deleted by Yulj 
/* 
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; 
}*/ 
// added by Yulj 2004.07.16 
// one bit "1" is added to the end of stream, then some bits "0" are added to bytealigned position. 
int write_align_stuff(OutputStream *p) 
{ 
	unsigned char c; 
	 
	c = 0xff << ( 8 - 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; 
} 
//---end 
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,p->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; 
	p->iBytePosition += 4; 
	p->iBitsCount += 32; 
	p->uPreBytes	= (unsigned int)code + 256; 
 
	return 0; 
} 
 
/* 
************************************************************************* 
* Function:Open the output file for the bytestream     
* Input: The filename of the file to be opened 
* Output: 
* Return: none.Function terminates the program in case of an error 
* Attention: 
************************************************************************* 
*/ 
 
 
void OpenBitStreamFile(char *Filename) 
{ 
	OpenORABS(pORABS,Filename); 
} 
void CloseBitStreamFile() 
{ 
	CloseORABS(pORABS); 
} 
 
/* 
************************************************************************* 
* Function:Write sequence header information 
* Input: 
* Output: 
* Return: sequence header length, including stuffing bits 
* Attention: 
************************************************************************* 
*/ 
 
int WriteSequenceHeader() 
{ 
	Bitstream *bitstream; 
	byte SequenceHeader[MAXHEADERSIZE]; 
	int  bitscount=0; 
	int  stuffbits; 
	int  i,j,k; 
	if ((bitstream=calloc(1, sizeof(Bitstream)))==NULL) 
		no_mem_exit("Seuqence Header: bitstream"); 
	 
	bitstream->streamBuffer = SequenceHeader; 
	bitstream->bits_to_go = 8; 
	 
	input->profile_id = 0x20; 
	input->level_id   = 0x42; 
	 
	input->display_horizontal_size = input->img_width; 
	input->display_vertical_size   = input->img_height; 
    input->sample_precision=1;//add by xfwang 2004.7.29 
	input->bbv_buffer_size=4096;//here we random give a value,but in fact it is not true. 
	 
	 
	bitscount+=u_v(32,"seqence start code",0x1b0,bitstream); 
	bitscount+=u_v(8,"profile_id",input->profile_id,bitstream); 
	bitscount+=u_v(8,"level_id",input->level_id,bitstream); 
	 
	bitscount+=u_v(1,"progressive_sequence",input->progressive_sequence,bitstream); 
	bitscount+=u_v(14,"picture width",input->img_width,bitstream); 
	bitscount+=u_v(14,"picture height",input->img_height,bitstream); 
	bitscount+=u_v(2,"chroma foramt",input->chroma_format,bitstream); 
	bitscount+=u_v(3,"sample precision",input->sample_precision,bitstream); 
	bitscount+=u_v(4,"aspect ratio information",input->aspect_ratio_information,bitstream); 
	bitscount+=u_v(4,"frame rate code",input->frame_rate_code,bitstream); 
	 
	//input->bit_rate_lower = input->bit_rate_upper = 0; 
	//xyji 12.23 
	bitscount+=u_v(18,"bit rate lower",input->bit_rate_lower,bitstream); 
	bitscount+=u_v(1,"marker bit",1,bitstream); 
	bitscount+=u_v(12,"bit rate upper",input->bit_rate_upper,bitstream); 
	bitscount+=u_v(1,"low delay",input->low_delay,bitstream); 
	bitscount+=u_v(1,"marker bit",1,bitstream); 
	bitscount+=u_v(18,"bbv buffer size",input->bbv_buffer_size,bitstream); 
	 
	bitscount+=u_v(3,"reserved bits",0,bitstream); 
 
	k = bitscount >> 3; 
	j = bitscount % 8; 
 
	stuffbits = 8-(bitscount%8); 
	 
	if (stuffbits<8) 
		bitscount+=u_v(stuffbits,"stuff bits for byte align",0,bitstream); 
	 
	write_start_code(pORABS, 0xb0); 
	for(i=4;istreamBuffer = SequenceHeader; 
	bitstream->bits_to_go = 8; 
	 
	bitscount+=u_v(24,"start code prefix",1,bitstream); 
	if(input->img_width > 2800) 
		bitscount+=u_v(3, "slice vertical position extension",0,bitstream); 
	  
	bitscount+=u_v(8, "slice start code",slice_nr,bitstream); 
	  
	if (!input->fixed_picture_qp) 
	{ 
		bitscount += u_v(1,"fixed_slice_qp",1,bitstream); 
		bitscount += u_v(6,"slice_qp",slice_qp,bitstream); 
	} 
 
	k = bitscount >> 3; 
	j = bitscount % 8; 
 
	stuffbits = 8-(bitscount%8); 
	 
	if (stuffbits<8) 
		bitscount+=u_v(stuffbits,"stuff bits for byte align",0,bitstream); 
	 
	write_start_code(pORABS, (unsigned char) slice_nr); 
	for(i=4;ivideo_format=1; 
	input->video_range=1; 
	input->display_horizontal_size=1920; 
	input->display_vertical_size=1280; 
	 
	bitstream->streamBuffer = SequenceDisplayExtension; 
	bitstream->bits_to_go = 8; 
	 
	bitscount+=u_v(32,"sequence display extension start code",0x1b5,bitstream); 
	bitscount+=u_v(4,"extension id",2,bitstream); 
	bitscount+=u_v(3,"video format",input->video_format,bitstream); 
	bitscount+=u_v(1,"video range",input->video_range,bitstream); 
	bitscount+=u_v(1,"color description",input->color_description,bitstream); 
	 
	if(input->color_description) 
	{ 
		bitscount+=u_v(8,"color primaries",input->color_primaries,bitstream); 
		bitscount+=u_v(8,"transfer characteristics",input->transfer_characteristics,bitstream); 
		bitscount+=u_v(8,"matrix coefficients",input->matrix_coefficients,bitstream); 
	} 
	 
	bitscount+=u_v(14,"display horizontal size",input->display_horizontal_size,bitstream); 
	//xyji 12.23 
	bitscount+=u_v(1,"marker bit",1,bitstream); 
	bitscount+=u_v(14,"display vertical size", input->display_vertical_size,bitstream); 
	//xyji 12.23 
	bitscount+=u_v(2,"reserved bits",0,bitstream); 
	 
	k = bitscount >> 3; 
	j = bitscount % 8; 
 
	stuffbits = 8-(bitscount%8); 
	 
	if (stuffbits<8) 
	{ 
		bitscount+=u_v(stuffbits,"stuff bits for byte align",0,bitstream); 
	} 
	 
		write_start_code(pORABS, 0xb5); 
	for(i=4;istreamBuffer = CopyrightExtension; 
  bitstream->bits_to_go = 8; 
   
	bitscount+=u_v(32,"copyright extension start code",0x1b5,bitstream); 
  bitscount+=u_v(4,"extension id",4,bitstream); 
  bitscount+=u_v(3,"copyright flag",cp->copyright_flag,bitstream); 
  bitscount+=u_v(1,"copyright id",cp->copyright_id,bitstream); 
  bitscount+=u_v(1,"original or copy",cp->original_or_copy,bitstream); 
	bitscount+=u_v(64,"copyright number",cp->copyright_number,bitstream); 
 
	k = bitscount >> 3; 
	j = bitscount % 8; 
 
  stuffbits = 8-(bitscount%8); 
   
  if (stuffbits<8) 
  { 
    bitscount+=u_v(stuffbits,"stuff bits for byte align",0,bitstream); 
  } 
   
  	write_start_code(pORABS, 0xb5); 
	for(i=4;istreamBuffer = CameraParametersExtension; 
  bitstream->bits_to_go = 8; 
   
	bitscount+=u_v(32,"camera parameters extension start code",0x1b5,bitstream); 
  bitscount+=u_v(4,"extension id",11,bitstream); 
	bitscount+=u_v(1,"reserved",0,bitstream); 
	bitscount+=u_v(7,"camera id",camera->camera_id,bitstream); 
 
  bitscount+=u_v(22,"height_of_image_device",camera->height_of_image_device,bitstream); 
  bitscount+=u_v(22,"focal_length",camera->focal_length,bitstream); 
  bitscount+=u_v(22,"f_number",camera->f_number,bitstream); 
	bitscount+=u_v(22,"vertical_angle_of_view",camera->vertical_angle_of_view,bitstream); 
	bitscount+=u_v(32,"camera_position_x",camera->camera_direction_x,bitstream); 
  bitscount+=u_v(32,"camera_position_y",camera->camera_direction_y,bitstream); 
	bitscount+=u_v(22,"camera_position_z",camera->camera_direction_z,bitstream); 
	bitscount+=u_v(22,"camera_direction_x",camera->camera_direction_x,bitstream); 
  bitscount+=u_v(22,"camera_direction_y",camera->camera_direction_y,bitstream); 
  bitscount+=u_v(22,"camera_direction_z",camera->camera_direction_z,bitstream); 
	bitscount+=u_v(22,"image_plane_vertical_x",camera->image_plane_vertical_x,bitstream); 
	bitscount+=u_v(22,"image_plane_vertical_y",camera->image_plane_vertical_y,bitstream); 
	bitscount+=u_v(32,"image_plane_vertical_z",camera->image_plane_vertical_z,bitstream); 
 
	k = bitscount >> 3; 
	j = bitscount % 8; 
 
  stuffbits = 8-(bitscount%8); 
   
  if (stuffbits<8) 
  { 
    bitscount+=u_v(stuffbits,"stuff bits for byte align",0,bitstream); 
  } 
   
  write_start_code(pORABS, 0xb5); 
	for(i=4;istreamBuffer = UserData; 
  bitstream->bits_to_go = 8; 
   
  bitscount += u_v(32,"user data start code", 0x1b2,bitstream); 
	write_start_code(pORABS, 0xb2); 
	while (*userdata) 
	{ 
		write_n_bit(pORABS,*userdata,8); 
		bitscount += u_v(8,"user data", *userdata++,bitstream); 
	} 
	write_align_stuff(pORABS); 
//	fwrite(UserData,1,bitscount/8,f); 
  free(bitstream); 
   
  return bitscount; 
} 
 
/* 
************************************************************************* 
* Function:Write bit steam to file 
* Input: 
* Output: 
* Return: none 
* Attention: 
************************************************************************* 
*/ 
 
void WriteBitstreamtoFile() 
{ 
	int n, i; 
	n = currBitStream->byte_pos; 
	// deleted by jlzheng 6.30 
/*	if(currBitStream->streamBuffer[0]==0 && currBitStream->streamBuffer[1]==0 && currBitStream->streamBuffer[2]==1) 
	{ 
		write_start_code(pORABS, currBitStream->streamBuffer[3]); 
		for(i=4;istreamBuffer[i],8); 
		} 
	} 
	else 
	{  
		for(i=0;istreamBuffer[i],8); 
	}*/    
	   
	// added by jlzheng 6.30 
   for(i=0;istreamBuffer[i]==0 && currBitStream->streamBuffer[i+1]==0 && currBitStream->streamBuffer[i+2]==1)	 
          { 
		write_start_code(pORABS, currBitStream->streamBuffer[i+3]); 
		i=i+4; 
	  }                                       
 
		write_n_bit(pORABS, currBitStream->streamBuffer[i],8); 
   }     
 
   write_align_stuff(pORABS);  //can be comment, it is uncessary to stuff here qhg 20060327 
     
	//bytecount = fwrite(currBitStream->streamBuffer,1,currBitStream->byte_pos,f); 
	stat->bit_ctr += 8*n; 
} 
#endif 
 
///////////////////////////////////////////////////////////////////////////////////////////// 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
void error(char *text, int code) 
{ 
	fprintf(stderr, "%s\n", text); 
	exit(code); 
} 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention: 
************************************************************************* 
*/ 
int start_sequence() 
{ 
	int len = 0; 
	char id_string[255] = "AVS test stream"; 
	OpenBitStreamFile(input->outfile); 
	len = WriteSequenceHeader(); 
	len += WriteSequenceDisplayExtension(); 
	if (strlen(id_string) > 1) 
		len += WriteUserData(id_string); 
	return len; 
} 
/* 
************************************************************************* 
* Function: 
* Input: 
* Output: 
* Return:  
* Attention:Mainly flushing of everything Add termination symbol, etc. 
************************************************************************* 
*/ 
int terminate_sequence() 
{ 
	int len; 
	len = WriteSequenceEnd(); 
	CloseBitStreamFile(); 
	return len;   // make lint happy 
}