www.pudn.com > avs-m3.rar > sei.c


/*! 
 ************************************************************************ 
 * \file  sei.c  
 * \brief 
 *    Functions to implement SEI messages in decoder 
 * \by liuhui 2005/03/20 liuhui@mail.ustc.edu.cn 
 ************************************************************************ 
 */ 
#include  
#include  
#include  
 
#include "global.h" 
#include "memalloc.h" 
#include "sei.h" 
#include "vlc.h" 
#include "header.h" 
#include "parset.h" 
#include "HRD.h" 
 
extern unsigned int seq_parameter_set_id; 
extern unsigned int cpb_dpb_cnt_minus1; 
extern unsigned int *cpb_underflow_allowable_flag; 
extern unsigned int *bit_rate_value_minus1_lsb; 
extern unsigned int *bit_rate_value_minus1_msb; 
extern unsigned int *cpb_size_value_minus1_lsb; 
extern unsigned int *cpb_size_value_minus1_msb; 
extern unsigned int *dpb_size_value_minus1_lsb; 
extern unsigned int *dpb_size_value_minus1_msb; 
extern unsigned int *initial_cpb_removal_delay_lsb; 
extern unsigned int *initial_cpb_removal_delay_msb; 
extern unsigned int *initial_cpb_removal_delay; 
extern unsigned int *initial_dpb_output_delay_lsb; 
extern unsigned int *initial_dpb_output_delay_msb; 
extern unsigned int *initial_dpb_output_delay; 
 
 
extern unsigned int *Bit_Buffer; 
 
extern unsigned int *ROT; 
extern struct DecodedPictureBuffer dpb; 
extern struct FrameBuffer outframe; 
extern struct FrameBuffer decframe; 
 
extern unsigned int outputtimer; 
extern int pre_picture_distance; 
 
 
 
 
 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     Interpret the SEI rbsp 
 *  \param msg 
 *     a pointer that point to the sei message. 
 *  \param size 
 *     the size of the sei message 
 *  \param img 
 *     the image pointer 
 *     
 ************************************************************************ 
 */ 
void InterpretSEIMessage(byte* msg, int size, Image *img) 
{ 
	int payload_type = 0; 
	int payload_size = 0; 
	int offset = 1;		//skip first NAL header byte 
 
#if TRACE 
    fprintf(p_trace,"\n"); 
    tracebits2("start_code_prefix",24,0x01); 
    fprintf(p_trace,"ANNEX B NALU, len %d, forbidden_bit %d, nal_reference_idc %d, nal_unit_type %d,\n", 
            nalu->len,nalu->forbidden_bit,nalu->nal_reference_idc,nalu->nal_unit_type); 
#endif 
 
#if TRACE 
   tracebits2("SEI: NALU Header",8,nalu->buf[0]); 
#endif 
 
	do 
	{ 
		// sei_message(); 
		payload_type = 0; 
 
		while ( msg[offset++] == 0xFF) 
			payload_type += 255; 
	 
		payload_type += msg[offset-1];   // this is the last byte 
		 
		payload_size = 0; 
 
		while ( msg[offset++] == 0xFF) 
			payload_size += 255; 
		 
		payload_size += msg[offset-1];   // this is the last byte 
		 
		switch ( payload_type )     // sei_payload( type, size ); 
		{  
		case SEI_USER_DATA: 
#if TRACE //liuhui 0601 
            tracebits2("SEI: UserData:PayloadType",8,payload_type); 
            tracebits2("SEI: UserData:PayloadSize",8,payload_size); 
#endif 
			interpret_user_data(msg+offset, payload_size, img ); 
			break; 
 
		case SEI_FULL_FRAME_FREEZE: 
#if TRACE //liuhui 0601 
            tracebits2("SEI: FullFrameFreeze:PayloadType",8,payload_type); 
            tracebits2("SEI: FullFrameFreeze:PayloadSize",8,payload_size); 
#endif 
			interpret_full_frame_freeze( msg+offset, payload_size, img ); 
			break; 
		case SEI_FULL_FRAME_FREEZE_RELEASE: 
#if TRACE //liuhui 0601 
            tracebits2("SEI: FullFrameFreezeRelease:PayloadType",8,payload_type); 
            tracebits2("SEI: FullFrameFreezeRelease:PayloadSize",8,payload_size); 
#endif 
			interpret_full_frame_freeze_release( msg+offset, payload_size, img ); 
			break; 
		case SEI_SCALABLE_LAYER_PROFILE_LEVEL: 
#if TRACE //liuhui 0601 
            tracebits2("SEI: ScalaLayerProfileLevel:PayloadType",8,payload_type); 
            tracebits2("SEI: ScalaLayerProfileLevel:PayloadSize",8,payload_size); 
#endif 
			interpret_scalable_layer_profile_level(msg+offset, payload_size, img ); 
			break; 
 
#ifdef _HRD_ 
		case SEI_HRD_BUFFERING_PARAMETERS:		 
#if TRACE //liuhui 0601 
            tracebits2("SEI: HRDBufferParam:PayloadType",8,payload_type); 
            tracebits2("SEI: HRDBufferParam:PayloadSize",8,payload_size); 
#endif 
			interpret_hrd_buffering_parameters(msg+offset, payload_size, img ); 
			break; 
#endif 
		case SEI_GRADUAL_RANDOM_ACCESS: 
#if TRACE //liuhui 0601 
            tracebits2("SEI: GradualRandomAccess:PayloadType",8,payload_type); 
            tracebits2("SEI: GradualRandomAccess:PayloadSize",8,payload_size); 
#endif 
			interpret_gradual_random_access(msg+offset, payload_size, img ); 
			break;	 
		default: 
#if TRACE //liuhui 0601 
            tracebits2("SEI: Reserved:PayloadType",8,payload_type); 
            tracebits2("SEI: Reserved:PayloadSize",8,payload_size); 
#endif 
			interpret_reserved( msg+offset, payload_size, img ); 
			break; 
		} 
		offset += payload_size; 
	}while( 0 ); 
 
} 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     Interpret the User data SEI message 
 *  \param payload 
 *     a pointer that point to the sei payload 
 *  \param size 
 *     the size of the sei message 
 *  \param img 
 *     the image pointer    
 ************************************************************************ 
 */ 
void interpret_user_data( byte* payload, int size, Image *img ) 
{ 
	byte uiUserData; 
    int i; 
	Bitstream *bitstream = AllocBitstream(); 
	for(i = 0; i < size; i++) 
		bitstream->streamBuffer[i] = payload[i]; 
	bitstream->frame_bitoffset = 0; 
	bitstream->bitstream_length = size; 
 
 
#ifdef PRINT_USER_DATA 
	printf("-----           USER_DATA SEI          -----\n"); 
#endif 
 
	for( i = 0; i < size*8/17; i++) 
	{ 
    uiUserData = SEI_u_v(8, "UserData", bitstream); 
		putchar(uiUserData); 
		uiUserData = SEI_u_v(8, "UserData", bitstream); 
		putchar(uiUserData); 
		uiUserData = SEI_u_v(1, "market_bit",  bitstream); 
	} 
    if(((size*8)%17) > 8)  /*Zhan Ma*/ 
	{ 
		uiUserData = SEI_u_v(8, "UserData", bitstream); 
		putchar(uiUserData); 
	 
	} 
	printf("\n"); 
#if TRACE //liuhui 0601 
    if( (size*8 - bitstream->frame_bitoffset) != 0 ) //read trailing_bits 
	{ 
	    i = size*8 - bitstream->frame_bitoffset; 
		SEI_u_v(i, "SEI: trailing_bits", bitstream); 
	} 
#endif 
 
 
} 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     Interpret the Full-frame freeze SEI message 
 *  \param payload 
 *     a pointer that point to the sei payload 
 *  \param size 
 *     the size of the sei message 
 *  \param img 
 *     the image pointer 
 *     
 ************************************************************************ 
 */ 
