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

📄 muxer_mpeg.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 5 页
字号:
{	uint16_t t1, t2, t3;	ts >>= 10;	ts &= 0x1FFFFFFFFULL;	//33 bits, no extension; input must be * 92160000	t1 = (ts >> 30) & 0x7;;	t2 = (ts >> 15) & 0x7fff;	t3 = ts & 0x7fff;		b[0] = (t1 << 3 ) | 0x44 | ((t2 >> 13) & 0x3);	b[1] = (t2 >> 5);	b[2] = (t2 & 0x1f) << 3 | 0x4 | ((t3 >> 13) & 0x3);	b[3] = (t3 >> 5);	b[4] = (t3 & 0x1f) << 3 | 0x4;	b[5] = 1;}static int write_mpeg_pack_header(muxer_t *muxer, char *buff){	int len;	muxer_priv_t *priv;		priv = (muxer_priv_t *) muxer->priv;	*(uint32_t *)buff = be2me_32(PACK_HEADER_START_CODE);	if(priv->mux==MUX_MPEG1)	{		write_mpeg_ts(&buff[4], priv->scr, 0x20); // 0010 and SCR		write_mpeg_rate(priv->mux, &buff[9], muxer->sysrate);		len = 12;	}	else	{		write_mpeg2_scr(&buff[4], priv->scr); // 0010 and SCR		write_mpeg_rate(priv->mux, &buff[10], muxer->sysrate);		buff[13] = 0xf8; //5 bits reserved + 3 set to 0 to indicate 0 stuffing bytes 		len = 14;	}	return len;}static int write_mpeg_system_header(muxer_t *muxer, char *buff){	int len;	uint8_t i;	muxer_priv_t *priv;	priv = (muxer_priv_t *) muxer->priv;		len = 0;	*(uint32_t *)(&buff[len]) = be2me_32(SYSTEM_HEADER_START_CODE);	len += 4;	*(uint16_t *)(&buff[len]) = 0; 	//fake length, we'll fix it later	len += 2;	write_mpeg_rate(MUX_MPEG1, &buff[len], muxer->sysrate);	len += 3;			buff[len++] = 0x4 | (priv->is_xvcd ? 1 : 0); 	//1 audio stream bound, no fixed, CSPS only for xvcd	buff[len++] = 0xe1;	//system_audio_lock, system_video_lock, marker, 1 video stream bound		buff[len++] = ((priv->mux == MUX_MPEG1) ? 0xff : 0x7f);	//in mpeg2 there's the packet rate restriction		for(i = 0; i < priv->sys_info.cnt; i++)	{		buff[len++] = priv->sys_info.streams[i].id;		write_mpeg_std(&buff[len], priv->sys_info.streams[i].bufsize, priv->sys_info.streams[i].type, 			(priv->sys_info.streams[i].type == 1 ? 0xe0: 0xc0));		len += 2;	}		*(uint16_t *)(&buff[4]) = be2me_16(len - 6);	// length field fixed		return len;}static int write_mpeg_psm(muxer_t *muxer, char *buff){	int len;	uint8_t i;	uint16_t dlen;	muxer_priv_t *priv;	priv = (muxer_priv_t *) muxer->priv;		len = 0;	*(uint32_t *)(&buff[len]) = be2me_32(PSM_START_CODE);	len += 4;	*(uint16_t *)(&buff[len]) = 0; 	//fake length, we'll fix it later	len += 2;	buff[len++] = 0xe0;		//1 current, 2 bits reserved, 5 version 0	buff[len++] = 0xff;		//7 reserved, 1 marker	buff[len] = buff[len+1] = 0;	//length  of the program descriptors (unused)	len += 2;	*(uint16_t *)(&buff[len]) = 0; //length of the es descriptors	len += 2;		dlen = 0;	for(i = 0; i < priv->psm_info.cnt; i++)	{		if(			(priv->psm_info.streams[i].id == 0xbd) || 			(priv->psm_info.streams[i].id >= 0xe0 && priv->psm_info.streams[i].id <= 0xef) || 			(priv->psm_info.streams[i].id >= 0xc0 && priv->psm_info.streams[i].id <= 0xcf)		)		{			buff[len++] = priv->psm_info.streams[i].type;			buff[len++] = priv->psm_info.streams[i].id;			buff[len++] = 0;	//len of descriptor upper ...			buff[len++] = 6;	//... lower						//registration descriptor			buff[len++] = 0x5;	//tag			buff[len++] = 4;	//length: 4 bytes			memcpy(&(buff[len]), (char*) &(priv->psm_info.streams[i].format), 4);			len += 4;			dlen += 10;		}	}	*(uint16_t *)(&buff[10]) = be2me_16(dlen);	//length of the es descriptors		*(uint16_t *)(&buff[4]) = be2me_16(len - 6 + 4);	// length field fixed, including size of CRC32		*(uint32_t *)(&buff[len]) = CalcCRC32(buff, len);		len += 4;	//for crc		return len;}static int write_mpeg_pes_header(muxer_headers_t *h, uint8_t *pes_id, uint8_t *buff, uint16_t plen, int stuffing_len, int mux_type){	int len;		len = 0;	memcpy(&buff[len], pes_id, 4);	len += 4;	buff[len] = buff[len+1] = 0;	//fake len	len += 2;	if(mux_type == MUX_MPEG1)	{		if(stuffing_len > 0)		{			memset(&buff[len], 0xff, stuffing_len);			len += stuffing_len;		}				if(h->buffer_size > 0)		{			write_mpeg_std(&buff[len], h->buffer_size, h->type, 0x40); // 01 is pes1 format				len += 2;		}	}	else	//MPEG2	{		buff[len] = (h->pes_is_aligned ? 0x84 : 0x80);	//0x10... 		len++;		buff[len] = ((h->buffer_size > 0) ?  1 : 0) | (h->pts ? (h->dts ? 0xC0 : 0x80) : 0);	//pes extension + pts/dts flags		len++;		buff[len] = (h->pts ? (h->dts ? 10 : 5) : 0) + ((h->buffer_size > 0) ?  3 : 0) + stuffing_len;//pts + std + stuffing		len++;	}			if(h->pts)	{		write_mpeg_ts(&buff[len], h->pts, (h->dts ? 0x30 : 0x20)); // 001x and both PTS/DTS		len += 5;				if(h->dts)		{			write_mpeg_ts(&buff[len], h->dts, 0x10); // 0001 before DTS			len += 5;		}	}	else	{		if(mux_type == MUX_MPEG1)		{			buff[len] = 0x0f;			len += 1;		}	}		if(mux_type == MUX_MPEG2)	{			if(h->buffer_size > 0)		{			buff[len] = 0x10;	//std flag			len++;						write_mpeg_std(&buff[len], h->buffer_size, h->type, 0x40);			len += 2;		}				if(stuffing_len > 0)		{			memset(&buff[len], 0xff, stuffing_len);			len += stuffing_len;		}	}	if(h->has_pes_priv_headers > 0)	{		memcpy(&buff[len], h->pes_priv_headers, h->has_pes_priv_headers);		len += h->has_pes_priv_headers;		}		*((uint16_t*) &buff[4]) = be2me_16(len + plen - 6);	//fix pes packet size		return len;}static void write_pes_padding(uint8_t *buff, uint16_t len){	//6 header bytes + len-6 0xff chars	buff[0] = buff[1] = 0;	buff[2] = 1;	buff[3] = 0xbe;	*((uint16_t*) &buff[4]) = be2me_16(len - 6);	memset(&buff[6], 0xff, len - 6);}static void write_psm_block(muxer_t *muxer, FILE *f){	uint16_t offset, stuffing_len;	muxer_priv_t *priv = (muxer_priv_t *) muxer->priv;	uint8_t *buff = priv->buff;		offset = write_mpeg_pack_header(muxer, buff);	offset += write_mpeg_psm(muxer, &buff[offset]);	stuffing_len = priv->packet_size - offset;	if(stuffing_len > 0)	{		//insert a PES padding packet		write_pes_padding(&buff[offset], stuffing_len);		offset += stuffing_len;	}	fwrite(buff, offset, 1, f);	priv->headers_size += offset;}static int write_nav_pack(uint8_t *buff){	// concatenation of pes_private2 + 03d4 x 0 and pes_private2 + 03fa x 0        int len;	mp_msg(MSGT_MUXER, MSGL_V, "NAV\n");	len = 0;	*(uint32_t *)(&buff[len]) = be2me_32(PES_PRIVATE2);	len += 4;	buff[len++] = 0x3;	buff[len++] = 0xd4;	memset(&buff[len], 0, 0x03d4);        len += 0x03d4;	*(uint32_t *)(&buff[len]) = be2me_32(PES_PRIVATE2);	len += 4;	buff[len++] = 0x3;	buff[len++] = 0xfa;	memset(&buff[len], 0, 0x03fa);        len += 0x03fa;	return len;}static uint32_t calc_pes_hlen(int format, muxer_headers_t *h, muxer_priv_t *priv){	uint32_t len;		if(format == MUX_MPEG1)		len = 6;	else		len = 9;	//era 12		if(h->pts)	{		len += 5;		if(h->dts)			len += 5;	}	else if(format == MUX_MPEG1)		len += 1;		if(h->buffer_size > 0)	{		if(format == MUX_MPEG2)			len += 3;		else			len += 2;	}	len += h->has_pes_priv_headers;		return len;}static uint32_t calc_pack_hlen(muxer_priv_t *priv, muxer_headers_t *h){	uint32_t len;	if(priv->mux == MUX_MPEG1)		len = 12;	else		len = 14;		/*if((priv->is_genmpeg1 || priv->is_genmpeg2) && priv->update_system_header)		len += (6 + (3*priv->sys_info.cnt));*/	if(h->min_pes_hlen > 0)		len += h->min_pes_hlen;	else		len += calc_pes_hlen(priv->mux, h, priv);		return len;}static int write_mpeg_pack(muxer_t *muxer, muxer_stream_t *s, FILE *f, char *bl, uint32_t len, int isoend){	size_t tot, offset, pes_hlen, pack_hlen;	muxer_priv_t *priv;	uint8_t *buff;	int stuffing_len = 0, stflen;	muxer_headers_t *spriv;	priv = (muxer_priv_t *) muxer->priv;	buff = priv->buff;	if(isoend)	{		buff[0] = buff[1] = 0;		buff[2] = 1;		buff[3] = 0xb9;		fwrite(buff, 4, 1, f);		return 1;	}			if((len == 0) || (bl == NULL))			//PACK headers only	{		offset = write_mpeg_pack_header(muxer, buff);		offset += write_mpeg_system_header(muxer, &buff[offset]);				//priv->update_system_header = 0;				if(priv->is_dvd)			offset += write_nav_pack(&buff[offset]);					stuffing_len = priv->packet_size - offset;		if(stuffing_len > 0)		{			//insert a PES padding packet			write_pes_padding(&buff[offset], stuffing_len);			offset += stuffing_len;		}					fwrite(buff, offset, 1, f);		priv->headers_size += offset;		tot = offset;		muxer->movi_end += tot;				return tot;	}	else	{		spriv = (muxer_headers_t *) s->priv;				mp_msg(MSGT_MUXER, MSGL_V, "\nwrite_mpeg_pack(MUX=%d, len=%u, rate=%u, id=%X, pts: %llu, dts: %llu, scr: %llu, PACK_size:%u\n", 		priv->mux, len, muxer->sysrate, s->ckid, spriv->pts, spriv->dts, priv->scr, priv->packet_size);				//stflen is the count of stuffing bytes in the pes header itself, 		//stuffing_len is the size of the stuffing pes stream (must be at least 7 bytes long)		stflen = stuffing_len = 0;		offset = 0;		offset = pack_hlen = write_mpeg_pack_header(muxer, &buff[offset]);				if(priv->update_system_header && (priv->is_genmpeg1 || priv->is_genmpeg2))		{			pack_hlen += write_mpeg_system_header(muxer, &buff[offset]);			priv->update_system_header = 0;		}		offset = pack_hlen;				pes_hlen = calc_pes_hlen(priv->mux, spriv, priv);		if(spriv->min_pes_hlen > 0)		{			if(spriv->min_pes_hlen > pes_hlen)				stflen = spriv->min_pes_hlen - pes_hlen;		}					if((len >= priv->packet_size - pack_hlen - max(pes_hlen, spriv->min_pes_hlen)))			stuffing_len = 0;		else			stuffing_len = priv->packet_size - pack_hlen - max(pes_hlen, spriv->min_pes_hlen) - len;				if(stuffing_len > 0)		{			if(stuffing_len < 7)			{				if(stflen + stuffing_len > 16)				{					int x = 7 - stuffing_len;					stflen -= x;					stuffing_len += x;				}				else				{					stflen += stuffing_len;					stuffing_len = 0;				}			}		}				if(priv->skip_padding)	//variable packet size, just for fun and to reduce file size		{			stuffing_len = 0;			len = min(len, priv->packet_size - pack_hlen - pes_hlen - stflen);		}		else			len = priv->packet_size - pack_hlen - pes_hlen - stflen - stuffing_len;				mp_msg(MSGT_MUXER, MSGL_V, "LEN=%d, pack: %d, pes: %d, stf: %d, stf2: %d\n", len, pack_hlen, pes_hlen, stflen, stuffing_len);		pes_hlen = write_mpeg_pes_header(spriv, (uint8_t *) &s->ckid, &buff[offset], len, stflen, priv->mux);		offset += pes_hlen;				fwrite(buff, offset, 1, f);		mp_msg(MSGT_MUXER, MSGL_V, "pack_len = %u, pes_hlen = %u, stuffing_len: %d+%d, SCRIVO: %d bytes di payload\n", 			pack_hlen, pes_hlen, stuffing_len, stflen, len);		fwrite(bl, len, 1, f);				offset += len;				if(stuffing_len > 0)		{			//insert a PES padding packet			mp_msg(MSGT_MUXER, MSGL_V, "STUFFING: %d\n", stuffing_len);			write_pes_padding(buff, stuffing_len);			fwrite(buff, stuffing_len, 1, f);		}		else			stuffing_len = 0;			offset += stuffing_len;				mp_msg(MSGT_MUXER, MSGL_V, "\nwritten len=%d, spriv: pack(%d), pes(%d), stuffing(%d) tot(%d), offset: %d\n", 			len, pack_hlen, pes_hlen, stuffing_len, pack_hlen + pes_hlen + stuffing_len, offset);				priv->headers_size += pack_hlen + pes_hlen + stuffing_len + stflen;		priv->data_size += len;		muxer->movi_end += offset;					return len;	}}static void patch_seq(muxer_priv_t *priv, unsigned char *buf){	if(priv->vwidth > 0)	{		buf[4] = (priv->vwidth >> 4) & 0xff;		buf[5] &= 0x0f;		buf[5] |= (priv->vwidth & 0x0f) << 4;	}		if(priv->vheight > 0)	{		buf[5] &= 0xf0;		buf[5] |= (priv->vheight >> 8) & 0x0f;		buf[6] = priv->vheight & 0xff;	}		if(priv->vaspect > 0)		buf[7] = (buf[7] & 0x0f) | (priv->vaspect << 4);

⌨️ 快捷键说明

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