Esempio n. 1
0
static void mpdin_dash_segment_netio(void *cbk, GF_NETIO_Parameter *param)
{
	GF_MPDGroup *group = (GF_MPDGroup *)cbk;

	if (param->msg_type == GF_NETIO_PARSE_HEADER) {
		if (!strcmp(param->name, "Dash-Newest-Segment")) {
			gf_dash_resync_to_segment(group->mpdin->dash, param->value, gf_dm_sess_get_header(param->sess, "Dash-Oldest-Segment") );
		}
	}

	if (param->msg_type == GF_NETIO_DATA_EXCHANGE) {
		group->has_new_data = 1;

		if (param->reply) {
			u32 bytes_per_sec;
			const char *url;
			gf_dm_sess_get_stats(group->sess, NULL, &url, NULL, NULL, &bytes_per_sec, NULL);
			GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] End of chunk received for %s at UTC "LLU" ms - estimated bandwidth %d kbps - chunk start at UTC "LLU"\n", url, gf_net_get_utc(), 8*bytes_per_sec/1000, gf_dm_sess_get_utc_start(group->sess)));

			if (group->mpdin->use_low_latency)
				MPD_NotifyData(group, 1);
		} else if (group->mpdin->use_low_latency==2) {
			MPD_NotifyData(group, 1);
		}

		if (group->mpdin->allow_http_abort)
			gf_dash_group_check_bandwidth(group->mpdin->dash, group->idx);
	}
	if (param->msg_type == GF_NETIO_DATA_TRANSFERED) {
		u32 bytes_per_sec;
		const char *url;
		gf_dm_sess_get_stats(group->sess, NULL, &url, NULL, NULL, &bytes_per_sec, NULL);
		GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("[MPD_IN] End of file %s download at UTC "LLU" ms - estimated bandwidth %d kbps - started file or last chunk at UTC "LLU"\n", url, gf_net_get_utc(), 8*bytes_per_sec/1000, gf_dm_sess_get_utc_start(group->sess)));
	}
}
Esempio n. 2
0
u32 mpdin_dash_io_get_total_size(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
{
	u32 size=0;
	GF_DownloadSession *sess = (GF_DownloadSession *)session;
    gf_dm_sess_get_stats((GF_DownloadSession *)session, NULL, NULL, &size, NULL, NULL, NULL);
	return size;
}
Esempio n. 3
0
u32 mpdin_dash_io_get_bytes_per_sec(GF_DASHFileIO *dashio, GF_DASHFileIOSession session)
{
	u32 bps=0;
	GF_DownloadSession *sess = (GF_DownloadSession *)session;
    gf_dm_sess_get_stats((GF_DownloadSession *)session, NULL, NULL, NULL, NULL, &bps, NULL);
	return bps;
}
Esempio n. 4
0
static GF_Err ISMA_GetGPAC_KMS(ISMAEAPriv *priv, GF_Channel *ch, const char *kms_url)
{
	GF_Err e;
	FILE *t;
	GF_DownloadSession * sess;
	if (!strnicmp(kms_url, "(ipmp)", 6)) return GF_NOT_SUPPORTED;
	else if (!strnicmp(kms_url, "(uri)", 5)) kms_url += 5;
	else if (!strnicmp(kms_url, "file://", 7)) kms_url += 7;

	e = GF_OK;
	/*try local*/
	t = (strstr(kms_url, "://") == NULL) ? gf_f64_open(kms_url, "r") : NULL;
	if (t) {
		fclose(t);
		return gf_ismacryp_gpac_get_info(ch->esd->ESID, (char *)kms_url, priv->key, priv->salt);
	}
	/*note that gpac doesn't have TLS support -> not really usefull. As a general remark, ISMACryp
	is supported as a proof of concept, crypto and IPMP being the last priority on gpac...*/
	GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[CENC/ISMA] Fetching ISMACryp key for channel %d\n", ch->esd->ESID) );

	sess = gf_term_download_new(ch->service, kms_url, 0, ISMA_KMS_NetIO, ch);
	if (!sess) return GF_IO_ERR;
	/*start our download (threaded)*/
	gf_dm_sess_process(sess);

	while (1) {
		e = gf_dm_sess_get_stats(sess, NULL, NULL, NULL, NULL, NULL, NULL);
		if (e) break;
	}
	if (e==GF_EOS) {
		e = gf_ismacryp_gpac_get_info(ch->esd->ESID, (char *) gf_dm_sess_get_cache_name(sess), priv->key, priv->salt);
	}
	gf_term_download_del(sess);
	return e;
}
Esempio n. 5
0
GF_EXPORT
void gf_service_download_update_stats(GF_DownloadSession * sess)
{
	GF_ClientService *serv;
	const char *szURI;
	u32 total_size, bytes_done, bytes_per_sec;
	GF_NetIOStatus net_status;

	if (!sess) return;

	gf_dm_sess_get_stats(sess, NULL, &szURI, &total_size, &bytes_done, &bytes_per_sec, &net_status);
	serv = (GF_ClientService *)gf_dm_sess_get_private(sess);
	switch (net_status) {
	case GF_NETIO_SETUP:
		gf_term_message(serv->term, serv->url, "Connecting", GF_OK);
		break;
	case GF_NETIO_CONNECTED:
		gf_term_message(serv->term, serv->url, "Connected", GF_OK);
		break;
	case GF_NETIO_WAIT_FOR_REPLY:
		gf_term_message(serv->term, serv->url, "Waiting for reply...", GF_OK);
		break;
	case GF_NETIO_PARSE_REPLY:
		gf_term_message(serv->term, serv->url, "Starting download...", GF_OK);
		break;
	case GF_NETIO_DATA_EXCHANGE:
		/*notify some connection / ...*/
		if (total_size) {
			GF_Event evt;
			evt.type = GF_EVENT_PROGRESS;
			evt.progress.progress_type = 1;
			evt.progress.service = szURI;
			evt.progress.total = total_size;
			evt.progress.done = bytes_done;
			evt.progress.bytes_per_seconds = bytes_per_sec;
			gf_term_send_event(serv->term, &evt);
		}
		GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[HTTP] %s received %d / %d\n", szURI, bytes_done, total_size));
		gf_term_service_media_event_with_download(serv->owner, GF_EVENT_MEDIA_PROGRESS, bytes_done, total_size, bytes_per_sec);
		break;
	case GF_NETIO_DATA_TRANSFERED:
		gf_term_service_media_event(serv->owner, GF_EVENT_MEDIA_LOAD_DONE);
		if (serv->owner && !(serv->owner->flags & GF_ODM_DESTROYED) && serv->owner->duration) {
			GF_Clock *ck = gf_odm_get_media_clock(serv->owner);
			if (!gf_clock_is_started(ck)) {
				GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP Resource] Done retrieving file - resuming playback\n"));
				if (serv->is_paused) {
					serv->is_paused = 0;
#ifndef GPAC_DISABLE_VRML
					mediacontrol_resume(serv->owner, 0);
#endif
				}
			}
		}
		break;
	default:
		break;
	}
}
Esempio n. 6
0
Bool gf_term_get_download_info(GF_Terminal *term, GF_ObjectManager *odm, u32 *d_enum, const char **server, const char **path, u32 *bytes_done, u32 *total_bytes, u32 *bytes_per_sec)
{
	GF_DownloadSession * sess;
	if (!term || !odm || !gf_term_check_odm(term, odm)) return 0;
	if (odm->net_service->owner != odm) return 0;

	if (*d_enum >= gf_list_count(odm->net_service->dnloads)) return 0;
	sess = (GF_DownloadSession*)gf_list_get(odm->net_service->dnloads, *d_enum);
	if (!sess) return 0;
	(*d_enum) ++;
	gf_dm_sess_get_stats(sess, server, path, bytes_done, total_bytes, bytes_per_sec, NULL);
	return 1;
}
Esempio n. 7
0
static Bool OGG_ReadPage(OGGReader *read, ogg_page *oggpage)
{
	char buf[OGG_BUFFER_SIZE];
	GF_Err e;

	/*remote file, check if we use cache*/
	if (read->is_remote) {
		u32 total_size;
		GF_NetIOStatus status;
		e = gf_dm_sess_get_stats(read->dnload, NULL, NULL, &total_size, NULL, NULL, &status);
		/*not ready*/
		if ((e<GF_OK) || (status > GF_NETIO_DATA_EXCHANGE)) return 0;
		if (status == GF_NETIO_DATA_EXCHANGE) {
			if (!total_size && !read->is_live) {
				read->is_live = 1;
				read->tune_in_time = gf_sys_clock();
			}
			else if (!read->is_live  && !read->ogfile) {
				const char *szCache = gf_dm_sess_get_cache_name(read->dnload);
				if (!szCache) return 0;
				read->ogfile = gf_fopen((char *) szCache, "rb");
				if (!read->ogfile) return 0;
			}
		}
	}

	while (ogg_sync_pageout(&read->oy, oggpage ) != 1 ) {
		char *buffer;
		u32 bytes;

		if (read->ogfile) {
			if (feof(read->ogfile)) {
				OGG_EndOfFile(read);
				return 0;
			}
			bytes = (u32) fread(buf, 1, OGG_BUFFER_SIZE, read->ogfile);
		} else {
			e = gf_dm_sess_fetch_data(read->dnload, buf, OGG_BUFFER_SIZE, &bytes);
			if (e) return 0;
		}
		if (!bytes) return 0;
		buffer = ogg_sync_buffer(&read->oy, bytes);
		memcpy(buffer, buf, bytes);
		ogg_sync_wrote(&read->oy, bytes);
	}
	return 1;
}
Esempio n. 8
0
/*Dummy input just send a file name, no multitrack to handle so we don't need to check sub_url nor expected type*/
static GF_Descriptor *DC_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url)
{
	u32 size = 0;
	char *uri;
	GF_ESD *esd;
	GF_BitStream *bs;
	DCReader *read = (DCReader *) plug->priv;
	GF_InitialObjectDescriptor *iod = (GF_InitialObjectDescriptor *) gf_odf_desc_new(GF_ODF_IOD_TAG);
	iod->scene_profileAndLevel = 1;
	iod->graphics_profileAndLevel = 1;
	iod->OD_profileAndLevel = 1;
	iod->audio_profileAndLevel = 0xFE;
	iod->visual_profileAndLevel = 0xFE;
	iod->objectDescriptorID = 1;

	if (read->is_views_url) {
		iod->URLString = gf_strdup(read->url);
		return (GF_Descriptor *)iod;
	}

	esd = gf_odf_desc_esd_new(0);
	esd->slConfig->timestampResolution = 1000;
	esd->slConfig->useTimestampsFlag = 1;
	esd->ESID = 0xFFFE;
	esd->decoderConfig->streamType = GF_STREAM_PRIVATE_SCENE;
	esd->decoderConfig->objectTypeIndication = read->oti;
	if (read->dnload) {
		uri = (char *) gf_dm_sess_get_cache_name(read->dnload);
		gf_dm_sess_get_stats(read->dnload, NULL, NULL, &size, NULL, NULL, NULL);
	} else {
		FILE *f = gf_fopen(read->url, "rt");
		gf_fseek(f, 0, SEEK_END);
		size = (u32) gf_ftell(f);
		gf_fclose(f);
		uri = read->url;
	}
	bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
	gf_bs_write_u32(bs, size);
	gf_bs_write_data(bs, uri, (u32) strlen(uri));
	gf_bs_get_content(bs, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength);
	gf_bs_del(bs);

	gf_list_add(iod->ESDescriptors, esd);
	return (GF_Descriptor *)iod;
}
Esempio n. 9
0
GF_EXPORT
void gf_term_download_update_stats(GF_DownloadSession * sess)
{
	GF_ClientService *serv;
	const char *szURI;
	u32 total_size, bytes_done, net_status, bytes_per_sec;

	if (!sess) return;

	gf_dm_sess_get_stats(sess, NULL, &szURI, &total_size, &bytes_done, &bytes_per_sec, &net_status);
	serv = (GF_ClientService *)gf_dm_sess_get_private(sess);
	switch (net_status) {
	case GF_NETIO_SETUP:
		gf_term_on_message(serv, GF_OK, "Connecting");
		break;
	case GF_NETIO_CONNECTED:
		gf_term_on_message(serv, GF_OK, "Connected");
		break;
	case GF_NETIO_WAIT_FOR_REPLY:
		gf_term_on_message(serv, GF_OK, "Waiting for reply...");
		break;
	case GF_NETIO_PARSE_REPLY:
		gf_term_on_message(serv, GF_OK, "Starting download...");
		break;
	case GF_NETIO_DATA_EXCHANGE:
		/*notify some connection / ...*/
		if (total_size) {
			GF_Event evt;
			evt.type = GF_EVENT_PROGRESS;
			evt.progress.progress_type = 1;
			evt.progress.service = szURI;
			evt.progress.total = total_size;
			evt.progress.done = bytes_done;
			evt.progress.bytes_per_seconds = bytes_per_sec;
			gf_term_send_event(serv->term, &evt);
		}
		GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[HTTP] %s received %d / %d\n", szURI, bytes_done, total_size));
		gf_term_service_media_event_with_download(serv->owner, GF_EVENT_MEDIA_PROGRESS, bytes_done, total_size, bytes_per_sec);

		/*JLF fix this*/
		if (0&& (serv->download_rebuffer || serv->auto_rebuffer) && serv->owner && !(serv->owner->flags & GF_ODM_DESTROYED) && serv->owner->duration) {
			GF_Clock *ck = gf_odm_get_media_clock(serv->owner);
			Double download_percent, playback_percent, adj_percent;
			download_percent = 100 * bytes_done;
			download_percent /= total_size;

			playback_percent = 100 * serv->owner->current_time;
			playback_percent /= serv->owner->duration;
			if (serv->auto_rebuffer)
				adj_percent = 0.0;
			else
				adj_percent = 100.0 * serv->download_rebuffer / serv->owner->duration;

			if (playback_percent >= download_percent) {
				if (gf_clock_is_started(ck)) {
					GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP Resource] Played %d %% but downloaded %d %% - Pausing\n", (u32) playback_percent, (u32) download_percent));
					if (!serv->is_paused) {
						serv->is_paused = 1;
						mediacontrol_pause(serv->owner);
					}
					gf_term_service_media_event(serv->owner, GF_EVENT_MEDIA_WAITING);
					gf_term_on_message(serv, GF_OK, "HTTP Buffering ...");
				}
			} else if (playback_percent + adj_percent <= download_percent) {
				Double time_to_play = 0;
				Double time_to_download = 0;
				/*automatic rebuffer: make sure we can finish playback before resuming*/
				if (serv->auto_rebuffer) {
					if (bytes_per_sec) {
						time_to_download = 1000.0*(total_size - bytes_done);
						time_to_download /= bytes_per_sec;
					}
					time_to_play = (Double) serv->owner->duration;
					time_to_play -= serv->owner->current_time;
				}
				if ((time_to_download<=time_to_play) && !gf_clock_is_started(ck)) {
					GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP Resource] Played %d %% and downloaded %d %% - Resuming\n", (u32) playback_percent, (u32) download_percent));
					if (serv->auto_rebuffer) {
						GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP Resource] Auto-rebuffer done: should be done downloading in %d ms and remains %d ms to play\n", (u32) time_to_download, (u32) (serv->owner->duration - serv->owner->current_time) ));
					}
					gf_term_service_media_event(serv->owner, GF_EVENT_MEDIA_PLAYING);
					if (serv->is_paused) {
						serv->is_paused = 0;
						mediacontrol_resume(serv->owner);
					}
					gf_term_on_message(serv, GF_OK, "HTTP Resuming playback");
				}
			}
		}
		break;
	case GF_NETIO_DATA_TRANSFERED:
		gf_term_service_media_event(serv->owner, GF_EVENT_MEDIA_LOAD_DONE);
		if (serv->owner && !(serv->owner->flags & GF_ODM_DESTROYED) && serv->owner->duration) {
			GF_Clock *ck = gf_odm_get_media_clock(serv->owner);
			if (!gf_clock_is_started(ck)) {
				GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP Resource] Done retrieving file - resuming playback\n"));
				if (serv->is_paused) {
					serv->is_paused = 0;
					mediacontrol_resume(serv->owner);
				}
			}
		}
		break;
	}
}
Esempio n. 10
0
void AC3_NetIO(void *cbk, GF_NETIO_Parameter *param)
{
	GF_Err e;
	const char *szCache;
	u32 total_size, bytes_done;
	AC3Reader *read = (AC3Reader *) cbk;

	e = param->error;
	/*done*/
	if (param->msg_type==GF_NETIO_DATA_TRANSFERED) {
		if (read->stream) {
			read->is_remote = 0;
			e = GF_EOS;
		} else if (!read->needs_connection) {
			return;
		}
	} else if (param->msg_type==GF_NETIO_PARSE_HEADER) {
		if (!strcmp(param->name, "icy-name")) {
			if (read->icy_name) gf_free(read->icy_name);
			read->icy_name = gf_strdup(param->value);
		}
		if (!strcmp(param->name, "icy-genre")) {
			if (read->icy_genre) gf_free(read->icy_genre);
			read->icy_genre = gf_strdup(param->value);
		}
		if (!strcmp(param->name, "icy-meta")) {
			GF_NetworkCommand com;
			char *meta;
			if (read->icy_track_name) gf_free(read->icy_track_name);
			read->icy_track_name = NULL;
			meta = param->value;
			while (meta && meta[0]) {
				char *sep = strchr(meta, ';');
				if (sep) sep[0] = 0;

				if (!strnicmp(meta, "StreamTitle=", 12)) {
					read->icy_track_name = gf_strdup(meta+12);
				}
				if (!sep) break;
				sep[0] = ';';
				meta = sep+1;
			}

			com.base.command_type = GF_NET_SERVICE_INFO;
			gf_service_command(read->service, &com, GF_OK);
		}
		return;
	} else {
		/*handle service message*/
		gf_service_download_update_stats(read->dnload);
		if (param->msg_type!=GF_NETIO_DATA_EXCHANGE) return;
	}

	/*data fetching or EOS*/
	if (e >= GF_OK) {
		if (read->needs_connection) {
			gf_dm_sess_get_stats(read->dnload, NULL, NULL, &total_size, NULL, NULL, NULL);
			if (!total_size) read->is_live = 1;
		}
		if (read->is_live) {
			if (!e) AC3_OnLiveData(read, param->data, param->size);
			return;
		}
		if (read->stream) return;

		/*open service*/
		szCache = gf_dm_sess_get_cache_name(read->dnload);
		if (!szCache) e = GF_IO_ERR;
		else {
			read->stream = gf_f64_open((char *) szCache, "rb");
			if (!read->stream) e = GF_SERVICE_ERROR;
			else {
				/*if full file at once (in cache) parse duration*/
				if (e==GF_EOS) read->is_remote = 0;
				e = GF_OK;
				/*not enough data*/
				if (!AC3_ConfigureFromFile(read)) {
					/*get amount downloaded and check*/
					gf_dm_sess_get_stats(read->dnload, NULL, NULL, NULL, &bytes_done, NULL, NULL);
					if (bytes_done>10*1024) {
						e = GF_CORRUPTED_DATA;
					} else {
						fclose(read->stream);
						read->stream = NULL;
						return;
					}
				}
			}
		}
	}
	/*OK confirm*/
	if (read->needs_connection) {
		read->needs_connection = 0;
		gf_service_connect_ack(read->service, NULL, e);
		if (!e) AC3_SetupObject(read);
	}
}
Esempio n. 11
0
void SDP_NetIO(void *cbk, GF_NETIO_Parameter *param)
{
	GF_Err e;
	RTPClient *rtp = (RTPClient *)cbk;
	SDPFetch *sdp = rtp->sdp_temp;

	gf_service_download_update_stats(rtp->dnload);

	e = param->error;
	switch (param->msg_type) {
	case GF_NETIO_GET_METHOD:
		if (sdp->original_url)
			param->name = "POST";
		return;
	case GF_NETIO_GET_CONTENT:
		if (sdp->original_url) {
			char szBody[4096], *opt;
			opt = (char *) gf_modules_get_option((GF_BaseInterface *) gf_service_get_interface(rtp->service), "Network", "MobileIP");
			sprintf(szBody, "ipadd\n%s\n\nurl\n%s\n\n", opt, sdp->original_url);
			param->data = szBody;
			param->size = (u32) strlen(szBody);
		}
		return;
	case GF_NETIO_DATA_TRANSFERED:
		if (sdp->original_url) {
			u32 sdp_size;
			e = gf_dm_sess_get_stats(rtp->dnload, NULL, NULL, &sdp_size, NULL, NULL, NULL);
			if (sdp_size) {
				const char *szFile = gf_dm_sess_get_cache_name(rtp->dnload);
				if (!szFile) {
					e = GF_SERVICE_ERROR;
				} else {
					e = GF_OK;
					RP_SDPFromFile(rtp, (char *) szFile, sdp->chan);
					gf_free(sdp->remote_url);
					if (sdp->original_url) gf_free(sdp->original_url);
					gf_free(sdp);
					rtp->sdp_temp = NULL;
					return;
				}
			}
		}
		break;
	default:
		if (e == GF_OK) return;
	}

	if (sdp->original_url) {
		char *url = sdp->original_url;
		gf_free(sdp->remote_url);
		gf_free(sdp);
		rtp->sdp_temp = NULL;
		RP_SendMessage(rtp->service, e, "Error fetching session state - restarting");
		RP_ConnectServiceEx(gf_service_get_interface(rtp->service), rtp->service, url, GF_TRUE);
		gf_free(url);
		return;
	}

	/*error*/
	if (sdp->chan) {
		gf_service_connect_ack(rtp->service, sdp->chan->channel, e);
	} else {
		gf_service_connect_ack(rtp->service, NULL, e);
		rtp->sdp_temp = NULL;
	}
	gf_free(sdp->remote_url);
	if (sdp->original_url) gf_free(sdp->original_url);
	gf_free(sdp);
	rtp->sdp_temp = NULL;
}
Esempio n. 12
0
void MP3_NetIO(void *cbk, GF_NETIO_Parameter *param)
{
	GF_Err e;
	const char *szCache;
	u32 total_size, bytes_done;
	MP3Reader *read = (MP3Reader *) cbk;

	e = param->error;
	/*done*/
	if (param->msg_type==GF_NETIO_DATA_TRANSFERED) {
		if (read->stream) {
			read->is_remote = 0;
			e = GF_EOS;
		} else {
			return;
		}
	}
	else if (param->msg_type==GF_NETIO_PARSE_HEADER) {
		if (!strcmp(param->name, "icy-name")) {
			if (read->icy_name) gf_free(read->icy_name);
			read->icy_name = gf_strdup(param->value);
		}
		if (!strcmp(param->name, "icy-genre")) {
			if (read->icy_genre) gf_free(read->icy_genre);
			read->icy_genre = gf_strdup(param->value);
		}
		if (!strcmp(param->name, "icy-meta")) {
			GF_NetworkCommand com;
			char *meta;
			meta = param->value;
			while (meta && meta[0]) {
				char *sep = strchr(meta, ';');
				if (sep) sep[0] = 0;

				if (!strnicmp(meta, "StreamTitle=", 12)) {
					 if (read->icy_track_name) gf_free(read->icy_track_name);
					    read->icy_track_name = NULL;
					read->icy_track_name = gf_strdup(meta+12);
					if (!strcmp(read->icy_track_name, "''")){
					  /* On some servers, '' means not track name */
					  gf_free(read->icy_track_name);
					  read->icy_track_name = NULL;
					}
				}
				if (!sep) break;
				sep[0] = ';';
				meta = sep+1;
			}

			com.base.command_type = GF_NET_SERVICE_INFO;
			gf_term_on_command(read->service, &com, GF_OK);
		}
		return;
	} else {
		/*handle service message*/
		gf_term_download_update_stats(read->dnload);
		if (param->msg_type!=GF_NETIO_DATA_EXCHANGE) return;
	}

	if (e >= GF_OK) {
		if (read->needs_connection) {
			gf_dm_sess_get_stats(read->dnload, NULL, NULL, &total_size, NULL, NULL, NULL);
			if (!total_size) read->is_live = 1;
		}
		/*looks like a live stream*/
		if (read->is_live) {
		  if (read->liveDataCopySize < param->size){
		      read->liveDataCopy = gf_realloc(read->liveDataCopy, param->size);
		  }
		  memcpy(read->liveDataCopy, param->data, param->size);
		  if (!e) MP3_OnLiveData(read, read->liveDataCopy, param->size);
		  return;
		}

		if (read->stream) return;

		/*open service*/
		szCache = gf_dm_sess_get_cache_name(read->dnload);
		if (!szCache) e = GF_IO_ERR;
		else {
			read->stream = gf_f64_open((char *) szCache, "rb");
			if (!read->stream) e = GF_SERVICE_ERROR;
			else {
				u32 minSizeToRead = 0;
				/*if full file at once (in cache) parse duration*/
				if (e==GF_EOS) read->is_remote = 0;
				e = GF_OK;
				/*not enough data*/
				if (!MP3_ConfigureFromFile(read, &minSizeToRead)) {
					gf_dm_sess_get_stats(read->dnload, NULL, NULL, NULL, &bytes_done, NULL, NULL);
					/*bad data - there's likely some ID3 around...*/
					if (bytes_done>(100*1024 + minSizeToRead)) {
						e = GF_CORRUPTED_DATA;
					} else {
						fclose(read->stream);
						read->stream = NULL;
						return;
					}
				}
			}
		}
	}

	/*OK confirm*/
	if (read->needs_connection) {
		read->needs_connection = 0;
		gf_term_on_connect(read->service, NULL, e);
		if (!e) mp3_setup_object(read);
	}
}
Esempio n. 13
0
void isor_check_buffer_level(ISOMReader *read)
{
	Double dld_time_remaining, mov_rate;
	GF_NetworkCommand com;
	u32 i, total, done, Bps;
	u64 dur;
	GF_NetIOStatus status;
	Bool do_buffer = GF_FALSE;
	if (!read->dnload) return;
	if (!read->mov) return;

	gf_dm_sess_get_stats(read->dnload, NULL, NULL, &total, &done, &Bps, &status);
	if (!Bps) return;


	gf_mx_p(read->segment_mutex);

	dld_time_remaining = total-done;
	dld_time_remaining /= Bps;

	//we add 30 seconds to smooth out bitrate variations ..;
	dld_time_remaining += 30;

	mov_rate = total;
	dur = gf_isom_get_duration(read->mov);
	if (dur) {
		mov_rate /= dur;
		mov_rate *= gf_isom_get_timescale(read->mov);
	}

	for (i=0; i<gf_list_count(read->channels); i++) {
		ISOMChannel *ch = gf_list_get(read->channels, i);
		Double time_remain_ch = (Double) gf_isom_get_media_duration(read->mov, ch->track);
		u32 buffer_level=0;
		if (total==done) {
			time_remain_ch = 0;
			do_buffer = GF_FALSE;
		} else if (ch->last_state == GF_EOS) {
			time_remain_ch = 0;
			do_buffer = GF_TRUE;
		} else {
			u64 data_offset;
			u32 di, sn = ch->sample_num ? ch->sample_num : 1;
			GF_ISOSample *samp = gf_isom_get_sample_info(read->mov, ch->track, sn, &di, &data_offset);
			if (!samp) continue;

			data_offset += samp->dataLength;

			//we only send buffer on/off based on remainging playback time in channel
#if 0
			//we don't have enough data
			if (((data_offset + ch->buffer_min * mov_rate/1000 > done))) {
				do_buffer = GF_TRUE;
			}
			//we have enough buffer
			else if ((data_offset + ch->buffer_max * mov_rate/1000 <= done)) {
				do_buffer = GF_FALSE;
			}
#endif
			time_remain_ch -= (samp->DTS + samp->CTS_Offset);
			if (time_remain_ch<0) time_remain_ch=0;
			gf_isom_sample_del(&samp);

			time_remain_ch /= ch->time_scale;
			if (time_remain_ch && (time_remain_ch < dld_time_remaining)) {
				do_buffer = GF_TRUE;
				if (!read->remain_at_buffering_start || (read->remain_at_buffering_start < dld_time_remaining)) {
					buffer_level = 0;
					read->remain_at_buffering_start = dld_time_remaining;
				} else {
					buffer_level = (u32) (100 * (read->remain_at_buffering_start - dld_time_remaining) / (read->remain_at_buffering_start - time_remain_ch) );
				}
			} else {
				do_buffer = GF_FALSE;
			}
		}

		if (do_buffer != ch->buffering) {
			GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[IsoMedia] Buffering %s at %d: %g sec still to download and %g sec still to play on track %d (movie rate %g - download rate %g kbps)\n", do_buffer ? "on" : "off", gf_sys_clock(), dld_time_remaining , time_remain_ch, ch->track_id, mov_rate*8/1000, Bps*8.0/1000));

			memset(&com, 0, sizeof(GF_NetworkCommand));
			com.command_type = do_buffer ? GF_NET_CHAN_PAUSE : GF_NET_CHAN_RESUME;
			com.buffer.on_channel = ch->channel;
			com.buffer.min = ch->buffer_min;
			com.buffer.max = ch->buffer_max;
			gf_service_command(read->service, &com, GF_OK);
			ch->buffering = do_buffer;
			read->buffering = do_buffer;
		} else if (ch->buffering) {
			memset(&com, 0, sizeof(GF_NetworkCommand));
			com.command_type = GF_NET_CHAN_BUFFER;
			com.buffer.on_channel = ch->channel;
			com.buffer.min = ch->buffer_min;
			com.buffer.max = ch->buffer_max;
			com.buffer.occupancy = buffer_level;
			gf_service_command(read->service, &com, GF_OK);
		}
	}
	gf_mx_v(read->segment_mutex);
}
Esempio n. 14
0
File: saf_in.c Progetto: Bevara/GPAC
static void SAF_NetIO(void *cbk, GF_NETIO_Parameter *param)
{
	GF_Err e;
	Bool is_rap, go;
	SAFChannel *ch;
	u32 cts, au_sn, au_size, type, i, stream_id;
	u64 bs_pos;
	GF_BitStream *bs;
	GF_SLHeader sl_hdr;

	SAFIn *read = (SAFIn *) cbk;

	e = param->error;
	/*done*/
	if (param->msg_type==GF_NETIO_DATA_TRANSFERED) {
		if (read->stream && (read->saf_type==SAF_FILE_REMOTE)) read->saf_type = SAF_FILE_LOCAL;
		return;
	} else {
		/*handle service message*/
		gf_service_download_update_stats(read->dnload);
		if (param->msg_type!=GF_NETIO_DATA_EXCHANGE) {
			if (e<0) {
				if (read->needs_connection) {
					read->needs_connection = 0;
					gf_service_connect_ack(read->service, NULL, e);
				}
				return;
			}
			if (read->needs_connection) {
				u32 total_size;
				gf_dm_sess_get_stats(read->dnload, NULL, NULL, &total_size, NULL, NULL, NULL);
				if (!total_size) read->saf_type = SAF_LIVE_STREAM;
			}
			return;
		}
	}
	if (!param->size) return;

	if (!read->run_state) return;

	if (read->alloc_size < read->saf_size + param->size) {
		read->saf_data = (char*)gf_realloc(read->saf_data, sizeof(char)*(read->saf_size + param->size) );
		read->alloc_size = read->saf_size + param->size;
	}
	memcpy(read->saf_data + read->saf_size, param->data, sizeof(char)*param->size);
	read->saf_size += param->size;

	/*first AU not complete yet*/
	if (read->saf_size<10) return;

	bs = gf_bs_new(read->saf_data, read->saf_size, GF_BITSTREAM_READ);
	bs_pos = 0;

	go = 1;
	while (go) {
		u64 avail = gf_bs_available(bs);
		bs_pos = gf_bs_get_position(bs);

		if (avail<10) break;

		is_rap = gf_bs_read_int(bs, 1);
		au_sn = gf_bs_read_int(bs, 15);
		gf_bs_read_int(bs, 2);
		cts = gf_bs_read_int(bs, 30);
		au_size = gf_bs_read_int(bs, 16);
		avail-=8;

		if (au_size > avail) break;
		assert(au_size>=2);

		is_rap = 1;

		type = gf_bs_read_int(bs, 4);
		stream_id = gf_bs_read_int(bs, 12);
		au_size -= 2;

		ch = saf_get_channel(read, stream_id, NULL);
		switch (type) {
		case 1:
		case 2:
		case 7:
			if (ch) {
				gf_bs_skip_bytes(bs, au_size);
			} else {
				SAFChannel *first = (SAFChannel *)gf_list_get(read->channels, 0);
				GF_SAFEALLOC(ch, SAFChannel);
				ch->stream_id = stream_id;
				ch->esd = gf_odf_desc_esd_new(0);
				ch->esd->ESID = stream_id;
				ch->esd->OCRESID = first ? first->stream_id : stream_id;
				ch->esd->slConfig->useRandomAccessPointFlag = 1;
				ch->esd->slConfig->AUSeqNumLength = 0;
				ch->esd->decoderConfig->objectTypeIndication = gf_bs_read_u8(bs);
				ch->esd->decoderConfig->streamType = gf_bs_read_u8(bs);
				ch->ts_res = ch->esd->slConfig->timestampResolution = gf_bs_read_u24(bs);
				ch->esd->decoderConfig->bufferSizeDB = gf_bs_read_u16(bs);
				au_size -= 7;
				if ((ch->esd->decoderConfig->objectTypeIndication == 0xFF) && (ch->esd->decoderConfig->streamType == 0xFF) ) {
					u16 mimeLen = gf_bs_read_u16(bs);
					gf_bs_skip_bytes(bs, mimeLen);
					au_size -= mimeLen+2;
				}
				if (type==7) {
					u16 urlLen = gf_bs_read_u16(bs);
					ch->esd->URLString = (char*)gf_malloc(sizeof(char)*(urlLen+1));
					gf_bs_read_data(bs, ch->esd->URLString, urlLen);
					ch->esd->URLString[urlLen] = 0;
					au_size -= urlLen+2;
				}
				if (au_size) {
					ch->esd->decoderConfig->decoderSpecificInfo->dataLength = au_size;
					ch->esd->decoderConfig->decoderSpecificInfo->data = (char*)gf_malloc(sizeof(char)*au_size);
					gf_bs_read_data(bs, ch->esd->decoderConfig->decoderSpecificInfo->data, au_size);
				}
				if (ch->esd->decoderConfig->streamType==4) ch->buffer_min=100;
				else if (ch->esd->decoderConfig->streamType==5) ch->buffer_min=400;
				else ch->buffer_min=0;

				if (read->needs_connection && (ch->esd->decoderConfig->streamType==GF_STREAM_SCENE)) {
					gf_list_add(read->channels, ch);
					read->needs_connection = 0;
					gf_service_connect_ack(read->service, NULL, GF_OK);
				} else if (read->needs_connection) {
					gf_odf_desc_del((GF_Descriptor *) ch->esd);
					gf_free(ch);
					ch = NULL;
				} else {
					GF_ObjectDescriptor *od;
					gf_list_add(read->channels, ch);

					od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG);
					gf_list_add(od->ESDescriptors, ch->esd);
					ch->esd = NULL;
					od->objectDescriptorID = ch->stream_id;
					gf_service_declare_media(read->service, (GF_Descriptor*)od, 0);

				}
			}
			break;
		case 4:
			if (ch) {
				bs_pos = gf_bs_get_position(bs);
				memset(&sl_hdr, 0, sizeof(GF_SLHeader));
				sl_hdr.accessUnitLength = au_size;
				sl_hdr.AU_sequenceNumber = au_sn;
				sl_hdr.compositionTimeStampFlag = 1;
				sl_hdr.compositionTimeStamp = cts;
				sl_hdr.randomAccessPointFlag = is_rap;
				if (read->start_range && (read->start_range*ch->ts_res>cts*1000)) {
					sl_hdr.compositionTimeStamp = read->start_range*ch->ts_res/1000;
				}
				gf_service_send_packet(read->service, ch->ch, read->saf_data+bs_pos, au_size, &sl_hdr, GF_OK);
			}
			gf_bs_skip_bytes(bs, au_size);
			break;
		case 3:
			if (ch) gf_service_send_packet(read->service, ch->ch, NULL, 0, NULL, GF_EOS);
			break;
		case 5:
			go = 0;
			read->run_state = 0;
			i=0;
			while ((ch = (SAFChannel *)gf_list_enum(read->channels, &i))) {
				gf_service_send_packet(read->service, ch->ch, NULL, 0, NULL, GF_EOS);
			}
			break;
		}
	}

	gf_bs_del(bs);
	if (bs_pos) {
		u32 remain = (u32) (read->saf_size - bs_pos);
		if (remain) memmove(read->saf_data, read->saf_data+bs_pos, sizeof(char)*remain);
		read->saf_size = remain;
	}
	SAF_Regulate(read);
}