void interpret_full_frame_freeze( byte* payload, int size, Image *img ) 
{ 
	//when this function executes, full frame freeze valids 
	assert(size == 1); 
	assert( *payload == 0x80 ); 
 
#if TRACE //liuhui 0601 
    tracebits2("SEI: trailing_bits",8,*payload); 
#endif 
 
#ifdef PRINT_FULL_FRAME_FREEZE 
	printf("-----       FULL_FRAME_FREEZE SEI      -----\n"); 
#endif 
} 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     Interpret the Full-frame freeze release SEI message 
 *  \param payload 
 *     a pointer that point to the sei payload 
 *  \param size 
 *     the size of the sei message 
 *  \param img 
 *     the image pointer 
 *     
 ************************************************************************ 
 */ 
void interpret_full_frame_freeze_release( byte* payload, int size, Image *img ) 
{ 
	assert(size == 1); 
	assert(*payload == 0x80); 
 
#if TRACE //liuhui 0601 
    tracebits2("SEI: trailing_bits",8,*payload); 
#endif 
 
#ifdef PRINT_FULL_FRAME_FREEZE_RELEASE 
    printf("-----   FULL_FRAME_FREEZE_RELEASE SEI  -----\n"); 
#endif 
} 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     Interpret the Scalable layer profile level SEI message 
 *  \param payload 
 *     a pointer that point to the sei payload 
 *  \param size 
 *     the size of the sei message 
 *  \param img 
 *     the image pointer    
 ************************************************************************ 
 */ 
void interpret_scalable_layer_profile_level(byte* payload, int size, Image *img ) 
{ 
	unsigned int ref_pic_profile_idc, ref_pic_level_idc; 
	assert(size == 3); 
 
	ref_pic_profile_idc = payload[0]; 
	ref_pic_level_idc   = payload[1]; 
 
#if TRACE //liuhui 0601 
    tracebits2("SEI: Profile_Idc",8,ref_pic_profile_idc); 
	tracebits2("SEI: Level_Idc",8,ref_pic_level_idc); 
	tracebits2("SEI: trailing_bits",8,payload[2]); 
#endif 
#ifdef PRINT_SCALABLE_LAYER_PROFILE_LEVEL 
 
	printf("----- SCALABLE_LAYER_PROFILE_LEVEL SEI -----\n"); 
	printf("Ref_pic_profile_idc:	%d\n", ref_pic_profile_idc ); 
	printf("Ref_pic_level_idc  :	%d\n", ref_pic_level_idc   ); 
 
#endif 
	 
} 
 
#ifdef _HRD_ //BUG_FIX liuhui 0512 
/*! 
 ************************************************************************ 
 *  \brief 
 *     Interpret the HRD buffering parameters SEI message 
 *  \param payload 
 *     a pointer that point to the sei payload 
 *  \param size 
 *     the size of the sei message 
 *  \param img 
 *     the image pointer    
 ************************************************************************ 
 */ 
