⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elementarystream.cpp

📁 Elementary Stream Guide
💻 CPP
字号:
/* YUNTAI KYONGAdvanced Internet Serviceterm project*/#include "assert.h"#include <malloc.h>#include "elementaryStream.h"#include "fileStream.h"extern void error(char*);elementaryStream::elementaryStream(fileStream *fs, CSocket *sock, 									unsigned long initTimeStamp, unsigned short initSequence){	assert(fs != NULL);	this->sock = sock;	this->fs = fs;		fs->get_next_data();	next_start_code();	m_slice_start_code = 0x101;	m_time_stamp = initTimeStamp;	m_seq_num = initSequence;}/* searching start code */int elementaryStream::next_start_code(void){		int size = 0;	while(!fs->BYTEALIGNED())	{		if(fs->get_bit())		/* get 0s until byte aligned */			error("Not an MPEG file.  Cannot find start code");	}		/* Check if we are at the start code.  	If not there is zero byte stuffing */		/* check starting code or skip zero byte stuffing */	while(!fs->next_bits(24, 0x000001)) 	{		if(fs->get_byte())			error("Not an MPEG file.  Cannot find start code");		size++; 	}	return size;}/* check how many bytes until next start code */int elementaryStream::find_next_start_code(void){	for(int bytes = 0; !fs->next_bits(24, 0x000001); bytes++)	{		if( fs->next_bits(24, 0x000001) == -2 )		{			printf("end of file!\n");			return -2;		}		fs->get_bits(8);	}	return bytes;}int elementaryStream::get_gop_header(unsigned char *payload, int bytesToGo){/* This procedure reads a Gop picture by picture.  */	if( !fs->next_bits(32, GROUP_START_CODE) )		return -2;	fs->mark();	fs->get_bits(32);						// skip group_start_code	gop_i.time_code   = fs->get_bits(25);	// time_code	gop_i.closed_gop  = fs->get_bit();		// closed_gop	gop_i.broken_link = fs->get_bit();		// broken_link	next_start_code();		// check exention header		if(fs->next_bits(32, EXTENSION_START_CODE))    {		fs->get_bits(32);		// skip extension_start_code		for(gop_i.gop_ext_data_size = 0; !fs->next_bits(24, 0x000001); gop_i.gop_ext_data_size++)			gop_i.gop_ext_data[gop_i.gop_ext_data_size] = fs->get_byte();		gop_i.gop_size = 4 + gop_i.gop_ext_data_size;		next_start_code();    }	else		gop_i.gop_ext_data_size = 0;	// check user data	if(fs->next_bits(32, USER_DATA_START_CODE))    {		fs->get_bits(32);		// skip user_data_start_code		for(gop_i.gop_user_data_size = 0; !fs->next_bits(24, 0x000001); gop_i.gop_user_data_size++)			gop_i.gop_user_data[gop_i.gop_user_data_size] = fs->get_byte();		gop_i.gop_size += 4 + gop_i.gop_user_data_size;		next_start_code();    }	else		gop_i.gop_user_data_size = 0;		//find_next_start_code();	next_start_code();	//assert( fs->next_bits(32, PICTURE_START_CODE) );	printf("get next start code()" );	if( fs->getSizeFromMark() <= bytesToGo )	{		fs->load( payload );				return fs->getSizeFromMark();	}	else	{		fs->rewind();			return -1;	}		}void elementaryStream::print_picture_header(){	printf("temporal reference: %d\n", picture_h.temporal_reference );	printf("picture config type: %d\n",picture_h.picture_config_type );	printf("vbv_delay: %d\n",picture_h.vbv_delay );	}int elementaryStream::get_picture_header(unsigned char *payload, int bytesToGo){			if(!fs->next_bits(32, PICTURE_START_CODE))	{		printf("get_bits: %d\n",fs->get_bits(32));		return -2;	}	fs->mark();	fs->get_bits(32);		// skip picture strat code		picture_h.temporal_reference	= fs->get_bits(10);	// temporal reference	picture_h.picture_config_type	= fs->get_bits(3);	// type of picture			picture_h.vbv_delay				= fs->get_bits(16);	// 	m_pic_type = picture_h.picture_config_type;	if( picture_h.picture_config_type == 2 || picture_h.picture_config_type == 3 )	{		picture_h.full_pel_forward_vector  = fs->get_bit();		picture_h.forward_f_code		   = fs->get_bits(3);	}		if( picture_h.picture_config_type == 3 )	{		picture_h.full_pel_backward_vector = fs->get_bit();		picture_h.backward_f_code		   = fs->get_bits(3);			}			while( fs->get_bit() )	{				fs->get_bits(8);		printf("get extra bits!\n");	}			next_start_code();		if( fs->getSizeFromMark() <= bytesToGo )	{		fs->load( payload );				return fs->getSizeFromMark();	}	else	{		fs->rewind();			return -1;	}			}int elementaryStream::get_user_data(unsigned char *payload, int bytesToGo){	if(!fs->next_bits(32, USER_DATA_START_CODE))		return -2;	fs->mark();		find_next_start_code();	if( fs->getSizeFromMark() <= bytesToGo )	{		fs->load( payload  );				return fs->getSizeFromMark();	}	else	{		fs->rewind();			return -1;	}	}int elementaryStream::get_sequence_header(unsigned char *payload, int bytesToGo){	if(!fs->next_bits(32, SEQUENCE_HEADER_CODE))		return -2;		fs->mark();	fs->get_bits(32);			// skip sequence_header_code	sequence_h.horizontal_size_value	= fs->get_bits(12);		// horizontal_size_value	sequence_h.vertical_size_value		= fs->get_bits(12);		// vertical_size_value	sequence_h.aspect_ratio_infomation	= fs->get_bits(4);		// aspect_ratio_infomation	sequence_h.frame_rate_value			= fs->get_bits(4);		// grame_rate_value	sequence_h.bit_rate_value			= fs->get_bits(18);		// bit_rate_value	sequence_h.marker_bit				= fs->get_bit();		// marker_bit( should be '1' )	if(!sequence_h.marker_bit)		error("Marker bit in SEQUENCE HEADER not set.  MPEG file is corrupted");		sequence_h.vbv_buffer_size_value		= fs->get_bits(10);		// vbv_buffer_size_value	sequence_h.constrained_parameters_flag	= fs->get_bit();		// constrained_parameters_flag(=0)		// check intra_quantiser_matrix and load	sequence_h.load_intra_quantiser_matrix	= fs->get_bit();		// load_intra_quantiser_matrix	if(sequence_h.load_intra_quantiser_matrix)		for(int i = 0; i < 64; i++)			sequence_h.intra_quantiser_matrix[i] = fs->get_bits(8);		// check non_intra_quantiser_matrix and load	sequence_h.load_non_intra_quantiser_matrix = fs->get_bit();	if(sequence_h.load_non_intra_quantiser_matrix)		for(int i = 0; i < 64; i++)			sequence_h.non_intra_quantiser_matrix[i] = fs->get_bits(8);		// seek to next start code	next_start_code();		// check extention_start_code	// TODO: should be parsed to get profile_and_level_indication	if(fs->next_bits(32, EXTENSION_START_CODE))	{		fs->get_bits(32);	// skip extension_start_code		for(sequence_h.ext_data_size = 0; !fs->next_bits(24, 0x000001); sequence_h.ext_data_size++)			sequence_h.ext_data[sequence_h.ext_data_size] = fs->get_byte();		next_start_code();	}	else		sequence_h.ext_data_size = 0;		next_start_code();	if(fs->next_bits(32, USER_DATA_START_CODE))	{		fs->get_bits(32);		for(sequence_h.user_data_size = 0; !fs->next_bits(24, 0x000001); sequence_h.user_data_size++)			sequence_h.user_data[sequence_h.user_data_size] = fs->get_byte();		next_start_code();	}	else		sequence_h.user_data_size = 0;		sequence_h.sequence_header_size = 12 + (64 * sequence_h.load_intra_quantiser_matrix) 						+ (64 * sequence_h.load_non_intra_quantiser_matrix);		if(sequence_h.ext_data_size)		sequence_h.sequence_header_size += 4 + sequence_h.ext_data_size;		if(sequence_h.user_data)		sequence_h.sequence_header_size += 4 + sequence_h.user_data_size;		find_next_start_code();		int loadSize = fs->getSizeFromMark();	printf("loadSize: %d\n", loadSize);	if( loadSize <= bytesToGo )	{		printf("load: %d\n", fs->load( payload  ) );		return loadSize;	}	else	{		fs->rewind();			return -1;	}		return 1;}int elementaryStream::get_extension(unsigned char *payload, int bytesToGo){	if(!fs->next_bits(32, EXTENSION_START_CODE))		return -2;		fs->mark();	fs->get_bits(32);		// skip EXTENSION_START_CODE	extension_h.extension_ID				= fs->get_bits(4);	// 4	extension_h.f_code00					= fs->get_bits(4);	// 4	extension_h.f_code01					= fs->get_bits(4);	// 4	extension_h.f_code10					= fs->get_bits(4);	// 4	extension_h.f_code11					= fs->get_bits(4);	// 4	extension_h.intra_dc_precision			= fs->get_bits(2);	// 2	extension_h.picture_structure			= fs->get_bits(2);	// 2	extension_h.top_field_first				= fs->get_bit();	// 1	extension_h.frame_pred_and_frame_dct	= fs->get_bit();	// 1	extension_h.cpmcealment_motion_vectors	= fs->get_bit();	// 1	extension_h.q_scale_type				= fs->get_bit();	// 1	extension_h.intra_vic_format			= fs->get_bit();	// 1	extension_h.alternate_scan				= fs->get_bit();	// 1	extension_h.repeat_first_field			= fs->get_bit();	// 1		extension_h.chroma_420_type				= fs->get_bit();	// 1	extension_h.progressive_frame			= fs->get_bit();	// 1	extension_h.composite_display_flag		= fs->get_bit();	// 1		if( extension_h.composite_display_flag )	{		extension_h.v_axis				= fs->get_bit();			// 1			extension_h.field_sequence		= fs->get_bits(3);			// 3		extension_h.sub_carrier			= fs->get_bit();			// 1		extension_h.burst_amplitude		= fs->get_bits(7);			// 7		extension_h.sub_carrier_phase	= fs->get_bits(8);			// 8	}	next_start_code();		if( fs->getSizeFromMark() <= bytesToGo )	{		fs->load( payload  );				return fs->getSizeFromMark();	}	else	{		fs->rewind();			return -1;	}	}void elementaryStream::print_gop(){		printf("Time code %x\n", gop_i.time_code);	printf("closed_gop %s\n", gop_i.closed_gop ? "true" : "false");	printf("broken_link %s\n", gop_i.broken_link ? "true" : "false");		if(gop_i.gop_ext_data_size)		printf("Extension data exists\n");		if(gop_i.gop_user_data_size)		printf("User data exists\n");		printf("Size of gop %d\n", gop_i.gop_size);}int elementaryStream::get_slices(unsigned char *payload, int bytesToGo){		fs->mark();	fs->get_bits(32);			// skip slice header	if( find_next_start_code() == -2 )	{		while( fs->get_byte() != -2 );		fs->load(payload);		printf("end of file!\n");		return -2;	}		while( !(fs->next_bits(32, GROUP_START_CODE) || fs->next_bits(32, SEQUENCE_HEADER_CODE) ||		fs->next_bits(32, SEQUENCE_END_CODE)|| fs->next_bits(32, PICTURE_START_CODE)) )	{		fs->get_bits(32);		if( find_next_start_code() == -2 )		{			while( fs->get_byte() != -2 );			fs->load(payload);			printf("end of file!\n");			return -2;		}	}	return fs->load(payload);		//printf("before find_next_start_code()\n" );	//printf("next start code: %u\n", next_start  );	//printf("after find_next_start_code()\n" );	//next_start_code();	/*	if( fs->getSizeFromMark() <= bytesToGo )	{			}	else	{		printf(" **************** insufficient...  *************** \n");		fs->rewind();		return -1;	}	*/	}voidelementaryStream::print_sequence_header(){	printf("Got MPEG sequence header\n");	printf("Sequence header size %d\n", sequence_h.sequence_header_size);	printf("Frame width %d\n", sequence_h.horizontal_size_value);	printf("Frame height %d\n", sequence_h.vertical_size_value);	printf("Pel aspect ratio (height to width) %d\n",(sequence_h.aspect_ratio_infomation > 16) ? 		0 : sequence_h.aspect_ratio_infomation);	printf("Picture rate %d\n", (sequence_h.frame_rate_value > 8) ?		9 : sequence_h.frame_rate_value);	printf("Bit rate ");	if(sequence_h.bit_rate_value == 0x3ffff)		printf("variable\n");	else		printf("%d bits/s (%5.2f Kbytes/s)\n", sequence_h.bit_rate_value * 400,        (sequence_h.bit_rate_value * 400.0) / 8192);	printf("Vbv buffer size %d\n", sequence_h.vbv_buffer_size_value);	if(sequence_h.load_intra_quantiser_matrix)		printf("Intra quantizer matrix exists\n");	else		printf("Uses default intra quantizer matrix\n");	if(sequence_h.load_non_intra_quantiser_matrix)		printf("Non intra quantizer matrix exists\n");	else		printf("Uses default non intra quantizer matrix\n");	if(sequence_h.ext_data_size)		printf("Extension data exists\n");	if(sequence_h.user_data_size)		printf("User data exists\n");}void elementaryStream::getVideoSpecficeHeader( unsigned char* vs_header, 										  int end_of_slice,										  int beginning_of_slce,										  int seq_header_present,										  int new_pic_header,											  int active_N_bit	){	VIDEO_SPECIFIC_HEADER *vh = (VIDEO_SPECIFIC_HEADER*)vs_header;	vh->TR		= picture_h.temporal_reference;	vh->T		= 1;	vh->MBZ		= 0;	vh->FFC		= picture_h.forward_f_code;	vh->FFV		= picture_h.full_pel_forward_vector;	vh->BFC		= picture_h.backward_f_code;	vh->FBV		= picture_h.full_pel_backward_vector;    vh->P		= picture_h.picture_config_type;    vh->E		= end_of_slice;	vh->B		= beginning_of_slce;    vh->S		= seq_header_present;    vh->N		= new_pic_header;	vh->AN		= active_N_bit;}void elementaryStream::getMPEG2ExtensionHeader( unsigned char* e_h){	MPEG2_VIDEO_SPECIFIC_HEADER_EXTENSION *h = (MPEG2_VIDEO_SPECIFIC_HEADER_EXTENSION*)e_h;		/* byte 0,1 */	h->backward_vertical_f_code		= extension_h.f_code11;	h->backward_horizontal_f_code	= extension_h.f_code10;	h->forward_vertical_f_code		= extension_h.f_code01;		h->forward_horizontal_f_code	= extension_h.f_code00;			h->E = 0;								/* Extensions present */	h->X = 0;								/* Unused	*/	/* byte 2,3 */	h->DC = extension_h.intra_dc_precision;				/* Intra_DC_precision  */	h->PS = extension_h.picture_structure;								/* picture_structure  */	h->T = extension_h.top_field_first;								/* top_field_first  */	h->P = extension_h.frame_pred_and_frame_dct;								/* frame_predicted_frame_dct   */	h->C = extension_h.cpmcealment_motion_vectors;								/* concealment_motion_vectors   */	h->Q = extension_h.q_scale_type;								/* q_scale type   */	h->V = extension_h.intra_vic_format;								/* intra_vlc_format   */	h->A = extension_h.alternate_scan;								/* alternate scan   */	h->R = extension_h.repeat_first_field;								/* repeat_first_field   */	h->H = extension_h.chroma_420_type;								/* chroma_420_type   */	h->G = extension_h.progressive_frame;								/* progressive frame   */	h->D = extension_h.composite_display_flag;								/* composite_display_flag   *//*		extension_h.v_axis;					// 1		extension_h.field_sequence;			// 3	extension_h.sub_carrier;				// 1	extension_h.burst_amplitude;			// 7	extension_h.sub_carrier_phase;			// 8*/	}intelementaryStream::sendRTPpacket(unsigned char* payload,int increment, int marker,int payloadSize){	static unsigned char    buffer[16384];	static unsigned char    RTP_pkt[sizeof(RTP_HEADER)+sizeof(buffer)];	static RTP_HEADER *rtp_header;	m_stream_num = 10;	rtp_header = (RTP_HEADER *)RTP_pkt;		rtp_header->csrc_len		= 0;				/* expect 0 */	rtp_header->extension	= 0;					rtp_header->padding		= 0;				/* expect 0 */	rtp_header->version		= RTP_VERSION;		/* expect 2 */		/* byte 1 */	rtp_header->payload		= MPV_PAYLOAD;			rtp_header->marker		= marker;				/* bytes 2, 3 */	rtp_header->seq_no		= htons(m_seq_num++);				/* bytes 4-7 */	if( marker )		Sleep( 33 ); // sleep 33 msec		if( increment )	{		m_time_stamp += (29700*hold);				hold = 0;	}	rtp_header->timestamp	= htonl(m_time_stamp);	/* bytes 8-11 */    rtp_header->ssrc		= htonl(m_stream_num);			/* stream number is used here. */		memcpy( RTP_pkt + sizeof(RTP_HEADER), payload, payloadSize );	return sock->write( (void*)&RTP_pkt, sizeof(RTP_HEADER)+payloadSize );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -