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

📄 demux_ts.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
	while((pos <= init_pos + param->probe) && (! demuxer->stream->eof))	{		pos = stream_tell(demuxer->stream);		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))			{				pptr = &pes_priv1[es.pid];				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;						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_video)			{				if (identify)					mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_VIDEO_ID=%d\n", es.pid);    				chosen_pid = (req_vpid == es.pid);				if((! chosen_pid) && (req_vpid > 0))					continue;			}			else if(is_audio)			{				if (identify)				{					mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_AUDIO_ID=%d\n", es.pid);					if (es.lang[0] > 0)						mp_msg(MSGT_GLOBAL, MSGL_INFO, "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)				{					if(pid_match_lang(priv, es.pid, param->alang) == -1)						continue;					chosen_pid = 1;					param->apid = req_apid = es.pid;				}			}			else if(is_sub)			{				if (identify)				{					mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_SUBTITLE_ID=%d\n", es.pid);					if (es.lang[0] > 0)						mp_msg(MSGT_GLOBAL, MSGL_INFO, "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)			{				//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((req_apid == -2) && video_found)			{				param->atype = 0;				break;			}			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_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_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;}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_INFO, "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 = malloc(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->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->audio->id = params.apid;	demuxer->video->id = params.vpid;	demuxer->sub->id = params.spid;	priv->prog = params.prog;	demux_aid_vid_mismatch = 1; // don't identify in new_sh_* since ids don't match	if(params.vtype != UNKNOWN)	{		ES_stream_t *es = priv->ts.pids[params.vpid];		sh_video = new_sh_video(demuxer, 0);		if(params.vtype == VIDEO_AVC && es->extradata && es->extradata_len)		{			int w = 0, h = 0;			sh_video->bih = (BITMAPINFOHEADER *) calloc(1, sizeof(BITMAPINFOHEADER) + 4096);			sh_video->bih->biSize= sizeof(BITMAPINFOHEADER) + es->extradata_len;			sh_video->bih->biCompression = params.vtype;			memcpy(sh_video->bih + 1, es->extradata, es->extradata_len);			mp_msg(MSGT_DEMUXER,MSGL_DBG2, "EXTRADATA(%d BYTES): \n", es->extradata_len);			for(i = 0;i < es->extradata_len; i++)				mp_msg(MSGT_DEMUXER,MSGL_DBG2, "%02x ", (int) es->extradata[i]);			mp_msg(MSGT_DEMUXER,MSGL_DBG2,"\n");			if(parse_avc_sps(es->extradata, es->extradata_len, &w, &h))			{				sh_video->bih->biWidth = w;				sh_video->bih->biHeight = h;			}		}		sh_video->ds = demuxer->video;		sh_video->format = params.vtype;		demuxer->video->sh = sh_video;	}	if(params.atype != UNKNOWN)	{		sh_audio = new_sh_audio(demuxer, 0);		sh_audio->ds = demuxer->audio;		sh_audio->format = params.atype;		demuxer->audio->sh = sh_audio;	}	mp_msg(MSGT_DEMUXER,MSGL_INFO, "Opened TS demuxer, audio: %x(pid %d), video: %x(pid %d)...POS=%llu\n", params.atype, demuxer->audio->id, params.vtype, demuxer->video->id, (uint64_t) start_pos);	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;}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){	int i, n, m, mp4_es_id = -1;	uint64_t v = 0;	uint32_t pl_size = 0; 	int deg_flag = 0;	mp4_es_descr_t *es = NULL;	mp4_sl_config_t *sl = NULL;	uint8_t au_start = 0, au_end = 0, rap_flag = 0, ocr_flag = 0, padding = 0,  padding_bits = 0, idle = 0;		pes_es->is_synced = 0;	mp_msg(MSGT_DEMUXER,MSGL_V, "mp4_parse_sl_packet, pid: %d, pmt: %pm, packet_len: %d\n", pid, pmt, packet_len);		if(! pmt || !packet_len)		return 0;		for(i = 0; i < pmt->es_cnt; i++)	{		if(pmt->es[i].pid == pid)			mp4_es_id = pmt->es[i].mp4_es_id;	}	if(mp4_es_id < 0)		return -1;		for(i = 0; i < pmt->mp4es_cnt; i++)	{		if(pmt->mp4es[i].id == mp4_es_id)			es = &(pmt->mp4es[i]);	}	if(! es)		return -1;		pes_es->subtype = es->decoder.object_type;		sl = &(es->sl);	if(!sl)		return -1;			//now es is the complete es_descriptor of out mp4 ES stream	mp_msg(MSGT_DEMUXER,MSGL_DBG2, "ID: %d, FLAGS: 0x%x, subtype: %x\n", es->id, sl->flags, pes_es->subtype);		n = 0;	if(sl->au_start)		pes_es->sl.au_start = au_start = getbits(buf, n++, 1);	else		pes_es->sl.au_start = (pes_es->sl.last_au_end ? 1 : 0);	if(sl->au_end)		pes_es->sl.au_end = au_end = getbits(buf, n++, 1);		if(!sl->au_start && !sl->au_end)	{		pes_es->sl.au_start = pes_es->sl.au_end = au_start = au_end = 1;	}	pes_es->sl.last_au_end = pes_es->sl.au_end;			if(sl->ocr_len > 0)		ocr_flag = getbits(buf, n++, 1);	if(sl->idle)		idle = getbits(buf, n++, 1);	if(sl->padding)		padding = getbits(buf, n++, 1);	if(padding)	{		padding_bits = getbits(buf, n, 3);		n += 3;	}		if(idle || (padding && !padding_bits))	{		pes_es->payload_size = 0;		return -1;	}		//(! idle && (!padding || padding_bits != 0)) is true	n += sl->packet_seqnum_len;	if(sl->degr_len)		deg_flag = getbits(buf, n++, 1);	if(deg_flag)		n += sl->degr_len;		if(ocr_flag)	{		n += sl->ocr_len;		mp_msg(MSGT_DEMUXER,MSGL_DBG2, "OCR: %d bits\n", sl->ocr_len);	}		if(packet_len * 8 <= n)		return -1;	

⌨️ 快捷键说明

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