void interpret_hrd_buffering_parameters(byte* payload, int size, Image *img ) 
{ 
//	unsigned int bit_rate,cpb_size,dpb_size,initCpbDelay,initDpbDelay;//guoyi BUG_FIX 01/06 
	unsigned int HrdIdx; 
	int i; 
	Bitstream *bitstream = AllocBitstream(); 
	for(i = 0; i < size; i++) 
		bitstream->streamBuffer[i] = payload[i]; 
	bitstream->frame_bitoffset = 0; 
	bitstream->bitstream_length = size; 
 
//#define _PRINT_		 
	seq_parameter_set_id = SEI_ue_v("seq_parameter_set_id", bitstream); 
	cpb_dpb_cnt_minus1   = SEI_ue_v("cpb_dpb_cnt_minus1", bitstream); 
	 
  init_hrd(cpb_dpb_cnt_minus1 + 1); 
 
#ifdef _PRINT_ 
		printf("\n\n----------HRD SEI informations----------\n"); 
		printf("seq_parameter_set_id			:%d\n",seq_parameter_set_id); 
		printf("cpb_dpb_cnt_minus1			:%d\n", cpb_dpb_cnt_minus1   ); 
#endif 
 
	for(HrdIdx = 0; HrdIdx < cpb_dpb_cnt_minus1 + 1; HrdIdx++) 
	{ 
		cpb_underflow_allowable_flag[HrdIdx] = SEI_u_1("cpb_underflow_allowable_flag[HrdIdx]", bitstream); 
        bit_rate_value_minus1_lsb[HrdIdx] = SEI_ue_v("bit_rate_value_minus1_lsb[HrdIdx]", bitstream); 
		SEI_u_v(1, "marker_bit", bitstream ); 
        bit_rate_value_minus1_msb[HrdIdx] = SEI_ue_v("bit_rate_value_minus1_msb[HrdIdx]", bitstream); 
		SEI_u_v(1, "marker_bit", bitstream ); 
		cpb_size_value_minus1_lsb[HrdIdx] = SEI_ue_v("cpb_size_value_minus1_lsb[HrdIdx]", bitstream); 
		SEI_u_v(1, "marker_bit", bitstream ); 
		cpb_size_value_minus1_msb[HrdIdx] = SEI_ue_v("cpb_size_value_minus1_msb[HrdIdx]", bitstream); 
		SEI_u_v(1, "marker_bit", bitstream ); 
        dpb_size_value_minus1_lsb[HrdIdx] = SEI_ue_v("dpb_size_value_minus1_lsb[HrdIdx]", bitstream); 
		SEI_u_v(1, "marker_bit", bitstream ); 
		dpb_size_value_minus1_msb[HrdIdx] = SEI_ue_v("dpb_size_value_minus1_msb[HrdIdx]", bitstream); 
		SEI_u_v(1, "marker_bit", bitstream ); 
		if( sps->initial_cpb_removal_delay_length > 16 ) 
		{ 
			initial_cpb_removal_delay_lsb[HrdIdx] = SEI_u_v(16,                                       "initial_cpb_removal_delay_lsb[HrdIdx]", bitstream); 
			SEI_u_v( 1, "marker_bit", bitstream ); 
			initial_cpb_removal_delay_msb[HrdIdx] = SEI_u_v(sps->initial_cpb_removal_delay_length-16, "initial_cpb_removal_delay_msb[HrdIdx]", bitstream); 
		} 
		else 
			initial_cpb_removal_delay[HrdIdx]     = SEI_u_v(sps->initial_cpb_removal_delay_length,     "initial_cpb_removal_delay   [HrdIdx]", bitstream); 
		SEI_u_v( 1, "marker_bit", bitstream ); 
		if( sps->initial_dpb_output_delay_length > 16 ) 
		{ 
			initial_dpb_output_delay_lsb [HrdIdx] = SEI_u_v(16,                                        "initial_dpb_output_delay_lsb[HrdIdx]", bitstream); 
			SEI_u_v( 1, "marker_bit", bitstream ); 
			initial_dpb_output_delay_msb [HrdIdx] = SEI_u_v(sps->initial_dpb_output_delay_length-16,   "initial_dpb_output_delay_msb[HrdIdx]", bitstream); 
		} 
		else 
			initial_dpb_output_delay     [HrdIdx] = SEI_u_v(sps->initial_dpb_output_delay_length,      "initial_dpb_output_delay    [HrdIdx]", bitstream); 
		SEI_u_v( 1, "marker_bit", bitstream ); 
#if TRACE //liuhui 0601 
		if( HrdIdx == cpb_dpb_cnt_minus1  ) //read trailing_bits 
		{ 
			i = size*8-bitstream->frame_bitoffset; 
		    assert(i); 
			SEI_u_v( i, "SEI: trailing_bits", bitstream); 
		} 
#endif 
 
#ifdef PRINT_HRD 
		printf("\nHrdIdx = %d	:\n",HrdIdx); 
		printf("cpb_underflow_allowable_flag[HrdIdx]	:%d\n",cpb_underflow_allowable_flag[HrdIdx]); 
		printf("bit_rate_value_minus1_lsb[HrdIdx]		:%d\n",bit_rate_value_minus1_lsb[HrdIdx]); 
		printf("bit_rate_value_minus1_msb[HrdIdx]		:%d\n",bit_rate_value_minus1_msb[HrdIdx]); 
		printf("cpb_size_value_minus1_lsb[HrdIdx]		:%d\n",cpb_size_value_minus1_lsb[HrdIdx]); 
		printf("cpb_size_value_minus1_msb[HrdIdx]		:%d\n",cpb_size_value_minus1_msb[HrdIdx]); 
		printf("dpb_size_value_minus1_lsb[HrdIdx]		:%d\n",dpb_size_value_minus1_lsb[HrdIdx]); 
		printf("dpb_size_value_minus1_msb[HrdIdx]		:%d\n",dpb_size_value_minus1_msb[HrdIdx]); 
		if(sps->initial_cpb_removal_delay_length>16) 
		{ 
			printf("initial_cpb_removal_delay_lsb[HrdIdx]	:%d\n",initial_cpb_removal_delay_lsb[HrdIdx]);	 
			printf("initial_cpb_removal_delay_msb[HrdIdx]	:%d\n",initial_cpb_removal_delay_msb[HrdIdx]); 
		} 
		else 
			printf("initial_cpb_removal_delay[HrdIdx]	:%d\n",initial_cpb_removal_delay[HrdIdx]); 
		if(sps->initial_dpb_output_delay_length>16) 
		{ 
			printf("initial_dpb_output_delay_lsb[HrdIdx]	:%d\n",initial_dpb_output_delay_lsb[HrdIdx]); 
			printf("initial_dpb_output_delay_msb[HrdIdx]	:%d\n",initial_dpb_output_delay_msb[HrdIdx]); 
		} 
		else 
			printf("initial_dpb_output_delay[HrdIdx]	:%d\n",initial_dpb_output_delay[HrdIdx]); 
 
 
    bit_rate=(bit_rate_value_minus1_lsb[HrdIdx]+1+(bit_rate_value_minus1_msb[HrdIdx]<<16))<<(6+sps->bit_rate_scale); 
		cpb_size=(cpb_size_value_minus1_lsb[HrdIdx]+1+(cpb_size_value_minus1_msb[HrdIdx]<<16))<<(4+sps->cpb_size_scale); 
		dpb_size=(dpb_size_value_minus1_lsb[HrdIdx]+1+(dpb_size_value_minus1_msb[HrdIdx]<<16))<<(4+sps->dpb_size_scale); 
		if( sps->initial_cpb_removal_delay_length > 16 ) 
		{ 
			initCpbDelay=initial_cpb_removal_delay_lsb[HrdIdx]+(initial_cpb_removal_delay_msb[HrdIdx]<<16); 
		} 
		else 
		{ 
            initCpbDelay=initial_cpb_removal_delay_lsb[HrdIdx]; 
		} 
		if( sps->initial_dpb_output_delay_length > 16 ) 
		{ 
			initDpbDelay=initial_dpb_output_delay_lsb[HrdIdx]+(initial_dpb_output_delay_msb[HrdIdx]<<16); 
		} 
		else 
		{ 
            initDpbDelay=initial_dpb_output_delay_lsb[HrdIdx]; 
		} 
		fprintf(p_trace,"\nHrdIdx=%d	:\n",HrdIdx); 
		fprintf(p_trace,"bit_rate		:%d\n",bit_rate); 
		fprintf(p_trace,"cpb_size		:%d\n",cpb_size); 
		fprintf(p_trace,"dpb_size		:%d\n",dpb_size); 
		fprintf(p_trace,"initCpbDelay(1/90000 s)		:%d\n",initCpbDelay); 
 
#endif 
 
 
#ifdef _PRINT_ 
		printf("\nHrdIdx = %d	:\n",HrdIdx); 
		printf("cpb_underflow_allowable_flag[HrdIdx]	:%d\n",cpb_underflow_allowable_flag[HrdIdx]); 
		printf("bit_rate_value_minus1[HrdIdx]		:%d\n",bit_rate_value_minus1[HrdIdx]); 
		printf("cpb_size_value_minus1[HrdIdx]		:%d\n",cpb_size_value_minus1[HrdIdx]); 
		printf("dpb_size_value_minus1[HrdIdx]		:%d\n",dpb_size_value_minus1[HrdIdx]); 
		printf("initial_cpb_removal_delay[HrdIdx]	:%d\n",initial_cpb_removal_delay[HrdIdx]); 
		printf("initial_dpb_output_delay[HrdIdx]	:%d\n\n",initial_dpb_output_delay[HrdIdx]); 
#endif 
 
	} 
 
	free(bitstream->streamBuffer); 
	free(bitstream); 
} 
#endif //_HRD_ 
/*! 
 ************************************************************************ 
 *  \brief 
 *     Interpret the gradual random access SEI message 
 *  \param payload 
 *     a pointer that point to the sei payload 
 *  \param size 
 *     the size of the sei message 
 *  \param img 
 *     the image pointer 
 *     
 ************************************************************************ 
 */ 
void interpret_gradual_random_access( byte* payload, int size, Image *img ) 
{ 
	int i, recovery_frame_cnt; 
	Bitstream *bitstream = AllocBitstream(); 
	for(i = 0; i < size; i++) 
		bitstream->streamBuffer[i] = payload[i]; 
	bitstream->frame_bitoffset = 0; 
	bitstream->bitstream_length = size; 
 
	recovery_frame_cnt = SEI_ue_v("recovery_frame_cnt", bitstream ); 
	assert( recovery_frame_cnt <= 31 && recovery_frame_cnt >= 0 ); 
 
#if TRACE //liuhui 0601 
	{ 
	    i = size*8 - bitstream->frame_bitoffset; 
		assert(i); 
		SEI_u_v(i, "SEI: trailing_bits", bitstream); 
	} 
#endif 
 
	printf("-----     GRADUAL_RANDOM_ACCESS SEI    -----\n"); 
	printf("recovery_frame_cnt       = %d\n", recovery_frame_cnt); 
	printf("\n"); 
 
} 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     Interpret the Reserved SEI message 
 *  \param payload 
 *     a pointer that point to the sei payload 
 *  \param size 
 *     the size of the sei message 
 *  \param img 
 *     the image pointer 
 *     
 ************************************************************************ 
 */ 
void interpret_reserved( byte* payload, int size, Image *img ) 
{ 
	byte uiReserved; 
    int i; 
	Bitstream *bitstream = AllocBitstream(); 
	for(i = 0; i < size; i++) 
		bitstream->streamBuffer[i] = payload[i]; 
	bitstream->frame_bitoffset = 0; 
	bitstream->bitstream_length = size; 
 
#ifdef PRINT_RESERVED 
	printf("-----           RESERVED SEI           -----\n"); 
#endif 
 
	for( i = 0; i < size*8/17; i++) 
	{ 
    uiReserved = SEI_u_v(8, "Reserved byte", bitstream); 
		putchar(uiReserved); 
		uiReserved = SEI_u_v(8, "Reserved byte", bitstream); 
		putchar(uiReserved); 
		uiReserved = SEI_u_v(1, "market_bit",  bitstream); 
	} 
    if(((size*8)%17) > 8) 
	{ 
		uiReserved = SEI_u_v(8, "Reserved byte", bitstream); 
		putchar(uiReserved); 
	} 
	printf("\n"); 
 
#if TRACE 
	{ 
	  i = 8*size - bitstream->frame_bitoffset; 
		assert(i); 
		SEI_u_v(i, "SEI: trailing_bits", bitstream); 
	} 
#endif 
} 
 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     SEI coding function like GetVLCSymbol(),different only at writing bitstream 
 *  \param info 
 *     refer to param in GetVLCSymbol() 
 *  \param bitstream 
 *     store the coded bit-stream of SEI 
 ************************************************************************ 
 */ 
int SEI_GetVLCSymbol (int *info, Bitstream *bitstream) 
{ 
	 
	register int inf; 
	long byteoffset;      // byte from start of buffer 
	int bitoffset;      // bit from start of byte 
	int ctr_bit=0;      // control bit for current bit posision 
	int bitcounter=1; 
	int len; 
	int info_bit; 
	byte *buffer = bitstream->streamBuffer; 
	int bytecount = bitstream->bitstream_length; 
	int totbitoffset = bitstream->frame_bitoffset; 
	byteoffset= totbitoffset/8; 
	bitoffset= 7-(totbitoffset%8); 
	ctr_bit = (buffer[byteoffset] & (0x01< bytecount) 
		{ 
			error("parse error", -1); 
			return -1; 
		} 
		inf=(inf<<1); 
		if(buffer[byteoffset] & (0x01<<(bitoffset))) 
			inf |=1; 
	}	 
	*info = inf;	 
	bitstream->frame_bitoffset += bitcounter; 
	return bitcounter;           // return absolute offset in bit from start of frame 
} 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     SEI coding function like read_VLC(),different only at writing bitstream 
 *  \param info 
 *     refer to param in read_VLC() 
 *  \param bitstream 
 *     store the coded bit-stream of SEI 
 ************************************************************************ 
 */ 
