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

📄 demux_ts.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 5 页
字号:
//copyright belongs to Michel Lespinasse <walken@zoy.org> and Aaron Holtzman <aholtzma@ess.engr.uvic.ca>int mp_a52_framesize(uint8_t * buf, int *srate){	int rate[] = {	32,  40,  48,  56,  64,  80,  96, 112,			128, 160, 192, 224, 256, 320, 384, 448,			512, 576, 640	};	uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3};	int frmsizecod, bitrate, half;		if((buf[0] != 0x0b) || (buf[1] != 0x77))	/* syncword */		return 0;		if(buf[5] >= 0x60)		/* bsid >= 12 */		return 0;	half = halfrate[buf[5] >> 3];		frmsizecod = buf[4] & 63;	if(frmsizecod >= 38)		return 0;	bitrate = rate[frmsizecod >> 1];		switch(buf[4] & 0xc0) 	{		case 0:	/* 48 KHz */			*srate = 48000 >> half;			return 4 * bitrate;		case 0x40:	/* 44.1 KHz */			*srate = 44100 >> half;			return 2 * (320 * bitrate / 147 + (frmsizecod & 1));		case 0x80: /* 32 KHz */			*srate = 32000 >> half;			return 6 * bitrate;	}		return 0;}//second stage: returns the count of A52 syncwords foundstatic int a52_check(char *buf, int len){	int cnt, frame_length, ok, srate;		cnt = ok = 0;	if(len < 8)		return 0;			while(cnt < len - 7)		{		if(buf[cnt] == 0x0B && buf[cnt+1] == 0x77)		{			frame_length = mp_a52_framesize(&buf[cnt], &srate);			if(frame_length>=7 && frame_length<=3840)			{				cnt += frame_length;				ok++;			}			else			    cnt++;		}		else			cnt++;	}	mp_msg(MSGT_DEMUXER, MSGL_V, "A52_CHECK(%d input bytes), found %d frame syncwords of %d bytes length\n", len, ok, frame_length);		return ok;}static off_t ts_detect_streams(demuxer_t *demuxer, tsdemux_init_t *param){	int video_found = 0, audio_found = 0, sub_found = 0, i, num_packets = 0, req_apid, req_vpid, req_spid;	int is_audio, is_video, is_sub, has_tables;	int32_t p, chosen_pid = 0;	off_t pos=0, ret = 0, init_pos, end_pos;	ES_stream_t es;	unsigned char tmp[TS_FEC_PACKET_SIZE];	ts_priv_t *priv = (ts_priv_t*) demuxer->priv;	struct {		char *buf;		int pos;	} pes_priv1[8192], *pptr;	char *tmpbuf;	priv->last_pid = 8192;		//invalid pid	req_apid = param->apid;	req_vpid = param->vpid;	req_spid = param->spid;	has_tables = 0;	memset(pes_priv1, 0, sizeof(pes_priv1));	init_pos = stream_tell(demuxer->stream);	mp_msg(MSGT_DEMUXER, MSGL_V, "PROBING UP TO %"PRIu64", PROG: %d\n", (uint64_t) param->probe, param->prog);	end_pos = init_pos + (param->probe ? param->probe : TS_MAX_PROBE_SIZE);	while(1)	{		pos = stream_tell(demuxer->stream);		if(pos > end_pos || demuxer->stream->eof)			break;		if(ts_parse(demuxer, &es, tmp, 1))		{			//Non PES-aligned A52 audio may escape detection if PMT is not present;			//in this case we try to find at least 3 A52 syncwords			if((es.type == PES_PRIVATE1) && (! audio_found) && req_apid > -2)			{				pptr = &pes_priv1[es.pid];				if(pptr->pos < 64*1024)				{				tmpbuf = (char*) realloc(pptr->buf, pptr->pos + es.size);				if(tmpbuf != NULL)				{					pptr->buf = tmpbuf;					memcpy(&(pptr->buf[ pptr->pos ]), es.start, es.size);					pptr->pos += es.size;					if(a52_check(pptr->buf, pptr->pos) > 2)					{						param->atype = AUDIO_A52;						param->apid = es.pid;						es.type = AUDIO_A52;					}				}				}			}						is_audio = IS_AUDIO(es.type) || ((es.type==SL_PES_STREAM) && IS_AUDIO(es.subtype));			is_video = IS_VIDEO(es.type) || ((es.type==SL_PES_STREAM) && IS_VIDEO(es.subtype));			is_sub   = ((es.type == SPU_DVD) || (es.type == SPU_DVB));			if((! is_audio) && (! is_video) && (! is_sub))				continue;			if(is_audio && req_apid==-2)				continue;			if(is_video)			{				mp_msg(MSGT_IDENTIFY, MSGL_V, "ID_VIDEO_ID=%d\n", es.pid);    				chosen_pid = (req_vpid == es.pid);				if((! chosen_pid) && (req_vpid > 0))					continue;			}			else if(is_audio)			{				mp_msg(MSGT_IDENTIFY, MSGL_V, "ID_AUDIO_ID=%d\n", es.pid);				if (es.lang[0] > 0)					mp_msg(MSGT_IDENTIFY, MSGL_V, "ID_AID_%d_LANG=%s\n", es.pid, es.lang);				if(req_apid > 0)				{					chosen_pid = (req_apid == es.pid);					if(! chosen_pid)						continue;				}				else if(param->alang[0] > 0 && es.lang[0] > 0)				{					if(pid_match_lang(priv, es.pid, param->alang) == -1)						continue;					chosen_pid = 1;					param->apid = req_apid = es.pid;				}			}			else if(is_sub)			{				mp_msg(MSGT_IDENTIFY, MSGL_V, "ID_SUBTITLE_ID=%d\n", es.pid);				if (es.lang[0] > 0)					mp_msg(MSGT_IDENTIFY, MSGL_V, "ID_SID_%d_LANG=%s\n", es.pid, es.lang);				chosen_pid = (req_spid == es.pid);				if((! chosen_pid) && (req_spid > 0))					continue;			}			if(req_apid < 0 && (param->alang[0] == 0) && req_vpid < 0 && req_spid < 0)				chosen_pid = 1;			if((ret == 0) && chosen_pid)			{				ret = stream_tell(demuxer->stream);			}			p = progid_for_pid(priv, es.pid, param->prog);			if(p != -1)				has_tables++;			if((param->prog == 0) && (p != -1))			{				if(chosen_pid)					param->prog = p;			}			if((param->prog > 0) && (param->prog != p))			{				if(audio_found)				{					if(is_video && (req_vpid == es.pid))					{						param->vtype = IS_VIDEO(es.type) ? es.type : es.subtype;						param->vpid = es.pid;						video_found = 1;						break;					}				}				if(video_found)				{					if(is_audio && (req_apid == es.pid))					{						param->atype = IS_AUDIO(es.type) ? es.type : es.subtype;						param->apid = es.pid;						audio_found = 1;						break;					}				}				continue;			}			mp_msg(MSGT_DEMUXER, MSGL_DBG2, "TYPE: %x, PID: %d, PROG FOUND: %d\n", es.type, es.pid, param->prog);			if(is_video)			{				if((req_vpid == -1) || (req_vpid == es.pid))				{					param->vtype = IS_VIDEO(es.type) ? es.type : es.subtype;					param->vpid = es.pid;					video_found = 1;				}			}			if(((req_vpid == -2) || (num_packets >= NUM_CONSECUTIVE_AUDIO_PACKETS)) && audio_found && !param->probe)			{				//novideo or we have at least 348 audio packets (64 KB) without video (TS with audio only)				param->vtype = 0;				break;			}			if(is_sub)			{				if((req_spid == -1) || (req_spid == es.pid))				{					param->stype = es.type;					param->spid = es.pid;					sub_found = 1;				}			}			if(is_audio)			{				if((req_apid == -1) || (req_apid == es.pid))				{					param->atype = IS_AUDIO(es.type) ? es.type : es.subtype;					param->apid = es.pid;					audio_found = 1;				}			}			if(audio_found && (param->apid == es.pid) && (! video_found))				num_packets++;			if((has_tables==0) && (video_found && audio_found) && (pos >= 1000000))				break;		}	}	for(i=0; i<8192; i++)	{		if(pes_priv1[i].buf != NULL)		{			free(pes_priv1[i].buf);			pes_priv1[i].buf = NULL;			pes_priv1[i].pos = 0;		}	}							if(video_found)	{		if(param->vtype == VIDEO_MPEG1)			mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG1(pid=%d) ", param->vpid);		else if(param->vtype == VIDEO_MPEG2)			mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG2(pid=%d) ", param->vpid);		else if(param->vtype == VIDEO_MPEG4)			mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO MPEG4(pid=%d) ", param->vpid);		else if(param->vtype == VIDEO_H264)			mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO H264(pid=%d) ", param->vpid);		else if(param->vtype == VIDEO_VC1)			mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO VC1(pid=%d) ", param->vpid);		else if(param->vtype == VIDEO_AVC)			mp_msg(MSGT_DEMUXER, MSGL_INFO, "VIDEO AVC(NAL-H264, pid=%d) ", param->vpid);	}	else	{		param->vtype = UNKNOWN;		//WE DIDN'T MATCH ANY VIDEO STREAM		mp_msg(MSGT_DEMUXER, MSGL_INFO, "NO VIDEO! ");	}	if(param->atype == AUDIO_MP2)		mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO MPA(pid=%d)", param->apid);	else if(param->atype == AUDIO_A52)		mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO A52(pid=%d)", param->apid);	else if(param->atype == AUDIO_DTS)		mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO DTS(pid=%d)", param->apid);	else if(param->atype == AUDIO_LPCM_BE)		mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO LPCM(pid=%d)", param->apid);	else if(param->atype == AUDIO_AAC)		mp_msg(MSGT_DEMUXER, MSGL_INFO, "AUDIO AAC(pid=%d)", param->apid);	else	{		audio_found = 0;		param->atype = UNKNOWN;		//WE DIDN'T MATCH ANY AUDIO STREAM, SO WE FORCE THE DEMUXER TO IGNORE AUDIO		mp_msg(MSGT_DEMUXER, MSGL_INFO, "NO AUDIO! ");	}	if(param->stype == SPU_DVD || param->stype == SPU_DVB)		mp_msg(MSGT_DEMUXER, MSGL_INFO, " SUB %s(pid=%d) ", (param->stype==SPU_DVD ? "DVD" : "DVB"), param->spid);	else	{		param->stype = UNKNOWN;		mp_msg(MSGT_DEMUXER, MSGL_INFO, " NO SUBS (yet)! ");	}	if(video_found || audio_found)	{		if(demuxer->stream->eof && (ret == 0))			ret = init_pos;		mp_msg(MSGT_DEMUXER, MSGL_INFO, " PROGRAM N. %d\n", param->prog);	}	else		mp_msg(MSGT_DEMUXER, MSGL_INFO, "\n");	for(i=0; i<8192; i++)	{		if(priv->ts.pids[i] != NULL)		{			priv->ts.pids[i]->payload_size = 0;			priv->ts.pids[i]->pts = priv->ts.pids[i]->last_pts = 0;			priv->ts.pids[i]->last_cc = -1;			priv->ts.pids[i]->is_synced = 0;		}	}	return ret;}static int parse_avc_sps(uint8_t *buf, int len, int *w, int *h){	int sps, sps_len;	unsigned char *ptr; 	mp_mpeg_header_t picture;	if(len < 6)		return 0;	sps = buf[5] & 0x1f;	if(!sps)		return 0;	sps_len = (buf[6] << 8) | buf[7];	if(!sps_len || (sps_len > len - 8))		return 0;	ptr = &(buf[8]);	picture.display_picture_width = picture.display_picture_height = 0;	h264_parse_sps(&picture, ptr, len - 8);	if(!picture.display_picture_width || !picture.display_picture_height)		return 0;	*w = picture.display_picture_width;	*h = picture.display_picture_height;	return 1;}static demuxer_t *demux_open_ts(demuxer_t * demuxer){	int i;	uint8_t packet_size;	sh_video_t *sh_video;	sh_audio_t *sh_audio;	off_t start_pos;	tsdemux_init_t params;	ts_priv_t * priv = (ts_priv_t*) demuxer->priv;	mp_msg(MSGT_DEMUX, MSGL_V, "DEMUX OPEN, AUDIO_ID: %d, VIDEO_ID: %d, SUBTITLE_ID: %d,\n",		demuxer->audio->id, demuxer->video->id, demuxer->sub->id);	demuxer->type= DEMUXER_TYPE_MPEG_TS;	stream_reset(demuxer->stream);	packet_size = ts_check_file(demuxer);	if(!packet_size)	    return NULL;	priv = calloc(1, sizeof(ts_priv_t));	if(priv == NULL)	{		mp_msg(MSGT_DEMUX, MSGL_FATAL, "DEMUX_OPEN_TS, couldn't allocate enough memory for ts->priv, exit\n");		return NULL;	}	for(i=0; i < 8192; i++)	{	    priv->ts.pids[i] = NULL;	    priv->ts.streams[i].id = -3;	}	priv->pat.progs = NULL;	priv->pat.progs_cnt = 0;	priv->pat.section.buffer = NULL;	priv->pat.section.buffer_len = 0;	priv->pmt = NULL;	priv->pmt_cnt = 0;	priv->keep_broken = ts_keep_broken;	priv->ts.packet_size = packet_size;	demuxer->priv = priv;	if(demuxer->stream->type != STREAMTYPE_FILE)		demuxer->seekable = 1;	else		demuxer->seekable = 1;	params.atype = params.vtype = params.stype = UNKNOWN;	params.apid = demuxer->audio->id;	params.vpid = demuxer->video->id;	params.spid = demuxer->sub->id;	params.prog = ts_prog;	params.probe = ts_probe;	if(dvdsub_lang != NULL)	{		strncpy(params.slang, dvdsub_lang, 3);		params.slang[3] = 0;	}	else		memset(params.slang, 0, 4);	if(audio_lang != NULL)	{		strncpy(params.alang, audio_lang, 3);		params.alang[3] = 0;	}	else		memset(params.alang, 0, 4);	start_pos = ts_detect_streams(demuxer, &params);	demuxer->sub->id = params.spid;	priv->prog = params.prog;	if(params.vtype != UNKNOWN)	{		ts_add_stream(demuxer, priv->ts.pids[params.vpid]);		sh_video = priv->ts.streams[params.vpid].sh;		demuxer->video->id = priv->ts.streams[params.vpid].id;		sh_video->ds = demuxer->video;		sh_video->format = params.vtype;		demuxer->video->sh = sh_video;	}	if(params.atype != UNKNOWN)	{		ES_stream_t *es = priv->ts.pids[params.apid]; 				if(!IS_AUDIO(es->type) && !IS_AUDIO(es->subtype) && IS_AUDIO(params.atype)) es->subtype = params.atype;		ts_add_stream(demuxer, priv->ts.pids[params.apid]);		sh_audio = priv->ts.streams[params.apid].sh;		demuxer->audio->id = priv->ts.streams[params.apid].id;		sh_audio->ds = demuxer->audio;		sh_audio->format = params.atype;		demuxer->audio->sh = sh_audio;	}	mp_msg(MSGT_DEMUXER,MSGL_V, "Opened TS demuxer, audio: %x(pid %d), video: %x(pid %d)...POS=%"PRIu64", PROBE=%"PRIu64"\n", params.atype, demuxer->audio->id, params.vtype, demuxer->video->id, (uint64_t) start_pos, ts_probe);	start_pos = (start_pos <= priv->ts.packet_size ? 0 : start_pos - priv->ts.packet_size);	demuxer->movi_start = start_pos;	stream_reset(demuxer->stream);	stream_seek(demuxer->stream, start_pos);	//IF IT'S FROM A PIPE IT WILL FAIL, BUT WHO CARES?	priv->last_pid = 8192;		//invalid pid	for(i = 0; i < 3; i++)	{		priv->fifo[i].pack  = NULL;		priv->fifo[i].offset = 0;	}	priv->fifo[0].ds = demuxer->audio;	priv->fifo[1].ds = demuxer->video;	priv->fifo[2].ds = demuxer->sub;	priv->fifo[0].buffer_size = 1536;	priv->fifo[1].buffer_size = 32767;	priv->fifo[2].buffer_size = 32767;	priv->pat.section.buffer_len = 0;	for(i = 0; i < priv->pmt_cnt; i++)		priv->pmt[i].section.buffer_len = 0;		demuxer->filepos = stream_tell(demuxer->stream);	return demuxer;}static void demux_close_ts(demuxer_t * demuxer){	uint16_t i;	ts_priv_t *priv = (ts_priv_t*) demuxer->priv;		if(priv)	{		if(priv->pat.section.buffer)			free(priv->pat.section.buffer);		if(priv->pat.progs)			free(priv->pat.progs);			if(priv->pmt)		{				for(i = 0; i < priv->pmt_cnt; i++)			{				if(priv->pmt[i].section.buffer)					free(priv->pmt[i].section.buffer);				if(priv->pmt[i].es)					free(priv->pmt[i].es);			}			free(priv->pmt);		}		free(priv);	}	demuxer->priv=NULL;}extern unsigned char mp_getbits(unsigned char*, unsigned int, unsigned char);#define getbits mp_getbitsstatic int mp4_parse_sl_packet(pmt_t *pmt, uint8_t *buf, uint16_t packet_len, int pid, ES_stream_t *pes_es){

⌨️ 快捷键说明

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