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

📄 mpeg2demux.c

📁 从 IEEE 1394总线接收传输流
💻 C
📖 第 1 页 / 共 4 页
字号:
				PAT_have_bytes_of_header=0;			}		}	}	if (!PAT_position)	{		fprintf(stderr,"skipping chunk of PAT, because it did not start yet\n");		return 1;	}	while (rest_of_ts_packet())	{		if (rest_of_pat_section) /* do we have to complete an old section? */		{			if (get_program_association_table_rest(start && !started))				return 1;		}		else if (PAT_have_bytes_of_header < 8) /* we have to read a PAT head */		{			if (PAT_have_bytes_of_header==0)			{				if (start)				{					if ((!started) && (start_position != rest_of_ts_packet()))					{						fprintf(stderr,"Pointer field at beginning of packet containing PAT was not correct\n");						PAT_position=0;						return 1;					}					else						started=1;				}				else				{					fprintf(stderr,"Packet with starting PAT section did not contain payload unit start indicator\n");					PAT_position=0;					return 1;				}			}				if (get_and_parse_program_association_table_header())			{				fprintf(stderr,"waiting for next PAT because of this error\n");				PAT_position=0;				return 1;			}		}	}	return 1;}static int get_pes_packet_data(int stream_id){	unsigned long long pts,dts;	int have_pts;	if ((stream_id >> 4) == 12 || (stream_id >> 4) == 13){		/* Just pick the first available stream if no ID is set */		if (audio_pid==-2) audio_pid=pid;		if (pid==audio_pid){			get_pes_packet_header(&pts, &dts, &have_pts);			if (have_pts) {				audio_pts.timestamp=pts;				audio_pts.have_timestamp=1;			}			return get_audio_data();		}	}	else if ((stream_id >> 4) == 14){		/* Just pick the first available stream if no ID is set */		if (video_pid==-2) video_pid=pid;		if (pid==video_pid){			if ((videobufferend + 1) % VIDEOPESPACKETSINBUFFER == videobufferstart) { /* if buffer is full */				fprintf(stderr,"Video buffer overrun! Discarding pes packet\n");			} else {				videobufferend++;				videobufferend %= VIDEOPESPACKETSINBUFFER; /* advance ringbuffercounter */				if (sem_post(&videobuffer_sem))				{					fprintf(stderr,"Cannot V semaphore\n");;					exit(0);				}			}			get_pes_packet_header(&pts, &videobuffer[videobufferend].dts,&videobuffer[videobufferend].havedts);			videobuffer[videobufferend].continuation=0;			videobuffer[videobufferend].length=0;			videobuffer[videobufferend].flags = 0;			return get_video_data();		}	}	else {		return 1;	}	/* skipbytes(MPEG2_TS_Packet_size - bytecount); */	return 1;}static int get_pes_packet_header(unsigned long long *pts, unsigned long long *dts, int *havepts){	unsigned int pes_header_bytes=0;	short PTS_DTS_flags;	int PES_header_data_length;	*havepts=0;	(void) getbits8();  /* drop first 8 bits */	PTS_DTS_flags=(getbits8() >> 6) & 0x3;	PES_header_data_length=getbits8();	/* Get Presentation Time stamps and Decoding Time Stamps */	if (PTS_DTS_flags==2){		*pts=(getbits8() >> 1) & 7;  /* Only low 3 bits (7==111) */		*pts<<=15;		*pts|=(getbits16() >> 1);		*pts<<=15;		*pts|=(getbits16() >> 1);		pes_header_bytes+=5;		*dts=*pts;    /* if dts is not explicitly encoded, its equal to pts */		*havepts=1;	}	else if (PTS_DTS_flags==3){      		*pts=(getbits8() >> 1) & 7;  /* Only low 3 bits (7==111) */		*pts<<=15;		*pts|=(getbits16() >> 1);		*pts<<=15;		*pts|=(getbits16() >> 1);		*havepts=1;		*dts=(getbits8() >> 1) & 7;  /* Only low 3 bits (7==111) */		*dts<<=15;		*dts|=(getbits16() >> 1);		*dts<<=15;		*dts|=(getbits16() >> 1);		pes_header_bytes+=10;	}  	skipbytes(PES_header_data_length - pes_header_bytes);	return 1;}static int get_pes_packet(){	unsigned int stream_id;	(void) getbits24();     /* skip startcode */	stream_id=getbits8();	/* int pes_packet_length=   Not used at this point; just drop */	(void) getbits16();	if (stream_id!=PRIVATE_STREAM_2 && stream_id!=PADDING_STREAM){		return get_pes_packet_data(stream_id);	}	else if (stream_id==PRIVATE_STREAM_2){		fprintf(stderr,"private stream\n");		//skipbytes(MPEG2_TS_Packet_size - bytecount);	}	else if (stream_id==PADDING_STREAM){		//skipbytes(MPEG2_TS_Packet_size - bytecount);	}	else {		fprintf(stderr,"unknown stream_id in pes packet\n");		// skipbytes(MPEG2_TS_Packet_size - bytecount);	}	return 1;}static int get_PMT_packet(int section_start){	int bufferindex=get_PMT_Buffer_Index(pid);	if (bufferindex == -1)	{		fprintf(stderr,"cannot read PMT, because no buffer is free\n");		return 0;	}	if (section_start)      /* if payload_start_indictor says, that we start a new section */	{		if (getbits8()!=0)		{			fprintf(stderr,"cannot handle packets with pmt section starts not aligned with payload start\n");			pmt_buffer[bufferindex].pid=-1;			return 0;		}		pmt_buffer[bufferindex].pid=pid;		pmt_buffer[bufferindex].byte_count=0;	}	else	{		if (pmt_buffer[bufferindex].pid != pid)		{			fprintf(stderr,"cannot continue PMT section in PID %d, because there is no beginning in buffer\n",pid);			return 0;		}	}	/* read PMT section */	pmt_buffer[bufferindex].byte_count += copybytes(pmt_buffer[bufferindex].buffer+pmt_buffer[bufferindex].byte_count,rest_of_ts_packet());	/* check if section is complete */	if (pmt_buffer[bufferindex].byte_count> 12) /* do we have a complete section header ?*/	{		unsigned int section_length=((pmt_buffer[bufferindex].buffer[1] & 0x0f) << 8) | pmt_buffer[bufferindex].buffer[2];		if (section_length > 1021) /* section too long */		{			fprintf(stderr,"Discarding PMT section, because section length says: %d (max 1021 allowed)\n",section_length);			pmt_buffer[bufferindex].pid=-1; /* clear buffer; */			return 0;		}		else if (pmt_buffer[bufferindex].byte_count >= section_length+3)		{ /* we have a complete section -> interpret it */			struct ProgramMapTableEntry *pmt_entry;			int program_number;			int PCR_PID;			int program_info_length;			unsigned int current_index;			pmt_buffer[bufferindex].pid=-1; /* clear buffer; when this method terminates (whether with or without error), this buffer is consumed */			if (pmt_buffer[bufferindex].buffer[0] != 2)			{				fprintf(stderr,"incorrect table_id in program map table\n");;				return 0;			}			if ((pmt_buffer[bufferindex].buffer[1] >> 4) != 11)			{				fprintf(stderr,"syntax error in program map table\n");;				return 0;			}			program_number=(pmt_buffer[bufferindex].buffer[3] << 8) | pmt_buffer[bufferindex].buffer[4];			if (!(pmt_buffer[bufferindex].buffer[5] & 1))			{				fprintf(stderr,"skipping next program map table\n");;				return 0;			}			if (pmt_buffer[bufferindex].buffer[6] || pmt_buffer[bufferindex].buffer[7])			{				fprintf(stderr,"error in PMT: section number or last section number != 0\n");;				return 0;			}			PCR_PID=((pmt_buffer[bufferindex].buffer[8] << 8) | pmt_buffer[bufferindex].buffer[9]) & 0x1fff;			program_info_length=((pmt_buffer[bufferindex].buffer[10] << 8) | pmt_buffer[bufferindex].buffer[11]) & 0x0fff;						current_index=12+program_info_length; /* here we start to read stream definitions */			if (pthread_mutex_lock(&mutex_PMT)) /* lock PMT to ensure that nobody reads it while we modify it */			{				fprintf(stderr,"cannot lock PMT mutex\n");;				exit(1);			}			pmt_entry = getProgramMapTableEntry(program_number);			if (pmt_entry) {				cleanPMTEntry(pmt_entry);			} else {				pmt_entry = malloc(sizeof(struct ProgramMapTableEntry));				if (!pmt_entry) {					fprintf(stderr,"cannot malloc program map table entry.\n");					exit(1);				}				pmt_entry->next=program_map_table;				pmt_entry->streams=NULL;				program_map_table=pmt_entry;			}			pmt_entry->PCR_PID = PCR_PID;			pmt_entry->program_number = program_number;			while (current_index+4 < section_length+3) /* while we are before CRC */			{				int ES_info_length;				struct stream_description *hilf=malloc(sizeof(struct stream_description));				if (hilf) {					hilf->stream_type=pmt_buffer[bufferindex].buffer[current_index++];					hilf->elementary_PID=(pmt_buffer[bufferindex].buffer[current_index++] << 8) & 0x1fff;					hilf->elementary_PID |= pmt_buffer[bufferindex].buffer[current_index++];					hilf->next=pmt_entry->streams;					pmt_entry->streams=hilf;				} else {					fprintf(stderr,"cannot malloc stream description.\n");					current_index += 3;				}				ES_info_length=(pmt_buffer[bufferindex].buffer[current_index++] << 8) & 0x0fff;				ES_info_length |= pmt_buffer[bufferindex].buffer[current_index++];				current_index += ES_info_length; /* skip info */			}			if (current_program == program_number) {				int new_v = getVideoPid(pmt_entry);				int new_a = getAudioPid(pmt_entry);				if ((video_pid != new_v) || (audio_pid != new_a) || (pcr_pid != PCR_PID)) {					fprintf(stderr,"program %d changed pids, restarting decoders\n", program_number);					set_pids_internal(new_v, new_a, PCR_PID);				}			}			if ((current_program == -1) && ((track_program == program_number) || (track_program == -2) || ((track_program == -3) && (program_number == getFirstProgram())))) {				int new_v = getVideoPid(pmt_entry);				int new_a = getAudioPid(pmt_entry);				if ((track_program  == program_number) || (track_program == -3) || ((new_v != -1) && (new_a != -1))) {					if (new_v == -1) {						fprintf(stderr,"program has no video\n");					}					if (new_a == -1) {						fprintf(stderr,"program has no audio\n");					}					if (debug) {						fprintf(stdout,"start decoding program %d with video: %d, audio: %d, pcr: %d\n", program_number, new_v, new_a, PCR_PID);					}					current_program = program_number;					set_pids_internal(new_v, new_a, PCR_PID);				}			}			if (pthread_mutex_unlock(&mutex_PMT)) /* unlock PMT */			{				fprintf(stderr,"cannot unlock PMT mutex\n");;				exit(1);			}			if (current_index+4 != section_length+3 ) {fprintf(stderr,"section length incorrect\n");; return 0;}			current_index+=4; /* skip CRC_32 */			if ((current_index < pmt_buffer[bufferindex].byte_count) && (pmt_buffer[bufferindex].buffer[current_index] != 0xff)) /* rest must be padding */				{fprintf(stderr,"illegal data at end of program map table section\n");;return 0;}		  return 1;		}		else			return 1; /* wait for next part of this section (header is already complete, but body incomplete) */	}	else		return 1; /* wait for next part of this section (header incomplete) */}static int get_audio_data() {	(void) audiobufferfill();	audio_packets++;	return 1;}static int get_video_data(){	unsigned int length=rest_of_ts_packet();	struct videobuffer_entry *currentbuffer=&videobuffer[videobufferend];	if (length <= (VIDEOBUFFER_ENTRY_SIZE - currentbuffer->length))		currentbuffer->length += copybytes(currentbuffer->buffer+currentbuffer->length,length);	else	{		/* fprintf(stderr,"Video PES packet too long -> splitted\n"); */		if ((videobufferend + 1) % VIDEOPESPACKETSINBUFFER == videobufferstart) { /* if buffer is full */				fprintf(stderr,"Video buffer overrun! Discarding packet\n");		} else {			videobufferend++;			videobufferend %= VIDEOPESPACKETSINBUFFER; /* advance ringbuffercounter */			if (sem_post(&videobuffer_sem))			{				fprintf(stderr,"Cannot V semaphore\n");				exit(0);			}			videobuffer[videobufferend].havedts=0;			videobuffer[videobufferend].continuation=1;			videobuffer[videobufferend].length=copybytes(videobuffer[videobufferend].buffer,length);			videobuffer[videobufferend].flags = 0;		}	}	video_packets++;	return 1;}static int head_read(unsigned long *head){	if (audio_header_bytes_read == 4) /* if we already have four bytes, then we shift */	{		audio_hbuf[0]=audio_hbuf[1];audio_hbuf[1]=audio_hbuf[2];audio_hbuf[2]=audio_hbuf[3];		audio_header_bytes_read=3;		skipped_mpegaudio_bytes++; /* we skipped a byte now */	}	while (audio_header_bytes_read < 4)	{		if (rest_of_ts_packet() > 0)			audio_hbuf[audio_header_bytes_read++]=getbits8();		else			return 0;	}	*head = ((unsigned long) audio_hbuf[0] << 24) | ((unsigned long) audio_hbuf[1] << 16) | ((unsigned long) audio_hbuf[2] << 8) | (unsigned long) audio_hbuf[3];	return 1;}/* * Exception from GNU General Public License: * This function (head_check) is a modification of that function * taken from mpg123.

⌨️ 快捷键说明

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