int SEI_read_VLC(SyntaxElement *sym, Bitstream *bitstream) 
{ 
	int frame_bitoffset = bitstream->frame_bitoffset; 
	byte *buf = bitstream->streamBuffer; 
	int BitstreamLengthInBytes = bitstream->bitstream_length;	 
	sym->len =  SEI_GetVLCSymbol (&(sym->inf), bitstream);	 
	if (sym->len == -1) 
		return -1;	 
	sym->mapping(sym->len,sym->inf,&(sym->value1));	 
#if TRACE //liuhui 0601 
  tracebits(sym->tracestring, sym->len, sym->inf, sym->value1); 
#endif	 
	return 1; 
} 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     SEI coding function like read_FLC(),different only at writing bitstream 
 *  \param info 
 *     refer to param in read_FLC() 
 *  \param bitstream 
 *     store the coded bit-stream of SEI 
 ************************************************************************ 
 */ 
int SEI_read_FLC(SyntaxElement *sym, Bitstream *bitstream) 
{ 
	int frame_bitoffset = bitstream->frame_bitoffset; 
	byte *buf = bitstream->streamBuffer; 
	int BitstreamLengthInBytes = bitstream->bitstream_length;	 
	if ((GetBits(buf, frame_bitoffset, &(sym->inf), BitstreamLengthInBytes, sym->len)) < 0) 
		return -1;	 
	bitstream->frame_bitoffset += sym->len; // move bitstream pointer 
	sym->value1 = sym->inf; 
#if TRACE //liuhui 0601 
    tracebits2(sym->tracestring, sym->len, sym->inf); 
#endif	 
	return 1; 
} 
 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     SEI coding function like ue_v(),different only at writing bitstream 
 *  \param info 
 *     refer to param in ue_v() 
 *  \param bitstream 
 *     store the coded bit-stream of SEI 
 ************************************************************************ 
 */ 
int SEI_ue_v(char *tracestring, Bitstream *bitstream) 
{ 
	SyntaxElement symbol, *sym=&symbol; 
	 
	assert (bitstream->streamBuffer != NULL); 
	sym->mapping = mapping_ue;   // Mapping rule 
#if TRACE 
	strncpy(sym->tracestring,tracestring,TRACESTRING_SIZE); 
#endif 
	SEI_read_VLC (sym, bitstream); 
	 
	return sym->value1; 
} 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     SEI coding function like u_v(),different only at writing bitstream 
 *  \param info 
 *     refer to param in u_v() 
 *  \param bitstream 
 *     store the coded bit-stream of SEI 
 ************************************************************************ 
 */ 
int SEI_u_v(int LenInBits, char* tracestring, Bitstream *bitstream) 
{ 
	SyntaxElement symbol, *sym=&symbol; 
	 
	assert (bitstream->streamBuffer != NULL); 
	//sym->type = SE_HEADER; 
	sym->mapping = mapping_ue;   // Mapping rule 
	sym->len = LenInBits; 
#if TRACE 
	strncpy(sym->tracestring, tracestring, TRACESTRING_SIZE); 
#endif 
	SEI_read_FLC (sym, bitstream); 
	 
	return sym->inf; 
} 
 
/*! 
 ************************************************************************ 
 *  \brief 
 *     SEI coding function like u_1(),different only at writing bitstream 
 *  \param info 
 *     refer to param in u_1() 
 *  \param bitstream 
 *     store the coded bit-stream of SEI 
 ************************************************************************ 
 */ 
int SEI_u_1 (char *tracestring, Bitstream *bitstream) 
{ 
	return SEI_u_v (1, tracestring, bitstream); 
}