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

📄 rtp_payloads.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
void RP_ParsePayloadAMR(RTPStream *ch, GF_RTPHeader *hdr, char *payload, u32 size){	unsigned char c, type;	char *data;	/*we support max 30 frames in one RTP packet...*/	u32 nbFrame, i, frame_size;	/*not supported yet*/	if (!(ch->flags & RTP_AMR_ALIGN) ) return;	/*process toc and locate start of payload data*/	nbFrame = 0;	while (1) {		c = payload[nbFrame + 1];		nbFrame++;		if (!(c & 0x80)) break;	}	data = payload + nbFrame + 1;	ch->sl_hdr.compositionTimeStamp = hdr->TimeStamp;	/*then each frame*/	for (i=0; i<nbFrame; i++) {		c = payload[i + 1];		type = ((c & 0x78) >> 3);		if (ch->rtptype==GP_RTP_PAYT_AMR) {			frame_size = GF_AMR_FRAME_SIZE[type];		} else {			frame_size = GF_AMR_WB_FRAME_SIZE[type];		}		ch->sl_hdr.compositionTimeStampFlag = 1;		ch->sl_hdr.accessUnitStartFlag = 1;		ch->sl_hdr.accessUnitEndFlag = 0;		/*send TOC*/		gf_term_on_sl_packet(ch->owner->service, ch->channel, &payload[i+1], 1, &ch->sl_hdr, GF_OK);		ch->sl_hdr.packetSequenceNumber ++;		ch->sl_hdr.compositionTimeStampFlag = 0;		ch->sl_hdr.accessUnitStartFlag = 0;		ch->sl_hdr.accessUnitEndFlag = 1;		/*send payload*/		gf_term_on_sl_packet(ch->owner->service, ch->channel, data, frame_size, &ch->sl_hdr, GF_OK);		data += frame_size;		ch->sl_hdr.compositionTimeStamp += 160;	}}void RP_ParsePayloadH263(RTPStream *ch, GF_RTPHeader *hdr, char *payload, u32 size){	GF_BitStream *bs;	Bool P_bit, V_bit;	u32 plen, plen_bits, offset;	char blank[2];	bs = gf_bs_new(payload, size, GF_BITSTREAM_READ);	/*reserved*/	gf_bs_read_int(bs, 5);	P_bit = gf_bs_read_int(bs, 1);	V_bit = gf_bs_read_int(bs, 1);	plen = gf_bs_read_int(bs, 6);	plen_bits = gf_bs_read_int(bs, 3);	/*VRC not supported yet*/	if (V_bit) {		gf_bs_read_u8(bs);	}	/*extra picture header not supported yet*/	if (plen) {		gf_bs_skip_bytes(bs, plen);	}	offset = (u32) gf_bs_get_position(bs);	gf_bs_del(bs);	blank[0] = blank[1] = 0;	/*start*/	if (P_bit) {		ch->sl_hdr.compositionTimeStamp = hdr->TimeStamp;		ch->sl_hdr.compositionTimeStampFlag = 1;		ch->sl_hdr.accessUnitStartFlag = 1;		ch->sl_hdr.accessUnitEndFlag = 0;		if (ch->sl_hdr.accessUnitStartFlag) {			/*the first 16 bytes are NOT sent on the wire*/			ch->sl_hdr.randomAccessPointFlag = (payload[offset+2]&0x02) ? 0 : 1;		}		/*send missing start code*/		gf_term_on_sl_packet(ch->owner->service, ch->channel, (char *) blank, 2, &ch->sl_hdr, GF_OK);		/*send payload*/		ch->sl_hdr.compositionTimeStampFlag = 0;		ch->sl_hdr.accessUnitStartFlag = 0;		ch->sl_hdr.randomAccessPointFlag = 0;		/*if M bit set, end of frame*/		ch->sl_hdr.accessUnitEndFlag = hdr->Marker;		gf_term_on_sl_packet(ch->owner->service, ch->channel, payload + offset, size - offset, &ch->sl_hdr, GF_OK);	} else {		/*middle/end of frames - if M bit set, end of frame*/		ch->sl_hdr.accessUnitEndFlag = hdr->Marker;		gf_term_on_sl_packet(ch->owner->service, ch->channel, payload + offset, size - offset, &ch->sl_hdr, GF_OK);	}}void rtp_ttxt_flush(RTPStream *ch, u32 ts){	GF_BitStream *bs;	char *data;	u32 data_size;	if (!ch->inter_bs) return;	ch->sl_hdr.compositionTimeStamp = ts;	ch->sl_hdr.compositionTimeStampFlag = 1;	ch->sl_hdr.accessUnitStartFlag = 1;	ch->sl_hdr.accessUnitEndFlag = 0;	ch->sl_hdr.randomAccessPointFlag = 1;	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);	gf_bs_write_int(bs, ch->sl_hdr.idleFlag, 1);	ch->sl_hdr.idleFlag = 0;	gf_bs_write_int(bs, 0, 4);	gf_bs_write_int(bs, 1, 3);	gf_bs_write_u16(bs, 8 + (u16) gf_bs_get_position(ch->inter_bs));	gf_bs_write_u8(bs, ch->sidx);	gf_bs_write_u24(bs, ch->sl_hdr.au_duration);	gf_bs_write_u16(bs, ch->txt_len);	gf_bs_get_content(bs, &data, &data_size);	gf_bs_del(bs);	gf_term_on_sl_packet(ch->owner->service, ch->channel, data, data_size, &ch->sl_hdr, GF_OK);	free(data);	ch->sl_hdr.accessUnitStartFlag = 0;	ch->sl_hdr.accessUnitEndFlag = 1;	gf_bs_get_content(ch->inter_bs, &data, &data_size);	gf_term_on_sl_packet(ch->owner->service, ch->channel, data, data_size, &ch->sl_hdr, GF_OK);	free(data);	gf_bs_del(ch->inter_bs);	ch->inter_bs = NULL;	ch->nb_txt_frag = ch->cur_txt_frag = ch->sidx = ch->txt_len = ch->nb_mod_frag = 0;}void RP_ParsePayloadText(RTPStream *ch, GF_RTPHeader *hdr, char *payload, u32 size){	Bool is_utf_16;	u32 type, ttu_len, pay_start, duration, ts, sidx, txt_size;	u32 nb_frag, cur_frag;	GF_BitStream *bs;	ts = hdr->TimeStamp;	bs = gf_bs_new(payload, size, GF_BITSTREAM_READ);	while (gf_bs_available(bs)) {		pay_start = (u32) gf_bs_get_position(bs);		is_utf_16 = gf_bs_read_int(bs, 1);		gf_bs_read_int(bs, 4);		type = gf_bs_read_int(bs, 3);		ttu_len = gf_bs_read_u16(bs);		if (ttu_len<2) break;		if (type==1) {			/*flush any existing packet*/			rtp_ttxt_flush(ch, (u32) ch->sl_hdr.compositionTimeStamp);						/*bad ttu(1)*/			if (ttu_len<8) break;			ch->sl_hdr.compositionTimeStamp = ts;			ch->sl_hdr.compositionTimeStampFlag = 1;			ch->sl_hdr.accessUnitStartFlag = 1;			ch->sl_hdr.accessUnitEndFlag = 1;			ch->sl_hdr.randomAccessPointFlag = 1;			gf_bs_read_u8(bs);			ch->sl_hdr.au_duration = gf_bs_read_u24(bs);			gf_term_on_sl_packet(ch->owner->service, ch->channel, payload + pay_start, ttu_len + 1, &ch->sl_hdr, GF_OK);			gf_bs_skip_bytes(bs, ttu_len - 6);			ts += ch->sl_hdr.au_duration;		}		/*text segment*/		else if (type==2) {			/*TS changed, flush packet*/			if (ch->sl_hdr.compositionTimeStamp < ts) {				rtp_ttxt_flush(ch, (u32) ch->sl_hdr.compositionTimeStamp);			}			if (ttu_len<9) break;			ch->sl_hdr.compositionTimeStamp = ts;			ch->sl_hdr.idleFlag = is_utf_16;			nb_frag = gf_bs_read_int(bs, 4);			cur_frag = gf_bs_read_int(bs, 4);			duration = gf_bs_read_u24(bs);			sidx = gf_bs_read_u8(bs);			gf_bs_read_u16(bs);/*complete text sample size, ignored*/			txt_size = size - 10;						/*init - 3GPP/MPEG-4 spliting is IMHO stupid: 				- nb frag & cur frags are not needed: rtp reordering insures packet are in order, and 			!!!we assume fragments are sent in order!!!				- any other TTU suffices to indicate end of text string (modifiers or != RTP TS)				- replacing these 8bits field with a 16 bit absolute character offset would add error recovery			*/			if (!ch->nb_txt_frag) {				ch->nb_txt_frag = nb_frag;				ch->cur_txt_frag = 0;				ch->sidx = sidx;			}			/*flush prev if any mismatch*/			if ((nb_frag != ch->nb_txt_frag) || (ch->cur_txt_frag>cur_frag)) {				rtp_ttxt_flush(ch, (u32) ch->sl_hdr.compositionTimeStamp);				ch->nb_txt_frag = nb_frag;				ch->sidx = sidx;			}			if (!ch->inter_bs) ch->inter_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);			/*we don't reorder - RTP reordering is done at lower level, if this is out of order too bad*/			ch->cur_txt_frag = cur_frag;			gf_bs_write_data(ch->inter_bs, payload+10, txt_size);			gf_bs_skip_bytes(bs, txt_size);			ch->sl_hdr.au_duration = duration;			/*done*/			if (hdr->Marker) {				ch->txt_len = (u32) gf_bs_get_position(ch->inter_bs);				rtp_ttxt_flush(ch, ts);			}		} else if ((type==3) || (type==4)) {			if (!ch->inter_bs) ch->inter_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);			/*first modifier, store effective written text*/			if (type==3) ch->txt_len = (u32) gf_bs_get_position(ch->inter_bs);			if (ttu_len<6) break;			nb_frag = gf_bs_read_int(bs, 4);			if (!ch->nb_mod_frag) ch->nb_mod_frag = nb_frag;			else if (ch->nb_mod_frag != nb_frag) {				rtp_ttxt_flush(ch, (u32) ch->sl_hdr.compositionTimeStamp);				ch->nb_mod_frag = nb_frag;			}			gf_bs_read_int(bs, 4);  /*cur_frag, ignore*/			ch->sl_hdr.au_duration = gf_bs_read_u24(bs);			gf_bs_write_data(ch->inter_bs, payload+7, ttu_len-6);			gf_bs_skip_bytes(bs, ttu_len-6);			/*done*/			if (hdr->Marker) rtp_ttxt_flush(ch, ts);		}	}	gf_bs_del(bs);}static void rtp_avc_flush(RTPStream*ch, GF_RTPHeader *hdr, Bool missed_end){	char *data;	u32 data_size, nal_s;	if (!ch->inter_bs) return;	data = NULL;	data_size = 0;	gf_bs_get_content(ch->inter_bs, &data, &data_size);	gf_bs_del(ch->inter_bs);	ch->inter_bs = NULL;	nal_s = data_size-4;	data[0] = nal_s>>24; data[1] = nal_s>>16; data[2] = nal_s>>8; data[3] = nal_s&0xFF;	/*set F-bit since nal is corrupted*/	if (missed_end) data[4] |= 0x80;	ch->sl_hdr.accessUnitEndFlag = hdr->Marker;	ch->sl_hdr.compositionTimeStampFlag = 1;	ch->sl_hdr.compositionTimeStamp = hdr->TimeStamp;	ch->sl_hdr.decodingTimeStamp = hdr->TimeStamp;	ch->sl_hdr.decodingTimeStampFlag = 1;	gf_term_on_sl_packet(ch->owner->service, ch->channel, data, data_size, &ch->sl_hdr, GF_OK);	ch->sl_hdr.accessUnitStartFlag = 0;	ch->sl_hdr.randomAccessPointFlag = 0;	free(data);}void RP_ParsePayloadH264(RTPStream *ch, GF_RTPHeader *hdr, char *payload, u32 size){	char nalhdr[4];	u32 nal_type;	if (ch->packetization_mode==2) return;	nal_type = payload[0] & 0x1F;	/*set start*/	if (ch->sl_hdr.compositionTimeStamp != hdr->TimeStamp) {		ch->sl_hdr.accessUnitEndFlag = 0;		ch->sl_hdr.accessUnitStartFlag = 1;		ch->sl_hdr.compositionTimeStamp = hdr->TimeStamp;		ch->sl_hdr.compositionTimeStampFlag = 1;		ch->sl_hdr.decodingTimeStamp = hdr->TimeStamp;		ch->sl_hdr.decodingTimeStampFlag = 1;		ch->sl_hdr.randomAccessPointFlag = 0;	}	/*single NALU*/	if (nal_type<23) {		if (nal_type==5) {			ch->sl_hdr.randomAccessPointFlag = 1;			ch->flags &= ~RTP_AVC_WAIT_RAP;		}		else if (ch->flags & RTP_AVC_WAIT_RAP) return;		ch->sl_hdr.accessUnitEndFlag = 0;		/*signal NALU size on 4 bytes*/		nalhdr[0] = size>>24; nalhdr[1] = size>>16; nalhdr[2] = size>>8; nalhdr[3] = size&0xFF;		gf_term_on_sl_packet(ch->owner->service, ch->channel, nalhdr, 4, &ch->sl_hdr, GF_OK);		ch->sl_hdr.accessUnitStartFlag = 0;		ch->sl_hdr.compositionTimeStampFlag = 0;		ch->sl_hdr.accessUnitEndFlag = hdr->Marker;		/*send NAL payload*/		gf_term_on_sl_packet(ch->owner->service, ch->channel, payload, size, &ch->sl_hdr, GF_OK);	}	/*STAP-A NALU*/	else if (nal_type==24) {		u32 offset = 1;		while (offset<size) {			Bool send = 1;			u32 nal_size = (u8) payload[offset]; nal_size<<=8; nal_size |= (u8) payload[offset+1]; 			offset += 2;			if ((payload[offset] & 0x1F) == 5) {				ch->sl_hdr.randomAccessPointFlag = 1;				ch->flags &= ~RTP_AVC_WAIT_RAP;			}			if (ch->flags & RTP_AVC_WAIT_RAP) send = 0;			/*signal NALU size on 4 bytes*/			nalhdr[0] = nal_size>>24; nalhdr[1] = nal_size>>16; nalhdr[2] = nal_size>>8; nalhdr[3] = nal_size&0xFF;			if (send) {				gf_term_on_sl_packet(ch->owner->service, ch->channel, nalhdr, 4, &ch->sl_hdr, GF_OK);				ch->sl_hdr.accessUnitStartFlag = 0;				ch->sl_hdr.compositionTimeStampFlag = 0;			}			ch->sl_hdr.accessUnitEndFlag = (hdr->Marker && (offset+nal_size==size)) ? 1 : 0;			if (send) gf_term_on_sl_packet(ch->owner->service, ch->channel, payload+offset, nal_size, &ch->sl_hdr, GF_OK);			offset += nal_size;		}	}	/*FU-A NALU*/	else if (nal_type==28) {		Bool is_start = payload[1] & 0x80;		Bool is_end = payload[1] & 0x40;		/*flush*/		if (is_start) rtp_avc_flush(ch, hdr, 1);		if ((payload[1] & 0x1F) == 5) {			ch->flags &= ~RTP_AVC_WAIT_RAP;			ch->sl_hdr.randomAccessPointFlag = 1;		} else if (ch->flags & RTP_AVC_WAIT_RAP) return;		/*setup*/		if (!ch->inter_bs) {			u8 nal_hdr;			ch->inter_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);			/*copy F and NRI*/			nal_hdr = payload[0] & 0xE0;			/*start bit not set, signal corrupted data (we missed start packet)*/			if (!is_start) nal_hdr |= 0x80;			/*copy NALU type*/			nal_hdr |= (payload[1] & 0x1F);			/*dummy size field*/			gf_bs_write_u32(ch->inter_bs, 0);			gf_bs_write_u8(ch->inter_bs, nal_hdr);		}		gf_bs_write_data(ch->inter_bs, payload+2, size-2);		if (is_end || hdr->Marker) rtp_avc_flush(ch, hdr, 0);	}}void RP_ParsePayloadLATM(RTPStream *ch, GF_RTPHeader *hdr, char *payload, u32 size){	u32 remain, latm_hdr_size, latm_size;	ch->sl_hdr.compositionTimeStamp = hdr->TimeStamp;	ch->sl_hdr.compositionTimeStampFlag = 1;	ch->sl_hdr.accessUnitStartFlag = ch->sl_hdr.accessUnitEndFlag = 1;	ch->sl_hdr.randomAccessPointFlag = 1;	remain = size;	while (remain) {		latm_hdr_size = latm_size = 0;		while (1) {			u8 c = *payload;			latm_hdr_size += 1;			latm_size += c;			payload ++;			if (c < 0xFF) break;		}		gf_term_on_sl_packet(ch->owner->service, ch->channel, (char *) payload, latm_size, &ch->sl_hdr, GF_OK);		payload += latm_size;		remain -= (latm_size+latm_hdr_size);		ch->sl_hdr.compositionTimeStamp += ch->unit_duration;	}}

⌨️ 快捷键说明

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