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

📄 rtp_depacketizer.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
	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(rtp->inter_bs));	gf_bs_write_u8(bs, rtp->sidx);	gf_bs_write_u24(bs, rtp->sl_hdr.au_duration);	gf_bs_write_u16(bs, rtp->txt_len);	gf_bs_get_content(bs, &data, &data_size);	gf_bs_del(bs);	rtp->on_sl_packet(rtp->udta, data, data_size, &rtp->sl_hdr, GF_OK);	free(data);	rtp->sl_hdr.accessUnitStartFlag = 0;	rtp->sl_hdr.accessUnitEndFlag = 1;	gf_bs_get_content(rtp->inter_bs, &data, &data_size);	rtp->on_sl_packet(rtp->udta, data, data_size, &rtp->sl_hdr, GF_OK);	free(data);	gf_bs_del(rtp->inter_bs);	rtp->inter_bs = NULL;	rtp->nb_txt_frag = rtp->cur_txt_frag = rtp->sidx = rtp->txt_len = rtp->nb_mod_frag = 0;}static void gf_rtp_parse_ttxt(GF_RTPDepacketizer *rtp, 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*/			gf_rtp_ttxt_flush(rtp, (u32) rtp->sl_hdr.compositionTimeStamp);						/*bad ttu(1)*/			if (ttu_len<8) break;			rtp->sl_hdr.compositionTimeStamp = ts;			rtp->sl_hdr.compositionTimeStampFlag = 1;			rtp->sl_hdr.accessUnitStartFlag = 1;			rtp->sl_hdr.accessUnitEndFlag = 1;			rtp->sl_hdr.randomAccessPointFlag = 1;			gf_bs_read_u8(bs);			rtp->sl_hdr.au_duration = gf_bs_read_u24(bs);			rtp->on_sl_packet(rtp->udta, payload + pay_start, ttu_len + 1, &rtp->sl_hdr, GF_OK);			gf_bs_skip_bytes(bs, ttu_len - 6);			ts += rtp->sl_hdr.au_duration;		}		/*text segment*/		else if (type==2) {			/*TS changed, flush packet*/			if (rtp->sl_hdr.compositionTimeStamp < ts) {				gf_rtp_ttxt_flush(rtp, (u32) rtp->sl_hdr.compositionTimeStamp);			}			if (ttu_len<9) break;			rtp->sl_hdr.compositionTimeStamp = ts;			rtp->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 (!rtp->nb_txt_frag) {				rtp->nb_txt_frag = nb_frag;				rtp->cur_txt_frag = 0;				rtp->sidx = sidx;			}			/*flush prev if any mismatch*/			if ((nb_frag != rtp->nb_txt_frag) || (rtp->cur_txt_frag > cur_frag)) {				gf_rtp_ttxt_flush(rtp, (u32) rtp->sl_hdr.compositionTimeStamp);				rtp->nb_txt_frag = nb_frag;				rtp->sidx = sidx;			}			if (!rtp->inter_bs) rtp->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*/			rtp->cur_txt_frag = cur_frag;			gf_bs_write_data(rtp->inter_bs, payload+10, txt_size);			gf_bs_skip_bytes(bs, txt_size);			rtp->sl_hdr.au_duration = duration;			/*done*/			if (hdr->Marker) {				rtp->txt_len = (u32) gf_bs_get_position(rtp->inter_bs);				gf_rtp_ttxt_flush(rtp, ts);			}		} else if ((type==3) || (type==4)) {			if (!rtp->inter_bs) rtp->inter_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);			/*first modifier, store effective written text*/			if (type==3) rtp->txt_len = (u32) gf_bs_get_position(rtp->inter_bs);			if (ttu_len<6) break;			nb_frag = gf_bs_read_int(bs, 4);			if (!rtp->nb_mod_frag) rtp->nb_mod_frag = nb_frag;			else if (rtp->nb_mod_frag != nb_frag) {				gf_rtp_ttxt_flush(rtp, (u32) rtp->sl_hdr.compositionTimeStamp);				rtp->nb_mod_frag = nb_frag;			}			gf_bs_read_int(bs, 4);  /*cur_frag, ignore*/			rtp->sl_hdr.au_duration = gf_bs_read_u24(bs);			gf_bs_write_data(rtp->inter_bs, payload+7, ttu_len-6);			gf_bs_skip_bytes(bs, ttu_len-6);			/*done*/			if (hdr->Marker) gf_rtp_ttxt_flush(rtp, ts);		}	}	gf_bs_del(bs);}static void gf_rtp_h264_flush(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, Bool missed_end){	char *data;	u32 data_size, nal_s;	if (!rtp->inter_bs) return;	data = NULL;	data_size = 0;	gf_bs_get_content(rtp->inter_bs, &data, &data_size);	gf_bs_del(rtp->inter_bs);	rtp->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;	rtp->sl_hdr.accessUnitEndFlag = hdr->Marker;	rtp->sl_hdr.compositionTimeStampFlag = 1;	rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp;	rtp->sl_hdr.decodingTimeStamp = hdr->TimeStamp;	rtp->sl_hdr.decodingTimeStampFlag = 1;	rtp->on_sl_packet(rtp->udta, data, data_size, &rtp->sl_hdr, GF_OK);	rtp->sl_hdr.accessUnitStartFlag = 0;	rtp->sl_hdr.randomAccessPointFlag = 0;	free(data);}static void gf_rtp_parse_h264(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size){	char nalhdr[4];	u32 nal_type;	if (rtp->h264_pck_mode==2) return;	nal_type = payload[0] & 0x1F;	/*set start*/	if (rtp->sl_hdr.compositionTimeStamp != hdr->TimeStamp) {		rtp->sl_hdr.accessUnitEndFlag = 0;		rtp->sl_hdr.accessUnitStartFlag = 1;		rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp;		rtp->sl_hdr.compositionTimeStampFlag = 1;		rtp->sl_hdr.decodingTimeStamp = hdr->TimeStamp;		rtp->sl_hdr.decodingTimeStampFlag = 1;		rtp->sl_hdr.randomAccessPointFlag = 0;	}	/*single NALU*/	if (nal_type<23) {		if (nal_type==5) {			rtp->sl_hdr.randomAccessPointFlag = 1;			rtp->flags &= ~GF_RTP_AVC_WAIT_RAP;		}		else if (rtp->flags & GF_RTP_AVC_WAIT_RAP) return;		rtp->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;		rtp->on_sl_packet(rtp->udta, nalhdr, 4, &rtp->sl_hdr, GF_OK);		rtp->sl_hdr.accessUnitStartFlag = 0;		rtp->sl_hdr.compositionTimeStampFlag = 0;		rtp->sl_hdr.accessUnitEndFlag = hdr->Marker;		/*send NAL payload*/		rtp->on_sl_packet(rtp->udta, payload, size, &rtp->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) {				rtp->sl_hdr.randomAccessPointFlag = 1;				rtp->flags &= ~GF_RTP_AVC_WAIT_RAP;			}			if (rtp->flags & GF_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) {				rtp->on_sl_packet(rtp->udta, nalhdr, 4, &rtp->sl_hdr, GF_OK);				rtp->sl_hdr.accessUnitStartFlag = 0;				rtp->sl_hdr.compositionTimeStampFlag = 0;			}			rtp->sl_hdr.accessUnitEndFlag = (hdr->Marker && (offset+nal_size==size)) ? 1 : 0;			if (send) rtp->on_sl_packet(rtp->udta, payload+offset, nal_size, &rtp->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) gf_rtp_h264_flush(rtp, hdr, 1);		if ((payload[1] & 0x1F) == 5) {			rtp->flags &= ~GF_RTP_AVC_WAIT_RAP;			rtp->sl_hdr.randomAccessPointFlag = 1;		} else if (rtp->flags & GF_RTP_AVC_WAIT_RAP) return;		/*setup*/		if (!rtp->inter_bs) {			u8 nal_hdr;			rtp->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(rtp->inter_bs, 0);			gf_bs_write_u8(rtp->inter_bs, nal_hdr);		}		gf_bs_write_data(rtp->inter_bs, payload+2, size-2);		if (is_end || hdr->Marker) gf_rtp_h264_flush(rtp, hdr, 0);	}}static void gf_rtp_parse_latm(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size){	u32 remain, latm_hdr_size, latm_size;	rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp;	rtp->sl_hdr.compositionTimeStampFlag = 1;	rtp->sl_hdr.accessUnitStartFlag = rtp->sl_hdr.accessUnitEndFlag = 1;	rtp->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;		}		rtp->on_sl_packet(rtp->udta, (char *) payload, latm_size, &rtp->sl_hdr, GF_OK);		payload += latm_size;		remain -= (latm_size+latm_hdr_size);		rtp->sl_hdr.compositionTimeStamp += rtp->sl_hdr.au_duration;	}}static u32 gf_rtp_get_payload_type(GF_RTPMap *map, GF_SDPMedia *media){	u32 i, j;	if (!stricmp(map->payload_name, "MP4V-ES") ) return GF_RTP_PAYT_MPEG4;	else if (!stricmp(map->payload_name, "mpeg4-generic")) return GF_RTP_PAYT_MPEG4;	else if (!stricmp(map->payload_name, "enc-mpeg4-generic")) return GF_RTP_PAYT_MPEG4;	/*optibase mm400 card hack*/	else if (!stricmp(map->payload_name, "enc-generic-mp4") ) {		free(map->payload_name);		map->payload_name = strdup("enc-mpeg4-generic");		return GF_RTP_PAYT_MPEG4;	}	/*LATM: only without multiplexing (not tested but should be straight AUs)*/	else if (!stricmp(map->payload_name, "MP4A-LATM")) {		GF_SDP_FMTP *fmtp;		i=0;		while ((fmtp = (GF_SDP_FMTP *) gf_list_enum(media->FMTP, &i))) {			GF_X_Attribute *att;			if (fmtp->PayloadType != map->PayloadType) continue;			//this is our payload. check cpresent is 0			j=0;			while ((att = (GF_X_Attribute *)gf_list_enum(fmtp->Attributes, &j))) {				if (!stricmp(att->Name, "cpresent") && atoi(att->Value)) return 0;			}		}		return GF_RTP_PAYT_LATM;	}	else if (!stricmp(map->payload_name, "MPA")) return GF_RTP_PAYT_MPEG12_AUDIO;	else if (!stricmp(map->payload_name, "MPV")) return GF_RTP_PAYT_MPEG12_VIDEO;	else if (!stricmp(map->payload_name, "H263-1998") || !stricmp(map->payload_name, "H263-2000")) return GF_RTP_PAYT_H263;	else if (!stricmp(map->payload_name, "AMR")) return GF_RTP_PAYT_AMR;	else if (!stricmp(map->payload_name, "AMR-WB")) return GF_RTP_PAYT_AMR_WB;	else if (!stricmp(map->payload_name, "3gpp-tt")) return GF_RTP_PAYT_3GPP_TEXT;	else if (!stricmp(map->payload_name, "H264")) return GF_RTP_PAYT_H264_AVC;	else return 0;}static GF_Err payt_set_param(GF_RTPDepacketizer *rtp, char *param_name, char *param_val){	u32 i, val;	char valS[3];	GF_BitStream *bs;	if (!rtp || !param_name) return GF_BAD_PARAM;	/*1 - mpeg4-generic / RFC 3016 payload type items*/	/*PL (not needed when IOD is here)*/	if (!stricmp(param_name, "Profile-level-id")) {		if (rtp->payt == GF_RTP_PAYT_H264_AVC) {			sscanf(param_val, "%x", &rtp->sl_map.PL_ID);		} else {			rtp->sl_map.PL_ID = atoi(param_val);		}	}	/*decoder specific info (not needed when IOD is here)*/	else if (!stricmp(param_name, "config")) {		u32 len = strlen(param_val);		//decode the buffer - the string buffer is MSB hexadecimal		bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);		valS[2] = 0;		for (i=0; i<len;i+=2) {			valS[0] = param_val[i];			valS[1] = param_val[i+1];			sscanf(valS, "%x", &val);			gf_bs_write_u8(bs, val);		}		if (rtp->sl_map.config) free(rtp->sl_map.config);		rtp->sl_map.config = NULL;		gf_bs_get_content(bs, &rtp->sl_map.config, &rtp->sl_map.configSize);		gf_bs_del(bs);	}	/*mpeg4-generic payload type items required*/		/*constant size (size of all AUs) */	else if (!stricmp(param_name, "ConstantSize")) {		rtp->sl_map.ConstantSize = atoi(param_val);	}	/*constant size (size of all AUs) */	else if (!stricmp(param_name, "ConstantDuration")) {		rtp->sl_map.ConstantDuration = atoi(param_val);	}	/*object type indication (not needed when IOD is here)*/	else if (!stricmp(param_name, "ObjectType")) {		rtp->sl_map.ObjectTypeIndication = atoi(param_val);	}	else if (!stricmp(param_name, "StreamType")) 		rtp->sl_map.StreamType = atoi(param_val);	else if (!stricmp(param_name, "mode")) {		strcpy(rtp->sl_map.mode, param_val);		/*in case no IOD and no streamType/OTI in the file*/		if (!stricmp(param_val, "AAC-hbr") || !stricmp(param_val, "AAC-lbr") || !stricmp(param_val, "CELP-vbr") || !stricmp(param_val, "CELP-cbr")) {			rtp->sl_map.StreamType = GF_STREAM_AUDIO;			rtp->sl_map.ObjectTypeIndication = 0x40;		}	}	else if (!stricmp(param_name, "DTSDeltaLength")) rtp->sl_map.DTSDeltaLength = atoi(param_val);	else if (!stricmp(param_name, "CTSDeltaLength")) rtp->sl_map.CTSDeltaLength = atoi(param_val);	else if (!stricmp(param_name, "SizeLength")) rtp->sl_map.SizeLength = atoi(param_val);	else if (!stricmp(param_name, "IndexLength")) rtp->sl_map.IndexLength = atoi(param_val);	else if (!stricmp(param_name, "IndexDeltaLength")) rtp->sl_map.IndexDeltaLength = atoi(param_val);	else if (!stricmp(param_name, "RandomAccessIndication")) rtp->sl_map.RandomAccessIndication = atoi(param_val);	else if (!stricmp(param_name, "StreamStateIndication")) rtp->sl_map.StreamStateIndication = atoi(param_val);	else if (!stricmp(param_name, "AuxiliaryDataSizeLength")) rtp->sl_map.AuxiliaryDataSizeLength = atoi(param_val);	/*H264/AVC config - we only handle mode 0 and 1*/	else if (!stricmp(param_name, "packetization-mode")) 		rtp->h264_pck_mode = 1;	/*AMR config*/	else if (!stricmp(param_name, "octet-align")) 		rtp->flags |= GF_RTP_AMR_ALIGN;	/*ISMACryp config*/	else if (!stricmp(param_name, "ISMACrypCryptoSuite")) {		if (!stricmp(param_val, "AES_CTR_128")) 			rtp->isma_scheme = GF_4CC('i','A','E','C');		else 			rtp->isma_scheme = 0;	}	else if (!stricmp(param_name, "ISMACrypSelectiveEncryption")) {		if (!stricmp(param_val, "1") || !stricmp(param_val, "true"))			rtp->flags |= GF_RTP_ISMA_SEL_ENC;		else			rtp->flags &= ~GF_RTP_ISMA_SEL_ENC;	}	else if (!stricmp(param_name, "ISMACrypIVLength")) 		rtp->sl_map.IV_length = atoi(param_val);	else if (!stricmp(param_name, "ISMACrypDeltaIVLength")) 		rtp->sl_map.IV_delta_length = atoi(param_val);	else if (!stricmp(param_name, "ISMACrypKeyIndicatorLength")) 		rtp->sl_map.KI_length = atoi(param_val);	else if (!stricmp(param_name, "ISMACrypKeyIndicatorPerAU")) {		if (!stricmp(param_val, "1") || !stricmp(param_val, "true"))			rtp->flags |= GF_RTP_ISMA_HAS_KEY_IDX;		else 			rtp->flags &= ~GF_RTP_ISMA_HAS_KEY_IDX;	}	else if (!stricmp(param_name, "ISMACrypKey")) 		rtp->key = strdup(param_val);		return GF_OK;}static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPMedia *media){	u32 i, j;	GF_SDP_FMTP *fmtp;	/*reset sl map*/

⌨️ 快捷键说明

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