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

📄 mpeg2demux.c

📁 从 IEEE 1394总线接收传输流
💻 C
📖 第 1 页 / 共 4 页
字号:
 * The modifications are under GNU GPL, but the the original code is * under copyright (C) 1995-1999 by Michael Hipp and has its own license. * mpg123 can be obtained under http://www.mpg123.de */static int head_check(unsigned long head){	if( (head & 0xffe00000) != 0xffe00000)		return 0;	if(!((head>>17)&3))		return 0;	if( ((head>>12)&0xf) == 0xf)		return 0;	if( ((head>>10)&0x3) == 0x3 )		return 0;	if ((head & 0xffff0000) == 0xfffe0000)		return 0;	return 1;}/* * Exception from GNU General Public License: * This function (decodee_header) is a modification of that function * taken from mpg123. * The modifications are under GNU GPL, but the the original code is * under copyright (C) 1995-1999 by Michael Hipp and has its own license. * mpg123 can be obtained under http://www.mpg123.de *//* * decode a header and write the information * into the frame structure */static int decode_header(struct frame *fr,unsigned long newhead, int *ssize){	if(!head_check(newhead))		return 0;	if( newhead & (1<<20) ) {		fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1;		fr->mpeg25 = 0;	}	else {		fr->lsf = 1;		fr->mpeg25 = 1;	}	fr->lay = 4-((newhead>>17)&3);	if( ((newhead>>10)&0x3) == 0x3) {		fprintf(stderr,"Audio Stream error\n");;		return 0;	}	if(fr->mpeg25)		fr->sampling_frequency = 6 + ((newhead>>10)&0x3);	else		fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3);	fr->error_protection = ((newhead>>16)&0x1)^0x1;	fr->bitrate_index = ((newhead>>12)&0xf);	fr->padding   = ((newhead>>9)&0x1);	fr->extension = ((newhead>>8)&0x1);	fr->mode      = ((newhead>>6)&0x3);	fr->mode_ext  = ((newhead>>4)&0x3);	fr->copyright = ((newhead>>3)&0x1);	fr->original  = ((newhead>>2)&0x1);	fr->emphasis  = newhead & 0x3;	fr->stereo    = (fr->mode == MPG_MD_MONO) ? 1 : 2;	if(!fr->bitrate_index) {		fprintf(stderr,"Free format not supported: (head 0x%lx)\n", newhead);		return 0;	}	switch(fr->lay) {		case 1:			fr->do_layer = do_layer1;			fr->framesize  = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;			fr->framesize /= freqs[fr->sampling_frequency];			fr->framesize  = ((fr->framesize+fr->padding)<<2)-4;			break;		case 2:			fr->do_layer = do_layer2;			fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;			fr->framesize /= freqs[fr->sampling_frequency];			fr->framesize += fr->padding - 4;			break;		case 3:			fr->do_layer = do_layer3;			if(fr->lsf)				*ssize = (fr->stereo == 1) ? 9 : 17;			else				*ssize = (fr->stereo == 1) ? 17 : 32;			if(fr->error_protection)				*ssize += 2;			fr->framesize  = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;			fr->framesize /= freqs[fr->sampling_frequency]<<(fr->lsf);			fr->framesize = fr->framesize + fr->padding - 4;			break;		default:        fprintf(stderr,"Sorry, unknown layer type.\n");;        return (0);    }    return 1;}static int get_audio_head(struct frame *fr,int *ssize){	unsigned long newhead;	do	{		if(!head_read(&newhead)) /* shift through stream and look for header, searching for header */			return 0;	}	while (!decode_header(fr, newhead, ssize));	if (skipped_mpegaudio_bytes)	{		fprintf(stderr,"Skipped %ld bytes of audio-stream\n",skipped_mpegaudio_bytes);		skipped_mpegaudio_bytes=0;	}	fr->header_change = 2;	if(old_mpegaudio_head) {		if((old_mpegaudio_head & 0xc00) == (newhead & 0xc00)) {			if( (old_mpegaudio_head & 0xc0) == 0 && (newhead & 0xc0) == 0)				fr->header_change = 1;			else if( (old_mpegaudio_head & 0xc0) > 0 && (newhead & 0xc0) > 0)				fr->header_change = 1;		}	}	old_mpegaudio_head=newhead;	return 1;}static int audiobufferfill(){	int bytesleft4buffer;	int readbytes;	while (rest_of_ts_packet() > 0)	{		if (!have_mpegaudio_header) /* if no new frame started */		{			if (!get_audio_head(&audiobuffer[audiobufferend].fr,&audiobuffer[audiobufferend].ssize))				return 1;			else			{				if ((audiobuffer[audiobufferend].havepts=audio_pts.have_timestamp)) {					audiobuffer[audiobufferend].pts=audio_pts.timestamp;					audio_pts.have_timestamp=0;				}				bytes_already_in_audiobuffer=0;				have_mpegaudio_header=1;			}		}		/* here we can be sure that we have a header */		bytesleft4buffer=audiobuffer[audiobufferend].fr.framesize-bytes_already_in_audiobuffer;		readbytes= bytesleft4buffer < rest_of_ts_packet()?bytesleft4buffer:(rest_of_ts_packet());		bytes_already_in_audiobuffer += copybytes(audiobuffer[audiobufferend].buffer+512+bytes_already_in_audiobuffer,readbytes);		if (bytes_already_in_audiobuffer == audiobuffer[audiobufferend].fr.framesize)	/* frame complete */		{			have_mpegaudio_header=0;	/* start new frame in next iteration */			audio_header_bytes_read=0;			audio_frames++;			if ( (audiobufferend + 2) % AUDIOFRAMESINBUFFER == audiobufferstart) {/* if buffer is full; 2 entries must be free, because mp3 also needs the last frame */				fprintf(stderr,"Audio buffer overrun! Discarding frame\n");			} else {				audiobufferend = (audiobufferend + 1) % AUDIOFRAMESINBUFFER; /* advance ringbuffercounter */				if (sem_post(&audiobuffer_sem))				{					fprintf(stderr,"Cannot V semaphore\n");					exit(0);				}			}		}	}	return 1;}int select_program(int program_number){	struct ProgramMapTableEntry *pmt_entry;	if (pthread_mutex_lock(&mutex_PMT)) /* lock PMT to ensure that nobody modifies it while we read it */	{		fprintf(stderr,"cannot lock PMT mutex\n");;		exit(1);	}	track_program = program_number;	current_program = -1;	pmt_entry = getProgramMapTableEntry(program_number);	if (pmt_entry)	{		int hilfv=getVideoPid(pmt_entry);		int hilfa=getAudioPid(pmt_entry);		if (hilfv==-1 && hilfa==-1)		{			fprintf(stderr,"stream does not have audio and video\n");;		}		set_pids_internal(hilfv,hilfa,getPCRPid(pmt_entry));		current_program = program_number;	}	else	{		if (debug) {			fprintf(stdout,"desired program not yet in PMT -> maybe it appears later...\n");		}		set_pids_internal(-1,-1,-1);	}	if (pthread_mutex_unlock(&mutex_PMT))	{		fprintf(stderr,"cannot unlock PMT mutex\n");;		exit(1);	}	return 0;}int select_any_program(){	struct ProgramMapTableEntry *pmt_temp;	if (pthread_mutex_lock(&mutex_PMT)) /* lock PMT to ensure that nobody modifies it while we read it */	{		fprintf(stderr,"cannot lock PMT mutex\n");;		exit(1);	}	track_program = -2;	current_program = -1;	for (pmt_temp = program_map_table; pmt_temp; pmt_temp=pmt_temp->next) {		int hilfv=getVideoPid(pmt_temp);		int hilfa=getAudioPid(pmt_temp);		if ((hilfv != -1) && (hilfa != -1))		{			set_pids_internal(hilfv,hilfa,getPCRPid(pmt_temp));			current_program = pmt_temp->program_number;			break;		}	}	if (current_program == -1) {		if (debug) {			fprintf(stdout,"no TV program available yet -> maybe later one appears...\n");		}		set_pids_internal(-1,-1,-1);	}	if (pthread_mutex_unlock(&mutex_PMT))	{		fprintf(stderr,"cannot unlock PMT mutex\n");;		exit(1);	}	return 0;}int select_first_program(){	struct ProgramMapTableEntry *pmt_entry;	int program_number;	if (pthread_mutex_lock(&mutex_PMT)) /* lock PMT to ensure that nobody modifies it while we read it */	{		fprintf(stderr,"cannot lock PMT mutex\n");;		exit(1);	}	track_program = -3;	current_program = -1;	program_number = getFirstProgram();	pmt_entry = getProgramMapTableEntry(program_number);	if (pmt_entry)	{		int hilfv=getVideoPid(pmt_entry);		int hilfa=getAudioPid(pmt_entry);		if (hilfv==-1 && hilfa==-1)		{			fprintf(stderr,"stream does not have audio and video\n");;		}		set_pids_internal(hilfv,hilfa,getPCRPid(pmt_entry));		current_program = program_number;	}	else	{		if (debug) {			fprintf(stdout,"first program not yet in PMT -> maybe it appears later...\n");		}		set_pids_internal(-1,-1,-1);	}	if (pthread_mutex_unlock(&mutex_PMT))	{		fprintf(stderr,"cannot unlock PMT mutex\n");;		exit(1);	}	return 0;}static void set_pids_internal(int videopid, int audiopid, int pcrpid) {	if (pthread_mutex_lock(&mutex_decoders)) /* lock decoders; their buffers will not get filled now */	{		fprintf(stderr,"cannot lock decoders mutex\n");;		exit(1);	}	(void) video_system_done(); /* reset video and audio decoders */	(void) audio_system_done();	(void) video_system_init();	(void) audio_system_init();	have_mpegaudio_header=0; /* initialization for audiobufferfill */	old_mpegaudio_head = 0,skipped_mpegaudio_bytes=0; /* initialization for get_audio_head */	audio_header_bytes_read=0; /* initialization for head_read */	video_pid=videopid;	audio_pid=audiopid;	pcr_pid=pcrpid;	disable_sync(); /* disable sync; we must re-sync now */	if (pthread_mutex_unlock(&mutex_decoders)) /* unlock decoders; now we can resume filling their buffers */	{		fprintf(stderr,"cannot unlock decoders mutex\n");;		exit(1);	}}void set_pids(int videopid, int audiopid, int pcrpid) {	current_program=-1;	track_program=-1;	set_pids_internal(videopid, audiopid, pcrpid);}void get_pids(int *videopid, int *audiopid, int *pcrpid) {	if (videopid) *videopid=video_pid;	if (audiopid) *audiopid=audio_pid;	if (pcrpid) *pcrpid=pcr_pid;}int get_videobuffer_size() {	return VIDEOPESPACKETSINBUFFER-1; /* one entry must stay free */}int get_videobuffer_state() {	return (videobufferend+VIDEOPESPACKETSINBUFFER-videobufferstart) % VIDEOPESPACKETSINBUFFER -1;}int get_audiobuffer_size() {	return AUDIOFRAMESINBUFFER-2; /* two entries stay free in audio buffer */}int get_audiobuffer_state() {	return (audiobufferend +AUDIOFRAMESINBUFFER - audiobufferstart) % AUDIOFRAMESINBUFFER;}int getProgramNumbers(int *number_array) {	int number=0;	struct ProgramMapTableEntry *pmt_entry;	if (pthread_mutex_lock(&mutex_PMT)) /* lock PMT */	{		fprintf(stderr,"cannot lock PMT mutex\n");;		exit(1);	}	for (pmt_entry = program_map_table; pmt_entry; pmt_entry=pmt_entry->next)	{		number_array[number++]=pmt_entry->program_number;	}	if (pthread_mutex_unlock(&mutex_PMT)) /* unlock PMT */	{		fprintf(stderr,"cannot unlock PMT mutex\n");;		exit(1);	}	return number;}

⌨️ 快捷键说明

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