Beispiel #1
0
void VTT_load_script(VTTDec *vttdec, GF_SceneGraph *graph)
{
	GF_Node *n, *root;
	GF_FieldInfo info;
	const char *path;
	FILE *jsfile;

	if (!graph) return;
	gf_sg_add_namespace(graph, "http://www.w3.org/2000/svg", NULL);
	gf_sg_add_namespace(graph, "http://www.w3.org/1999/xlink", "xlink");
	gf_sg_add_namespace(graph, "http://www.w3.org/2001/xml-events", "ev");
	gf_sg_set_scene_size_info(graph, 800, 600, GF_TRUE);

	/* modify the scene with an Inline/Animation pointing to the VTT Renderer */
	n = root = gf_node_new(graph, TAG_SVG_svg);
	gf_node_register(root, NULL);
	gf_sg_set_root_node(graph, root);
	gf_node_get_attribute_by_name(n, "xmlns", 0, GF_TRUE, GF_FALSE, &info);
	gf_svg_parse_attribute(n, &info, "http://www.w3.org/2000/svg", 0);
	VTT_UpdateSizeInfo(vttdec);
	gf_node_init(n);

	n = gf_node_new(graph, TAG_SVG_script);
	gf_node_register(n, root);
	gf_node_list_add_child(&((GF_ParentNode *)root)->children, n);
	path = gf_modules_get_option((GF_BaseInterface *)vttdec->module, "WebVTT", "RenderingScript");
	if (!path) {
		/* try to find the JS renderer in the default GPAC installation folder */
		const char *startuppath = gf_modules_get_option((GF_BaseInterface *)vttdec->module, "General", "StartupFile");
		path = gf_url_concatenate(startuppath, "webvtt-renderer.js");
		jsfile = gf_fopen(path, "rt");
		if (jsfile) {
			gf_modules_set_option((GF_BaseInterface *)vttdec->module, "WebVTT", "RenderingScript", path);
			gf_fclose(jsfile);
		} else {
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[WebVTT] Cannot find Rendering Script [WebVTT:RenderingScript] - check config file\n"));
			return;
		}
	}
	jsfile = gf_fopen(path, "rt");
	if (jsfile) {
		gf_fclose(jsfile);
		gf_node_get_attribute_by_tag(n, TAG_XLINK_ATT_href, GF_TRUE, GF_FALSE, &info);
		if (strstr(path, ":\\")) {
			gf_svg_parse_attribute(n, &info, (char *) path, 0);
		} else {
			char szPath[GF_MAX_PATH];
			strcpy(szPath, "file://");
			strcat(szPath, path);
			gf_svg_parse_attribute(n, &info, (char *) szPath, 0);
		}

		vttdec->has_rendering_script = GF_TRUE;
	} else {
		GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[WebVTT] Cannot open Rendering Script - %s\n", path));
		return;
	}
	gf_node_init(n);

}
Beispiel #2
0
GF_EXPORT
GF_DownloadSession *gf_term_download_new(GF_ClientService *service, const char *url, u32 flags, gf_dm_user_io user_io, void *cbk)
{
	GF_Err e;
	GF_DownloadSession * sess;
	char *sURL, *orig_url;
	if (!service){
                 GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[HTTP] service is null, cannot create new download session for %s.\n", url));
		 return NULL;
	}

	sURL = gf_url_concatenate(service->url, url);
	/*path was absolute*/
	if (!sURL) sURL = gf_strdup(url);
	assert( service->term );

	orig_url = service->pending_service_session ? (char *) gf_dm_sess_get_original_resource_name(service->pending_service_session) : NULL;
	/*this will take care of URL formatting (%20 etc ..) */
	if (orig_url) orig_url = gf_url_concatenate(service->url, orig_url);

	if (orig_url && !strcmp(orig_url, sURL)) {
		sess = service->pending_service_session;
		service->pending_service_session = NULL;
		/*resetup*/
		gf_dm_sess_reassign(sess, flags, user_io, cbk);
	} else {
		sess = gf_dm_sess_new(service->term->downloader, sURL, flags, user_io, cbk, &e);
	}
	if (orig_url) gf_free(orig_url);

	if (!sess){
		GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[HTTP] session could not be created for %s : %s. service url=%s, url=%s.\n", sURL, gf_error_to_string(e), service->url, url));
		gf_free(sURL);
		sURL = NULL;
		return NULL;
	}
	gf_free(sURL);
	sURL = NULL;
	gf_dm_sess_set_private(sess, service);
	gf_list_add(service->dnloads, sess);
	return sess;
}
Beispiel #3
0
char *gf_term_resolve_xlink(GF_Node *node, char *the_url)
{
	char *url;
	GF_Scene *scene = gf_sg_get_private(gf_node_get_graph(node));
	if (!scene) return NULL;

	url = gf_strdup(the_url);
	/*apply XML:base*/
	while (node) {
		GF_FieldInfo info;
		if (gf_node_get_attribute_by_tag(node, TAG_XML_ATT_base, 0, 0, &info)==GF_OK) {
			char *new_url = gf_url_concatenate( ((XMLRI*)info.far_ptr)->string, url);
			if (new_url) {
				gf_free(url);
				url = new_url;
			}
		}
		node = gf_node_get_parent(node, 0);
	}

	/*if this is a fragment and no XML:BASE was found, this is a fragment of the current document*/
	if (url[0]=='#') return url;

	if (scene) {
		char *the_url;
		if (scene->redirect_xml_base) {
			the_url = gf_url_concatenate(scene->redirect_xml_base, url);
		} else {
//			the_url = gf_url_concatenate(is->root_od->net_service->url, url);
			/*the root url of a document should be "." if not specified, so that the final URL resolve happens only once
			at the service level*/
			the_url = gf_strdup(url);
		}
		gf_free(url);
		return the_url;
	}
	return url;
}
Beispiel #4
0
LONG CMainFrame::OnNavigate(WPARAM /*wParam*/, LPARAM /*lParam*/)
{
	COsmo4 *app = GetApp();
	char to_url[MAX_PATH];
	CE_WideToChar((LPTSTR) (LPCTSTR) app->m_navigate_url, to_url);

	if (gf_term_is_supported_url(app->m_term, to_url, 1, app->m_no_mime_fetch)) {
		char fileName[MAX_PATH];
		TCHAR w_to_url[MAX_PATH];
		CE_WideToChar((LPTSTR) (LPCTSTR) app->m_filename, fileName);
		char *str = gf_url_concatenate(fileName, to_url);
		if (!str) str = strdup(to_url);
		CE_CharToWide(str, w_to_url);
		free(str);
		app->m_filename = w_to_url;
		Open(0, 0);
	} else {
		SHELLEXECUTEINFO info;
		console_message = app->m_navigate_url;
		console_err = GF_OK;
		PostMessage(WM_CONSOLEMSG);

		
		if (m_full_screen) {
			OnViewFullscreen();
			app->ShowTaskBar(1);
			m_restore_fs = 1;
		}
	
		memset(&info, 0, sizeof(SHELLEXECUTEINFO));
		info.cbSize = sizeof(SHELLEXECUTEINFO);
		info.lpVerb = L"open";
		info.fMask = SEE_MASK_NOCLOSEPROCESS;
		info.lpFile = L"iexplore";
		info.lpParameters = (LPCTSTR) app->m_navigate_url;
		info.nShow = SW_SHOWNORMAL;
		ShellExecuteEx(&info);
	}
	return 1;	
}
Beispiel #5
0
void CGPAXPlugin::UpdateURL()
{
	/*get absolute URL*/
	if (!strlen(m_url)) return;
	IMoniker* pMoniker	= NULL;
	LPOLESTR sDisplayName;

	if (SUCCEEDED(m_spClientSite->GetMoniker(OLEGETMONIKER_TEMPFORUSER,
									   OLEWHICHMK_CONTAINER,
									   &pMoniker) ) ) {
		char parent_url[1024];
		pMoniker->GetDisplayName(NULL, NULL, &sDisplayName);
		wcstombs(parent_url, sDisplayName, 300);
		pMoniker->Release();

		char *abs_url = gf_url_concatenate(parent_url, m_url);
		if (abs_url) {
			strcpy(m_url, abs_url);
			gf_free(abs_url);
		}
	}
}
Beispiel #6
0
Datei: url.c Projekt: erelh/gpac
char *gf_url_get_absolute_path(const char *pathName, const char *parentPath)
{
	u32 prot_type = URL_GetProtocolType(pathName);

	/*abs path name*/
	if (prot_type == GF_URL_TYPE_FILE) {
	  /*abs path*/
		if (!strstr(pathName, "://") && !strstr(pathName, "|//")) return gf_strdup(pathName);
		pathName += 6;
		/*not sure if "file:///C:\..." is std, but let's handle it anyway*/
		if ((pathName[0]=='/') && (pathName[2]==':')) pathName += 1;
		return gf_strdup(pathName);
	}
	if (prot_type==GF_URL_TYPE_ANY) return NULL;
	if (!parentPath) return gf_strdup(pathName);

	/*try with the parent URL*/
	prot_type = URL_GetProtocolType(parentPath);
	/*if abs parent path concatenate*/
	if (prot_type == GF_URL_TYPE_FILE) return gf_url_concatenate(parentPath, pathName);
	if (prot_type != GF_URL_TYPE_RELATIVE) return NULL;
	/*if we are here, parentPath is also relative... return the original PathName*/
	return gf_strdup(pathName);
}
Beispiel #7
0
GF_Err gf_bifs_enc_sf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field)
{
	GF_Err e;

	if (node) {
		e = gf_bifs_enc_quant_field(codec, bs, node, field);
		if (e != GF_EOS) return e;
	}
	switch (field->fieldType) {
	case GF_SG_VRML_SFBOOL:
		GF_BIFS_WRITE_INT(codec, bs, * ((SFBool *)field->far_ptr), 1, "SFBool", NULL);
		break;
	case GF_SG_VRML_SFCOLOR:
		BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->red, bs, "color.red");
		BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->green, bs, "color.green");
		BE_WriteSFFloat(codec, ((SFColor *)field->far_ptr)->blue, bs, "color.blue");
		break;
	case GF_SG_VRML_SFFLOAT:
		BE_WriteSFFloat(codec, * ((SFFloat *)field->far_ptr), bs, NULL);
		break;
	case GF_SG_VRML_SFINT32:
		GF_BIFS_WRITE_INT(codec, bs, * ((SFInt32 *)field->far_ptr), 32, "SFInt32", NULL);
		break;
	case GF_SG_VRML_SFROTATION:
		BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->x, bs, "rot.x");
		BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->y, bs, "rot.y");
		BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->z, bs, "rot.z");
		BE_WriteSFFloat(codec, ((SFRotation  *)field->far_ptr)->q, bs, "rot.theta");
		break;

	case GF_SG_VRML_SFSTRING:
		if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) {
			u32 size, val;
			char buf[4096];
			char *res_src = NULL;
			const char *src = ((SFString*)field->far_ptr)->buffer;
			FILE *f;
			if (codec->src_url) res_src = gf_url_concatenate(codec->src_url, src);

			f = gf_fopen(res_src ? res_src : src, "rb");
			if (!f) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot open source file %s for encoding CacheTexture\n", res_src ? res_src : src));
				return GF_URL_ERROR;
			}
			if (res_src) gf_free(res_src);
			gf_fseek(f, 0, SEEK_END);
			size = (u32) gf_ftell(f);
			val = gf_get_bit_size(size);
			GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL);
			GF_BIFS_WRITE_INT(codec, bs, size, val, "length", NULL);
			gf_fseek(f, 0, SEEK_SET);
			while (size) {
				u32 read = (u32) fread(buf, 1, 4096, f);
				gf_bs_write_data(bs, buf, read);
				size -= read;
			}
		} else {
			u32 i, val, len;
			char *str = (char *) ((SFString*)field->far_ptr)->buffer;
			if (node && (node->sgprivate->tag==TAG_MPEG4_BitWrapper) ) {
				len = ((M_BitWrapper*)node)->buffer_len;
			} else {
				len = str ? (u32) strlen(str) : 0;
			}
			val = gf_get_bit_size(len);
			GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL);
			GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL);
			for (i=0; i<len; i++) gf_bs_write_int(bs, str[i], 8);
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\n", 8*len, str) );
		}
		break;

	case GF_SG_VRML_SFTIME:
		gf_bs_write_double(bs, *((SFTime *)field->far_ptr));
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] SFTime\t\t%d\t\t%g\n", 64, *((SFTime *)field->far_ptr)));
		break;

	case GF_SG_VRML_SFVEC2F:
		BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->x, bs, "vec2f.x");
		BE_WriteSFFloat(codec, ((SFVec2f *)field->far_ptr)->y, bs, "vec2f.y");
		break;

	case GF_SG_VRML_SFVEC3F:
		BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->x, bs, "vec3f.x");
		BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->y, bs, "vec3f.y");
		BE_WriteSFFloat(codec, ((SFVec3f *)field->far_ptr)->z, bs, "vec3f.z");
		break;

	case GF_SG_VRML_SFURL:
	{
		SFURL *url = (SFURL *) field->far_ptr;
		GF_BIFS_WRITE_INT(codec, bs, (url->OD_ID>0) ? 1 : 0, 1, "hasODID", "SFURL");
		if (url->OD_ID>0) {
			GF_BIFS_WRITE_INT(codec, bs, url->OD_ID, 10, "ODID", "SFURL");
		} else {
			u32 i, len = url->url ? (u32) strlen(url->url) : 0;
			u32 val = gf_get_bit_size(len);
			GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL);
			GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL);
			for (i=0; i<len; i++) gf_bs_write_int(bs, url->url[i], 8);
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\t\t//SFURL\n", 8*len, url->url));
		}
	}
	break;
	case GF_SG_VRML_SFIMAGE:
	{
		u32 size, i;
		SFImage *img = (SFImage *)field->far_ptr;
		GF_BIFS_WRITE_INT(codec, bs, img->width, 12, "width", "SFImage");
		GF_BIFS_WRITE_INT(codec, bs, img->height, 12, "height", "SFImage");
		GF_BIFS_WRITE_INT(codec, bs, img->numComponents - 1, 2, "nbComp", "SFImage");
		size = img->width * img->height * img->numComponents;
		for (i=0; i<size; i++) gf_bs_write_int(bs, img->pixels[i], 8);
		GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] pixels\t\t%d\t\tnot dumped\t\t//SFImage\n", 8*size));
	}
	break;

	case GF_SG_VRML_SFCOMMANDBUFFER:
	{
		SFCommandBuffer *cb = (SFCommandBuffer *) field->far_ptr;
		if (cb->buffer) gf_free(cb->buffer);
		cb->buffer = NULL;
		cb->bufferSize = 0;
		if (gf_list_count(cb->commandList)) {
			u32 i, nbBits;
			GF_BitStream *bs_cond = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*SFCommandBuffer*/\n" ));
			e = gf_bifs_enc_commands(codec, cb->commandList, bs_cond);
			if (!e) gf_bs_get_content(bs_cond, (char**)&cb->buffer, &cb->bufferSize);
			gf_bs_del(bs_cond);
			if (e) return e;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] /*End SFCommandBuffer*/\n"));
			nbBits = gf_get_bit_size(cb->bufferSize);
			GF_BIFS_WRITE_INT(codec, bs, nbBits, 5, "NbBits", NULL);
			GF_BIFS_WRITE_INT(codec, bs, cb->bufferSize, nbBits, "BufferSize", NULL);
			for (i=0; i<cb->bufferSize; i++) GF_BIFS_WRITE_INT(codec, bs, cb->buffer[i], 8, "buffer byte", NULL);
		}
		/*empty command buffer*/
		else {
			GF_BIFS_WRITE_INT(codec, bs, 0, 5, "NbBits", NULL);
		}
	}
	break;

	case GF_SG_VRML_SFNODE:
		return gf_bifs_enc_node(codec, *((GF_Node **)field->far_ptr), field->NDTtype, bs, node);

	case GF_SG_VRML_SFSCRIPT:
