Ejemplo n.º 1
0
GF_EXPORT
Bool gf_inline_is_default_viewpoint(GF_Node *node)
{
	const char *nname, *seg_name;
	GF_SceneGraph *sg = gf_node_get_graph(node);
	GF_Scene *scene = sg ? (GF_Scene *) gf_sg_get_private(sg) : NULL;
	if (!scene) return 0;

	nname = gf_node_get_name(node);
	if (!nname) return 0;

	/*check any viewpoint*/
	seg_name = strrchr(scene->root_od->net_service->url, '#');
	
	/*check the URL of the parent*/
	if (!seg_name && scene->current_url) {
		if (scene->current_url->count && scene->current_url->vals[0].url) 
			seg_name = strrchr(scene->current_url->vals[0].url, '#');
	} else if (!seg_name && scene->root_od->mo && scene->root_od->mo->URLs.count && scene->root_od->mo->URLs.vals[0].url) {
		seg_name = strrchr(scene->root_od->mo->URLs.vals[0].url, '#');
	}
	if (!seg_name) return 0;
	seg_name += 1;
	/*look for a media segment with this name - if none found, this is a viewpoint name*/
	if (gf_odm_find_segment(scene->root_od, (char *) seg_name) != NULL) return 0;

	return (!strcmp(nname, seg_name));
}
Ejemplo n.º 2
0
/* Creates a subscene from the xlink:href */
static GF_Scene *gf_svg_get_subscene(GF_Node *elt, XLinkAttributesPointers *xlinkp, SMILSyncAttributesPointers *syncp, Bool use_sync, Bool primary_resource)
{
	MFURL url;
	Bool lock_timelines = 0;
	GF_MediaObject *mo;
	GF_SceneGraph *graph = gf_node_get_graph(elt);
	GF_Scene *scene = (GF_Scene *)gf_sg_get_private(graph);
	if (!scene) return NULL;

	if (use_sync && syncp) {
		switch ((syncp->syncBehavior?*syncp->syncBehavior:SMIL_SYNCBEHAVIOR_DEFAULT)) {
		case SMIL_SYNCBEHAVIOR_LOCKED:
		case SMIL_SYNCBEHAVIOR_CANSLIP:
			lock_timelines = 1;
			break;
		case SMIL_SYNCBEHAVIOR_DEFAULT:
		{
#if 0
			if (svg && syncp) {
				switch ((syncp->syncBehaviorDefault ? *syncp->syncBehaviorDefault : SMIL_SYNCBEHAVIOR_LOCKED)) {
				case SMIL_SYNCBEHAVIOR_LOCKED:
				case SMIL_SYNCBEHAVIOR_CANSLIP:
					lock_timelines = 1;
					break;
				default:
					break;
				}
			}
#endif
		}
		default:
			break;
		}
	}
	memset(&url, 0, sizeof(MFURL));
	if (!xlinkp->href) return NULL;

	gf_term_get_mfurl_from_xlink(elt, &url);

	while (scene->secondary_resource && scene->root_od->parentscene)
		scene = scene->root_od->parentscene;

	mo = gf_scene_get_media_object_ex(scene, &url, GF_MEDIA_OBJECT_SCENE, lock_timelines, NULL, primary_resource, elt);
	gf_sg_vrml_mf_reset(&url, GF_SG_VRML_MFURL);

	if (!mo || !mo->odm) return NULL;
	mo->odm->subscene->secondary_resource = primary_resource ? 0 : 1;
	return mo->odm->subscene;
}
Ejemplo n.º 3
0
GF_Node *gf_scene_get_keynav(GF_SceneGraph *sg, GF_Node *sensor)
{
#ifndef GPAC_DISABLE_VRML
	u32 i, count;
	GF_Scene *scene = gf_sg_get_private(sg);
	if (!scene) return NULL;
	if (!sensor) return gf_list_get(scene->keynavigators, 0);

	count = gf_list_count(scene->keynavigators);
	for (i=0; i<count; i++) {
		M_KeyNavigator *kn = gf_list_get(scene->keynavigators, i);
		if (kn->sensor==sensor) return (GF_Node *) kn;
	}
#endif
	return NULL;
}
Ejemplo n.º 4
0
static void TraverseInputSensor(GF_Node *node, void *rs, Bool is_destroy)
{
	ISStack *st = (ISStack*)gf_node_get_private(node);
	M_InputSensor *is = (M_InputSensor *)node;

	if (is_destroy) {
		GF_Scene *scene;
		if (st->registered) IS_Unregister(node, st);
		scene = (GF_Scene*)gf_sg_get_private(gf_node_get_graph(node));
		gf_term_unqueue_node_traverse(scene->root_od->term, node);
		gf_free(st);
	} else {
		/*get decoder object */
		if (!st->mo) st->mo = gf_mo_register(node, &is->url, 0, 0);
		/*register with decoder*/
		if (st->mo && !st->registered) IS_Register(node);
	}
}
Ejemplo n.º 5
0
static void RenderInputSensor(GF_Node *node, void *rs, Bool is_destroy)
{
	ISStack *st = (ISStack*)gf_node_get_private(node);
	M_InputSensor *is = (M_InputSensor *)node;

	if (is_destroy) {
		GF_InlineScene *is;
		if (st->registered) IS_Unregister(st);
		is = (GF_InlineScene*)gf_sg_get_private(gf_node_get_graph(node));
		gf_term_rem_render_node(is->root_od->term, node);
		free(st);
	} else {
		/*get decoder object */
		if (!st->mo) st->mo = gf_mo_find(node, &is->url, 0);
		/*register with decoder*/
		if (st->mo && !st->registered) IS_Register(node);
	}
}
Ejemplo n.º 6
0
static Bool gf_inline_set_scene(M_Inline *root)
{
	GF_MediaObject *mo;
	GF_Scene *parent;
	GF_SceneGraph *graph = gf_node_get_graph((GF_Node *) root);
	parent = (GF_Scene *)gf_sg_get_private(graph);
	if (!parent) return 0;

	mo = gf_scene_get_media_object_ex(parent, &root->url, GF_MEDIA_OBJECT_SCENE, 0, NULL, 0, (GF_Node*)root);
	if (!mo || !mo->odm) return 0;

	if (!mo->odm->subscene) {
		gf_term_invalidate_compositor(parent->root_od->term);
		return 0;
	}
	/*assign inline scene as private stack of inline node, and remember inline node for event propagation*/
	gf_node_set_private((GF_Node *)root, mo->odm->subscene);
	/*play*/
	gf_mo_play(mo, 0, -1, 0);
	return 1;
}
Ejemplo n.º 7
0
GF_EXPORT
GF_Err gf_term_get_mfurl_from_xlink(GF_Node *node, MFURL *mfurl)
{
	u32 stream_id = 0;
	GF_Err e = GF_OK;
	SFURL *sfurl = NULL;
	GF_FieldInfo info;
	XMLRI *iri;
	GF_Scene *scene = gf_sg_get_private(gf_node_get_graph(node));
	if (!scene) return GF_BAD_PARAM;

	gf_sg_vrml_mf_reset(mfurl, GF_SG_VRML_MFURL);

	e = gf_node_get_attribute_by_tag(node, TAG_XLINK_ATT_href, 0, 0, &info);
	if (e) return e;

	iri = (XMLRI*)info.far_ptr;

	if (iri->type==XMLRI_STREAMID) {
		stream_id = iri->lsr_stream_id;
	} else if (!iri->string) return GF_OK;

	mfurl->count = 1;
	GF_SAFEALLOC(mfurl->vals, SFURL)
	sfurl = mfurl->vals;
	sfurl->OD_ID = stream_id;
	if (stream_id) return GF_OK;

	if (!strncmp(iri->string, "data:", 5)) {
		const char *cache_dir = gf_cfg_get_key(scene->root_od->term->user->config, "General", "CacheDirectory");
		e = gf_node_store_embedded_data(iri, cache_dir, "embedded_");
		if (e) return e;
		sfurl->url = gf_strdup(iri->string);
		return GF_OK;
	}
	sfurl->url = gf_term_resolve_xlink(node, iri->string);
	return e;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
GF_MediaObject *gf_mo_load_xlink_resource(GF_Node *node, Bool primary_resource, Double clipBegin, Double clipEnd)
{
	GF_Scene *new_resource;
	SVGAllAttributes all_atts;
	XLinkAttributesPointers xlinkp;
	SMILSyncAttributesPointers syncp;
	GF_Scene *scene = gf_sg_get_private(gf_node_get_graph(node));
	if (!scene) return NULL;

	gf_svg_flatten_attributes((SVG_Element *)node, &all_atts);
	xlinkp.actuate = all_atts.xlink_actuate;
	xlinkp.arcrole = all_atts.xlink_arcrole;
	xlinkp.href = all_atts.xlink_href;
	xlinkp.role = all_atts.xlink_role;
	xlinkp.show = all_atts.xlink_show;
	xlinkp.title = all_atts.xlink_title;
	xlinkp.type = all_atts.xlink_type;
	syncp.syncBehavior = all_atts.syncBehavior;
	syncp.syncBehaviorDefault = all_atts.syncBehaviorDefault;
	syncp.syncMaster = all_atts.syncMaster;
	syncp.syncReference = all_atts.syncReference;
	syncp.syncTolerance = all_atts.syncTolerance;
	syncp.syncToleranceDefault = all_atts.syncToleranceDefault;

	if (!xlinkp.href) return NULL;

	if (xlinkp.href->type == XMLRI_ELEMENTID) return NULL;
//	else if (xlinkp.href->string && (xlinkp.href->string[0]=='#')) return NULL;

	new_resource = gf_svg_get_subscene(node, &xlinkp, &syncp, primary_resource ? 1 : 0, primary_resource);
	if (!new_resource) return NULL;

	/*play*/
	gf_mo_play(new_resource->root_od->mo, 0, -1, 0);

	return new_resource->root_od->mo;
}
Ejemplo n.º 10
0
GF_EXPORT
GF_MediaObject *gf_mo_register(GF_Node *node, MFURL *url, Bool lock_timelines, Bool force_new_res)
{
	u32 obj_type;
#ifndef GPAC_DISABLE_SVG
	Bool post_pone;
	GF_FieldInfo info;
#endif
	GF_Scene *scene;
	GF_MediaObject *res, *syncRef;
	GF_SceneGraph *sg = gf_node_get_graph(node);
	if (!sg) return NULL;
	scene = (GF_Scene*)gf_sg_get_private(sg);
	if (!scene) return NULL;

	syncRef = NULL;

	/*keep track of the kind of object expected if URL is not using OD scheme*/
	switch (gf_node_get_tag(node)) {
#ifndef GPAC_DISABLE_VRML
	/*MPEG-4 / VRML / X3D only*/
	case TAG_MPEG4_AudioClip:
	case TAG_MPEG4_AudioSource:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_AudioClip:
#endif
		obj_type = GF_MEDIA_OBJECT_AUDIO;
		break;
	case TAG_MPEG4_SBVCAnimation:
	case TAG_MPEG4_AnimationStream:
		obj_type = GF_MEDIA_OBJECT_UPDATES;
		break;
	case TAG_MPEG4_BitWrapper:
		obj_type = GF_MEDIA_OBJECT_SCENE;
		break;
	case TAG_MPEG4_InputSensor:
		obj_type = GF_MEDIA_OBJECT_INTERACT;
		break;
	case TAG_MPEG4_Background2D:
	case TAG_MPEG4_Background:
	case TAG_MPEG4_ImageTexture:
	case TAG_MPEG4_CacheTexture:
	case TAG_MPEG4_MovieTexture:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Background:
	case TAG_X3D_ImageTexture:
	case TAG_X3D_MovieTexture:
#endif
		obj_type = GF_MEDIA_OBJECT_VIDEO;
		break;
	case TAG_MPEG4_Inline:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Inline:
#endif
		obj_type = GF_MEDIA_OBJECT_SCENE;
		break;
#endif /*GPAC_DISABLE_VRML*/

		/*SVG*/
#ifndef GPAC_DISABLE_SVG
	case TAG_SVG_audio:
		obj_type = GF_MEDIA_OBJECT_AUDIO;
		if (gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_syncReference, GF_FALSE, GF_FALSE, &info)==GF_OK) {
			syncRef = get_sync_reference(scene, (XMLRI *)info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone);
			/*syncRef is specified but doesn't exist yet, post-pone*/
			if (post_pone) return NULL;
		}
		break;
	case TAG_SVG_video:
		obj_type = GF_MEDIA_OBJECT_VIDEO;
		if (gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_syncReference, GF_FALSE, GF_FALSE, &info)==GF_OK) {
			syncRef = get_sync_reference(scene, (XMLRI *)info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone);
			/*syncRef is specified but doesn't exist yet, post-pone*/
			if (post_pone) return NULL;
		}
		break;
	case TAG_SVG_image:
		obj_type = GF_MEDIA_OBJECT_VIDEO;
		break;
	case TAG_SVG_foreignObject:
	case TAG_SVG_animation:
		obj_type = GF_MEDIA_OBJECT_SCENE;
		break;
	case TAG_LSR_updates:
		obj_type = GF_MEDIA_OBJECT_UPDATES;
		break;
#endif

	default:
		obj_type = GF_MEDIA_OBJECT_UNDEF;
		break;
	}

	/*move to primary resource handler*/
	while (scene->secondary_resource && scene->root_od->parentscene)
		scene = scene->root_od->parentscene;

	res = gf_scene_get_media_object_ex(scene, url, obj_type, lock_timelines, syncRef, force_new_res, node);
	return res;
}
Ejemplo n.º 11
0
static void gf_inline_traverse(GF_Node *n, void *rs, Bool is_destroy)
{
	MFURL *current_url;
	GF_Scene *scene = (GF_Scene *)gf_node_get_private(n);

	if (is_destroy) {
		GF_MediaObject *mo;
		if (!scene) return;
		mo = scene->root_od ? scene->root_od->mo : NULL;

		gf_scene_notify_event(scene, GF_EVENT_UNLOAD, n, NULL, GF_OK);
		if (!mo) return;
		gf_list_del_item(mo->nodes, n);

		/*disconnect current inline if we're the last one using it (same as regular OD session leave/join)*/
		if (mo->num_open) {
			mo->num_open --;
			if (!mo->num_open) {
				gf_term_lock_media_queue(scene->root_od->term, 1);

				/*this is unspecified in the spec: whenever an inline not using the 
				OD framework is destroyed, destroy the associated resource*/
				if (mo->OD_ID == GF_MEDIA_EXTERNAL_ID) {
					/*get parent scene and remove MediaObject in case the ressource
					gets re-requested later on*/
					GF_Scene *parent_scene = (GF_Scene *)gf_sg_get_private(gf_node_get_graph((GF_Node *) n) );
					if (gf_list_del_item(parent_scene->scene_objects, mo)>=0) {
						gf_sg_vrml_mf_reset(&mo->URLs, GF_SG_VRML_MFURL);
						gf_list_del(mo->nodes);
						if (mo->odm) mo->odm->mo = NULL;
						gf_free(mo);
					}
					scene->root_od->action_type = GF_ODM_ACTION_DELETE;
					gf_list_add(scene->root_od->term->media_queue, scene->root_od);
				} else {
					scene->root_od->action_type = GF_ODM_ACTION_SCENE_DISCONNECT;
					gf_list_add(scene->root_od->term->media_queue, scene->root_od);
				}
				gf_term_lock_media_queue(scene->root_od->term, 0);
			}
		}
		return;
	}


	//if no private scene is associated	get the node parent graph, retrieve the IS and find the OD
	if (!scene) {
		M_Inline *inl = (M_Inline *)n;
		gf_inline_set_scene(inl);
		scene = (GF_Scene *)gf_node_get_private(n);
		if (!scene) {
			/*just like protos, we must invalidate parent graph until attached*/
			if (inl->url.count) {
				if (!inl->url.vals[0].OD_ID && (!inl->url.vals[0].url || !strlen(inl->url.vals[0].url) ) ) {
					gf_sg_vrml_mf_reset(&inl->url, GF_SG_VRML_MFURL);
				} else {
					gf_node_dirty_set(n, 0, 1);
				}
			}
			return;
		}
	}

	gf_inline_check_restart(scene);

	/*if we need to restart, shutdown graph and do it*/
	if (scene->needs_restart) {
		/*special case: scene change*/
		if (scene->needs_restart==2) {
			scene->needs_restart = 0;
			gf_inline_on_modified(n);
			return;
		}

		scene->needs_restart = 0;
		gf_term_lock_media_queue(scene->root_od->term, 1);
		scene->root_od->action_type = GF_ODM_ACTION_SCENE_INLINE_RESTART;
		gf_list_add(scene->root_od->term->media_queue, scene->root_od);
		gf_term_lock_media_queue(scene->root_od->term, 0);

		gf_node_dirty_set(n, 0, 1);
		return;
	} 
	
	/*if not attached return (attaching the graph cannot be done in render since render is not called while unattached :) */
	if (!scene->graph_attached) {
		/*just like protos, we must invalidate parent graph until attached*/
		gf_node_dirty_set(n, 0, 1);
		return;
	}
	/*clear dirty flags for any sub-inlines, bitmaps or protos*/
	gf_node_dirty_clear(n, 0);

	current_url = scene->current_url;
	scene->current_url = & ((M_Inline*)n)->url;
	gf_sc_traverse_subscene(scene->root_od->term->compositor, n, scene->graph, rs);
	scene->current_url = current_url;
}