Beispiel #1
0
u32 RP_Thread(void *param)
{
	u32 i;
	GF_NetworkCommand com;
	RTSPSession *sess;
	RTPStream *ch;
	RTPClient *rtp = (RTPClient *)param;

	rtp->th_state = 1;
	com.command_type = GF_NET_CHAN_BUFFER_QUERY;
	while (rtp->th_state) {
		gf_mx_p(rtp->mx);

		/*fecth data on udp*/
		i=0;
		while ((ch = (RTPStream *)gf_list_enum(rtp->channels, &i))) {
			if ((ch->flags & RTP_EOS) || (ch->status!=RTP_Running) ) continue;
			/*for interleaved channels don't read too fast, query the buffer occupancy*/
			if (ch->flags & RTP_INTERLEAVED) {
				com.base.on_channel = ch->channel;
				gf_term_on_command(rtp->service, &com, GF_OK);
				/*if no buffering, use a default value (3 sec of data should do it)*/
				if (!com.buffer.max) com.buffer.max = 3000;
				if (com.buffer.occupancy <= com.buffer.max) ch->rtsp->flags |= RTSP_TCP_FLUSH;
			} else {
				RP_ReadStream(ch);
			}
		}

		/*and process commands / flush TCP*/
		i=0;
		while ((sess = (RTSPSession *)gf_list_enum(rtp->sessions, &i))) {
			RP_ProcessCommands(sess);

			if (sess->connect_error) {
				gf_term_on_connect(sess->owner->service, NULL, sess->connect_error);
				sess->connect_error = 0;
			}

		}

		gf_mx_v(rtp->mx);

		gf_sleep(1);
	}

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

	rtp->th_state = 2;
	return 0;
}
Beispiel #2
0
static GF_Err AC3_CloseService(GF_InputService *plug)
{
	AC3Reader *read = plug->priv;
	if (read->stream) fclose(read->stream);
	read->stream = NULL;
	if (read->dnload) gf_term_download_del(read->dnload);
	read->dnload = NULL;

	if (read->data) gf_free(read->data);
	read->data = NULL;
	gf_term_on_disconnect(read->service, NULL, GF_OK);
	return GF_OK;
}
Beispiel #3
0
static GF_Err M2TS_CloseService(GF_InputService *plug)
{
    M2TSIn *m2ts = plug->priv;
    GF_M2TS_Demuxer* ts = m2ts->ts;

    TSDemux_CloseDemux(ts);


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

    gf_term_on_disconnect(m2ts->service, NULL, GF_OK);
    return GF_OK;
}
Beispiel #4
0
static GF_Err SAF_CloseService(GF_InputService *plug)
{
	SAFIn *read = (SAFIn *)plug->priv;

	if (read->th) {
		if (read->run_state == 1) {
			read->run_state=0;
			while (read->run_state!=2) gf_sleep(2);
		}
		gf_th_del(read->th);
		read->th = NULL;
	}

	if (read->stream) fclose(read->stream);
	read->stream = NULL;
	if (read->dnload) gf_term_download_del(read->dnload);
	read->dnload = NULL;
	gf_term_on_disconnect(read->service, NULL, GF_OK);
	return GF_OK;
}
Beispiel #5
0
static GF_Err TTIn_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
{
    GF_Err e;
    TTIn *tti = (TTIn *)plug->priv;
    if (!plug || !url)
        return GF_BAD_PARAM;
    tti->service = serv;

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

    /*remote fetch*/
    if (!TTIn_is_local(url)) {
        TTIn_download_file(plug, url);
        return GF_OK;
    }
    e = TTIn_LoadFile(plug, url, 0);
    gf_term_on_connect(serv, NULL, e);
    if (!e && !tti->od_done) tti_setup_object(tti);
    return GF_OK;
}
Beispiel #6
0
GF_Err ISOR_CloseService(GF_InputService *plug)
{
    GF_Err reply;
    ISOMReader *read;
    if (!plug || !plug->priv) return GF_SERVICE_ERROR;
    read = (ISOMReader *) plug->priv;
    reply = GF_OK;

    if (read->mov) gf_isom_close(read->mov);
    read->mov = NULL;

    while (gf_list_count(read->channels)) {
        ISOMChannel *ch = (ISOMChannel *)gf_list_get(read->channels, 0);
        gf_list_rem(read->channels, 0);
        isor_delete_channel(read, ch);
    }

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

    gf_term_on_disconnect(read->service, NULL, reply);
    return GF_OK;
}
Beispiel #7
0
static GF_Err VTT_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
{
	GF_Err e;
	VTTIn *vttin = (VTTIn *)plug->priv;
        if (!plug || !url)
          return GF_BAD_PARAM;
	vttin->service = serv;

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

	/*remote fetch*/
	if (!VTT_is_local(url)) {
		VTT_download_file(plug, url);
		return GF_OK;
	} else {
		e = GF_OK;
		//e = TTIn_LoadFile(plug, url, 0);
		gf_term_on_connect(serv, NULL, e);
		//if (!e && !vttin->od_done) tti_setup_object(vttin);
	}
	return GF_OK;
}
Beispiel #8
0
static GF_Err MP3_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
{
	char szURL[2048];
	u32 minSizeToRead = 0;
	char *ext;
	GF_Err reply;
	MP3Reader *read = plug->priv;
	read->service = serv;

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

	strcpy(szURL, url);
	ext = strrchr(szURL, '#');
	if (ext) ext[0] = 0;

	/*remote fetch*/
	read->is_remote = !mp3_is_local(szURL);
	if (read->is_remote) {
		mp3_download_file(plug, (char *) szURL);
		return GF_OK;
	}

	reply = GF_OK;
	read->stream = gf_f64_open(szURL, "rb");
	if (!read->stream) {
		reply = GF_URL_ERROR;
	} else if (!MP3_ConfigureFromFile(read, &minSizeToRead)) {
		fclose(read->stream);
		read->stream = NULL;
		reply = GF_NOT_SUPPORTED;
	}
	gf_term_on_connect(serv, NULL, reply);
	if (!reply) mp3_setup_object(read);
	return GF_OK;
}
Beispiel #9
0
static GF_Err SAF_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
{
	char szURL[2048];
	char *ext;
	SAFIn *read = (SAFIn *)plug->priv;
	read->service = serv;

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

	strcpy(szURL, url);
	ext = strrchr(szURL, '#');
	if (ext) ext[0] = 0;

	read->needs_connection = 1;
	read->duration = 0;

	read->saf_type = SAF_FILE_LOCAL;
	/*remote fetch*/
	if (strnicmp(url, "file://", 7) && strstr(url, "://")) {
		read->saf_type = SAF_FILE_REMOTE;
		SAF_DownloadFile(plug, (char *) szURL);
		return GF_OK;
	}

	read->stream = gf_f64_open(szURL, "rb");
	if (!read->stream) {
		gf_term_on_connect(serv, NULL, GF_URL_ERROR);
		return GF_OK;
	}
	SAF_CheckFile(read);
	read->th = gf_th_new("SAFDemux");
	/*start playing for tune-in*/
	gf_th_run(read->th, SAF_Run, read);
	return GF_OK;
}
Beispiel #10
0
void mpdin_dash_io_del(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
{
	gf_term_download_del((GF_DownloadSession *)session);
}
Beispiel #11
0
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;
}
Beispiel #12
0
void RP_SaveSessionState(RTPClient *rtp)
{
	GF_Err e;
	char *sdp_buf;
	const char *opt;
	GF_X_Attribute*att;
	u32 i, j;
	GF_SDPInfo *sdp;
	RTSPSession *sess = NULL;

	if (!rtp->session_state_data) return;

	sdp_buf = rtp->session_state_data + strlen("data:application/sdp,");
	sdp = gf_sdp_info_new();
	e = gf_sdp_info_parse(sdp, sdp_buf, (u32) strlen(sdp_buf) );

	for (i=0; i<gf_list_count(rtp->channels); i++) {
		GF_SDPMedia *media = NULL;
		RTPStream *ch = gf_list_get(rtp->channels, i);
		if (!ch->control) continue;

		for (j=0; j<gf_list_count(sdp->media_desc); j++) {
			u32 k;
			GF_SDPMedia *med = (GF_SDPMedia*)gf_list_get(sdp->media_desc, j);

			for (k=0; k<gf_list_count(med->Attributes); k++) {
				att = (GF_X_Attribute*)gf_list_get(med->Attributes, k);
				if (!stricmp(att->Name, "control") && (strstr(att->Value, ch->control)!=NULL) ) {
					media = med;
					break;
				}
			}
			if (media)
				break;
		}
		if (!media) continue;

		if (ch->rtp_ch->net_info.IsUnicast) {
			char szPorts[4096];
			u16 porta, portb;
			media->PortNumber = ch->rtp_ch->net_info.client_port_first;

			/*remove x-server-port extension*/
			for (j=0; j<gf_list_count(media->Attributes); j++) {
				att = (GF_X_Attribute*)gf_list_get(media->Attributes, j);
				if (!stricmp(att->Name, "x-stream-state") ) {
					gf_free(att->Name);
					gf_free(att->Value);
					gf_free(att);
					gf_list_rem(media->Attributes, j);
				}
			}
			ch->current_start += gf_rtp_get_current_time(ch->rtp_ch);

			GF_SAFEALLOC(att, GF_X_Attribute);
			att->Name = gf_strdup("x-stream-state");
			porta = ch->rtp_ch->net_info.port_first ? ch->rtp_ch->net_info.port_first : ch->rtp_ch->net_info.client_port_first;
			portb = ch->rtp_ch->net_info.port_last ? ch->rtp_ch->net_info.port_last : ch->rtp_ch->net_info.client_port_last;

			sprintf(szPorts, "server-port=%d-%d;ssrc=%X;npt=%g;seq=%d;rtptime=%d",
				porta,
				portb,
				ch->rtp_ch->SenderSSRC,
				ch->current_start,
				ch->rtp_ch->rtp_first_SN,
				ch->rtp_ch->rtp_time
			);
			att->Value = gf_strdup(szPorts);
			gf_list_add(media->Attributes, att);

			if (ch->rtsp)
				sess = ch->rtsp;
		} else {
			media->PortNumber = ch->rtp_ch->net_info.port_first;
		}

	}
	/*remove x-server-port/x-session-id extension*/
	for (j=0; j<gf_list_count(sdp->Attributes); j++) {
		att = (GF_X_Attribute*)gf_list_get(sdp->Attributes, j);
		if (!stricmp(att->Name, "x-session-id") || !stricmp(att->Name, "x-session-name")
		) {
			gf_free(att->Name);
			gf_free(att->Value);
			gf_free(att);
			gf_list_rem(sdp->Attributes, j);
		}
	}
	if (sess) {
		char szURL[4096];

		if (sess->session_id) {
			GF_SAFEALLOC(att, GF_X_Attribute);
			att->Name = gf_strdup("x-session-id");
			att->Value = gf_strdup(sess->session_id);
			gf_list_add(sdp->Attributes, att);
		}

		GF_SAFEALLOC(att, GF_X_Attribute);
		att->Name = gf_strdup("x-session-name");
		sprintf(szURL, "rtsp://%s:%d/%s", sess->session->Server, sess->session->Port, sess->session->Service);
		att->Value = gf_strdup(szURL);
		gf_list_add(sdp->Attributes, att);
	}

	gf_free(rtp->session_state_data);
	sdp_buf = NULL;
	gf_sdp_info_write(sdp, &sdp_buf);
	if (sdp_buf) {
		rtp->session_state_data = gf_malloc(sizeof(char) * (strlen("data:application/sdp,") + strlen(sdp_buf) + 1) );
		strcpy(rtp->session_state_data, "data:application/sdp,");
		strcat(rtp->session_state_data, sdp_buf);
		gf_free(sdp_buf);
	}


	gf_sdp_info_del(sdp);


	opt = (char *) gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(rtp->service), "Streaming", "SessionMigrationServer");
	if (opt) {
		if (rtp->dnload) gf_term_download_del(rtp->dnload);
		rtp->dnload = NULL;

		if (strnicmp(opt, "http://", 7)) {
			rtp->dnload = gf_term_download_new(rtp->service, opt, GF_NETIO_SESSION_NOT_THREADED, MigrateSDP_NetIO, rtp);
			while (1) {
				char buffer[100];
				u32 read;
				e = gf_dm_sess_fetch_data(rtp->dnload, buffer, 100, &read);
				if (e && (e!=GF_IP_NETWORK_EMPTY)) break;
			}
			gf_term_download_del(rtp->dnload);
			rtp->dnload = NULL;
		} else {
			FILE *f = gf_f64_open(opt, "wt");
			if (f) {
				sdp_buf = rtp->session_state_data + strlen("data:application/sdp,");
				gf_fwrite(sdp_buf, 1, strlen(sdp_buf), f);
				fclose(f);
			} else {
				e = GF_IO_ERR;
			}
		}
		if (e<0) {
			gf_term_on_message(sess->owner->service, e, "Error saving session state");
		}
	}
}
Beispiel #13
0
GF_Err DC_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url)
{
	DCReader *read = (DCReader *) plug->priv;
	FILE *test;
	char *tmp, *ext;

	if (!read || !serv || !url) return GF_BAD_PARAM;

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

	read->url = gf_strdup(url);
	ext = strchr(read->url, '#');
	if (ext) {
		char *anext;
		ext[0] = 0;
		anext = strrchr(read->url, '.');
		ext[0] = '#';
		ext = anext;
	} else {
		ext = strrchr(read->url, '.');
	}
	if (ext && !stricmp(ext, ".gz")) {
		char *anext;
		ext[0] = 0;
		anext = strrchr(read->url, '.');
		ext[0] = '.';
		ext = anext;
	}
	read->service = serv;

	if (ext) {
		char *cgi_par = NULL;
		ext += 1;
		if (ext) {
			tmp = strchr(ext, '#'); if (tmp) tmp[0] = 0;
			/* Warning the '?' sign should not be present in local files but it is convenient to have it
			   to test web content locally */
			cgi_par = strchr(ext, '?'); if (cgi_par) cgi_par[0] = 0;
		}
		if (!stricmp(ext, "bt") || !stricmp(ext, "btz") || !stricmp(ext, "bt.gz")
			|| !stricmp(ext, "xmta")
			|| !stricmp(ext, "xmt") || !stricmp(ext, "xmt.gz") || !stricmp(ext, "xmtz")
			|| !stricmp(ext, "wrl") || !stricmp(ext, "wrl.gz")
			|| !stricmp(ext, "x3d") || !stricmp(ext, "x3d.gz") || !stricmp(ext, "x3dz")
			|| !stricmp(ext, "x3dv") || !stricmp(ext, "x3dv.gz") || !stricmp(ext, "x3dvz")
			|| !stricmp(ext, "swf")
			)
			read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC;

		else if (!stricmp(ext, "svg") || !stricmp(ext, "svgz") || !stricmp(ext, "svg.gz")) {
			read->oti = GPAC_OTI_PRIVATE_SCENE_SVG;
		}
		/*XML LASeR*/
		else if (!stricmp(ext, "xsr"))
			read->oti = GPAC_OTI_PRIVATE_SCENE_LASER;
		else if (!stricmp(ext, "xbl"))
			read->oti = GPAC_OTI_PRIVATE_SCENE_XBL;
		else if (!stricmp(ext, "wgt") || !stricmp(ext, "mgt"))
			read->oti = GPAC_OTI_PRIVATE_SCENE_WGT;

		if (cgi_par) cgi_par[0] = '?';
	}

	if (!read->oti && (!strnicmp(url, "file://", 7) || !strstr(url, "://"))) {
		char *rtype = gf_xml_get_root_type(url, NULL);
		if (rtype) {
			if (!strcmp(rtype, "SAFSession")) read->oti = GPAC_OTI_PRIVATE_SCENE_LASER;
			else if (!strcmp(rtype, "svg")) read->oti = GPAC_OTI_PRIVATE_SCENE_SVG;
			else if (!strcmp(rtype, "XMT-A")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC;
			else if (!strcmp(rtype, "X3D")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC;
			else if (!strcmp(rtype, "bindings")) read->oti = GPAC_OTI_PRIVATE_SCENE_XBL;
			else if (!strcmp(rtype, "widget")) read->oti = GPAC_OTI_PRIVATE_SCENE_WGT;
			gf_free(rtype);
		}
	}

	/*remote fetch*/
	if (!strnicmp(url, "file://", 7)) {
		url += 7;
	}
	else if (strstr(url, "://")) {
		DC_DownloadFile(plug, read->url);
		return GF_OK;
	}

	test = gf_f64_open(read->url, "rt");
	if (!test) {
		gf_term_on_connect(serv, NULL, GF_URL_ERROR);
		return GF_OK;
	}
	fclose(test);
	if (!read->is_service_connected) {
		gf_term_on_connect(serv, NULL, GF_OK);
		read->is_service_connected = 1;
	}
	return GF_OK;
}
Beispiel #14
0
void m2ts_net_io(void *cbk, GF_NETIO_Parameter *param)
{
	GF_Err e;
	M2TSIn *m2ts = (M2TSIn *) cbk;
	assert( m2ts );
	/*handle service message*/
	gf_term_download_update_stats(m2ts->ts->dnload);

	if (param->msg_type==GF_NETIO_DATA_TRANSFERED) {
		e = GF_EOS;
	} else if (param->msg_type==GF_NETIO_DATA_EXCHANGE) {
		e = GF_OK;
		assert( m2ts->ts);
		if (param->size > 0){
			/*process chunk*/
			assert(param->data);
			if (m2ts->network_buffer_size < param->size){
				m2ts->network_buffer = gf_realloc(m2ts->network_buffer, sizeof(char) * param->size);
				m2ts->network_buffer_size = param->size;
			}
			assert( m2ts->network_buffer );
			memcpy(m2ts->network_buffer, param->data, param->size);
			gf_m2ts_process_data(m2ts->ts, m2ts->network_buffer, param->size);
		}

		/*if asked to regulate, wait until we get a play request*/
		if (m2ts->ts->run_state && !m2ts->ts->nb_playing && (m2ts->ts->file_regulate==1)) {
			while (m2ts->ts->run_state && !m2ts->ts->nb_playing && (m2ts->ts->file_regulate==1) ) {
				gf_sleep(50);
				continue;
			}
		} else {
			gf_sleep(1);
		}
#if 1 //see commit 3642: crashes when reload quickly with http
		if (!m2ts->ts->run_state) {
			if (m2ts->ts->dnload)
				gf_term_download_del( m2ts->ts->dnload );
			m2ts->ts->dnload = NULL;
		}
#endif

	} else {
		e = param->error;
	}

	switch (e){
	  case GF_EOS:
		  if (!m2ts->is_connected) {
			  gf_term_on_connect(m2ts->service, NULL, GF_OK);
		  }
		  return;
	  case GF_OK:
		  return;
	  default:
		  if (!m2ts->ts_setup) {
			  m2ts->ts_setup = 1;
		  }
		  GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER,("[MPEGTSIn] : Error while getting data : %s\n", gf_error_to_string(e)));
		  gf_term_on_connect(m2ts->service, NULL, e);
	}
}