#ifdef GPAC_HAS_SPIDERMONKEY
		codec->LastError = SFScript_Encode(codec, (SFScript *)field->far_ptr, bs, node);
#else
		return GF_NOT_SUPPORTED;
#endif
		break;
	case GF_SG_VRML_SFATTRREF:
	{
		u32 idx=0;
		SFAttrRef *ar = (SFAttrRef *)field->far_ptr;
		u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1);
		GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(ar->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL);

		gf_bifs_field_index_by_mode(ar->node, ar->fieldIndex, GF_SG_FIELD_CODING_DEF, &idx);
		GF_BIFS_WRITE_INT(codec, bs, idx, nbBitsDEF, "field", NULL);
	}
	break;
	default:
		return GF_NOT_SUPPORTED;
	}
	return codec->LastError;
}
Beispiel #8
0
GF_SceneGraph *gf_inline_get_proto_lib(void *_is, MFURL *lib_url)
{
	GF_ProtoLink *pl;
	u32 i;
	GF_Scene *scene = (GF_Scene *) _is;
	if (!scene || !lib_url->count) return NULL;

	if (gf_inline_is_hardcoded_proto(lib_url, scene->root_od->term->user->config)) return GF_SG_INTERNAL_PROTO;

	i=0;
	while ((pl = (GF_ProtoLink*)gf_list_enum(scene->extern_protos, &i))) {
		if (!pl->mo) continue;
		if (gf_mo_get_od_id(pl->url) != GF_MEDIA_EXTERNAL_ID) {
			if (gf_mo_get_od_id(pl->url) == gf_mo_get_od_id(lib_url)) {
				if (!pl->mo->odm || !pl->mo->odm->subscene) return NULL;
				return pl->mo->odm->subscene->graph;
			}
		}
	}

	/*for string URL based protos, recursively check until top if the proto lib is not already present*/
	if (lib_url->vals[0].url) {
		GF_Scene *check_scene = scene;
		while (check_scene) {
			i=0;
			while ((pl = (GF_ProtoLink*)gf_list_enum(check_scene->extern_protos, &i))) {
				char *url1, *url2;
				Bool ok;
				if (!pl->mo) continue;
				if (gf_mo_get_od_id(pl->url) != GF_MEDIA_EXTERNAL_ID) continue;
				/*not the same url*/
				if (!gf_mo_is_same_url(pl->mo, lib_url, NULL, 0)) continue;
				/*check the url path is the same*/
				url1 = gf_url_concatenate(pl->mo->odm->net_service->url, lib_url->vals[0].url);
				url2 = gf_url_concatenate(scene->root_od->net_service->url, lib_url->vals[0].url);
				ok = 0;
				if (url1 && url2 && !strcmp(url1, url2)) ok=1;
				if (url1) gf_free(url1);
				if (url2) gf_free(url2);
				if (!ok) continue;
				if (!pl->mo->odm || !pl->mo->odm->subscene) return NULL;
				return pl->mo->odm->subscene->graph;
			}
			check_scene = check_scene->root_od->parentscene;
		}
	}

	/*not found, let's try to load it*/

	if (!lib_url || !lib_url->count) return NULL;

	/*internal, don't waste ressources*/
	if (gf_inline_is_hardcoded_proto(lib_url, scene->root_od->term->user->config)) return NULL;
	
	i=0;
	while ((pl = (GF_ProtoLink*)gf_list_enum(scene->extern_protos, &i)) ) {
		if (pl->url == lib_url) return NULL;
		if (pl->url->vals[0].OD_ID && (pl->url->vals[0].OD_ID == lib_url->vals[0].OD_ID)) return NULL;
		if (pl->url->vals[0].url && lib_url->vals[0].url && !stricmp(pl->url->vals[0].url, lib_url->vals[0].url) ) return NULL;
	}
	pl = (GF_ProtoLink*)gf_malloc(sizeof(GF_ProtoLink));
	pl->url = lib_url;
	gf_list_add(scene->extern_protos, pl);
	pl->mo = gf_scene_get_media_object(scene, lib_url, GF_MEDIA_OBJECT_SCENE, 0);
	/*this may already be destroyed*/
	if (pl->mo) gf_mo_play(pl->mo, 0, -1, 0);

	/*and return NULL*/
	return NULL;
}
Beispiel #9
0
Datei: url.c Projekt: erelh/gpac
GF_EXPORT
char *gf_url_concatenate(const char *parentName, const char *pathName)
{
	u32 pathSepCount, i, prot_type;
	char *outPath, *name, *rad;
	char tmp[GF_MAX_PATH];

	if (!pathName && !parentName) return NULL;
	if (!pathName) return gf_strdup(parentName);
	if (!parentName) return gf_strdup(pathName);

	if ( (strlen(parentName) > GF_MAX_PATH) || (strlen(pathName) > GF_MAX_PATH) ) return NULL;

	prot_type = URL_GetProtocolType(pathName);
	if (prot_type != GF_URL_TYPE_RELATIVE) {
		char *sep = NULL;
		if (pathName[0]=='/') sep = strstr(parentName, "://");
		if (sep) sep = strchr(sep+3, '/');
		if (sep) {
			u32 len;
			sep[0] = 0;
			len = (u32) strlen(parentName);
			outPath = (char*)gf_malloc(sizeof(char)*(len+1+strlen(pathName)));
			strcpy(outPath, parentName);
			strcat(outPath, pathName);
			sep[0] = '/';
		} else {
			outPath = gf_strdup(pathName);
		}
		goto check_spaces;
	}

	/*old upnp addressing a la Platinum*/
	rad = strstr(parentName, "%3fpath=");
	if (!rad) rad = strstr(parentName, "%3Fpath=");
	if (!rad) rad = strstr(parentName, "?path=");
	if (rad) {
		char *the_path;
		rad = strchr(rad, '=');
		rad[0] = 0;
		the_path = gf_strdup(rad+1);
		i=0;
		while (1) {
			if (the_path[i]==0) break;
			if (!strnicmp(the_path+i, "%5c", 3) || !strnicmp(the_path+i, "%2f", 3) ) {
				the_path[i] = '/';
				memmove(the_path+i+1, the_path+i+3, strlen(the_path+i+3)+1);
			}
			else if (!strnicmp(the_path+i, "%05c", 4) || !strnicmp(the_path+i, "%02f", 4) ) {
				the_path[i] = '/';
				memmove(the_path+i+1, the_path+i+4, strlen(the_path+i+4)+1);
			}
			i++;
		}
		name = gf_url_concatenate(the_path, pathName);
		outPath = gf_malloc(strlen(parentName) + strlen(name) + 2);
		sprintf(outPath, "%s=%s", parentName, name);
		rad[0] = '=';
		gf_free(name);
		gf_free(the_path);
		return outPath;
	}

	/*rewrite path to use / not % encoding*/
	rad = strchr(parentName, '%');
	if (rad && (!strnicmp(rad, "%5c", 3) || !strnicmp(rad, "%05c", 4) || !strnicmp(rad, "%2f", 3)  || !strnicmp(rad, "%02f", 4))) {
		char *the_path = gf_strdup(parentName);
		i=0;
		while (1) {
			if (the_path[i]==0) break;
			if (!strnicmp(the_path+i, "%5c", 3) || !strnicmp(the_path+i, "%2f", 3) ) {
				the_path[i] = '/';
				memmove(the_path+i+1, the_path+i+3, strlen(the_path+i+3)+1);
			}
			else if (!strnicmp(the_path+i, "%05c", 4) || !strnicmp(the_path+i, "%02f", 4) ) {
				the_path[i] = '/';
				memmove(the_path+i+1, the_path+i+4, strlen(the_path+i+4)+1);
			}
			i++;
		}
		name = gf_url_concatenate(the_path, pathName);
		gf_free(the_path);
		return name;
	}


	pathSepCount = 0;
	name = NULL;
	if (pathName[0] == '.') {
		if (!strcmp(pathName, "..")) {
			pathSepCount = 1;
			name = "";
		}
		if (!strcmp(pathName, "./")) {
			pathSepCount = 0;
			name = "";
		}
		for (i = 0; i< strlen(pathName) - 2; i++) {
			/*current dir*/
			if ( (pathName[i] == '.')
				&& ( (pathName[i+1] == GF_PATH_SEPARATOR) || (pathName[i+1] == '/') ) ) {
				i++;
				continue;
			}
			/*parent dir*/
			if ( (pathName[i] == '.') && (pathName[i+1] == '.')
				&& ( (pathName[i+2] == GF_PATH_SEPARATOR) || (pathName[i+2] == '/') )
				) {
				pathSepCount ++;
				i+=2;
				name = (char *) &pathName[i+1];
			} else {
				name = (char *) &pathName[i];
				break;
			}
		}
	}
	if (!name) name = (char *) pathName;

	strcpy(tmp, parentName);
	while (strchr(" \r\n\t", tmp[strlen(tmp)-1])) {
		tmp[strlen(tmp)-1] = 0;
	}

	/*remove the last /*/
	for (i = (u32) strlen(parentName); i > 0; i--) {
		//break our path at each separator
		if ((parentName[i-1] == GF_PATH_SEPARATOR) || (parentName[i-1] == '/'))  {
			tmp[i-1] = 0;
			if (!pathSepCount) break;
			pathSepCount--;
		}
	}
	//if i==0, the parent path was relative, just return the pathName
	if (!i) {
		tmp[i] = 0;
		while (pathSepCount) {
			strcat(tmp, "../");
			pathSepCount--;
		}
	} else {
		strcat(tmp, "/");
	}

	i = (u32) strlen(tmp);
	outPath = (char *) gf_malloc(i + strlen(name) + 1);
	sprintf(outPath, "%s%s", tmp, name);

	/*cleanup paths sep for win32*/
	for (i = 0; i<strlen(outPath); i++)
		if (outPath[i]=='\\') outPath[i] = '/';

check_spaces:
	i=0;
	while (outPath[i]) {
		if (outPath[i] == '?') break;

		if (outPath[i] != '%') {
			i++;
			continue;
		}
		if (!strnicmp(outPath+i, "%3f", 3)) break;
		if (!strnicmp(outPath+i, "%20", 3)) {
			outPath[i]=' ';
			memmove(outPath + i+1, outPath+i+3, strlen(outPath+i)-2);
		}
		i++;
	}
	return outPath;
}
Beispiel #10
0
static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, const char *inBuffer, u32 inBufferLength,
                                  u16 ES_ID, u32 stream_time, u32 mmlevel)
{
	GF_Err e = GF_OK;
	u32 i, j, k, nb_updates, last_rap=0;
	GF_AUContext *au;
	Bool can_delete_com;
	GF_StreamContext *sc;
	CTXLoadPriv *priv = (CTXLoadPriv *)plug->privateStack;

	/*something failed*/
	if (priv->load_flags==3) return GF_EOS;

	/*this signals main scene deconnection, destroy the context if needed*/
	assert(ES_ID);
	if (!priv->ctx) {
		e = CTXLoad_Setup((GF_BaseDecoder *)plug);
		if (e) return e;
	}


	if (stream_time==(u32)-1) {
		/*seek on root stream: destroy the context manager and reload it. We cannot seek on the main stream
		because commands may have changed node attributes/children and we d'ont track the initial value*/
		if (priv->load_flags && (priv->base_stream_id == ES_ID)) {
			if (priv->src) gf_fclose(priv->src);
			priv->src = NULL;
			gf_sm_load_done(&priv->load);
			priv->file_pos = 0;
			/*queue scene for detach*/
			gf_term_lock_media_queue(priv->scene->root_od->term, GF_TRUE);
			priv->scene->root_od->action_type = GF_ODM_ACTION_SCENE_RECONNECT;
			gf_list_add(priv->scene->root_od->term->media_queue, priv->scene->root_od);
			gf_term_lock_media_queue(priv->scene->root_od->term, GF_FALSE);

			return CTXLoad_Setup((GF_BaseDecoder *)plug);
		}
		i=0;
		while ((sc = (GF_StreamContext *)gf_list_enum(priv->ctx->streams, &i))) {
			/*not our stream*/
			if (!sc->in_root_od && (sc->ESID != ES_ID)) continue;
			/*not the base stream*/
			if (sc->in_root_od && (priv->base_stream_id != ES_ID)) continue;
			/*handle SWF media extraction*/
			if ((sc->streamType == GF_STREAM_OD) && (priv->load_flags==1)) continue;
			sc->last_au_time = 0;
		}
		return GF_OK;
	}

	if (priv->load_flags != 2) {

		if (priv->progressive_support) {
			u32 entry_time;
			char file_buf[4096+1];
			if (!priv->src) {
				priv->src = gf_fopen(priv->file_name, "rb");
				if (!priv->src) return GF_URL_ERROR;
				priv->file_pos = 0;
			}
			priv->load.type = GF_SM_LOAD_XMTA;
			e = GF_OK;
			entry_time = gf_sys_clock();
			gf_fseek(priv->src, priv->file_pos, SEEK_SET);
			while (1) {
				u32 diff;
				s32 nb_read = (s32) fread(file_buf, 1, 4096, priv->src);
				if (nb_read<0) {
					return GF_IO_ERR;
				}
				file_buf[nb_read] = 0;
				if (!nb_read) {
					if (priv->file_pos==priv->file_size) {
						gf_fclose(priv->src);
						priv->src = NULL;
						priv->load_flags = 2;
						gf_sm_load_done(&priv->load);
						break;
					}
					break;
				}

				e = gf_sm_load_string(&priv->load, file_buf, GF_FALSE);
				priv->file_pos += nb_read;
				if (e) break;
				diff = gf_sys_clock() - entry_time;
				if (diff > priv->sax_max_duration) break;
			}
			if (!priv->scene->graph_attached) {
				gf_sg_set_scene_size_info(priv->scene->graph, priv->ctx->scene_width, priv->ctx->scene_height, priv->ctx->is_pixel_metrics);
				gf_scene_attach_to_compositor(priv->scene);

				CTXLoad_CheckStreams(priv);
			}
		}
		/*load first frame only*/
		else if (!priv->load_flags) {
			/*we need the whole file*/
			if (!CTXLoad_CheckDownload(priv)) return GF_OK;

			priv->load_flags = 1;
			e = gf_sm_load_init(&priv->load);
			if (!e) {
				CTXLoad_CheckStreams(priv);
				gf_sg_set_scene_size_info(priv->scene->graph, priv->ctx->scene_width, priv->ctx->scene_height, priv->ctx->is_pixel_metrics);
				/*VRML, override base clock*/
				if ((priv->load.type==GF_SM_LOAD_VRML) || (priv->load.type==GF_SM_LOAD_X3DV) || (priv->load.type==GF_SM_LOAD_X3D)) {
					/*override clock callback*/
					gf_sg_set_scene_time_callback(priv->scene->graph, CTXLoad_GetVRMLTime);
				}
			}
		}
		/*load the rest*/
		else {
			priv->load_flags = 2;
			e = gf_sm_load_run(&priv->load);
			gf_sm_load_done(&priv->load);
			/*in case this was not set in the first pass (XMT)*/
			gf_sg_set_scene_size_info(priv->scene->graph, priv->ctx->scene_width, priv->ctx->scene_height, priv->ctx->is_pixel_metrics);
		}

		if (e<0) {
			gf_sm_load_done(&priv->load);
			gf_sm_del(priv->ctx);
			priv->ctx = NULL;
			priv->load_flags = 3;
			return e;
		}

		/*and figure out duration of root scene, and take care of XMT timing*/
		if (priv->load_flags==2) {
			CTXLoad_CheckStreams(priv);
			if (!gf_list_count(priv->ctx->streams)) {
				gf_scene_attach_to_compositor(priv->scene);
			}
		}
	}

	nb_updates = 0;

	i=0;
	while ((sc = (GF_StreamContext *)gf_list_enum(priv->ctx->streams, &i))) {
		/*not our stream*/
		if (!sc->in_root_od && (sc->ESID != ES_ID)) continue;
		/*not the base stream*/
		if (sc->in_root_od && (priv->base_stream_id != ES_ID)) continue;
		/*handle SWF media extraction*/
		if ((sc->streamType == GF_STREAM_OD) && (priv->load_flags==1)) continue;

		/*check for seek*/
		if (sc->last_au_time > 1 + stream_time) {
			sc->last_au_time = 0;
		}

		can_delete_com = GF_FALSE;
		if (sc->in_root_od && (priv->load_flags==2)) can_delete_com = GF_TRUE;

		/*we're in the right stream, apply update*/
		j=0;

		/*seek*/
		if (!sc->last_au_time) {
			while ((au = (GF_AUContext *)gf_list_enum(sc->AUs, &j))) {
				u32 au_time = (u32) (au->timing*1000/sc->timeScale);

				if (au_time > stream_time)
					break;
				if (au->flags & GF_SM_AU_RAP) last_rap = j-1;
			}
			j = last_rap;
		}

		while ((au = (GF_AUContext *)gf_list_enum(sc->AUs, &j))) {
			u32 au_time = (u32) (au->timing*1000/sc->timeScale);

			if (au_time + 1 <= sc->last_au_time) {
				/*remove first replace command*/
				if (can_delete_com && (sc->streamType==GF_STREAM_SCENE)) {
					while (gf_list_count(au->commands)) {
						GF_Command *com = (GF_Command *)gf_list_get(au->commands, 0);
						gf_list_rem(au->commands, 0);
						gf_sg_command_del(com);
					}
					j--;
					gf_list_rem(sc->AUs, j);
					gf_list_del(au->commands);
					gf_free(au);
				}
				continue;
			}

			if (au_time > stream_time) {
				nb_updates++;
				break;
			}

			if (sc->streamType == GF_STREAM_SCENE) {
				GF_Command *com;
				/*apply the commands*/
				k=0;
				while ((com = (GF_Command *)gf_list_enum(au->commands, &k))) {
					e = gf_sg_command_apply(priv->scene->graph, com, 0);
					if (e) break;
					/*remove commands on base layer*/
					if (can_delete_com) {
						k--;
						gf_list_rem(au->commands, k);
						gf_sg_command_del(com);
					}
				}
			}
			else if (sc->streamType == GF_STREAM_OD) {
				/*apply the commands*/
				while (gf_list_count(au->commands)) {
					Bool keep_com = GF_FALSE;
					GF_ODCom *com = (GF_ODCom *)gf_list_get(au->commands, 0);
					gf_list_rem(au->commands, 0);
					switch (com->tag) {
					case GF_ODF_OD_UPDATE_TAG:
					{
						GF_ODUpdate *odU = (GF_ODUpdate *)com;
						while (gf_list_count(odU->objectDescriptors)) {
							GF_ESD *esd;
							char *remote;
							GF_MuxInfo *mux = NULL;
							GF_ObjectDescriptor *od = (GF_ObjectDescriptor *)gf_list_get(odU->objectDescriptors, 0);
							gf_list_rem(odU->objectDescriptors, 0);
							/*we can only work with single-stream ods*/
							esd = (GF_ESD*)gf_list_get(od->ESDescriptors, 0);
							if (!esd) {
								if (od->URLString) {
									ODS_SetupOD(priv->scene, od);
								} else {
									gf_odf_desc_del((GF_Descriptor *) od);
								}
								continue;
							}
							/*fix OCR dependencies*/
							if (CTXLoad_StreamInRootOD(priv->ctx->root_od, esd->OCRESID)) esd->OCRESID = priv->base_stream_id;

							/*forbidden if ESD*/
							if (od->URLString) {
								gf_odf_desc_del((GF_Descriptor *) od);
								continue;
							}
							/*look for MUX info*/
							k=0;
							while ((mux = (GF_MuxInfo*)gf_list_enum(esd->extensionDescriptors, &k))) {
								if (mux->tag == GF_ODF_MUXINFO_TAG) break;
								mux = NULL;
							}
							/*we need a mux if not animation stream*/
							if (!mux || !mux->file_name) {
								/*only animation streams are handled*/
								if (!esd->decoderConfig) {
									gf_odf_desc_del((GF_Descriptor *) od);
								} else if (esd->decoderConfig->streamType==GF_STREAM_SCENE) {
									/*set ST to private scene to get sure the stream will be redirected to us*/
									esd->decoderConfig->streamType = GF_STREAM_PRIVATE_SCENE;
									esd->dependsOnESID = priv->base_stream_id;
									ODS_SetupOD(priv->scene, od);
								} else if (esd->decoderConfig->streamType==GF_STREAM_INTERACT) {
									GF_UIConfig *cfg = (GF_UIConfig *) esd->decoderConfig->decoderSpecificInfo;
									gf_odf_encode_ui_config(cfg, &esd->decoderConfig->decoderSpecificInfo);
									gf_odf_desc_del((GF_Descriptor *) cfg);
									ODS_SetupOD(priv->scene, od);
								} else {
									gf_odf_desc_del((GF_Descriptor *) od);
								}
								continue;
							}
							//solve url before import
							if (mux->src_url) {
								char *res_url = gf_url_concatenate(mux->src_url, mux->file_name);
								if (res_url) {
									gf_free(mux->file_name);
									mux->file_name = res_url;
								}
								gf_free(mux->src_url);
								mux->src_url = NULL;
							}
							/*text import*/
							if (mux->textNode) {
#ifdef GPAC_DISABLE_MEDIA_IMPORT
								gf_odf_desc_del((GF_Descriptor *) od);
								continue;
#else
								e = gf_sm_import_bifs_subtitle(priv->ctx, esd, mux);
								if (e) {
									e = GF_OK;
									gf_odf_desc_del((GF_Descriptor *) od);
									continue;
								}
								/*set ST to private scene and dependency to base to get sure the stream will be redirected to us*/
								esd->decoderConfig->streamType = GF_STREAM_PRIVATE_SCENE;
								esd->dependsOnESID = priv->base_stream_id;
								ODS_SetupOD(priv->scene, od);
								continue;
#endif
							}

							/*soundstreams are a bit of a pain, they may be declared before any data gets written*/
							if (mux->delete_file) {
								FILE *t = gf_fopen(mux->file_name, "rb");
								if (!t) {
									keep_com = GF_TRUE;
									gf_list_insert(odU->objectDescriptors, od, 0);
									break;
								}
								gf_fclose(t);
							}
							/*remap to remote URL - warning, the URL has already been resolved according to the parent path*/
							remote = (char*)gf_malloc(sizeof(char) * (strlen("gpac://")+strlen(mux->file_name)+1) );
							strcpy(remote, "gpac://");
							strcat(remote, mux->file_name);
							k = od->objectDescriptorID;
							/*if files were created we'll have to clean up (swf import)*/
							if (mux->delete_file) gf_list_add(priv->files_to_delete, gf_strdup(remote));

							gf_odf_desc_del((GF_Descriptor *) od);
							od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG);
							od->URLString = remote;
							od->objectDescriptorID = k;
							ODS_SetupOD(priv->scene, od);
						}
						if (keep_com) break;
					}
					break;
					case GF_ODF_OD_REMOVE_TAG:
					{
						GF_ODRemove *odR = (GF_ODRemove*)com;
						for (k=0; k<odR->NbODs; k++) {
							GF_ObjectManager *odm = gf_scene_find_odm(priv->scene, odR->OD_ID[k]);
							if (odm) gf_odm_disconnect(odm, 1);
						}
					}
					break;
					default:
						break;
					}
					if (keep_com) {
						gf_list_insert(au->commands, com, 0);
						break;
					} else {
						gf_odf_com_del(&com);
					}
					if (e) break;
				}

			}
			sc->last_au_time = au_time + 1;
			/*attach graph to renderer*/
			if (!priv->scene->graph_attached)
				gf_scene_attach_to_compositor(priv->scene);
			if (e) return e;

			/*for root streams remove completed AUs (no longer needed)*/
			if (sc->in_root_od && !gf_list_count(au->commands) ) {
				j--;
				gf_list_rem(sc->AUs, j);
				gf_list_del(au->commands);
				gf_free(au);
			}
		}
	}
	if (e) return e;
	if ((priv->load_flags==2) && !nb_updates) return GF_EOS;
	return GF_OK;
}
Beispiel #11
0
GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL, Program * in_program, PlaylistElement *sub_playlist)
{
	int len, i, currentLineNumber;
	FILE * f=NULL;
	char *m3u8_payload;
	u32 m3u8_size, m3u8pos;
	VariantPlaylist * pl;
	char currentLine[M3U8_BUF_SIZE];
	char ** attributes = NULL;
	s_accumulated_attributes attribs;

	if (!strncmp(file, "gmem://", 7)) {
		if (sscanf(file, "gmem://%d@%p", &m3u8_size, &m3u8_payload) != 2) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_DASH,("[M3U8] Cannot Open m3u8 source %s for reading\n", file));
			return GF_SERVICE_ERROR;
		}
	} else {
		f = gf_f64_open(file, "rt");
		if (!f) {
			GF_LOG(GF_LOG_ERROR, GF_LOG_DASH,("[M3U8] Cannot Open m3u8 file %s for reading\n", file));
			return GF_SERVICE_ERROR;
		}
	}
	if (*playlist == NULL) {
		*playlist = variant_playlist_new();
		if (!(*playlist)) {
			if (f) fclose(f);
			return GF_OUT_OF_MEM;
		}
	}
	pl = *playlist;
	currentLineNumber = 0;
	bzero(&attribs, sizeof(s_accumulated_attributes));
	attribs.bandwidth = 0;
	attribs.durationInSeconds = 0;
	attribs.targetDurationInSeconds = 0;
	attribs.isVariantPlaylist = 0;
	attribs.isPlaylistEnded = 0;
	attribs.minMediaSequence = 0;
	attribs.currentMediaSequence = 0;
	m3u8pos=0;
	while (1) {
		char * eof;
		if (f) {
			if (!fgets(currentLine, sizeof(currentLine), f))
				break;
		} else {
			u32 __idx=0;
			if (m3u8pos>=m3u8_size)
				break;
			while (1) {
				currentLine[__idx] = m3u8_payload[m3u8pos];
				__idx++;
				m3u8pos++;
				if ((currentLine[__idx-1]=='\n') || (currentLine[__idx-1]=='\r')) {
					currentLine[__idx]=0;
					break;
				}
			}
		}
		currentLineNumber++;
		eof = strchr(currentLine, '\r');
		if (eof)
			eof[0] = '\0';
		eof = strchr(currentLine, '\n');
		if (eof)
			eof[0] = '\0';
		len = strlen( currentLine);
		if (len < 1)
			continue;
		if (currentLineNumber == 1) {
			/* Playlist MUST start with #EXTM3U */
/*			if (len < 7 || strncmp("#EXTM3U", currentLine, 7)!=0) {
				fclose(f);
				variant_playlist_del(pl);
				GF_LOG(GF_LOG_ERROR, GF_LOG_DASH, ("Failed to parse M3U8 File, it should start with #EXTM3U, but was : %s\n", currentLine));
				return GF_STREAM_NOT_FOUND;
			}
			continue;
*/		}
		if (currentLine[0] == '#') {
			/* A comment or a directive */
			if (strncmp("#EXT", currentLine, 4)==0) {
				attributes = parseAttributes(currentLine, &attribs);
				if (attributes == NULL) {
					MYLOG(("Comment at line %d : %s\n", currentLineNumber, currentLine));
				} else {
					MYLOG(("Directive at line %d: \"%s\", attributes=", currentLineNumber, currentLine));
					i = 0;
					while (attributes[i] != NULL) {
						MYLOG((" [%d]='%s'", i, attributes[i]));
						gf_free(attributes[i]);
						attributes[i] = NULL;
						i++;
					}
					MYLOG(("\n"));
					gf_free(attributes);
					attributes = NULL;
				}
				if (attribs.isPlaylistEnded) {
					pl->playlistNeedsRefresh = 0;
				}
			}
		} else {
			char * fullURL = currentLine;

			if (gf_url_is_local(currentLine)) {
				/*
				if (gf_url_is_local(baseURL)){
				int num_chars = -1;
				if (baseURL[strlen(baseURL)-1] == '/'){
				num_chars = asprintf(&fullURL, "%s%s", baseURL, currentLine);
				} else {
				num_chars = asprintf(&fullURL, "%s/%s", baseURL, currentLine);
				}
				if (num_chars < 0 || fullURL == NULL){
				variant_playlist_del(*playlist);
				playlist = NULL;
				return GF_OUT_OF_MEM;
				}
				} else */ {
					fullURL = gf_url_concatenate(baseURL, currentLine);
			}
			assert( fullURL );
			}
			{
				u32 count;
				PlaylistElement * currentPlayList = sub_playlist;
				/* First, we have to find the matching program */
				Program * program = in_program;
				if (!in_program) program = variant_playlist_find_matching_program(pl, attribs.programId);
				/* We did not found the program, we create it */
				if (program == NULL) {
					program = program_new(attribs.programId);
					if (program == NULL) {
						/* OUT of memory */
						variant_playlist_del(*playlist);
						if (f) fclose(f);
						playlist = NULL;
						return GF_OUT_OF_MEM;
					}
					gf_list_add(pl->programs, program);
					if (pl->currentProgram < 0)
						pl->currentProgram = program->programId;
				}

				/* OK, we have a program, we have to choose the elements with same bandwidth */
				assert( program );
				assert( program->bitrates);
				count = gf_list_count( program->bitrates);

				if (!currentPlayList) {
					for (i = 0; i < (s32) count; i++) {
						PlaylistElement * itPlayListElement = gf_list_get(program->bitrates, i);
						assert( itPlayListElement );
						if (itPlayListElement->bandwidth == attribs.bandwidth) {
							currentPlayList = itPlayListElement;
							break;
						}
					}
				}

				if (attribs.isVariantPlaylist) {
					/* We are the Variant Playlist */
					if (currentPlayList != NULL) {
						/* should not happen, it means we redefine something previsouly added */
						//assert( 0 );
					}
					currentPlayList = playlist_element_new(
						TYPE_UNKNOWN,
						fullURL,
						attribs.title,
						attribs.codecs,
						attribs.durationInSeconds,
						attribs.byteRangeStart, attribs.byteRangeEnd);
					if (currentPlayList == NULL) {
						/* OUT of memory */
						variant_playlist_del(*playlist);
						playlist = NULL;
						if (f) fclose(f);
						return GF_OUT_OF_MEM;
					}
					assert( fullURL);
					currentPlayList->url = gf_strdup(fullURL);
					currentPlayList->title = attribs.title ? gf_strdup(attribs.title):NULL;
					currentPlayList->codecs = attribs.codecs ? gf_strdup(attribs.codecs):NULL;
					gf_list_add(program->bitrates, currentPlayList);
					currentPlayList->width = attribs.width;
					currentPlayList->height = attribs.height;
				} else {
					/* Normal Playlist */
					assert( pl->programs);
					if (currentPlayList == NULL) {
						/* This is in facts a "normal" playlist without any element in it */
						PlaylistElement * subElement;
						assert(baseURL);
						currentPlayList = playlist_element_new(
							TYPE_PLAYLIST,
							baseURL,
							attribs.title,
							attribs.codecs,
							attribs.durationInSeconds,
							attribs.byteRangeStart, attribs.byteRangeEnd);
						if (currentPlayList == NULL) {
							/* OUT of memory */
							variant_playlist_del(*playlist);
							playlist = NULL;
							if (f) fclose(f);
							return GF_OUT_OF_MEM;
						}
						assert(currentPlayList->element.playlist.elements);
						assert( fullURL);
						assert( currentPlayList->url);
						currentPlayList->title = NULL;
						currentPlayList->codecs = NULL;
						subElement = playlist_element_new(
							TYPE_UNKNOWN,
							fullURL,
							attribs.title,
							attribs.codecs,
							attribs.durationInSeconds,
							attribs.byteRangeStart, attribs.byteRangeEnd);
						if (subElement == NULL) {
							variant_playlist_del(*playlist);
							playlist_element_del(currentPlayList);
							playlist = NULL;
							if (f) fclose(f);
							return GF_OUT_OF_MEM;
						}
						gf_list_add(currentPlayList->element.playlist.elements, subElement);
						gf_list_add(program->bitrates, currentPlayList);
						currentPlayList->element.playlist.computed_duration += subElement->durationInfo;
						assert( program );
						assert( program->bitrates);
						assert( currentPlayList);

					} else {
						PlaylistElement * subElement = playlist_element_new(
							TYPE_UNKNOWN,
							fullURL,
							attribs.title,
							attribs.codecs,
							attribs.durationInSeconds,
							attribs.byteRangeStart, attribs.byteRangeEnd);
						if (currentPlayList->elementType != TYPE_PLAYLIST) {
							currentPlayList->elementType = TYPE_PLAYLIST;
							if (!currentPlayList->element.playlist.elements)
								currentPlayList->element.playlist.elements = gf_list_new();
						}
						if (subElement == NULL) {
							variant_playlist_del(*playlist);
							playlist_element_del(currentPlayList);
							playlist = NULL;
							if (f) fclose(f);
							return GF_OUT_OF_MEM;
						}
						gf_list_add(currentPlayList->element.playlist.elements, subElement);
						currentPlayList->element.playlist.computed_duration += subElement->durationInfo;
					}
				}

				currentPlayList->element.playlist.currentMediaSequence = attribs.currentMediaSequence ;
				/* We first set the default duration for element, aka targetDuration */
				if (attribs.targetDurationInSeconds > 0) {
					currentPlayList->element.playlist.target_duration = attribs.targetDurationInSeconds;
					currentPlayList->durationInfo = attribs.targetDurationInSeconds;
				}
				if (attribs.durationInSeconds) {
					if (currentPlayList->durationInfo == 0) {
						/* we set the playlist duration info as the duration of a segment, only if it's not set
						   There are cases of playlist with the last segment with a duration different from the others
						   (example: Apple bipbop test)*/
						currentPlayList->durationInfo = attribs.durationInSeconds;
					}
				}
				currentPlayList->element.playlist.mediaSequenceMin = attribs.minMediaSequence;
				currentPlayList->element.playlist.mediaSequenceMax = attribs.currentMediaSequence++;
				if (attribs.bandwidth > 1)
					currentPlayList->bandwidth = attribs.bandwidth;
				if (attribs.isPlaylistEnded)
					currentPlayList->element.playlist.is_ended = 1;
			}
			/* Cleanup all line-specific fields */
			if (attribs.title) {
				gf_free(attribs.title);
				attribs.title = NULL;
			}
			attribs.durationInSeconds = 0;
			attribs.bandwidth = 0;
			attribs.programId = 0;
			if (attribs.codecs != NULL) {
				gf_free(attribs.codecs);
				attribs.codecs = NULL;
			}
			if (fullURL != currentLine) {
				gf_free(fullURL);
			}
		}
	}
	if (f) fclose(f);

	for (i=0; i < (int) gf_list_count(pl->programs); i++) {
		u32 j;
		Program *prog = gf_list_get(pl->programs, i);
		prog->computed_duration = 0;
		for (j=0; j<gf_list_count(prog->bitrates); j++) {
			PlaylistElement *ple = gf_list_get(prog->bitrates, j);
			if (ple->elementType==TYPE_PLAYLIST) {
				if (ple->element.playlist.computed_duration > prog->computed_duration)
					prog->computed_duration = ple->element.playlist.computed_duration;
			}
		}
	}
	return GF_OK;
}
Beispiel #12
0
BOOL Osmo4::InitInstance()
{
	CCommandLineInfo cmdInfo;

	m_logs = NULL;

	m_term = NULL;

	memset(&m_user, 0, sizeof(GF_User));

	/*get Osmo4.exe path*/
	strcpy((char *) szApplicationPath, AfxGetApp()->m_pszHelpFilePath);
	while (szApplicationPath[strlen((char *) szApplicationPath)-1] != '\\') szApplicationPath[strlen((char *) szApplicationPath)-1] = 0;
	if (szApplicationPath[strlen((char *) szApplicationPath)-1] != '\\') strcat(szApplicationPath, "\\");

	gf_sys_init(0);

	/*setup user*/
	memset(&m_user, 0, sizeof(GF_User));

	Bool first_launch = 0;
	/*init config and modules*/
	m_user.config = gf_cfg_init(NULL, &first_launch);
	if (!m_user.config) {
		MessageBox(NULL, "GPAC Configuration file not found", "Fatal Error", MB_OK);
		m_pMainWnd->PostMessage(WM_CLOSE);
	}

	char *name = gf_cfg_get_filename(m_user.config);
	char *sep = strrchr(name, '\\');
	if (sep) sep[0] = 0;
	strcpy(szUserPath, name);
	if (sep) sep[0] = '\\';
	gf_free(name);

	const char *opt = gf_cfg_get_key(m_user.config, "General", "SingleInstance");
	m_SingleInstance = (opt && !stricmp(opt, "yes")) ? 1 : 0;

	m_hMutex = NULL;
	if (m_SingleInstance) {
		m_hMutex = CreateMutex(NULL, FALSE, "Osmo4_GPAC_INSTANCE");
		if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
			char szDIR[1024];
			if (m_hMutex) CloseHandle(m_hMutex);
			m_hMutex = NULL;

			if (!static_gpac_hwnd || !IsWindow(static_gpac_hwnd) ) {
				::MessageBox(NULL, "Osmo4 ghost process detected", "Error at last shutdown" , MB_OK);
			} else {
				::SetForegroundWindow(static_gpac_hwnd);

				if (m_lpCmdLine && strlen(m_lpCmdLine)) {
					DWORD res;
					u32 len;
					char *the_url, *cmd;
					GetCurrentDirectory(1024, szDIR);
					if (szDIR[strlen(szDIR)-1] != '\\') strcat(szDIR, "\\");
					cmd = (char *)(const char *) m_lpCmdLine;
					strcpy(static_szCmdLine, "");
					if (cmd[0]=='"') cmd+=1;

					if (!strnicmp(cmd, "-queue ", 7)) {
						strcat(static_szCmdLine, "-queue ");
						cmd += 7;
					}
					the_url = gf_url_concatenate(szDIR, cmd);
					if (!the_url) {
						strcat(static_szCmdLine, cmd);
					} else {
						strcat(static_szCmdLine, the_url);
						gf_free(the_url);
					}
					while ( (len = strlen(static_szCmdLine)) ) {
						char s = static_szCmdLine[len-1];
						if ((s==' ') || (s=='"')) static_szCmdLine[len-1]=0;
						else break;
					}
					::SendMessageTimeout(static_gpac_hwnd, WM_NEWINSTANCE, 0, 0, 0, 1000, &res);
				}
			}
			
			return FALSE;
		}
	}

