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

📄 demux_ts.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 5 页
字号:
			es->lang[3] = 0;			mp_msg(MSGT_DEMUX, MSGL_V, "Language Descriptor: %s\n", es->lang);		}		else if(ptr[j] == 0x5)	//Registration Descriptor (looks like e fourCC :) )		{			mp_msg(MSGT_DEMUX, MSGL_DBG2, "Registration Descriptor\n");			if(descr_len < 4)			{				mp_msg(MSGT_DEMUX, MSGL_DBG2, "Registration Descriptor length too short: %d, SKIPPING\n", descr_len);			}			else			{				char *d;				memcpy(es->format_descriptor, &ptr[j+2], 4);				es->format_descriptor[4] = 0;				d = &ptr[j+2];				if(d[0] == 'A' && d[1] == 'C' && d[2] == '-' && d[3] == '3')				{					es->type = AUDIO_A52;				}				else if(d[0] == 'D' && d[1] == 'T' && d[2] == 'S' && d[3] == '1')				{					es->type = AUDIO_DTS;				}				else if(d[0] == 'D' && d[1] == 'T' && d[2] == 'S' && d[3] == '2')				{					es->type = AUDIO_DTS;				}				else if(d[0] == 'V' && d[1] == 'C' && d[2] == '-' && d[3] == '1')				{					es->type = VIDEO_VC1;				}				else					es->type = UNKNOWN;				mp_msg(MSGT_DEMUX, MSGL_DBG2, "FORMAT %s\n", es->format_descriptor);			}		}		else if(ptr[j] == 0x1e)		{			es->mp4_es_id = (ptr[j+2] << 8) | ptr[j+3];			mp_msg(MSGT_DEMUX, MSGL_V, "SL Descriptor: ES_ID: %d(%x), pid: %d\n", es->mp4_es_id, es->mp4_es_id, es->pid);		}		else			mp_msg(MSGT_DEMUX, MSGL_DBG2, "Unknown descriptor 0x%x, SKIPPING\n", ptr[j]);		len -= 2 + descr_len;		j += 2 + descr_len;	}	return 1;}static int parse_sl_section(pmt_t *pmt, ts_section_t *section, int is_start, unsigned char *buff, int size){	int tid, len, skip;	uint8_t *ptr;	skip = collect_section(section, is_start, buff, size);	if(! skip)		return 0;			ptr = &(section->buffer[skip]);	tid = ptr[0];	len = ((ptr[1] & 0x0f) << 8) | ptr[2];	mp_msg(MSGT_DEMUX, MSGL_V, "TABLEID: %d (av. %d), skip=%d, LEN: %d\n", tid, section->buffer_len, skip, len);	if(len > 4093 || section->buffer_len < len || tid != 5)	{		mp_msg(MSGT_DEMUX, MSGL_V, "SECTION TOO LARGE or wrong section type, EXIT\n");		return 0;	}		if(! (ptr[5] & 1))		return 0;		//8 is the current position, len - 9 is the amount of data available	parse_mp4_descriptors(pmt, &ptr[8], len - 9, NULL);		return 1;}static int parse_pmt(ts_priv_t * priv, uint16_t progid, uint16_t pid, int is_start, unsigned char *buff, int size){	unsigned char *base, *es_base;	pmt_t *pmt;	int32_t idx, es_count, section_bytes;	uint8_t m=0;	int skip;	pmt_t *tmp;	struct pmt_es_t *tmp_es;	ts_section_t *section;	ES_stream_t *tss;		idx = progid_idx_in_pmt(priv, progid);	if(idx == -1)	{		int sz = (priv->pmt_cnt + 1) * sizeof(pmt_t);		tmp = realloc_struct(priv->pmt, priv->pmt_cnt + 1, sizeof(pmt_t));		if(tmp == NULL)		{			mp_msg(MSGT_DEMUX, MSGL_ERR, "PARSE_PMT: COULDN'T REALLOC %d bytes, NEXT\n", sz);			return 0;		}		priv->pmt = tmp;		idx = priv->pmt_cnt;		memset(&(priv->pmt[idx]), 0, sizeof(pmt_t));		priv->pmt_cnt++;		priv->pmt[idx].progid = progid;	}	pmt = &(priv->pmt[idx]);	section = &(pmt->section);	skip = collect_section(section, is_start, buff, size);	if(! skip)		return 0;			base = &(section->buffer[skip]);	mp_msg(MSGT_DEMUX, MSGL_V, "FILL_PMT(prog=%d), PMT_len: %d, IS_START: %d, TS_PID: %d, SIZE=%d, M=%d, ES_CNT=%d, IDX=%d, PMT_PTR=%p\n",		progid, pmt->section.buffer_len, is_start, pid, size, m, pmt->es_cnt, idx, pmt);	pmt->table_id = base[0];	if(pmt->table_id != 2)		return -1;	pmt->ssi = base[1] & 0x80;	pmt->section_length = (((base[1] & 0xf) << 8 ) | base[2]);	pmt->version_number = (base[5] >> 1) & 0x1f;	pmt->curr_next = (base[5] & 1);	pmt->section_number = base[6];	pmt->last_section_number = base[7];	pmt->PCR_PID = ((base[8] & 0x1f) << 8 ) | base[9];	pmt->prog_descr_length = ((base[10] & 0xf) << 8 ) | base[11];	if(pmt->prog_descr_length > pmt->section_length - 9)	{		mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_PMT, INVALID PROG_DESCR LENGTH (%d vs %d)\n", pmt->prog_descr_length, pmt->section_length - 9);		return -1;	}	if(pmt->prog_descr_length)		parse_program_descriptors(pmt, &base[12], pmt->prog_descr_length);	es_base = &base[12 + pmt->prog_descr_length];	//the beginning of th ES loop	section_bytes= pmt->section_length - 13 - pmt->prog_descr_length;	es_count  = 0;	while(section_bytes >= 5)	{		int es_pid, es_type;		es_type = es_base[0];		es_pid = ((es_base[1] & 0x1f) << 8) | es_base[2];		idx = es_pid_in_pmt(pmt, es_pid);		if(idx == -1)		{			int sz = sizeof(struct pmt_es_t) * (pmt->es_cnt + 1);			tmp_es = realloc_struct(pmt->es, pmt->es_cnt + 1, sizeof(struct pmt_es_t));			if(tmp_es == NULL)			{				mp_msg(MSGT_DEMUX, MSGL_ERR, "PARSE_PMT, COULDN'T ALLOCATE %d bytes for PMT_ES\n", sz);				continue;			}			pmt->es = tmp_es;			idx = pmt->es_cnt;			memset(&(pmt->es[idx]), 0, sizeof(struct pmt_es_t));			pmt->es_cnt++;		}		pmt->es[idx].descr_length = ((es_base[3] & 0xf) << 8) | es_base[4];		if(pmt->es[idx].descr_length > section_bytes - 5)		{			mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_PMT, ES_DESCR_LENGTH TOO LARGE %d > %d, EXIT\n",				pmt->es[idx].descr_length, section_bytes - 5);			return -1;		}		pmt->es[idx].pid = es_pid;		if(es_type != 0x6)			pmt->es[idx].type = UNKNOWN;		else			pmt->es[idx].type = es_type;				parse_descriptors(&pmt->es[idx], &es_base[5]);		switch(es_type)		{			case 1:				pmt->es[idx].type = VIDEO_MPEG1;				break;			case 2:				pmt->es[idx].type = VIDEO_MPEG2;				break;			case 3:			case 4:				pmt->es[idx].type = AUDIO_MP2;				break;			case 6:				if(pmt->es[idx].type == 0x6)	//this could have been ovrwritten by parse_descriptors					pmt->es[idx].type = UNKNOWN;				break;			case 0x10:				pmt->es[idx].type = VIDEO_MPEG4;				break;			case 0x0f:			case 0x11:				pmt->es[idx].type = AUDIO_AAC;				break;			case 0x1b:				pmt->es[idx].type = VIDEO_H264;				break;			case 0x12:				pmt->es[idx].type = SL_PES_STREAM;				break;			case 0x13:				pmt->es[idx].type = SL_SECTION;				break;			case 0x81:				pmt->es[idx].type = AUDIO_A52;				break;			case 0x8A:				pmt->es[idx].type = AUDIO_DTS;				break;			case 0xEA:				pmt->es[idx].type = VIDEO_VC1;				break;			default:				mp_msg(MSGT_DEMUX, MSGL_DBG2, "UNKNOWN ES TYPE=0x%x\n", es_type);				pmt->es[idx].type = UNKNOWN;		}				tss = priv->ts.pids[es_pid];			//an ES stream		if(tss == NULL)		{			tss = new_pid(priv, es_pid);			if(tss)				tss->type = pmt->es[idx].type;		}		section_bytes -= 5 + pmt->es[idx].descr_length;		mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_PMT(%d INDEX %d), STREAM: %d, FOUND pid=0x%x (%d), type=0x%x, ES_DESCR_LENGTH: %d, bytes left: %d\n",			progid, idx, es_count, pmt->es[idx].pid, pmt->es[idx].pid, pmt->es[idx].type, pmt->es[idx].descr_length, section_bytes);		es_base += 5 + pmt->es[idx].descr_length;		es_count++;	}	mp_msg(MSGT_DEMUX, MSGL_V, "----------------------------\n");	return 1;}static pmt_t* pmt_of_pid(ts_priv_t *priv, int pid, mp4_decoder_config_t **mp4_dec){	int32_t i, j, k;	if(priv->pmt)	{		for(i = 0; i < priv->pmt_cnt; i++)		{			if(priv->pmt[i].es && priv->pmt[i].es_cnt)			{				for(j = 0; j < priv->pmt[i].es_cnt; j++)				{					if(priv->pmt[i].es[j].pid == pid)					{						//search mp4_es_id						if(priv->pmt[i].es[j].mp4_es_id)						{							for(k = 0; k < priv->pmt[i].mp4es_cnt; k++)							{								if(priv->pmt[i].mp4es[k].id == priv->pmt[i].es[j].mp4_es_id)								{									*mp4_dec = &(priv->pmt[i].mp4es[k].decoder);									break;								}							}						}												return &(priv->pmt[i]);					}				}			}		}	}		return NULL;}static inline int32_t pid_type_from_pmt(ts_priv_t *priv, int pid){	int32_t pmt_idx, pid_idx, i, j;	pmt_idx = progid_idx_in_pmt(priv, priv->prog);	if(pmt_idx != -1)	{		pid_idx = es_pid_in_pmt(&(priv->pmt[pmt_idx]), pid);		if(pid_idx != -1)			return priv->pmt[pmt_idx].es[pid_idx].type;	}	//else	//{		for(i = 0; i < priv->pmt_cnt; i++)		{			pmt_t *pmt = &(priv->pmt[i]);			for(j = 0; j < pmt->es_cnt; j++)				if(pmt->es[j].pid == pid)					return pmt->es[j].type;		}	//}	return UNKNOWN;}static inline uint8_t *pid_lang_from_pmt(ts_priv_t *priv, int pid){	int32_t pmt_idx, pid_idx, i, j;	pmt_idx = progid_idx_in_pmt(priv, priv->prog);	if(pmt_idx != -1)	{		pid_idx = es_pid_in_pmt(&(priv->pmt[pmt_idx]), pid);		if(pid_idx != -1)			return priv->pmt[pmt_idx].es[pid_idx].lang;	}	else	{		for(i = 0; i < priv->pmt_cnt; i++)		{			pmt_t *pmt = &(priv->pmt[i]);			for(j = 0; j < pmt->es_cnt; j++)				if(pmt->es[j].pid == pid)					return pmt->es[j].lang;		}	}	return NULL;}static int fill_packet(demuxer_t *demuxer, demux_stream_t *ds, demux_packet_t **dp, int *dp_offset, TS_stream_info *si){	int ret = 0;	if((*dp != NULL) && (*dp_offset > 0))	{		ret = *dp_offset;		resize_demux_packet(*dp, ret);	//shrinked to the right size		ds_add_packet(ds, *dp);		mp_msg(MSGT_DEMUX, MSGL_DBG2, "ADDED %d  bytes to %s fifo, PTS=%.3f\n", ret, (ds == demuxer->audio ? "audio" : (ds == demuxer->video ? "video" : "sub")), (*dp)->pts);		if(si)		{			float diff = (*dp)->pts - si->last_pts;			float dur;			if(abs(diff) > 1) //1 second, there's a discontinuity			{				si->duration += si->last_pts - si->first_pts;				si->first_pts = si->last_pts = (*dp)->pts;			}			else			{				si->last_pts = (*dp)->pts;			}			si->size += ret;			dur = si->duration + (si->last_pts - si->first_pts);			if(dur > 0 && ds == demuxer->video)			{				ts_priv_t * priv = (ts_priv_t*) demuxer->priv;				if(dur > 1)	//otherwise it may be unreliable					priv->vbitrate = (uint32_t) ((float) si->size / dur);			}		}	}	*dp = NULL;	*dp_offset = 0;	return ret;}static int fill_extradata(mp4_decoder_config_t * mp4_dec, ES_stream_t *tss){	uint8_t *tmp;		mp_msg(MSGT_DEMUX, MSGL_DBG2, "MP4_dec: %p, pid: %d\n", mp4_dec, tss->pid);			if(mp4_dec->buf_size > tss->extradata_alloc)	{		tmp = (uint8_t *) realloc(tss->extradata, mp4_dec->buf_size);		if(!tmp)			return 0;		tss->extradata = tmp;		tss->extradata_alloc = mp4_dec->buf_size;	}	memcpy(tss->extradata, mp4_dec->buf, mp4_dec->buf_size);	tss->extradata_len = mp4_dec->buf_size;	mp_msg(MSGT_DEMUX, MSGL_V, "EXTRADATA: %p, alloc=%d, len=%d\n", tss->extradata, tss->extradata_alloc, tss->extradata_len);		return tss->extradata_len;}// 0 = EOF or no stream found// else = [-] number of bytes written to the packetstatic int ts_parse(demuxer_t *demuxer , ES_stream_t *es, unsigned char *packet, int probe){	ES_stream_t *tss;	uint8_t done = 0;	int buf_size, is_start, pid, base;	int len, cc, cc_ok, afc, retv = 0, is_video, is_audio, is_sub;	ts_priv_t * priv = (ts_priv_t*) demuxer->priv;	stream_t *stream = demuxer->stream;	char *p;	demux_stream_t *ds = NULL;	demux_packet_t **dp = NULL;	int *dp_offset = 0, *buffer_size = 0;	int32_t progid, pid_type, bad, ts_error;	int junk = 0, rap_flag = 0;	pmt_t *pmt;	mp4_decoder_config_t *mp4_dec;	TS_stream_info *si;	while(! done)	{		bad = ts_error = 0;		ds = (demux_stream_t*) NULL;		dp = (demux_packet_t **) NULL;		dp_offset = buffer_size = NULL;		rap_flag = 0;		mp4_dec = NULL;		es->is_synced = 0;		si = NULL;		junk = priv->ts.packet_size - TS_PACKET_SIZE;		buf_size = priv->ts.packet_size - junk;		if(stream_eof(stream))		{			if(! probe)			{				ts_dump_streams(priv);				demuxer->filepos = stream_tell(demuxer->stream);			}			return 0;		}		if(! ts_sync(stream))		{			mp_msg(MSGT_DEMUX, MSGL_INFO, "TS_PARSE: COULDN'T SYNC\n");			return 0;		}		len = stream_read(stream, &packet[1], 3);		if (len != 3)			return 0;		buf_size -= 4;		if((packet[1]  >> 7) & 0x01)	//transport error			ts_error = 1;		is_start = packet[1] & 0x40;		pid = ((packet[1] & 0x1f) << 8) | packet[2];		tss = priv->ts.pids[pid];			//an ES stream		if(tss == NULL)		{			tss = new_pid(priv, pid);			if(tss == NULL)				continue;		}		cc = (packet[3] & 0xf);		cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc));		tss->last_cc = cc;		    		bad = ts_error; // || (! cc_ok);		if(bad)		{			if(priv->keep_broken == 0)			{				stream_skip(stream, buf_size-1+junk);				continue;			}						is_start = 0;	//queued to the packet data		}		if(is_start)			tss->is_synced = 1;		if((!is_start && !tss->is_synced) || ((pid > 1) && (pid < 16)) || (pid == 8191))		//invalid pid		{			stream_skip(stream, buf_size-1+junk);			continue;		}    		afc = (packet[3] >> 4) & 3;		if(! (afc % 2))	//no payload in this TS packet		{			stream_skip(stream, buf_size-1+junk);			continue;		}				if(afc > 1)		{			int c;			c = stream_read_char(stream);			buf_size--;			if(c < 0 || c > 183)	//broken from the stream layer or invalid			{				stream_skip(stream, buf_size-1+junk);				continue;			}						//c==0 is allowed!			if(c > 0)			{				rap_flag = (stream_read_char(stream) & 0x40) >> 6;				buf_size--;					c--;				stream_skip(stream, c);				buf_size -= c;				if(buf_size == 0)					continue;			}		}		//find the program that the pid belongs to; if (it's the right one or -1) && pid_type==SL_SECTION		//call parse_sl_section()		pmt = pmt_of_pid(priv, pid, &mp4_dec);		if(mp4_dec)	

⌨️ 快捷键说明

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