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

📄 sdp.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
			bw = (GF_SDPBandwidth*)malloc(sizeof(GF_SDPBandwidth));			bw->name = strdup(comp);			pos = gf_token_get(LineBuf, pos, ":\r\n", comp, 3000);			bw->value = atoi(comp);			if (media) {				gf_list_add(media->Bandwidths, bw);			} else {				gf_list_add(sdp->b_bandwidth, bw);			}			break;		case 't':			if (media) break;			//create a new time structure for each entry			GF_SAFEALLOC(timing, GF_SDPTiming);			pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000);			timing->StartTime = atoi(comp);			pos = gf_token_get(LineBuf, pos, "\r\n", comp, 3000);			timing->StopTime = atoi(comp);			gf_list_add(sdp->Timing, timing);			break;		case 'r':			if (media) break;			pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000);			timing->RepeatInterval = SDP_MakeSeconds(comp);			pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000);			timing->ActiveDuration = SDP_MakeSeconds(comp);			while (1) {				pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000);				if (pos <= 0) break;				timing->OffsetFromStart[timing->NbRepeatOffsets] = SDP_MakeSeconds(comp);				timing->NbRepeatOffsets += 1;			}			break;		case 'z':			if (media) break;			pos = 2;			while (1) {				pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000);				if (pos <= 0) break;				timing->AdjustmentTime[timing->NbZoneOffsets] = atoi(comp);				pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000);				timing->AdjustmentOffset[timing->NbZoneOffsets] = SDP_MakeSeconds(comp);				timing->NbZoneOffsets += 1;			}			break;		case 'k':			pos = gf_token_get(LineBuf, 2, ":\t\r\n", comp, 3000);			if (media) {				media->k_method = strdup(comp);			} else {				sdp->k_method = strdup(comp);			}			pos = gf_token_get(LineBuf, pos, ":\r\n", comp, 3000);			if (pos > 0) {				if (media) {					media->k_key = strdup(comp);				} else {					sdp->k_key = strdup(comp);				}			}			break;		case 'a':			SDP_ParseAttribute(sdp, LineBuf+2, media);			break;		case 'm':			pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000);			if (strcmp(comp, "audio") 				&& strcmp(comp, "data") 				&& strcmp(comp, "control") 				&& strcmp(comp, "video") 				&& strcmp(comp, "text") 				&& strcmp(comp, "application")) {				return GF_SERVICE_ERROR;			}			media = gf_sdp_media_new();			//media type			if (!strcmp(comp, "video")) media->Type = 1;			else if (!strcmp(comp, "audio")) media->Type = 2;			else if (!strcmp(comp, "text")) media->Type = 3;			else if (!strcmp(comp, "data")) media->Type = 4;			else if (!strcmp(comp, "control")) media->Type = 5;			else media->Type = 0;			//port numbers						gf_token_get(LineBuf, pos, " ", comp, 3000);			if (!strstr(comp, "/")) {				pos = gf_token_get(LineBuf, pos, " \r\n", comp, 3000);				media->PortNumber = atoi(comp);				media->NumPorts = 0;			} else {				pos = gf_token_get(LineBuf, pos, " /\r\n", comp, 3000);				media->PortNumber = atoi(comp);				pos = gf_token_get(LineBuf, pos, " \r\n", comp, 3000);				media->NumPorts = atoi(comp);			}			//transport Profile			pos = gf_token_get(LineBuf, pos, " \r\n", comp, 3000);			media->Profile = strdup(comp);			pos = gf_token_get(LineBuf, pos, " \r\n", comp, 3000);			media->fmt_list = strdup(comp);			gf_list_add(sdp->media_desc, media);			break;		}	}	//finally rewrite the fmt_list for all media, and remove dynamic payloads 	//from the list	i=0;	while ((media = (GF_SDPMedia*)gf_list_enum(sdp->media_desc, &i))) {		pos = 0;		LinePos = 1;		strcpy(LineBuf, "");		while (1) {			if (!media->fmt_list) break;			pos = gf_token_get(media->fmt_list, pos, " ", comp, 3000);			if (pos <= 0) break;			if (!SDP_IsDynamicPayload(media, comp)) {				if (!LinePos) {					strcat(LineBuf, " ");				} else {					LinePos = 0;				}				strcat(LineBuf, comp);			}			free(media->fmt_list);			media->fmt_list = NULL;			if (strlen(LineBuf)) {				media->fmt_list = strdup(LineBuf);			}		}	}	return GF_OK;}GF_Err SDP_CheckConnection(GF_SDPConnection *conn){	if (!conn) return GF_BAD_PARAM;	if (!conn->host || !conn->add_type || !conn->net_type) return GF_REMOTE_SERVICE_ERROR;	if (gf_sk_is_multicast_address(conn->host)) {		if (conn->TTL < 0 || conn->TTL > 255) return GF_REMOTE_SERVICE_ERROR;	} else {		conn->TTL = -1;		conn->add_count = 0;	}	return GF_OK;}//return GF_BAD_PARAM if invalid structure, GF_REMOTE_SERVICE_ERROR if bad formatting//or GF_OKGF_EXPORTGF_Err gf_sdp_info_check(GF_SDPInfo *sdp){	GF_Err e;	u32 i, j, count;	GF_SDPMedia *media;	GF_SDPConnection *conn;	GF_RTPMap *map;	Bool HasGlobalConnection, HasSeveralPorts;	if (!sdp || !sdp->media_desc || !sdp->Attributes) return GF_BAD_PARAM;	//we force at least one media per SDP	if (!gf_list_count(sdp->media_desc)) return GF_REMOTE_SERVICE_ERROR;	//normative fields	//o=	if (!sdp->o_add_type || !sdp->o_address || !sdp->o_username || !sdp->o_session_id || !sdp->o_version) 		return GF_REMOTE_SERVICE_ERROR;	//s=	if (!sdp->s_session_name) return GF_REMOTE_SERVICE_ERROR;	//t=//	if () return GF_REMOTE_SERVICE_ERROR;	//c=	if (sdp->c_connection) { 		e = SDP_CheckConnection(sdp->c_connection);		if (e) return e;		//multiple addresses are only for media desc		if (sdp->c_connection->add_count >= 2) return GF_REMOTE_SERVICE_ERROR;		HasGlobalConnection = 1;	} else {		HasGlobalConnection = 0;	}	//then check all media	i=0;	while ((media = (GF_SDPMedia*)gf_list_enum(sdp->media_desc, &i))) {		HasSeveralPorts = 0;		//m= : force non-null port, profile and fmt_list		if (!media->PortNumber || !media->Profile) return GF_REMOTE_SERVICE_ERROR;		if (media->NumPorts) HasSeveralPorts = 1;		//no connections specified - THIS IS AN ERROR IN SDP BUT NOT IN ALL RTSP SESSIONS...//		if (!HasGlobalConnection && !gf_list_count(media->Connections)) return GF_REMOTE_SERVICE_ERROR;		//too many connections specified		if (HasGlobalConnection && gf_list_count(media->Connections)) return GF_REMOTE_SERVICE_ERROR;		//check all connections, and make sure we don't have multiple addresses 		//and multiple ports at the same time		count = gf_list_count(media->Connections);		if (count>1 && HasSeveralPorts) return GF_REMOTE_SERVICE_ERROR;		for (j=0; j<count; j++) {			conn = (GF_SDPConnection*)gf_list_get(media->Connections, j);			e = SDP_CheckConnection(conn);			if (e) return e;			if ((conn->add_count >= 2) && HasSeveralPorts) return GF_REMOTE_SERVICE_ERROR; 		}		//RTPMaps. 0 is tolerated, but if some are specified check them		j=0;		while ((map = (GF_RTPMap*)gf_list_enum(media->RTPMaps, &j))) {			//RFC2327 is not clear here, but we assume the PayloadType should be a DYN one			//however this depends on the profile (RTP/AVP or others) so don't check it			//ClockRate SHALL NOT be NULL			if (!map->payload_name || !map->ClockRate) return GF_REMOTE_SERVICE_ERROR;		}	}	//Encryption: nothing tells wether the scope of the global key is eclusive or not.	//we accept a global key + keys per media entry, assuming that the media key primes	//on the global key	return GF_OK;}#define SDP_WRITE_ALLOC_STR(str, space)		\		if (str) {		\			if (strlen(str)+pos + (space ? 1 : 0) >= buf_size) {	\				buf_size += SDP_WRITE_STEPALLOC;	\				buf = (char*)realloc(buf, sizeof(char)*buf_size);		\			}	\			strcpy(buf+pos, str);		\			pos += strlen(str);		\			if (space) {			\				strcat(buf+pos, " ");	\				pos += 1;		\			}		\		}#define SDP_WRITE_ALLOC_INT(d, spa, sig)		\	if (sig) { \		sprintf(temp, "%d", d);		\	} else { \		sprintf(temp, "%u", d);		\	}	\	SDP_WRITE_ALLOC_STR(temp, spa);#define SDP_WRITE_ALLOC_FLOAT(d, spa)		\	sprintf(temp, "%.2f", d);		\	SDP_WRITE_ALLOC_STR(temp, spa);#define TEST_SDP_WRITE_SINGLE(type, str, sep)		\	if (str) {		\		SDP_WRITE_ALLOC_STR(type, 0);		\		if (sep) SDP_WRITE_ALLOC_STR(":", 0);		\		SDP_WRITE_ALLOC_STR(str, 0);		\		SDP_WRITE_ALLOC_STR("\r\n", 0);		\	}#define SDP_WRITE_CONN(conn)		\	if (conn) {			\		SDP_WRITE_ALLOC_STR("c=", 0);	\		SDP_WRITE_ALLOC_STR(conn->net_type, 1);		\		SDP_WRITE_ALLOC_STR(conn->add_type, 1);		\		SDP_WRITE_ALLOC_STR(conn->host, 0);			\		if (gf_sk_is_multicast_address(conn->host)) {	\			SDP_WRITE_ALLOC_STR("/", 0);			\			SDP_WRITE_ALLOC_INT(conn->TTL, 0, 0);		\			if (conn->add_count >= 2) {		\				SDP_WRITE_ALLOC_STR("/", 0);		\				SDP_WRITE_ALLOC_INT(conn->add_count, 0, 0);	\			}		\		}	\		SDP_WRITE_ALLOC_STR("\r\n", 0);		\	}GF_EXPORTGF_Err gf_sdp_info_write(GF_SDPInfo *sdp, char **out_str_buf){	char *buf;	GF_SDP_FMTP *fmtp;	char temp[50];	GF_SDPMedia *media;	GF_SDPBandwidth *bw;	u32 buf_size, pos, i, j, k;	GF_RTPMap *map;	GF_SDPConnection *conn;	GF_Err e;	GF_SDPTiming *timing;	GF_X_Attribute *att;	e = gf_sdp_info_check(sdp);	if (e) return e;	buf = (char *)malloc(SDP_WRITE_STEPALLOC);	buf_size = SDP_WRITE_STEPALLOC;	pos = 0;	//v	SDP_WRITE_ALLOC_STR("v=", 0);	SDP_WRITE_ALLOC_INT(sdp->Version, 0, 0);	SDP_WRITE_ALLOC_STR("\r\n", 0);	//o	SDP_WRITE_ALLOC_STR("o=", 0);	SDP_WRITE_ALLOC_STR(sdp->o_username, 1);	SDP_WRITE_ALLOC_STR(sdp->o_session_id, 1);	SDP_WRITE_ALLOC_STR(sdp->o_version, 1);	SDP_WRITE_ALLOC_STR(sdp->o_net_type, 1);	SDP_WRITE_ALLOC_STR(sdp->o_add_type, 1);	SDP_WRITE_ALLOC_STR(sdp->o_address, 0);	SDP_WRITE_ALLOC_STR("\r\n", 0);	//s	TEST_SDP_WRITE_SINGLE("s=", sdp->s_session_name, 0);	//i	TEST_SDP_WRITE_SINGLE("i=", sdp->i_description, 0);	//u	TEST_SDP_WRITE_SINGLE("u=", sdp->u_uri, 0);	//e	TEST_SDP_WRITE_SINGLE("e=", sdp->e_email, 0);	//p	TEST_SDP_WRITE_SINGLE("p=", sdp->p_phone, 0);	//c	SDP_WRITE_CONN(sdp->c_connection);	//b	i=0;	while ((bw = (GF_SDPBandwidth*)gf_list_enum(sdp->b_bandwidth, &i))) {		SDP_WRITE_ALLOC_STR("b=", 0);		SDP_WRITE_ALLOC_STR(bw->name, 0);		SDP_WRITE_ALLOC_STR(":", 0);		SDP_WRITE_ALLOC_INT(bw->value, 0, 0);		SDP_WRITE_ALLOC_STR("\r\n", 0);	}	//t+r+z	i=0;	while ((timing = (GF_SDPTiming*)gf_list_enum(sdp->Timing, &i))) {		if (timing->NbRepeatOffsets > GF_SDP_MAX_TIMEOFFSET) timing->NbRepeatOffsets = GF_SDP_MAX_TIMEOFFSET;		if (timing->NbZoneOffsets > GF_SDP_MAX_TIMEOFFSET) timing->NbZoneOffsets = GF_SDP_MAX_TIMEOFFSET;		//t		SDP_WRITE_ALLOC_STR("t=", 0);		SDP_WRITE_ALLOC_INT(timing->StartTime, 1, 0);		SDP_WRITE_ALLOC_INT(timing->StopTime, 0, 0);		SDP_WRITE_ALLOC_STR("\r\n", 0);		if (timing->NbRepeatOffsets) {			SDP_WRITE_ALLOC_STR("r=", 0);			SDP_WRITE_ALLOC_INT(timing->RepeatInterval, 1, 0);			SDP_WRITE_ALLOC_INT(timing->ActiveDuration, 0, 0);			for (j=0; j<timing->NbRepeatOffsets; j++) {				SDP_WRITE_ALLOC_STR(" ", 0);				SDP_WRITE_ALLOC_INT(timing->OffsetFromStart[j], 0, 0);			}			SDP_WRITE_ALLOC_STR("\r\n", 0);		}		if (timing->NbZoneOffsets) {			SDP_WRITE_ALLOC_STR("z=", 0);			for (j=0; j<timing->NbZoneOffsets; j++) {				SDP_WRITE_ALLOC_INT(timing->AdjustmentTime[j], 1, 0);				if (j+1 == timing->NbRepeatOffsets) {					SDP_WRITE_ALLOC_INT(timing->AdjustmentOffset[j], 0, 1);				} else {					SDP_WRITE_ALLOC_INT(timing->AdjustmentOffset[j], 1, 1);				}			}			SDP_WRITE_ALLOC_STR("\r\n", 0);		}	}	//k	if (sdp->k_method) {		SDP_WRITE_ALLOC_STR("k=", 0);		SDP_WRITE_ALLOC_STR(sdp->k_method, 0);		if (sdp->k_key) {			SDP_WRITE_ALLOC_STR(":", 0);			SDP_WRITE_ALLOC_STR(sdp->k_key, 0);		}		SDP_WRITE_ALLOC_STR("\r\n", 0);	}	//a=cat	TEST_SDP_WRITE_SINGLE("a=cat", sdp->a_cat, 1);	//a=keywds	TEST_SDP_WRITE_SINGLE("a=keywds", sdp->a_keywds, 1);	//a=tool	TEST_SDP_WRITE_SINGLE("a=tool", sdp->a_tool, 1);	//a=SendRecv	switch (sdp->a_SendRecieve) {	case 1:		TEST_SDP_WRITE_SINGLE("a=", "recvonly", 0);		break;	case 2:		TEST_SDP_WRITE_SINGLE("a=", "sendonly", 0);		break;	case 3:		TEST_SDP_WRITE_SINGLE("a=", "sendrecv", 0);		break;	default:		break;	}	//a=type	TEST_SDP_WRITE_SINGLE("a=type", sdp->a_type, 1);	//a=charset	TEST_SDP_WRITE_SINGLE("a=charset", sdp->a_charset, 1);	//a=sdplang	TEST_SDP_WRITE_SINGLE("a=sdplang", sdp->a_sdplang, 1);	//a=lang	TEST_SDP_WRITE_SINGLE("a=lang", sdp->a_lang, 1);	//the rest	i=0;	while ((att = (GF_X_Attribute*)gf_list_enum(sdp->Attributes, &i))) {		SDP_WRITE_ALLOC_STR("a=", 0);		SDP_WRITE_ALLOC_STR(att->Name, 0);		if (att->Value) {			SDP_WRITE_ALLOC_STR(":", 0);			SDP_WRITE_ALLOC_STR(att->Value, 0);		}		SDP_WRITE_ALLOC_STR("\r\n", 0);	}	//now write media specific	i=0;	while ((media = (GF_SDPMedia*)gf_list_enum(sdp->media_desc, &i))) {		//m=		SDP_WRITE_ALLOC_STR("m=", 0);		switch (media->Type) {		case 1:			SDP_WRITE_ALLOC_STR("video", 1);			break;		case 2:			SDP_WRITE_ALLOC_STR("audio", 1);			break;		case 3:			SDP_WRITE_ALLOC_STR("data", 1);			break;		case 4:			SDP_WRITE_ALLOC_STR("control", 1);			break;		default:			SDP_WRITE_ALLOC_STR("application", 1);			break;		}		SDP_WRITE_ALLOC_INT(media->PortNumber, 0, 0);		if (media->NumPorts >= 2) {			SDP_WRITE_ALLOC_STR("/", 0);			SDP_WRITE_ALLOC_INT(media->NumPorts, 1, 0);		} else {			SDP_WRITE_ALLOC_STR(" ", 0);		}		SDP_WRITE_ALLOC_STR(media->Profile, 1);		SDP_WRITE_ALLOC_STR(media->fmt_list, 0);		j=0;		while ((map = (GF_RTPMap*)gf_list_enum(media->RTPMaps, &j))) {			SDP_WRITE_ALLOC_STR(" ", 0);			SDP_WRITE_ALLOC_INT(map->PayloadType, 0, 0);		}		SDP_WRITE_ALLOC_STR("\r\n", 0);		//c=		j=0;		while ((conn = (GF_SDPConnection*)gf_list_enum(media->Connections, &j))) {			SDP_WRITE_CONN(conn);		}		//k=		if (media->k_method) {			SDP_WRITE_ALLOC_STR("k=", 0);			SDP_WRITE_ALLOC_STR(media->k_method, 0);			if (media->k_key) {				SDP_WRITE_ALLOC_STR(":", 0);				SDP_WRITE_ALLOC_STR(media->k_key, 0);			}			SDP_WRITE_ALLOC_STR("\r\n", 0);		}		//b		j=0;		while ((bw = (GF_SDPBandwidth*)gf_list_enum(media->Bandwidths, &j))) {			SDP_WRITE_ALLOC_STR("b=", 0);			SDP_WRITE_ALLOC_STR(bw->name, 0);			SDP_WRITE_ALLOC_STR(":", 0);			SDP_WRITE_ALLOC_INT(bw->value, 0, 0);			SDP_WRITE_ALLOC_STR("\r\n", 0);		}		//a=rtpmap		j=0;		while ((map = (GF_RTPMap*)gf_list_enum(media->RTPMaps, &j))) {			SDP_WRITE_ALLOC_STR("a=rtpmap", 0);			SDP_WRITE_ALLOC_STR(":", 0);			SDP_WRITE_ALLOC_INT(map->PayloadType, 1, 0);			SDP_WRITE_ALLOC_STR(map->payload_name, 0);			SDP_WRITE_ALLOC_STR("/", 0);			SDP_WRITE_ALLOC_INT(map->ClockRate, 0, 0);			if (map->AudioChannels > 1) {				SDP_WRITE_ALLOC_STR("/", 0);				SDP_WRITE_ALLOC_INT(map->AudioChannels, 0, 0);			}			SDP_WRITE_ALLOC_STR("\r\n", 0);		}		//a=fmtp		j=0;		while ((fmtp = (GF_SDP_FMTP*)gf_list_enum(media->FMTP, &j))) {			SDP_WRITE_ALLOC_STR("a=fmtp:", 0);			SDP_WRITE_ALLOC_INT(fmtp->PayloadType, 1 , 0);			k=0;			while ((att = (GF_X_Attribute*)gf_list_enum(fmtp->Attributes, &k)) ) {				if (k>1) SDP_WRITE_ALLOC_STR(";", 0);				SDP_WRITE_ALLOC_STR(att->Name, 0);				if (att->Value) {					SDP_WRITE_ALLOC_STR("=", 0);					SDP_WRITE_ALLOC_STR(att->Value, 0);				}			}			SDP_WRITE_ALLOC_STR("\r\n", 0);		}		//a=ptime		if (media->PacketTime) {			SDP_WRITE_ALLOC_STR("a=ptime:", 0);			SDP_WRITE_ALLOC_INT(media->PacketTime, 0, 0);			SDP_WRITE_ALLOC_STR("\r\n", 0);		}		//a=FrameRate		if (media->Type == 1 && media->FrameRate) {			SDP_WRITE_ALLOC_STR("a=framerate:", 0);			SDP_WRITE_ALLOC_FLOAT(media->FrameRate, 0);			SDP_WRITE_ALLOC_STR("\r\n", 0);		}		//a=SendRecv		switch (media->SendRecieve) {		case 1:			TEST_SDP_WRITE_SINGLE("a=", "recvonly", 0);			break;		case 2:			TEST_SDP_WRITE_SINGLE("a=", "sendonly", 0);			break;		case 3:			TEST_SDP_WRITE_SINGLE("a=", "sendrecv", 0);			break;		default:			break;		}		//a=orient		TEST_SDP_WRITE_SINGLE("a=orient", media->orientation, 1);		//a=sdplang		TEST_SDP_WRITE_SINGLE("a=sdplang", media->sdplang, 1);		//a=lang		TEST_SDP_WRITE_SINGLE("a=lang", media->lang, 1);		//a=quality		if (media->Quality >= 0) {			SDP_WRITE_ALLOC_STR("a=quality:", 0);			SDP_WRITE_ALLOC_INT(media->Quality, 0, 0);			SDP_WRITE_ALLOC_STR("\r\n", 0);		}				//the rest		j=0;		while ((att = (GF_X_Attribute*)gf_list_enum(media->Attributes, &j))) {			SDP_WRITE_ALLOC_STR("a=", 0);			SDP_WRITE_ALLOC_STR(att->Name, 0);			if (att->Value) {				SDP_WRITE_ALLOC_STR(":", 0);				SDP_WRITE_ALLOC_STR(att->Value, 0);			}			SDP_WRITE_ALLOC_STR("\r\n", 0);		}	}	//finally realloc	//finall NULL char	pos += 1;	buf = (char *)realloc(buf, pos);	*out_str_buf = buf;	return GF_OK;}	

⌨️ 快捷键说明

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