#if 0
	// Standard initialization
#ifdef _AFXDLL
	Enable3dControls();			// Call this when using MFC in a shared DLL
#else
	Enable3dControlsStatic();	// Call this when linking to MFC statically
#endif

#endif

	SetRegistryKey(_T("GPAC"));
	CMainFrame* pFrame = new CMainFrame;
	m_pMainWnd = pFrame;
	pFrame->LoadFrame(IDR_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL);
	m_pMainWnd->DragAcceptFiles();

	if (m_SingleInstance) static_gpac_hwnd = m_pMainWnd->m_hWnd;

	const char *str = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory");
	m_user.modules = gf_modules_new(str, m_user.config);
	if (!m_user.modules || ! gf_modules_get_count(m_user.modules) ) {
		MessageBox(NULL, "No modules available - system cannot work", "Fatal Error", MB_OK);
		m_pMainWnd->PostMessage(WM_CLOSE);
	}
	else if (first_launch) {
		/*first launch, register all files ext*/
		u32 i;
		for (i=0; i<gf_modules_get_count(m_user.modules); i++) {
			GF_InputService *ifce = (GF_InputService *) gf_modules_load_interface(m_user.modules, i, GF_NET_CLIENT_INTERFACE);
			if (!ifce) continue;
			if (ifce) {
				ifce->CanHandleURL(ifce, "test.test");
				gf_modules_close_interface((GF_BaseInterface *)ifce);
			}
		}
		/*set some shortcuts*/
		gf_cfg_set_key(m_user.config, "Shortcuts", "VolumeUp", "ctrl+Up");
		gf_cfg_set_key(m_user.config, "Shortcuts", "VolumeDown", "ctrl+Down");
		gf_cfg_set_key(m_user.config, "Shortcuts", "FastRewind", "ctrl+Left");
		gf_cfg_set_key(m_user.config, "Shortcuts", "FastForward", "ctrl+Right");
		gf_cfg_set_key(m_user.config, "Shortcuts", "Play", "ctrl+ ");
	}

	/*check log file*/
	str = gf_cfg_get_key(m_user.config, "General", "LogFile");
	if (str) {
		m_logs = gf_f64_open(str, "wt");
		gf_log_set_callback(m_logs, osmo4_do_log);
	}
	else m_logs = NULL;

	/*set log level*/
	if (gf_log_set_tools_levels(gf_cfg_get_key(m_user.config, "General", "Logs")) != GF_OK)
		fprintf(stdout, "osmo4: invalid log level specified\n");

	m_user.opaque = this;
	m_user.os_window_handler = pFrame->m_pWndView->m_hWnd;
	m_user.EventProc = Osmo4_EventProc;

	m_reset = 0;
	orig_width = 320;
	orig_height = 240;

	gf_set_progress_callback(this, Osmo4_progress_cbk);

	m_term = gf_term_new(&m_user);
	if (! m_term) {
		MessageBox(NULL, "Cannot load GPAC Terminal", "Fatal Error", MB_OK);
		m_pMainWnd->PostMessage(WM_CLOSE);
		return TRUE;
	}
	SetOptions();
	UpdateRenderSwitch();

	pFrame->SendMessage(WM_SETSIZE, orig_width, orig_height);
	pFrame->m_Address.ReloadURLs();

	pFrame->m_Sliders.SetVolume();

	m_reconnect_time = 0;


	ParseCommandLine(cmdInfo);

	start_mode = 0;

	if (! cmdInfo.m_strFileName.IsEmpty()) {
		pFrame->m_pPlayList->QueueURL(cmdInfo.m_strFileName);
		pFrame->m_pPlayList->RefreshList();
		pFrame->m_pPlayList->PlayNext();
	} else {
		char sPL[MAX_PATH];
		strcpy((char *) sPL, szUserPath);
		strcat(sPL, "gpac_pl.m3u");
		pFrame->m_pPlayList->OpenPlayList(sPL);
		const char *sOpt = gf_cfg_get_key(GetApp()->m_user.config, "General", "PLEntry");
		if (sOpt) {
			s32 count = (s32)gf_list_count(pFrame->m_pPlayList->m_entries);
			pFrame->m_pPlayList->m_cur_entry = atoi(sOpt);
			if (pFrame->m_pPlayList->m_cur_entry>=count)
				pFrame->m_pPlayList->m_cur_entry = count-1;
		} else {
			pFrame->m_pPlayList->m_cur_entry = -1;
		}
#if 0
		if (pFrame->m_pPlayList->m_cur_entry>=0) {
			start_mode = 1;
			pFrame->m_pPlayList->Play();
		}
#endif

		sOpt = gf_cfg_get_key(GetApp()->m_user.config, "General", "StartupFile");
		if (sOpt) gf_term_connect(m_term, sOpt);
	}
	pFrame->SetFocus();
	pFrame->SetForegroundWindow();
	return TRUE;
}
Beispiel #13
0
GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL, Program * in_program, PlaylistElement *sub_playlist)
{
	int readen, readPointer, len, i, currentLineNumber;
	FILE * f;
	VariantPlaylist * pl;
	char currentLine[M3U8_BUF_SIZE];
	char ** attributes = NULL;
	s_accumulated_attributes attribs;
	f = gf_f64_open(file, "rt");
	if (!f) {
		GF_LOG( GF_LOG_ERROR, GF_LOG_CONTAINER,("[M3U8] Cannot Open m3u8 file %s for reading\n", file));
		return GF_SERVICE_ERROR;
	}
	if (*playlist == NULL) {
		*playlist = variant_playlist_new();
		if (!(*playlist)) {
			fclose(f);
			return GF_OUT_OF_MEM;
		}
	}
	pl = *playlist;
	readen=0;
	readPointer = 0;
	currentLineNumber = 0;
	bzero(&attribs, sizeof(s_accumulated_attributes));
	attribs.bandwidth = 0;
	attribs.durationInSeconds = 0;
	attribs.targetDurationInSeconds = 0;
	attribs.isVariantPlaylist = 0;
	attribs.isPlaylistEnded = 0;
	attribs.minMediaSequence = 0;
	attribs.currentMediaSequence = 0;
	while (fgets(currentLine, sizeof(currentLine), f)) {
		char * eof;
		currentLineNumber++;
		eof = strchr(currentLine, '\r');
		if (eof)
			eof[0] = '\0';
		eof = strchr(currentLine, '\n');
		if (eof)
			eof[0] = '\0';
		len = strlen( currentLine);
		if (len < 1)
			continue;
		if (currentLineNumber == 1) {
			/* Playlist MUST start with #EXTM3U */
			if (len < 7 || strncmp("#EXTM3U", currentLine, 7)!=0) {
				fclose(f);
				variant_playlist_del(pl);
				GF_LOG( GF_LOG_ERROR, GF_LOG_CONTAINER, ("Failed to parse M3U8 File, it should start with #EXTM3U, but was : %s\n", currentLine));
				return GF_STREAM_NOT_FOUND;
			}
			continue;
		}
		if (currentLine[0] == '#') {
			/* A comment or a directive */
			if (strncmp("#EXT", currentLine, 4)==0) {
				attributes = parseAttributes(currentLine, &attribs);
				if (attributes == NULL) {
					MYLOG(("Comment at line %d : %s\n", currentLineNumber, currentLine));
				} else {
					MYLOG(("Directive at line %d: \"%s\", attributes=", currentLineNumber, currentLine));
					i = 0;
					while (attributes[i] != NULL) {
						MYLOG((" [%d]='%s'", i, attributes[i]));
						gf_free(attributes[i]);
						attributes[i] = NULL;
						i++;
					}
					MYLOG(("\n"));
					gf_free(attributes);
					attributes = NULL;
				}
				if (attribs.isPlaylistEnded) {
					pl->playlistNeedsRefresh = 0;
				}
			}
		} else {
			char * fullURL = currentLine;
			//printf("Line %d: '%s'\n", currentLineNumber, currentLine);

			if (gf_url_is_local(currentLine)) {
				/*
				if (gf_url_is_local(baseURL)){
				int num_chars = -1;
				if (baseURL[strlen(baseURL)-1] == '/'){
				num_chars = asprintf(&fullURL, "%s%s", baseURL, currentLine);
				} else {
				num_chars = asprintf(&fullURL, "%s/%s", baseURL, currentLine);
				}
				if (num_chars < 0 || fullURL == NULL){
				variant_playlist_del(*playlist);
				playlist = NULL;
				return GF_OUT_OF_MEM;
				}
				} else */ {
					fullURL = gf_url_concatenate(baseURL, currentLine);
			}
			assert( fullURL );
			/*printf("*** calculated full path = %s from %s and %s\n", fullURL, currentLine, baseURL);*/
			}
			{
				u32 count;
				PlaylistElement * currentPlayList = sub_playlist;
				/* First, we have to find the matching program */
				Program * program = in_program;
				if (!in_program) program = variant_playlist_find_matching_program(pl, attribs.programId);
				/* We did not found the program, we create it */
				if (program == NULL) {
					program = program_new(attribs.programId);
					if (program == NULL) {
						/* OUT of memory */
						variant_playlist_del(*playlist);
						fclose(f);
						playlist = NULL;
						return GF_OUT_OF_MEM;
					}
					gf_list_add(pl->programs, program);
					if (pl->currentProgram < 0)
						pl->currentProgram = program->programId;
				}

				/* OK, we have a program, we have to choose the elements with same bandwidth */
				assert( program );
				assert( program->bitrates);
				count = gf_list_count( program->bitrates);

				if (!currentPlayList) {
					for (i = 0; i < (s32) count; i++) {
						PlaylistElement * itPlayListElement = gf_list_get(program->bitrates, i);
						assert( itPlayListElement );
						if (itPlayListElement->bandwidth == attribs.bandwidth) {
							currentPlayList = itPlayListElement;
							break;
						}
					}
				}

				if (attribs.isVariantPlaylist) {
					/* We are the Variant Playlist */
					if (currentPlayList != NULL) {
						/* should not happen, it means we redefine something previsouly added */
						//assert( 0 );
					}
					currentPlayList = playlist_element_new(
						TYPE_UNKNOWN,
						fullURL,
						attribs.title,
						attribs.codecs,
						attribs.durationInSeconds);
					if (currentPlayList == NULL) {
						/* OUT of memory */
						variant_playlist_del(*playlist);
						playlist = NULL;
						fclose(f);
						return GF_OUT_OF_MEM;
					}
					assert( fullURL);
					currentPlayList->url = gf_strdup(fullURL);
					currentPlayList->title = attribs.title ? gf_strdup(attribs.title):NULL;
					currentPlayList->codecs = attribs.codecs ? gf_strdup(attribs.codecs):NULL;
					gf_list_add(program->bitrates, currentPlayList);
				} else {
					/* Normal Playlist */
					assert( pl->programs);
					if (currentPlayList == NULL) {
						/* This is in facts a "normal" playlist without any element in it */
						PlaylistElement * subElement;
						assert(baseURL);
						currentPlayList = playlist_element_new(
							TYPE_PLAYLIST,
							baseURL,
							attribs.title,
							attribs.codecs,
							attribs.durationInSeconds);
						if (currentPlayList == NULL) {
							/* OUT of memory */
							variant_playlist_del(*playlist);
							playlist = NULL;
							fclose(f);
							return GF_OUT_OF_MEM;
						}
						assert(currentPlayList->element.playlist.elements);
						assert( fullURL);
						assert( currentPlayList->url);
						currentPlayList->title = NULL;
						currentPlayList->codecs = NULL;
						subElement = playlist_element_new(
							TYPE_UNKNOWN,
							fullURL,
							attribs.title,
							attribs.codecs,
							attribs.durationInSeconds);
						if (subElement == NULL) {
							variant_playlist_del(*playlist);
							playlist_element_del(currentPlayList);
							playlist = NULL;
							fclose(f);
							return GF_OUT_OF_MEM;
						}
						gf_list_add(currentPlayList->element.playlist.elements, subElement);
						gf_list_add(program->bitrates, currentPlayList);
						assert( program );
						assert( program->bitrates);
						assert( currentPlayList);

					} else {
						PlaylistElement * subElement = playlist_element_new(
							TYPE_UNKNOWN,
							fullURL,
							attribs.title,
							attribs.codecs,
							attribs.durationInSeconds);
						if (currentPlayList->elementType != TYPE_PLAYLIST) {
							currentPlayList->elementType = TYPE_PLAYLIST;
							if (!currentPlayList->element.playlist.elements)
								currentPlayList->element.playlist.elements = gf_list_new();
						}
						if (subElement == NULL) {
							variant_playlist_del(*playlist);
							playlist_element_del(currentPlayList);
							playlist = NULL;
							fclose(f);
							return GF_OUT_OF_MEM;
						}
						gf_list_add(currentPlayList->element.playlist.elements, subElement);
					}
				}

				currentPlayList->element.playlist.currentMediaSequence = attribs.currentMediaSequence ;
				/* We first set the default duration for element, aka targetDuration */
				if (attribs.targetDurationInSeconds > 0) {
					currentPlayList->element.playlist.target_duration = attribs.targetDurationInSeconds;
					currentPlayList->durationInfo = attribs.targetDurationInSeconds;
				}
				if (attribs.durationInSeconds) {
					currentPlayList->durationInfo = attribs.durationInSeconds;
				}
				currentPlayList->element.playlist.mediaSequenceMin = attribs.minMediaSequence;
				currentPlayList->element.playlist.mediaSequenceMax = attribs.currentMediaSequence++;
				if (attribs.bandwidth > 1)
					currentPlayList->bandwidth = attribs.bandwidth;
				if (attribs.isPlaylistEnded)
					currentPlayList->element.playlist.is_ended = 1;
			}
			/* Cleanup all line-specific fields */
			if (attribs.title) {
				gf_free(attribs.title);
				attribs.title = NULL;
			}
			attribs.durationInSeconds = 0;
			attribs.bandwidth = 0;
			attribs.programId = 0;
			if (attribs.codecs != NULL) {
				gf_free(attribs.codecs);
				attribs.codecs = NULL;
			}
			if (fullURL != currentLine) {
				gf_free(fullURL);
			}
		}
	}
	fclose(f);
	return GF_OK;
}
Beispiel #14
0
static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char *url, const char *parent_url, Bool no_mime_check, char **out_url, GF_Err *ret_code, GF_DownloadSession **the_session)
{
	u32 i;
	GF_Err e;
	char *sURL, *qm, *frag, *ext, *mime_type, *url_res;
	char szExt[50];
	const char *force_module = NULL;
	GF_InputService *ifce;
	Bool skip_mime = 0;
	memset(szExt, 0, sizeof(szExt));

	(*ret_code) = GF_OK;
	ifce = NULL;
	mime_type = NULL;
	GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Looking for plugin for URL %s\n", url));
	*out_url = NULL;
	sURL = NULL;
	if (!url || !strncmp(url, "\\\\", 2) ) {
		(*ret_code) = GF_URL_ERROR;
		goto exit;
	}

	if (!strnicmp(url, "libplayer://", 12)) {
		force_module = "LibPlayer";
	}

	/*used by GUIs scripts to skip URL concatenation*/
	if (!strncmp(url, "gpac://", 7)) sURL = gf_strdup(url+7);
	/*opera-style localhost URLs*/
	else if (!strncmp(url, "file://localhost", 16)) sURL = gf_strdup(url+16);

	else if (parent_url) sURL = gf_url_concatenate(parent_url, url);

	/*path absolute*/
	if (!sURL) sURL = gf_strdup(url);

	if (gf_url_is_local(sURL))
		gf_url_to_fs_path(sURL);

	if (the_session) *the_session = NULL;
	if (no_mime_check) {
		mime_type = NULL;
	} else {
		/*fetch a mime type if any. If error don't even attempt to open the service
		TRYTOFIXME: it would be nice to reuse the downloader created while fetching the mime type, however
		we don't know if the plugin will want it threaded or not....
		*/
		mime_type = get_mime_type(term, sURL, &e, the_session);
		if (e) {
			(*ret_code) = e;
			goto exit;
		}
	}

	if (mime_type &&
		(!stricmp(mime_type, "text/plain")
			|| !stricmp(mime_type, "video/quicktime")
			|| !stricmp(mime_type, "application/octet-stream")
		)
	) {
		skip_mime = 1;
	}

	ifce = NULL;

	/*load from mime type*/
	if (mime_type && !skip_mime) {
		const char *sPlug = gf_cfg_get_key(term->user->config, "MimeTypes", mime_type);
		GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Mime type found: %s\n", mime_type));
		if (!sPlug) {
			gf_free(mime_type);
			mime_type=NULL;
		}
		if (sPlug) sPlug = strrchr(sPlug, '"');
		if (sPlug) {
			sPlug += 2;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_DASH, ("%s:%d FOUND matching module %s\n", __FILE__, __LINE__, sPlug));
			ifce = (GF_InputService *) gf_modules_load_interface_by_name(term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE);
			if (force_module && ifce && !strstr(ifce->module_name, force_module)) {
				gf_modules_close_interface((GF_BaseInterface *) ifce);
				ifce = NULL;
			}
			if (ifce && !net_check_interface(ifce) ) {
				gf_modules_close_interface((GF_BaseInterface *) ifce);
				ifce = NULL;
			}
		}
	}

	/* The file extension, if any, is before '?' if any or before '#' if any.*/
	url_res = strrchr(sURL, '/');
	if (!url_res) url_res = strrchr(sURL, '\\');
	if (!url_res) url_res = sURL;
	qm = strchr(url_res, '?');
	if (qm) {
		qm[0] = 0;
		ext = strrchr(url_res, '.');
		qm[0] = '?';
	} else {
		frag = strchr(url_res, '#');
		if (frag) {
			frag[0] = 0;
			ext = strrchr(url_res, '.');
			frag[0] = '#';
		} else {
			ext = strrchr(url_res, '.');
		}
	}
	if (ext && !stricmp(ext, ".gz")) {
		char *anext;
		ext[0] = 0;
		anext = strrchr(sURL, '.');
		ext[0] = '.';
		ext = anext;
	}
	/*no mime type: either local or streaming. If streaming discard extension checking*/
	if (!ifce && !mime_type && strstr(sURL, "://") && strnicmp(sURL, "file://", 7)) ext = NULL;

	/*browse extensions for prefered module*/
	if (!ifce && ext) {
		u32 keyCount;
		strncpy(szExt, &ext[1], 49);
		ext = strrchr(szExt, '?');
		if (ext) ext[0] = 0;
		ext = strrchr(szExt, '#');
		if (ext) ext[0] = 0;

		GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] No mime type found - checking by extension %s\n", szExt));
		assert( term && term->user && term->user->modules);
		keyCount = gf_cfg_get_key_count(term->user->config, "MimeTypes");
		for (i=0; i<keyCount; i++) {
			char *sPlug;
			const char *sKey;
			const char *sMime;
			sMime = gf_cfg_get_key_name(term->user->config, "MimeTypes", i);
			if (!sMime) continue;
			sKey = gf_cfg_get_key(term->user->config, "MimeTypes", sMime);
			if (!sKey) continue;
			if (!check_extension(sKey, szExt)) continue;
			sPlug = strrchr(sKey, '"');
			if (!sPlug) continue;	/*bad format entry*/
			sPlug += 2;

			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Trying module[%i]=%s, mime=%s\n", i, sPlug, sMime));
			ifce = (GF_InputService *) gf_modules_load_interface_by_name(term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE);
			if (!ifce){
				GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] module[%i]=%s, mime=%s, cannot be loaded for GF_NET_CLIENT_INTERFACE.\n", i, sPlug, sMime));
				continue;
			}
			if (force_module && ifce && !strstr(ifce->module_name, force_module)) {
				gf_modules_close_interface((GF_BaseInterface *) ifce);
				ifce = NULL;
				continue;
			}
			if (ifce && !net_check_interface(ifce)) {
				gf_modules_close_interface((GF_BaseInterface *) ifce);
				ifce = NULL;
				continue;
			}
			break;
		}
	}

	/*browse all modules*/
	if (!ifce) {
		GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Not found any interface, trying browsing all modules...\n"));
		for (i=0; i< gf_modules_get_count(term->user->modules); i++) {
			ifce = (GF_InputService *) gf_modules_load_interface(term->user->modules, i, GF_NET_CLIENT_INTERFACE);
			if (!ifce) continue;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Checking if module %s supports URL %s\n", ifce->module_name, sURL));
			if (force_module && ifce && !strstr(ifce->module_name, force_module)) {
			}
			else if (net_check_interface(ifce) && ifce->CanHandleURL(ifce, sURL)) {
				break;
			}
			gf_modules_close_interface((GF_BaseInterface *) ifce);
			ifce = NULL;
		}
	}
exit:
	if (!ifce){
  	    GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("[Terminal] Did not find any input plugin for URL %s (%s)\n", sURL ? sURL : url, mime_type ? mime_type : "no mime type"));
	    if (sURL) gf_free(sURL);
		if ( (*ret_code) == GF_OK) (*ret_code) = GF_NOT_SUPPORTED;
	    *out_url = NULL;

		if (the_session && *the_session) {
			gf_dm_sess_del(*the_session);
		}
	} else {
	    *out_url = sURL;
	    GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[Terminal] Found input plugin %s for URL %s (%s)\n", ifce->module_name, sURL, mime_type ? mime_type : "no mime type"));
	}
	if (mime_type)
	  gf_free(mime_type);
	mime_type = NULL;
	return ifce;
}
Beispiel #15
0
static void imagetexture_update(GF_TextureHandler *txh)
{
	if (gf_node_get_tag(txh->owner)!=TAG_MPEG4_CacheTexture) {
		MFURL url = ((M_ImageTexture *) txh->owner)->url;

		/*setup texture if needed*/
		if (!txh->is_open && url.count) {
			gf_sc_texture_play(txh, &url);
		}
		gf_sc_texture_update_frame(txh, 0);

		if (
		    /*URL is present but not opened - redraw till fetch*/
		    /* (txh->stream && !txh->tx_io) && */
		    /*image has been updated*/
		    txh->needs_refresh) {
			/*mark all subtrees using this image as dirty*/
			gf_node_dirty_parents(txh->owner);
			gf_sc_invalidate(txh->compositor, NULL);
		}
		return;
	}
	/*cache texture case*/
	else {
		M_CacheTexture *ct = (M_CacheTexture *) txh->owner;

		/*decode cacheTexture data */
		if ((ct->data || ct->image.buffer) && !txh->data) {
#ifndef GPAC_DISABLE_AV_PARSERS
			u32 out_size;
			GF_Err e;

			/*BT/XMT playback: load to memory*/
			if (ct->image.buffer) {
				char *par = (char *) gf_scene_get_service_url( gf_node_get_graph(txh->owner ) );
				char *src_url = gf_url_concatenate(par, ct->image.buffer);
				FILE *test = gf_fopen( src_url ? src_url : ct->image.buffer, "rb");
				if (test) {
					fseek(test, 0, SEEK_END);
					ct->data_len = (u32) gf_ftell(test);
					ct->data = gf_malloc(sizeof(char)*ct->data_len);
					fseek(test, 0, SEEK_SET);
					if (ct->data_len != fread(ct->data, 1, ct->data_len, test)) {
						GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor] Failed to load CacheTexture data from file %s: IO err\n", src_url ? src_url : ct->image.buffer ) );
						gf_free(ct->data);
						ct->data = NULL;
						ct->data_len = 0;
					}
					gf_fclose(test);
				} else {
					GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor] Failed to load CacheTexture data from file %s: not found\n", src_url ? src_url : ct->image.buffer ) );
				}
				ct->image.buffer = NULL;
				if (src_url) gf_free(src_url);
			}

			/*BIFS decoded playback*/
			switch (ct->objectTypeIndication) {
			case GPAC_OTI_IMAGE_JPEG:
				out_size = 0;
				e = gf_img_jpeg_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, NULL, &out_size, 3);
				if (e==GF_BUFFER_TOO_SMALL) {
					u32 BPP;
					txh->data = gf_malloc(sizeof(char) * out_size);
					if (txh->pixelformat==GF_PIXEL_GREYSCALE) BPP = 1;
					else BPP = 3;

					e = gf_img_jpeg_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, txh->data, &out_size, BPP);
					if (e==GF_OK) {
						gf_sc_texture_allocate(txh);
						gf_sc_texture_set_data(txh);
						txh->needs_refresh = 1;
						txh->stride = out_size / txh->height;
					}
				}
				break;
			case GPAC_OTI_IMAGE_PNG:
				out_size = 0;
				e = gf_img_png_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, NULL, &out_size);
				if (e==GF_BUFFER_TOO_SMALL) {
					txh->data = gf_malloc(sizeof(char) * out_size);
					e = gf_img_png_dec((char *) ct->data, ct->data_len, &txh->width, &txh->height, &txh->pixelformat, txh->data, &out_size);
					if (e==GF_OK) {
						gf_sc_texture_allocate(txh);
						gf_sc_texture_set_data(txh);
						txh->needs_refresh = 1;
						txh->stride = out_size / txh->height;
					}
				}
				break;
			}

#endif // GPAC_DISABLE_AV_PARSERS

			/*cacheURL is specified, store the image*/
			if (ct->cacheURL.buffer) {
				u32 i;
				u8 hash[20];
				FILE *cached_texture;
				char szExtractName[GF_MAX_PATH], section[64], *opt, *src_url;
				opt = (char *) gf_cfg_get_key(txh->compositor->user->config, "General", "CacheDirectory");
				if (opt) {
					strcpy(szExtractName, opt);
				} else {
					opt = gf_get_default_cache_directory();
					strcpy(szExtractName, opt);
					gf_free(opt);
				}
				strcat(szExtractName, "/");
				src_url = (char *) gf_scene_get_service_url( gf_node_get_graph(txh->owner ) );

				gf_sha1_csum((u8 *)src_url, (u32) strlen(src_url), hash);
				for (i=0; i<20; i++) {
					char t[3];
					t[2] = 0;
					sprintf(t, "%02X", hash[i]);
					strcat(szExtractName, t);
				}
				strcat(szExtractName, "_");

				strcat(szExtractName, ct->cacheURL.buffer);
				cached_texture = gf_fopen(szExtractName, "wb");
				if (cached_texture) {
					gf_fwrite(ct->data, 1, ct->data_len, cached_texture);
					gf_fclose(cached_texture);
				}

				/*and write cache info*/
				if (ct->expirationDate!=0) {
					sprintf(section, "@cache=%p", ct);
					gf_cfg_set_key(txh->compositor->user->config, section, "serviceURL", src_url);
					gf_cfg_set_key(txh->compositor->user->config, section, "cacheFile", szExtractName);
					gf_cfg_set_key(txh->compositor->user->config, section, "cacheName", ct->cacheURL.buffer);

					if (ct->expirationDate>0) {
						char exp[50];
						u32 sec, frac;
						gf_net_get_ntp(&sec, &frac);
						sec += ct->expirationDate;
						sprintf(exp, "%u", sec);
						gf_cfg_set_key(txh->compositor->user->config, section, "expireAfterNTP", exp);
					} else {
						gf_cfg_set_key(txh->compositor->user->config, section, "expireAfterNTP", "0");
					}
				}
			}

			/*done with image, destroy buffer*/
			if (ct->data) gf_free(ct->data);
			ct->data = NULL;
			ct->data_len = 0;
		}
	}
}
Beispiel #16
0
void gf_sm_update_bitwrapper_buffer(GF_Node *node, const char *fileName)
{
    u32 data_size = 0;
    char *data = NULL;
    char *buffer;
    M_BitWrapper *bw = (M_BitWrapper *)node;

    if (!bw->buffer.buffer) return;
    buffer = bw->buffer.buffer;
    if (!strnicmp(buffer, "file://", 7)) {
        char *url = gf_url_concatenate(fileName, buffer+7);
        if (url) {
            FILE *f = fopen(url, "rb");
            if (f) {
                fseek(f, 0, SEEK_END);
                data_size = ftell(f);
                fseek(f, 0, SEEK_SET);
                data = gf_malloc(sizeof(char)*data_size);
                if (data) {
                    size_t s = fread(data, 1, data_size, f);
                    assert(s == data_size);
                }
                fclose(f);
            }
            gf_free(url);
        }
    } else {
        Bool base_64 = 0;
        if (!strnicmp(buffer, "data:application/octet-string", 29)) {
            char *sep = strchr(bw->buffer.buffer, ',');
            base_64 = strstr(bw->buffer.buffer, ";base64") ? 1 : 0;
            if (sep) buffer = sep+1;
        }

        if (base_64) {
            data_size = 2 * (u32) strlen(buffer);
            data = (char*)gf_malloc(sizeof(char)*data_size);
            if (data)
                data_size = gf_base64_decode(buffer, (u32) strlen(buffer), data, data_size);
        } else {
            u32 i, c;
            char s[3];
            data_size = (u32) strlen(buffer) / 3;
            data = (char*)gf_malloc(sizeof(char) * data_size);
            if (data) {
                s[2] = 0;
                for (i=0; i<data_size; i++) {
                    s[0] = buffer[3*i+1];
                    s[1] = buffer[3*i+2];
                    sscanf(s, "%02X", &c);
                    data[i] = (unsigned char) c;
                }
            }
        }
    }
    gf_free(bw->buffer.buffer);
    bw->buffer.buffer = NULL;
    bw->buffer_len = 0;
    if (data) {
        bw->buffer.buffer = data;
        bw->buffer_len = data_size;
    }

}
Beispiel #17
0
static GF_Err gf_dm_setup_from_url(GF_DownloadSession *sess, char *url)
{
	char *tmp, tmp_url[GF_MAX_PATH];
	const char *opt;
	if (!strnicmp(url, "http://", 7)) {
		url += 7;
		sess->port = 80;
		sess->do_requests = http_do_requests;
	} 
	else if (!strnicmp(url, "https://", 8)) {
		url += 8;
		sess->port = 443;
#ifndef GPAC_HAS_SSL
		return GF_NOT_SUPPORTED;
#endif
		sess->flags |= GF_DOWNLOAD_SESSION_USE_SSL;
		sess->do_requests = http_do_requests;
	}
	else if (!strnicmp(url, "ftp://", 6)) {
		url += 6;
		sess->port = 21;
		sess->do_requests = NULL;
		return GF_NOT_SUPPORTED;
	} 
	/*relative URL*/
	else if (!strstr(url, "://")) {
		u32 i;
		if (!sess->remote_path) return GF_BAD_PARAM;
		tmp = gf_url_concatenate(sess->remote_path, url);
		free(sess->remote_path);
		sess->remote_path = tmp;
		for (i=0; i<strlen(sess->remote_path); i++)
			if (sess->remote_path[i]=='\\') sess->remote_path[i]='/';

	} else {
		return GF_BAD_PARAM;
	}


	tmp = strchr(url, '/');
	sess->remote_path = strdup(tmp ? tmp : "/");
	if (tmp) {
		tmp[0] = 0;
		strcpy(tmp_url, url);
		tmp[0] = '/';
	} else {
		strcpy(tmp_url, url);
	}
	
	tmp = strrchr(tmp_url, ':');
	if (tmp) {
		sess->port = atoi(tmp+1);
		tmp[0] = 0;
	}
	tmp = strrchr(tmp_url, '@');
	if (tmp) {
		sess->server_name = strdup(tmp+1);
		tmp[0] = 0;
		tmp = strchr(tmp_url, ':');
		if (sess->user) free(sess->user);
		sess->user = NULL;
		if (sess->passwd) free(sess->passwd);
		sess->passwd = NULL;

		if (tmp) {
			sess->passwd = strdup(tmp+1);
			tmp[0] = 0;
		}
		sess->user = strdup(tmp_url);
	} else {
		sess->server_name = strdup(tmp_url);
	}

	/*setup BW limiter*/
	sess->limit_data_rate = 0;
	opt = gf_cfg_get_key(sess->dm->cfg, "Downloader", "MaxRate");
	if (opt) {
		/*use it in in BYTES per second*/
		sess->limit_data_rate = 1024 * atoi(opt) / 8;
	}

	return GF_OK;
}