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

📄 sdp.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / IETF RTP/RTSP/SDP sub-project * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include <gpac/ietf.h>#include <gpac/token.h>#define SDP_WRITE_STEPALLOC		2048GF_EXPORTGF_SDP_FMTP *gf_sdp_fmtp_new(){	GF_SDP_FMTP *tmp = (GF_SDP_FMTP*)malloc(sizeof(GF_SDP_FMTP));	tmp->PayloadType = 0;	tmp->Attributes = gf_list_new();	return tmp;}GF_EXPORTvoid gf_sdp_fmtp_del(GF_SDP_FMTP *fmtp){	GF_X_Attribute *att;	if (!fmtp) return;	while (gf_list_count(fmtp->Attributes)) {		att = (GF_X_Attribute*)gf_list_get(fmtp->Attributes, 0);		gf_list_rem(fmtp->Attributes, 0);		if (att->Name) free(att->Name);		if (att->Value) free(att->Value);		free(att);	}	gf_list_del(fmtp->Attributes);	free(fmtp);}GF_SDP_FMTP *SDP_GetFMTPForPayload(GF_SDPMedia *media, u32 PayloadType){	GF_SDP_FMTP *tmp;	u32 i;	if (!media) return NULL;	i=0;	while ((tmp = (GF_SDP_FMTP*)gf_list_enum(media->FMTP, &i))) {		if (tmp->PayloadType == PayloadType) return tmp;	}	return NULL;}void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media){	s32 pos;	u32 PayT;	char comp[3000];	GF_RTPMap *map;	GF_SDP_FMTP *fmtp;	GF_X_Attribute *att;	pos = gf_token_get(buffer, 0, " :\t\r\n", comp, 3000);	if (!strcmp(comp, "cat")) {		if (media) return;		pos = gf_token_get(buffer, pos, ":\t\r\n", comp, 3000);		sdp->a_cat = strdup(comp);		return;	}	if (!strcmp(comp, "keywds")) {		if (media) return;		pos = gf_token_get(buffer, pos, ":\t\r\n", comp, 3000);		sdp->a_keywds = strdup(comp);		return;	}	if (!strcmp(comp, "tool")) {		if (media) return;		pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000);		sdp->a_tool = strdup(comp);		return;	}	if (!strcmp(comp, "ptime")) {		if (!media) return;		pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000);		media->PacketTime = atoi(comp);		return;	}	if (!strcmp(comp, "recvonly")) {		if (!media) {			sdp->a_SendRecieve = 1;		} else {			media->SendRecieve = 1;		}		return;	}	if (!strcmp(comp, "sendonly")) {		if (!media) {			sdp->a_SendRecieve = 2;		} else {			media->SendRecieve = 2;		}		return;	}	if (!strcmp(comp, "sendrecv")) {		if (!media) {			sdp->a_SendRecieve = 3;		} else {			media->SendRecieve = 3;		}		return;	}	if (!strcmp(comp, "orient")) {		if (!media || media->Type) return;		pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000);		media->orientation = strdup(comp);		return;	}	if (!strcmp(comp, "type")) {		if (media) return;		pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000);		sdp->a_type = strdup(comp);		return;	}	if (!strcmp(comp, "charset")) {		if (media) return;		pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000);		sdp->a_charset = strdup(comp);		return;	}	if (!strcmp(comp, "sdplang")) {		pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000);		if (media) {			media->sdplang = strdup(comp);		} else {			sdp->a_sdplang = strdup(comp);		}		return;	}	if (!strcmp(comp, "lang")) {		pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000);		if (media) {			media->lang = strdup(comp);		} else {			sdp->a_lang = strdup(comp);		}		return;	}	if (!strcmp(comp, "framerate")) {		//only for video		if (!media || (media->Type != 1)) return;		pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000);		media->FrameRate = atof(comp);		return;	}	if (!strcmp(comp, "quality")) {		if (!media) return;		pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000);		media->Quality = atoi(comp);		return;	}	if (!strcmp(comp, "rtpmap")) {		if (!media) return;		map = (GF_RTPMap*)malloc(sizeof(GF_RTPMap));		pos = gf_token_get(buffer, pos, ": \r\n", comp, 3000);		map->PayloadType = atoi(comp);		pos = gf_token_get(buffer, pos, " /\r\n", comp, 3000);		map->payload_name = strdup(comp);		pos = gf_token_get(buffer, pos, " /\r\n", comp, 3000);		map->ClockRate = atoi(comp);		pos = gf_token_get(buffer, pos, " /\r\n", comp, 3000);		map->AudioChannels = (pos > 0) ? atoi(comp) : 0;		gf_list_add(media->RTPMaps, map);		return;	}	//FMTP	if (!strcmp(comp, "fmtp")) {		if (!media) return;		pos = gf_token_get(buffer, pos, ": \r\n", comp, 3000);		PayT = atoi(comp);		fmtp = SDP_GetFMTPForPayload(media, PayT);		if (!fmtp) {			fmtp = gf_sdp_fmtp_new();			fmtp->PayloadType = PayT;			gf_list_add(media->FMTP, fmtp);		}		while (1) {			pos = gf_token_get(buffer, pos, "; =\r\n", comp, 3000);			if (pos <= 0) break;			att = (GF_X_Attribute*)malloc(sizeof(GF_X_Attribute));			att->Name = strdup(comp);			att->Value = NULL;			pos ++;			pos = gf_token_get(buffer, pos, ";\r\n", comp, 3000);			if (pos > 0) att->Value = strdup(comp);			gf_list_add(fmtp->Attributes, att);		}		return;	}	//the rest cannot be discarded that way as it may be application-specific	//so keep it.	//a= <attribute> || <attribute>:<value>	//we add <attribute> <value> in case ...	pos = gf_token_get(buffer, 0, " :\r\n", comp, 3000);	att = (GF_X_Attribute*)malloc(sizeof(GF_X_Attribute));	att->Name = strdup(comp);	att->Value = NULL;	pos += 1;	if (buffer[pos] == ' ') pos += 1;	pos = gf_token_get(buffer, pos, "\r\n", comp, 3000);	if (pos > 0) att->Value = strdup(comp);	if (media) {		gf_list_add(media->Attributes, att);	} else {		gf_list_add(sdp->Attributes, att);	}}#define SDPM_DESTROY(p) if (media->p) free(media->p)GF_EXPORTvoid gf_sdp_media_del(GF_SDPMedia *media){	GF_SDPBandwidth *bw;	GF_RTPMap *map;	GF_SDPConnection *conn;	GF_SDP_FMTP *fmtp;	GF_X_Attribute *att;	if (!media) return;	while (gf_list_count(media->FMTP)) {		fmtp = (GF_SDP_FMTP*)gf_list_get(media->FMTP, 0);		gf_list_rem(media->FMTP, 0);		gf_sdp_fmtp_del(fmtp);	}	gf_list_del(media->FMTP);	while (gf_list_count(media->Attributes)) {		att = (GF_X_Attribute*)gf_list_get(media->Attributes, 0);		gf_list_rem(media->Attributes, 0);		if (att->Name) free(att->Name);		if (att->Value) free(att->Value);		free(att);	}	gf_list_del(media->Attributes);	while (gf_list_count(media->RTPMaps)) {		map = (GF_RTPMap*)gf_list_get(media->RTPMaps, 0);		free(map->payload_name);		free(map);		gf_list_rem(media->RTPMaps, 0);	}	gf_list_del(media->RTPMaps);		while (gf_list_count(media->Connections)) {		conn = (GF_SDPConnection*)gf_list_get(media->Connections, 0);		gf_list_rem(media->Connections, 0);		gf_sdp_conn_del(conn);	}	gf_list_del(media->Connections);	while (gf_list_count(media->Bandwidths)) {		bw = (GF_SDPBandwidth*)gf_list_get(media->Bandwidths, 0);		gf_list_rem(media->Bandwidths, 0);		if (bw->name) free(bw->name);		free(bw);	}	gf_list_del(media->Bandwidths);	SDPM_DESTROY(orientation);	SDPM_DESTROY(sdplang);	SDPM_DESTROY(lang);	SDPM_DESTROY(Profile);	SDPM_DESTROY(fmt_list);	SDPM_DESTROY(k_method);	SDPM_DESTROY(k_key);	free(media);}GF_EXPORTGF_SDPConnection *gf_sdp_conn_new(){	GF_SDPConnection *conn;	GF_SAFEALLOC(conn, GF_SDPConnection);	conn->TTL = -1;	return conn;}GF_EXPORTvoid gf_sdp_conn_del(GF_SDPConnection *conn){	if (conn->add_type) free(conn->add_type);	if (conn->host) free(conn->host);	if (conn->net_type) free(conn->net_type);	free(conn);}GF_EXPORTGF_SDPMedia *gf_sdp_media_new(){	GF_SDPMedia *tmp;	GF_SAFEALLOC(tmp, GF_SDPMedia);	tmp->FMTP = gf_list_new();	tmp->RTPMaps = gf_list_new();	tmp->Attributes = gf_list_new();	tmp->Connections = gf_list_new();	tmp->Bandwidths = gf_list_new();	tmp->Quality = -1;	return tmp;}GF_EXPORTGF_SDPInfo *gf_sdp_info_new(){	GF_SDPInfo *sdp;	GF_SAFEALLOC(sdp, GF_SDPInfo);	sdp->b_bandwidth = gf_list_new();	sdp->media_desc = gf_list_new();	sdp->Attributes = gf_list_new();	sdp->Timing = gf_list_new();	return sdp;}#define SDP_DESTROY(p) if (sdp->p)	\					free(sdp->p);	\					sdp->p = NULL;GF_EXPORTvoid gf_sdp_info_reset(GF_SDPInfo *sdp){	GF_SDPBandwidth *bw;	GF_SDPMedia *media;	GF_SDPTiming *timing;	GF_X_Attribute *att;	if (!sdp) return;		while (gf_list_count(sdp->media_desc)) {		media = (GF_SDPMedia*)gf_list_get(sdp->media_desc, 0);		gf_list_rem(sdp->media_desc, 0);		gf_sdp_media_del(media);	}	while (gf_list_count(sdp->Attributes)) {		att = (GF_X_Attribute*)gf_list_get(sdp->Attributes, 0);		gf_list_rem(sdp->Attributes, 0);		if (att->Name) free(att->Name);		if (att->Value) free(att->Value);		free(att);	}	while (gf_list_count(sdp->b_bandwidth)) {		bw = (GF_SDPBandwidth*)gf_list_get(sdp->b_bandwidth, 0);		gf_list_rem(sdp->b_bandwidth, 0);		if (bw->name) free(bw->name);		free(bw);	}	while (gf_list_count(sdp->Timing)) {		timing = (GF_SDPTiming*)gf_list_get(sdp->Timing, 0);		gf_list_rem(sdp->Timing, 0);		free(timing);	}	//then delete all info ...	SDP_DESTROY(o_username);	SDP_DESTROY(o_session_id);	SDP_DESTROY(o_version);	SDP_DESTROY(o_address);	SDP_DESTROY(o_net_type);	SDP_DESTROY(o_add_type);	SDP_DESTROY(s_session_name);	SDP_DESTROY(i_description);	SDP_DESTROY(u_uri);	SDP_DESTROY(e_email);	SDP_DESTROY(p_phone);	SDP_DESTROY(k_method);	SDP_DESTROY(k_key);	SDP_DESTROY(a_cat);	SDP_DESTROY(a_keywds);	SDP_DESTROY(a_tool);	SDP_DESTROY(a_type);	SDP_DESTROY(a_charset);	SDP_DESTROY(a_sdplang);	SDP_DESTROY(a_lang);	if (sdp->c_connection) {		gf_sdp_conn_del(sdp->c_connection);		sdp->c_connection = NULL;	}	sdp->a_SendRecieve = 0;}GF_EXPORTvoid gf_sdp_info_del(GF_SDPInfo *sdp){		if (!sdp) return;	gf_sdp_info_reset(sdp);	gf_list_del(sdp->media_desc);	gf_list_del(sdp->Attributes);	gf_list_del(sdp->b_bandwidth);	gf_list_del(sdp->Timing);	free(sdp);}Bool SDP_IsDynamicPayload(GF_SDPMedia *media, char *payt){	u32 i;	GF_RTPMap *map;	char buf[10];	i=0;	while ((map = (GF_RTPMap*)gf_list_enum(media->RTPMaps, &i))) {		sprintf(buf, "%d", map->PayloadType);		if (!strcmp(payt, buf)) return 1;	}	return 0;}//translate h || m || d in sec. Fractions are not allowed with this writing s32 SDP_MakeSeconds(char *buf){	s32 sign;	char num[30], *test;	sign = 1;	if (buf[0] == '-') {		sign = -1;		buf += 1;	}	memset(num, 0, 30);	test = strstr(buf, "d");	if (test) {		strncpy(num, buf, strlen(buf)-strlen(test));		return (atoi(num)*sign*86400);	}	test = strstr(buf, "h");	if (test) {		strncpy(num, buf, strlen(buf)-strlen(test));		return (atoi(num)*sign*3600);	}	test = strstr(buf, "m");	if (test) {		strncpy(num, buf, strlen(buf)-strlen(test));		return (atoi(num)*sign*60);	}	return (atoi(buf) * sign);}GF_EXPORTGF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size){	GF_SDPBandwidth *bw;	GF_SDPConnection *conn;	GF_SDPMedia *media;	GF_SDPTiming *timing;	u32 i;	s32 pos, LinePos;	char LineBuf[3000], comp[3000];	media = NULL;	timing = NULL;	if (!sdp) return GF_BAD_PARAM;	//Clean SDP info	gf_sdp_info_reset(sdp);	LinePos = 0;	while (1) {		LinePos = gf_token_get_line(sdp_text, LinePos, text_size, LineBuf, 3000);		if (LinePos <= 0) break;		if (!strcmp(LineBuf, "\r\n") || !strcmp(LineBuf, "\n") || !strcmp(LineBuf, "\r")) continue;		switch (LineBuf[0]) {		case 'v':			pos = gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000);			sdp->Version = atoi(comp);			break;		case 'o':			pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000);			sdp->o_username = strdup(comp);			pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000);			sdp->o_session_id = strdup(comp);			pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000);			sdp->o_version = strdup(comp);						pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000);			sdp->o_net_type = strdup(comp);			pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000);			sdp->o_add_type = strdup(comp);			pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000);			sdp->o_address = strdup(comp);			break;		case 's':			pos = gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000);			sdp->s_session_name = strdup(comp);			break;		case 'i':			pos = gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000);			sdp->i_description = strdup(comp);			break;		case 'u':			pos = gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000);			sdp->u_uri = strdup(comp);			break;		case 'e':			pos = gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000);			sdp->e_email = strdup(comp);			break;		case 'p':			pos = gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000);			sdp->p_phone = strdup(comp);			break;		case 'c':			//if at session level, only 1 is allowed for all SDP			if (sdp->c_connection) break;						conn = gf_sdp_conn_new();			pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000);			conn->net_type = strdup(comp);						pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000);			conn->add_type = strdup(comp);			pos = gf_token_get(LineBuf, pos, " /\r\n", comp, 3000);			conn->host = strdup(comp);			if (gf_sk_is_multicast_address(conn->host)) {				//a valid SDP will have TTL if address is multicast				pos = gf_token_get(LineBuf, pos, "/\r\n", comp, 3000);				if (pos <= 0) {					gf_sdp_conn_del(conn);					break;				}				conn->TTL = atoi(comp);				//multiple address indication is only valid for media				pos = gf_token_get(LineBuf, pos, "/\r\n", comp, 3000);				if (pos > 0) {					if (!media) {						gf_sdp_conn_del(conn);						break;					}					conn->add_count = atoi(comp);				}			}			if (!media) 				sdp->c_connection = conn;			else 				gf_list_add(media->Connections, conn);			break;		case 'b':			pos = gf_token_get(LineBuf, 2, ":\r\n", comp, 3000);			if (strcmp(comp, "CT") && strcmp(comp, "AS") && (comp[0] != 'X')) break;

⌨️ 快捷键说明

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