Exemple #1
0
static Bool RP_CanHandleURLInService(GF_InputService *plug, const char *url)
{
	RTSPSession *sess;
	RTPClient *priv = (RTPClient *)plug->priv;

	if (strstr(url, "data:application/mpeg4-od-au;base64")
		|| strstr(url, "data:application/mpeg4-bifs-au;base64")
		|| strstr(url, "data:application/mpeg4-es-au;base64")
		) return 1;

	if (url[0]=='#') {
		Bool st_type = 0;
		if (!stricmp(url, "#video")) st_type = GF_STREAM_VISUAL;
		else if (!stricmp(url, "#audio")) st_type = GF_STREAM_AUDIO;

		if (st_type) {
			u32 i=0;
			RTPStream *st;
			while ((st = (RTPStream *)gf_list_enum(priv->channels, &i))) {
				if (st->depacketizer && (st->depacketizer->sl_map.StreamType==st_type))
					return 1;
			}
		}
		return 0;
	} else if (!RP_CanHandleURL(plug, url)) {
		return 0;
	}
	/*if this URL is part of a running session then ok*/
	sess = RP_CheckSession(priv, (char *) url);
	if (sess) return 1;
	return 0;
}
Exemple #2
0
GF_Err RP_AddStream(RTPClient *rtp, RTPStream *stream, char *session_control)
{
	Bool has_aggregated_control;
	char *service_name, *ctrl;
	RTSPSession *in_session = RP_CheckSession(rtp, session_control);

	has_aggregated_control = 0;
	if (session_control) {
		//if (!strcmp(session_control, "*")) session_control = NULL;
		if (session_control) has_aggregated_control = 1;
	}

	/*regular setup in an established session (RTSP DESCRIBE)*/
	if (in_session) {
		in_session->flags |= RTSP_AGG_CONTROL;
		stream->rtsp = in_session;
		gf_list_add(rtp->channels, stream);
		return GF_OK;
	}

	/*setup through SDP with control - assume this is RTSP and try to create a session*/
	if (stream->control) {
		/*stream control is relative to main session*/
		if (strnicmp(stream->control, "rtsp://", 7) && strnicmp(stream->control, "rtspu://", 7)) {
			/*locate session by control - if no control was provided for the session, use default
			session*/
			if (!in_session) in_session = RP_CheckSession(rtp, session_control ? session_control : "*");
			/*none found, try to create one*/
			if (!in_session) in_session = RP_NewSession(rtp, session_control);
			/*cannot add an RTSP session for this channel, check if multicast*/
//			if (!in_session && gf_rtp_is_unicast(stream->rtp_ch) ) return GF_SERVICE_ERROR;
		}
		/*stream control is absolute*/
		else {
			in_session = RP_CheckSession(rtp, stream->control);
			if (!in_session) in_session = RP_CheckSession(rtp, session_control);
			if (!in_session) {
				if (session_control && strstr(stream->control, session_control))
					in_session = RP_NewSession(rtp, session_control);
				else
					in_session = RP_NewSession(rtp, stream->control);
				if (!in_session) return GF_SERVICE_ERROR;
			}
			/*remove session control part from channel control*/
			service_name = gf_rtsp_get_service_name(in_session->session);
			ctrl = strstr(stream->control, service_name);
			if (ctrl && (strlen(ctrl) != strlen(service_name)) ) {
				ctrl += strlen(service_name) + 1;
				service_name = gf_strdup(ctrl);
				gf_free(stream->control);
				stream->control = service_name;
			}
		}
	}
	/*no control specified, assume this is multicast*/
	else {
		in_session = NULL;
	}

	if (in_session) {
		if (has_aggregated_control)
			in_session->flags |= RTSP_AGG_CONTROL;
	} else if (stream->control) {
		gf_free(stream->control);
		stream->control = NULL;
	}
	stream->rtsp = in_session;
	gf_list_add(rtp->channels, stream);
	return GF_OK;
}
Exemple #3
0
static GF_Err RP_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream)
{
	u32 ESID;
	RTPStream *ch;
	RTSPSession *sess;
	char *es_url;
	RTPClient *priv = (RTPClient *)plug->priv;
	if (upstream) return GF_NOT_SUPPORTED;


	GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP] Connecting channel @%08x - %s\n", channel, url));

	ch = RP_FindChannel(priv, channel, 0, (char *) url, 0);
	if (ch && (ch->status != RTP_Disconnected) ) return GF_SERVICE_ERROR;

	es_url = NULL;
	sess = NULL;
	if (strstr(url, "ES_ID=")) {
		sscanf(url, "ES_ID=%ud", &ESID);
		/*first case: simple URL (same namespace)*/
		ch = RP_FindChannel(priv, NULL, ESID, NULL, 0);
		/*this should not happen, the sdp must describe all streams in the service*/
		if (!ch) return GF_STREAM_NOT_FOUND;

		/*assign app channel*/
		ch->channel = channel;
		sess = ch->rtsp;
	}
	/*rtsp url - create a session if needed*/
	else if (!strnicmp(url, "rtsp://", 7) || !strnicmp(url, "rtspu://", 8)) {
		sess = RP_CheckSession(priv, (char *) url);
		if (!sess) sess = RP_NewSession(priv, (char *) url);
		es_url = (char *) url;
	}
	/*data: url*/
	else if (strstr(url, "data:application/mpeg4-od-au;base64")
		|| strstr(url, "data:application/mpeg4-bifs-au;base64")
		|| strstr(url, "data:application/mpeg4-es-au;base64")
		) {

		GF_SAFEALLOC(ch, RTPStream);
		ch->control = gf_strdup(url);
		ch->owner = priv;
		ch->channel = channel;
		ch->status = RTP_Connected;
		/*register*/
		gf_list_add(priv->channels, ch);
		RP_ConfirmChannelConnect(ch, GF_OK);

		return GF_OK;
	}
	/*session migration resume - don't send data to the server*/
	if (ch->status==RTP_SessionResume) {
		ch->flags |= RTP_CONNECTED;
		RP_InitStream(ch, 0);
		RP_ConfirmChannelConnect(ch, GF_OK);
		return GF_OK;
	}
	/*send a DESCRIBE (not a setup) on the channel. If the channel is already created then the
	describe is skipped and a SETUP is sent directly, otherwise the channel is first described then setup*/
	if (sess) RP_Describe(sess, es_url, channel);
	/*otherwise confirm channel connection*/
	else RP_ConfirmChannelConnect(ch, GF_OK);

	return GF_OK;
}