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