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; }
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; }
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; }