예제 #1
0
파일: rtp_in.c 프로젝트: jnorthrup/gpac
GF_Err RP_ConnectServiceEx(GF_InputService *plug, GF_ClientService *serv, const char *url, Bool skip_migration)
{
	char *session_cache;
	RTSPSession *sess;
	RTPClient *priv = (RTPClient *)plug->priv;

	/*store user address*/
	priv->service = serv;

	if (priv->dnload) gf_term_download_del(priv->dnload);
	priv->dnload = NULL;

	GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] Opening service %s\n", url));

	/*load preferences*/
	RT_LoadPrefs(plug, priv);

	/*start thread*/
	gf_th_run(priv->th, RP_Thread, priv);

	if (!skip_migration) {
		session_cache = (char *) gf_modules_get_option((GF_BaseInterface *) plug, "Streaming", "SessionMigrationFile");
		if (session_cache && session_cache[0]) {
			FILE *f = gf_f64_open(session_cache, "rb");
			if (f) {
				fclose(f);
				GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] Restarting RTSP session from %s\n", session_cache));
				RP_FetchSDP(priv, (char *) session_cache, NULL, (char *) url);
				return GF_OK;
			}
			if (!strncmp(session_cache, "http://", 7)) {
				GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] Restarting RTSP session from %s\n", session_cache));
				RP_FetchSDP(priv, (char *) session_cache, NULL, (char *) url);
				return GF_OK;
			}
		}
	}


	/*local or remote SDP*/
	if (strstr(url, "data:application/sdp") || (strnicmp(url, "rtsp", 4) && strstr(url, ".sdp")) ) {
		RP_FetchSDP(priv, (char *) url, NULL, NULL);
		return GF_OK;
	}

	/*rtsp and rtsp over udp*/
	if (!strnicmp(url, "rtsp://", 7) || !strnicmp(url, "rtspu://", 8)) {
		char *the_url = gf_strdup(url);
		char *the_ext = strrchr(the_url, '#');
		if (the_ext) {
			if (!stricmp(the_ext, "#audio")) priv->media_type = GF_MEDIA_OBJECT_AUDIO;
			else if (!stricmp(the_ext, "#video")) priv->media_type = GF_MEDIA_OBJECT_VIDEO;
			the_ext[0] = 0;
		}
		sess = RP_NewSession(priv, (char *) the_url);
		gf_free(the_url);
		if (!sess) {
			gf_term_on_connect(serv, NULL, GF_NOT_SUPPORTED);
		} else {
			RP_Describe(sess, 0, NULL);
		}
		return GF_OK;
	}

	/*direct RTP (no control) or embedded data - this means the service is attached to a single channel (no IOD)
	reply right away*/
	gf_term_on_connect(serv, NULL, GF_OK);
	RP_SetupObjects(priv);
	return GF_OK;
}
예제 #2
0
파일: sdp_load.c 프로젝트: erelh/gpac
void RP_LoadSDP(RTPClient *rtp, char *sdp_text, u32 sdp_len, RTPStream *stream)
{
	GF_Err e;
	u32 i;
	GF_SDPInfo *sdp;
	Bool is_isma_1, has_iod;
	char *iod_str;
	GF_X_Attribute *att;

	is_isma_1 = 0;
	iod_str = NULL;
	sdp = gf_sdp_info_new();
	e = gf_sdp_info_parse(sdp, sdp_text, sdp_len);

	if (e == GF_OK) e = RP_SetupSDP(rtp, sdp, stream);

	/*root SDP, attach service*/
	if (! stream) {
		/*look for IOD*/
		if (e==GF_OK) {
			i=0;
			while ((att = (GF_X_Attribute*)gf_list_enum(sdp->Attributes, &i))) {
				if (!iod_str && !strcmp(att->Name, "mpeg4-iod") ) iod_str = att->Value;
				if (!is_isma_1 && !strcmp(att->Name, "isma-compliance") ) {
					if (!stricmp(att->Value, "1,1.0,1")) is_isma_1 = 1;
				}
			}

			/*force iod reconstruction with ISMA to use proper clock dependencies*/
			if (is_isma_1) iod_str = NULL;

			/*some folks have weird notions of MPEG-4 systems, they use hardcoded IOD
			with AAC ESD even when streaming AMR...*/
			if (iod_str) {
				RTPStream *ch;
				i=0;
				while ((ch = (RTPStream *)gf_list_enum(rtp->channels, &i))) {
					if ((ch->depacketizer->payt==GF_RTP_PAYT_AMR) || (ch->depacketizer->payt==GF_RTP_PAYT_AMR_WB) ) {
						iod_str = NULL;
						break;
					}
				}
			}
			if (!iod_str) {
				RTPStream *ch;
				Bool needs_iod = 0;
				i=0;
				while ((ch = (RTPStream *)gf_list_enum(rtp->channels, &i))) {
					if ((ch->depacketizer->payt==GF_RTP_PAYT_MPEG4) && (ch->depacketizer->sl_map.StreamType==GF_STREAM_SCENE)
//						|| ((ch->depacketizer->payt==GF_RTP_PAYT_3GPP_DIMS) && (ch->depacketizer->sl_map.StreamType==GF_STREAM_SCENE))
						) {
						needs_iod = 1;
						break;
					}
				}
				if (needs_iod) {
					rtp->session_desc = (GF_Descriptor *)RP_GetChannelOD(ch, 0);
				}
			}

			if (iod_str) e = RP_SDPLoadIOD(rtp, iod_str);
		}
		/*attach service*/
		has_iod = rtp->session_desc ? 1 : 0;
		gf_term_on_connect(rtp->service, NULL, e);
		if (!e && !has_iod && !rtp->media_type) RP_SetupObjects(rtp);
		rtp->media_type = 0;
	}
	/*channel SDP */
	else {
		if (e) {
			gf_term_on_connect(rtp->service, stream->channel, e);
			stream->status = RTP_Unavailable;
		} else {
			/*connect*/
			RP_SetupChannel(stream, NULL);
		}
	}
	/*store SDP for later session migration*/
	if (sdp) {
		char *buf=NULL;
		gf_sdp_info_write(sdp, &buf);
		if (buf) {
			rtp->session_state_data = gf_malloc(sizeof(char) * (strlen("data:application/sdp,") + strlen(buf) + 1) );
			strcpy(rtp->session_state_data, "data:application/sdp,");
			strcat(rtp->session_state_data, buf);
			gf_free(buf);
		}
		gf_sdp_info_del(sdp);
	}
}