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

📄 demux_ts.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
		mp_msg(MSGT_DEMUX, MSGL_DBG2, "PARSE_MP4_DESC_LEN(%d), bytes: ", *len);	j = min(*len, 4);	while(i < j)	{		mp_msg(MSGT_DEMUX, MSGL_DBG2, " %x ", buf[i]);		size |= (buf[i] & 0x7f);		if(!(buf[i] & 0x80))			break;		size <<= 7;		i++;	}	mp_msg(MSGT_DEMUX, MSGL_DBG2, ", SIZE=%d\n", size);		*len = i+1;	return size;}static uint16_t parse_mp4_slconfig_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem){	int i = 0;	mp4_es_descr_t *es;	mp4_sl_config_t *sl;		mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_SLCONFIG_DESCRIPTOR(%d)\n", len);	es = (mp4_es_descr_t *) elem;	if(!es)	{		mp_msg(MSGT_DEMUX, MSGL_V, "argh! NULL elem passed, skip\n");		return len;	}	sl = &(es->sl);	sl->ts_len = sl->ocr_len = sl->au_len = sl->instant_bitrate_len = sl->degr_len = sl->au_seqnum_len = sl->packet_seqnum_len = 0;	sl->ocr = sl->dts = sl->cts = 0;		if(buf[0] == 0)	{		i++;		sl->flags = buf[i];		i++;		sl->ts_resolution = (buf[i] << 24) | (buf[i+1] << 16) | (buf[i+2] << 8) | buf[i+3];		i += 4;		sl->ocr_resolution = (buf[i] << 24) | (buf[i+1] << 16) | (buf[i+2] << 8) | buf[i+3];		i += 4;		sl->ts_len = buf[i];		i++;		sl->ocr_len = buf[i];		i++;		sl->au_len = buf[i];		i++;		sl->instant_bitrate_len = buf[i];		i++;		sl->degr_len = (buf[i] >> 4) & 0x0f;		sl->au_seqnum_len = ((buf[i] & 0x0f) << 1) | ((buf[i+1] >> 7) & 0x01);		i++;		sl->packet_seqnum_len = ((buf[i] >> 2) & 0x1f);		i++;			}	else if(buf[0] == 1)	{		sl->flags = 0;		sl->ts_resolution = 1000;		sl->ts_len = 32;		i++;	}	else if(buf[0] == 2)	{		sl->flags = 4;		i++;	}	else 	{		sl->flags = 0;		i++;	}		sl->au_start = (sl->flags >> 7) & 0x1;	sl->au_end = (sl->flags >> 6) & 0x1;	sl->random_accesspoint = (sl->flags >> 5) & 0x1;	sl->random_accesspoint_only = (sl->flags >> 4) & 0x1;	sl->padding = (sl->flags >> 3) & 0x1;	sl->use_ts = (sl->flags >> 2) & 0x1;	sl->idle = (sl->flags >> 1) & 0x1;	sl->duration = sl->flags & 0x1;		if(sl->duration)	{		sl->timescale = (buf[i] << 24) | (buf[i+1] << 16) | (buf[i+2] << 8) | buf[i+3];		i += 4;		sl->au_duration = (buf[i] << 8) | buf[i+1];		i += 2;		sl->cts_duration = (buf[i] << 8) | buf[i+1];		i += 2; 	}	else	//no support for fixed durations atm		sl->timescale = sl->au_duration = sl->cts_duration = 0;		mp_msg(MSGT_DEMUX, MSGL_V, "MP4SLCONFIG(len=0x%x), predef: %d, flags: %x, use_ts: %d, tslen: %d, timescale: %d, dts: %llu, cts: %llu\n", 		len, buf[0], sl->flags, sl->use_ts, sl->ts_len, sl->timescale, (uint64_t) sl->dts, (uint64_t) sl->cts);		return len;}static int parse_mp4_descriptors(pmt_t *pmt, uint8_t *buf, int len, void *elem);static uint16_t parse_mp4_decoder_config_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem){	int i = 0, j;	mp4_es_descr_t *es;	mp4_decoder_config_t *dec;		mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_DECODER_CONFIG_DESCRIPTOR(%d)\n", len);	es = (mp4_es_descr_t *) elem;	if(!es)	{		mp_msg(MSGT_DEMUX, MSGL_V, "argh! NULL elem passed, skip\n");		return len;	}	dec = (mp4_decoder_config_t*) &(es->decoder);		dec->object_type = buf[i];	dec->stream_type =  (buf[i+1]>>2) & 0x3f;		if(dec->object_type == 1 && dec->stream_type == 1)	{		 dec->object_type = MP4_OD;		 dec->stream_type = MP4_OD;	}	else if(dec->stream_type == 4)	{		if(dec->object_type == 0x6a)			dec->object_type = VIDEO_MPEG1;		if(dec->object_type >= 0x60 && dec->object_type <= 0x65)			dec->object_type = VIDEO_MPEG2;		else if(dec->object_type == 0x20)			dec->object_type = VIDEO_MPEG4;		else if(dec->object_type == 0x21)			dec->object_type = VIDEO_AVC;		/*else if(dec->object_type == 0x22)			fprintf(stderr, "TYPE 0x22\n");*/		else dec->object_type = UNKNOWN;	}	else if(dec->stream_type == 5)	{		if(dec->object_type == 0x40)			dec->object_type = AUDIO_AAC;		else if(dec->object_type == 0x6b)			dec->object_type = AUDIO_MP2;		else if(dec->object_type >= 0x66 && dec->object_type <= 0x69)			dec->object_type = AUDIO_MP2;		else			dec->object_type = UNKNOWN;	}	else		dec->object_type = dec->stream_type = UNKNOWN;		if(dec->object_type != UNKNOWN)	{		//update the type of the current stream		for(j = 0; j < pmt->es_cnt; j++)		{			if(pmt->es[j].mp4_es_id == es->id)			{				pmt->es[j].type = SL_PES_STREAM;			}		}	}		if(len > 13)		parse_mp4_descriptors(pmt, &buf[13], len-13, dec);		mp_msg(MSGT_DEMUX, MSGL_V, "MP4DECODER(0x%x), object_type: 0x%x, stream_type: 0x%x\n", len, dec->object_type, dec->stream_type);		return len;}static uint16_t parse_mp4_decoder_specific_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem){	int i;	mp4_decoder_config_t *dec;		mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_DECODER_SPECIFIC_DESCRIPTOR(%d)\n", len);	dec = (mp4_decoder_config_t *) elem;	if(!dec)	{		mp_msg(MSGT_DEMUX, MSGL_V, "argh! NULL elem passed, skip\n");		return len;	}		mp_msg(MSGT_DEMUX, MSGL_DBG2, "MP4 SPECIFIC INFO BYTES: \n");	for(i=0; i<len; i++)		mp_msg(MSGT_DEMUX, MSGL_DBG2, "%02x ", buf[i]);	mp_msg(MSGT_DEMUX, MSGL_DBG2, "\n");	memcpy(dec->buf, buf, len);	dec->buf_size = len;		return len;}static uint16_t parse_mp4_es_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem){	int i = 0, j = 0, k, found;	uint8_t flag;	mp4_es_descr_t es, *target_es = NULL, *tmp;		mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4ES: len=%d\n", len);	memset(&es, 0, sizeof(mp4_es_descr_t));	while(i < len)	{		es.id = (buf[i] << 8) | buf[i+1];		mp_msg(MSGT_DEMUX, MSGL_V, "MP4ES_ID: %d\n", es.id);		i += 2;		flag = buf[i];		i++;		if(flag & 0x80)			i += 2;		if(flag & 0x40)			i += buf[i]+1;		if(flag & 0x20)		//OCR, maybe we need it			i += 2;				j = parse_mp4_descriptors(pmt, &buf[i], len-i, &es);		mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4ES, types after parse_mp4_descriptors: 0x%x, 0x%x\n", es.decoder.object_type, es.decoder.stream_type);		if(es.decoder.object_type != UNKNOWN && es.decoder.stream_type != UNKNOWN)		{			found = 0;			//search this ES_ID if we already have it			for(k=0; k < pmt->mp4es_cnt; k++)			{				if(pmt->mp4es[k].id == es.id)				{					target_es = &(pmt->mp4es[k]);					found = 1;				}			}						if(! found)			{				tmp = (mp4_es_descr_t *) realloc(pmt->mp4es, sizeof(mp4_es_descr_t)*(pmt->mp4es_cnt+1));				if(tmp == NULL)				{					fprintf(stderr, "CAN'T REALLOC MP4_ES_DESCR\n");					continue;				}				pmt->mp4es = tmp;				target_es = &(pmt->mp4es[pmt->mp4es_cnt]);				pmt->mp4es_cnt++;			}			memcpy(target_es, &es, sizeof(mp4_es_descr_t));			mp_msg(MSGT_DEMUX, MSGL_V, "MP4ES_CNT: %d, ID=%d\n", pmt->mp4es_cnt, target_es->id);		}		i += j;	}		return len;}static void parse_mp4_object_descriptor(pmt_t *pmt, uint8_t *buf, int len, void *elem){	int i, j = 0, id;		id = (buf[0] << 2) | ((buf[1] & 0xc0) >> 6);	mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_OBJECT_DESCRIPTOR: len=%d, OD_ID=%d\n", len, id);	if(buf[1] & 0x20)	{		i += buf[2] + 1;	//url		mp_msg(MSGT_DEMUX, MSGL_V, "URL\n");	}	else	{		i = 2;				while(i < len)		{			j = parse_mp4_descriptors(pmt, &(buf[i]), len-i, elem);			mp_msg(MSGT_DEMUX, MSGL_V, "OBJD, NOW i = %d, j=%d, LEN=%d\n", i, j, len);			i += j;		}	}}static void parse_mp4_iod(pmt_t *pmt, uint8_t *buf, int len, void *elem){	int i, j = 0;	mp4_od_t *iod = &(pmt->iod);		iod->id = (buf[0] << 2) | ((buf[1] & 0xc0) >> 6);	mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_IOD: len=%d, IOD_ID=%d\n", len, iod->id);	i = 2;	if(buf[1] & 0x20)	{		i += buf[2] + 1;	//url		mp_msg(MSGT_DEMUX, MSGL_V, "URL\n");	}	else	{		i = 7;		while(i < len)		{			j = parse_mp4_descriptors(pmt, &(buf[i]), len-i, elem);			mp_msg(MSGT_DEMUX, MSGL_V, "IOD, NOW i = %d, j=%d, LEN=%d\n", i, j, len);			i += j;		}	}}static int parse_mp4_descriptors(pmt_t *pmt, uint8_t *buf, int len, void *elem){	int tag, descr_len, i = 0, j = 0;		mp_msg(MSGT_DEMUX, MSGL_V, "PARSE_MP4_DESCRIPTORS, len=%d\n", len);	if(! len)		return len;		while(i < len)	{		tag = buf[i];		j = len - i -1;		descr_len = get_mp4_desc_len(&(buf[i+1]), &j);		mp_msg(MSGT_DEMUX, MSGL_V, "TAG=%d (0x%x), DESCR_len=%d, len=%d, j=%d\n", tag, tag, descr_len, len, j);		if(descr_len > len - j+1)		{			mp_msg(MSGT_DEMUX, MSGL_V, "descriptor is too long, exit\n");			return len;		}		i += j+1;				switch(tag)		{			case 0x1:				parse_mp4_object_descriptor(pmt, &(buf[i]), descr_len, elem);				break;			case 0x2:				parse_mp4_iod(pmt, &(buf[i]), descr_len, elem);				break;			case 0x3:				parse_mp4_es_descriptor(pmt, &(buf[i]), descr_len, elem);				break;			case 0x4:				parse_mp4_decoder_config_descriptor(pmt, &buf[i], descr_len, elem);				break;			case 0x05:				parse_mp4_decoder_specific_descriptor(pmt, &buf[i], descr_len, elem);				break;			case 0x6:				parse_mp4_slconfig_descriptor(pmt, &buf[i], descr_len, elem);				break;			default:				mp_msg(MSGT_DEMUX, MSGL_V, "Unsupported mp4 descriptor 0x%x\n", tag);		}		i += descr_len;	}		return len;}static ES_stream_t *new_pid(ts_priv_t *priv, int pid){	ES_stream_t *tss;		tss = malloc(sizeof(ES_stream_t));	if(! tss)		return NULL;	memset(tss, 0, sizeof(ES_stream_t));	tss->pid = pid;	tss->last_cc = -1;	tss->type = UNKNOWN;	tss->subtype = UNKNOWN;	tss->is_synced = 0;	tss->extradata = NULL;	tss->extradata_alloc = tss->extradata_len = 0;	priv->ts.pids[pid] = tss;		return tss;}static int parse_program_descriptors(pmt_t *pmt, uint8_t *buf, uint16_t len){	uint16_t i = 0, k, olen = len;	while(len > 0)	{		mp_msg(MSGT_DEMUX, MSGL_V, "PROG DESCR, TAG=%x, LEN=%d(%x)\n", buf[i], buf[i+1], buf[i+1]);		if(buf[i+1] > len-2)		{			mp_msg(MSGT_DEMUX, MSGL_V, "ERROR, descriptor len is too long, skipping\n");			return olen;		}		if(buf[i] == 0x1d)		{			if(buf[i+3] == 2)	//buggy versions of vlc muxer make this non-standard mess (missing iod_scope)				k = 3;			else				k = 4;		//this is standard compliant			parse_mp4_descriptors(pmt, &buf[i+k], (int) buf[i+1]-(k-2), NULL);		}		len -= 2 + buf[i+1];	}		return olen;}static int parse_descriptors(struct pmt_es_t *es, uint8_t *ptr){	int j, descr_len, len;	j = 0;	len = es->descr_length;	while(len > 2)	{		descr_len = ptr[j+1];		mp_msg(MSGT_DEMUX, MSGL_V, "...descr id: 0x%x, len=%d\n", ptr[j], descr_len);		if(descr_len > len)		{			mp_msg(MSGT_DEMUX, MSGL_ERR, "INVALID DESCR LEN for tag %02x: %d vs %d max, EXIT LOOP\n", ptr[j], descr_len, len);			return -1;		}		if(ptr[j] == 0x6a)	//A52 Descriptor		{			if(es->type == 0x6)			{				es->type = AUDIO_A52;				mp_msg(MSGT_DEMUX, MSGL_DBG2, "DVB A52 Descriptor\n");			}		}		else if(ptr[j] == 0x59)	//Subtitling Descriptor		{			uint8_t subtype;			mp_msg(MSGT_DEMUX, MSGL_DBG2, "Subtitling Descriptor\n");			if(descr_len < 8)			{				mp_msg(MSGT_DEMUX, MSGL_DBG2, "Descriptor length too short for DVB Subtitle Descriptor: %d, SKIPPING\n", descr_len);			}			else			{				memcpy(es->lang, &ptr[j+2], 3);				es->lang[3] = 0;				subtype = ptr[j+5];				if(					(subtype >= 0x10 && subtype <= 0x13) ||					(subtype >= 0x20 && subtype <= 0x23)				)				{					es->type = SPU_DVB;					//page parameters: compo page 2 bytes, ancillary page 2 bytes				}				else					es->type = UNKNOWN;			}		}		else if(ptr[j] == 0x50)	//Component Descriptor		{			mp_msg(MSGT_DEMUX, MSGL_DBG2, "Component Descriptor\n");			memcpy(es->lang, &ptr[j+5], 3);			es->lang[3] = 0;		}		else if(ptr[j] == 0xa)	//Language Descriptor		{			memcpy(es->lang, &ptr[j+2], 3);			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					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, uint16_t progid, uint16_t pid, 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 skip, m=0;	pmt_t *tmp;	struct pmt_es_t *tmp_es;	ts_section_t *section;	ES_stream_t *tss;	

⌨️ 快捷键说明

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