コード例 #1
0
/*activate all routes in the order they where triggered*/
GF_EXPORT
void gf_sg_activate_routes(GF_SceneGraph *sg)
{
	GF_Route *r;
	GF_Node *targ;
	if (!sg) return;

	sg->simulation_tick++;

	while (gf_list_count(sg->routes_to_activate)) {
		r = (GF_Route *)gf_list_get(sg->routes_to_activate, 0);
		gf_list_rem(sg->routes_to_activate, 0);
		if (r) {
			targ = r->ToNode;
			if (gf_sg_route_activate(r)) {
#ifdef GF_SELF_REPLACE_ENABLE
				if (sg->graph_has_been_reset) {
					sg->graph_has_been_reset = 0;
					return;
				}
#endif
				if (r->is_setup) gf_node_changed(targ, &r->ToField);
			}
		}
	}
	gf_sg_destroy_routes(sg);
}
コード例 #2
0
static void Node_on_remove_children(GF_Node *node)
{
	GF_ChildNodeItem *list;
	GF_FieldInfo field;
	GF_VRMLParent *n = (GF_VRMLParent *)node;

	if (!n->removeChildren) return;

	list = n->removeChildren;
	while (list) {
		if (gf_node_list_del_child(& n->children, list->node)) {
			gf_node_unregister(list->node, node);
		}
		list = list->next;
	}
	gf_node_unregister_children(node, n->removeChildren);
	n->removeChildren = NULL;

	/*signal children field is modified*/
	field.name = "children";
	field.eventType = GF_SG_EVENT_EXPOSED_FIELD;
	field.fieldType = GF_SG_VRML_MFNODE;
	field.NDTtype = 0;
	field.fieldIndex = 2;
	field.far_ptr = & n->children;
	gf_node_changed(node, &field);
}
コード例 #3
0
ファイル: timedtext_dec.c プロジェクト: jnorthrup/gpac
static void TTD_ResetDisplay(TTDPriv *priv)
{
	gf_list_reset(priv->blink_nodes);
	gf_node_unregister_children((GF_Node*)priv->dlist, priv->dlist->children);
	priv->dlist->children = NULL;
	gf_node_changed((GF_Node *) priv->dlist, NULL);
	priv->tr_scroll = NULL;
}
コード例 #4
0
ファイル: timedtext_dec.c プロジェクト: jnorthrup/gpac
static void ttd_set_scroll_fraction(GF_Node *node, GF_Route *route)
{
	Fixed frac;
	TTDPriv *priv = (TTDPriv *)gf_node_get_private(node);
	frac = priv->process_scroll->set_fraction;
	if (frac==FIX_ONE) priv->is_active = 0;
	if (!priv->tr_scroll) return;

	switch (priv->scroll_type - 1) {
	case GF_TXT_SCROLL_CREDITS:
	case GF_TXT_SCROLL_DOWN:
		priv->tr_scroll->translation.x = 0;
		if (priv->scroll_mode & GF_TXT_SCROLL_IN) {
			if (frac>priv->scroll_time) {
				priv->scroll_mode &= ~GF_TXT_SCROLL_IN;
				priv->tr_scroll->translation.y = 0;
			} else {
				priv->tr_scroll->translation.y = gf_muldiv(priv->dlist->size.y, frac, priv->scroll_time) - priv->dlist->size.y;
			}
		} else if (priv->scroll_mode & GF_TXT_SCROLL_OUT) {
			if (frac < FIX_ONE - priv->scroll_time) return;
			frac -= FIX_ONE - priv->scroll_time;
			if (priv->scroll_type - 1 == GF_TXT_SCROLL_DOWN) {
				priv->tr_scroll->translation.y = gf_muldiv(priv->dlist->size.y, frac, priv->scroll_time);
			} else {
				priv->tr_scroll->translation.y = gf_muldiv(priv->dlist->size.y, frac, priv->scroll_time);
			}
		}
			if (priv->scroll_type - 1 == GF_TXT_SCROLL_DOWN) priv->tr_scroll->translation.y *= -1;
		break;
	case GF_TXT_SCROLL_MARQUEE:
	case GF_TXT_SCROLL_RIGHT:
		priv->tr_scroll->translation.y = 0;
		if (priv->scroll_mode & GF_TXT_SCROLL_IN) {
			if (! (priv->scroll_mode & GF_TXT_SCROLL_OUT)) {
				if (frac<priv->scroll_delay) return;
				frac-=priv->scroll_delay;
			}
			if (frac>priv->scroll_time) {
				priv->scroll_mode &= ~GF_TXT_SCROLL_IN;
				priv->tr_scroll->translation.x = 0;
			} else {
				priv->tr_scroll->translation.x = gf_muldiv(priv->dlist->size.x, frac, priv->scroll_time) - priv->dlist->size.x;
			}
		} else if (priv->scroll_mode & GF_TXT_SCROLL_OUT) {
			if (frac < FIX_ONE - priv->scroll_time) return;
			frac -= FIX_ONE - priv->scroll_time;
			priv->tr_scroll->translation.x = gf_muldiv(priv->dlist->size.x, frac, priv->scroll_time);
		}
		if (priv->scroll_type - 1 == GF_TXT_SCROLL_MARQUEE) priv->tr_scroll->translation.x *= -1;
		break;
	default:
		break;
	}
	gf_node_changed((GF_Node *)priv->tr_scroll, NULL);
}
コード例 #5
0
static void SG_CheckFieldChange(GF_Node *node, GF_FieldInfo *field)
{
	/*and propagate eventIn if any*/
	if (field->on_event_in) {
		field->on_event_in(node);
	} else if ((field->eventType==GF_SG_EVENT_IN) && (gf_node_get_tag(node) == TAG_MPEG4_Script)) {
		gf_sg_script_event_in(node, field);
	} else {
		/*Notify eventOut in all cases to handle protos*/
		gf_node_event_out(node, field->fieldIndex);
	}
	/*signal node modif*/
	gf_node_changed(node, field);
}
コード例 #6
0
ファイル: field_decode.c プロジェクト: Bevara/GPAC
void gf_bifs_check_field_change(GF_Node *node, GF_FieldInfo *field)
{
	if (field->fieldType==GF_SG_VRML_MFNODE) node->sgprivate->flags |= GF_SG_CHILD_DIRTY;
	/*signal node modif*/
	gf_node_changed(node, field);
	/*Notify eventOut in all cases to handle protos*/
	gf_node_event_out(node, field->fieldIndex);
	/*and propagate eventIn if any*/
	if (field->on_event_in) {
		field->on_event_in(node, NULL);
	} else if ((gf_node_get_tag(node) == TAG_MPEG4_Script) && (field->eventType==GF_SG_EVENT_IN)) {
		gf_sg_script_event_in(node, field);
	}

}
コード例 #7
0
ファイル: timedtext_dec.c プロジェクト: jnorthrup/gpac
static void ttd_set_blink_fraction(GF_Node *node, GF_Route *route)
{
	M_Material2D *m;
	u32 i;
	TTDPriv *priv = (TTDPriv *)gf_node_get_private(node);

	Bool blink_on = 1;
	if (priv->process_blink->set_fraction>FIX_ONE/2) blink_on = 0;
	i=0;
	while ((m = (M_Material2D*)gf_list_enum(priv->blink_nodes, &i))) {
		if (m->filled != blink_on) {
			m->filled = blink_on;
			gf_node_changed((GF_Node *) m, NULL);
		}
	}
}
コード例 #8
0
ファイル: vrml_tools.c プロジェクト: erelh/gpac
static void Node_on_remove_children(GF_Node *node, GF_Route *route)
{
	GF_ChildNodeItem *list;
	GF_FieldInfo field;
	GF_VRMLParent *n = (GF_VRMLParent *)node;

	if (!n->removeChildren) return;

	list = n->removeChildren;
	while (list) {
		if (gf_node_list_del_child(& n->children, list->node)) {
			gf_node_unregister(list->node, node);
		}
		list = list->next;
	}
	gf_node_unregister_children(node, n->removeChildren);
	n->removeChildren = NULL;

	/*signal children field is modified*/
	field.name = "children";
	field.eventType = GF_SG_EVENT_EXPOSED_FIELD;
	field.fieldType = GF_SG_VRML_MFNODE;
	field.NDTtype = -1;
	if ( node->sgprivate->tag == TAG_MPEG4_Transform )
		field.fieldIndex = 3;
	else
		field.fieldIndex = 2;
	field.far_ptr = & n->children;
	gf_node_event_out(node, field.fieldIndex);
	gf_node_changed(node, &field);


	if (node->sgprivate->scenegraph->on_node_modified) {
		field.name = "removeChildren";
		field.eventType = GF_SG_EVENT_IN;
		field.fieldType = GF_SG_VRML_MFNODE;
		field.NDTtype = -1;
		field.fieldIndex = 1;
		field.far_ptr = & n->removeChildren;
		node->sgprivate->scenegraph->on_node_modified(node->sgprivate->scenegraph, node, &field, NULL);
	}
}
コード例 #9
0
ファイル: smil_timing.c プロジェクト: noelove/GPAC-old
/* Inserts a new resolved time instant in the begin or end attribute. 
   The insertion preserves the sorting and removes the previous insertions
    which have become obsolete
   WARNING: Only used for inserting time when an <a> element, whose target is a timed element, is activated. */
GF_EXPORT
void gf_smil_timing_insert_clock(GF_Node *elt, Bool is_end, Double clock)
{
	u32 i, count, found;
	SVGTimedAnimBaseElement *timed = (SVGTimedAnimBaseElement*)elt;
	SMIL_Time *begin;
	GF_List *l;
	GF_SAFEALLOC(begin, SMIL_Time);

	begin->type = GF_SMIL_TIME_EVENT_RESOLVED;
	begin->clock = clock;

	l = is_end ? *timed->timingp->end : *timed->timingp->begin;

	found = 0;
	count = gf_list_count(l);
	for (i=0; i<count; i++) {
		SMIL_Time *first = (SMIL_Time *)gf_list_get(l, i);
		/*remove past instanciations*/
		if ((first->type==GF_SMIL_TIME_EVENT_RESOLVED) && (first->clock < begin->clock)) {
			gf_list_rem(l, i);
			gf_free(first);
			i--;
			count--;
			continue;
		}
		if ( (first->type == GF_SMIL_TIME_INDEFINITE) 
			|| ( (first->type == GF_SMIL_TIME_CLOCK) && (first->clock > begin->clock) ) 
		) {
			gf_list_insert(l, begin, i);
			found = 1;
			break;
		}
	}
	if (!found) gf_list_add(l, begin);

	/* call gf_smil_timing_modified */
	gf_node_changed(elt, NULL);
}
コード例 #10
0
ファイル: vrml_tools.c プロジェクト: erelh/gpac
static void Node_on_add_children(GF_Node *node, GF_Route *route)
{
	GF_ChildNodeItem *list;
	GF_FieldInfo field;
	GF_VRMLParent *n = (GF_VRMLParent *)node;

	if (n->children) {
		list = n->children;
		while (list->next) list = list->next;
		list->next = n->addChildren;
	} else {
		n->children = n->addChildren;
	}
	n->addChildren = NULL;

	/*signal children field is modified*/
	field.name = "children";
	field.eventType = GF_SG_EVENT_EXPOSED_FIELD;
	field.fieldType = GF_SG_VRML_MFNODE;
	field.NDTtype = -1;
	if ( node->sgprivate->tag == TAG_MPEG4_Transform )
		field.fieldIndex = 3;
	else
		field.fieldIndex = 2;
	field.far_ptr = & n->children;
	gf_node_event_out(node, field.fieldIndex);
	gf_node_changed(node, &field);

	if (node->sgprivate->scenegraph->on_node_modified) {
		field.name = "addChildren";
		field.eventType = GF_SG_EVENT_IN;
		field.fieldType = GF_SG_VRML_MFNODE;
		field.NDTtype = -1;
		field.fieldIndex = 0;
		field.far_ptr = & n->addChildren;
		node->sgprivate->scenegraph->on_node_modified(node->sgprivate->scenegraph, node, &field, NULL);
	}
}
コード例 #11
0
static void Node_on_add_children(GF_Node *node)
{
	GF_ChildNodeItem *list;
	GF_FieldInfo field;
	GF_VRMLParent *n = (GF_VRMLParent *)node;

	if (n->children) {
		list = n->children;
		while (list->next) list = list->next;
		list->next = n->addChildren;
	} else {
		n->children = n->addChildren;
	}
	n->addChildren = NULL;

	/*signal children field is modified*/
	field.name = "children";
	field.eventType = GF_SG_EVENT_EXPOSED_FIELD;
	field.fieldType = GF_SG_VRML_MFNODE;
	field.NDTtype = 0;
	field.fieldIndex = 2;
	field.far_ptr = & n->children;
	gf_node_changed(node, &field);
}
コード例 #12
0
ファイル: mpeg4_inline.c プロジェクト: golgol7777/gpac
static void gf_storage_load(M_Storage *storage)
{
	const char *opt;
	char szID[20];
	u32 i, count;
	u32 sec, exp, frac;
	GF_Config *cfg = storage_get_cfg(storage);
	char *section = storage_get_section(storage);
	if (!cfg || !section) return;

	if (!gf_cfg_get_key_count(cfg, section)) {
		gf_free(section);
		return;
	}
	opt = gf_cfg_get_key(cfg, section, "expireAfterNTP");
	gf_net_get_ntp(&sec, &frac);
	sscanf(opt, "%u", &exp);
	if (exp && (exp<=sec)) {
		gf_cfg_del_section(cfg, section);
		gf_free(section);
		return;
	}

	count = gf_cfg_get_key_count(cfg, section)-1;
	if (!count || (count!=storage->storageList.count)) {
		gf_cfg_del_section(cfg, section);
		gf_free(section);
		return;
	}

	for (i=0; i<count; i++) {
		GF_FieldInfo info;
		sprintf(szID, "%d", i);
		opt = gf_cfg_get_key(cfg, section, szID);
		if (!opt) break;
		if (!storage->storageList.vals[i].node) break;
		if (gf_node_get_field(storage->storageList.vals[i].node, storage->storageList.vals[i].fieldIndex, &info) != GF_OK) break;

		if (gf_sg_vrml_is_sf_field(info.fieldType)) {
			storage_parse_sf(info.far_ptr, info.fieldType, (char *) opt);
		} else {
			u32 sftype = gf_sg_vrml_get_sf_type(info.fieldType);
			char *sep, *val;
			void *slot;
			gf_sg_vrml_mf_reset(info.far_ptr, info.fieldType);
			while (1) {
				val = strchr(opt, '\'');
				sep = val ? strchr(val+1, '\'') : NULL;
				if (!val || !sep) break;

				sep[0] = 0;
				gf_sg_vrml_mf_append(info.far_ptr, info.fieldType, &slot);
				storage_parse_sf(slot, sftype, val+1);
				sep[0] = '\'';
				opt = sep+1;
			}
		}
		gf_node_changed(storage->storageList.vals[i].node, &info);
	}
	gf_free(section);
}
コード例 #13
0
GF_EXPORT
GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_offset)
{
	GF_Err e;
	GF_CommandField *inf;
	GF_FieldInfo field;
	GF_Node *def, *node;
	void *slot_ptr;

	if (!com || !graph) return GF_BAD_PARAM;

	e = GF_OK;
	switch (com->tag) {
	case GF_SG_SCENE_REPLACE:
		/*unregister root*/
		gf_node_unregister(graph->RootNode, NULL);
		/*remove all protos and routes*/
		while (gf_list_count(graph->routes_to_activate)) 
			gf_list_rem(graph->routes_to_activate, 0);
		
		/*destroy all routes*/
		while (gf_list_count(graph->Routes)) {
			GF_Route *r = (GF_Route *)gf_list_get(graph->Routes, 0);
			/*this will unregister the route from the graph, so don't delete the chain entry*/
			gf_sg_route_del(r);
		}
		/*destroy all proto*/
		while (gf_list_count(graph->protos)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(graph->protos, 0);
			/*this will unregister the proto from the graph, so don't delete the chain entry*/
			gf_sg_proto_del(p);
		}
		/*DO NOT TOUCH node registry*/
		/*DO NOT TOUCH UNREGISTERED PROTOS*/

		/*move all protos in graph*/
		while (gf_list_count(com->new_proto_list)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0);
			gf_list_rem(com->new_proto_list, 0);
			gf_list_del_item(graph->unregistered_protos, p);
			gf_list_add(graph->protos, p);
		}
		/*assign new root (no need to register/unregister)*/
		graph->RootNode = com->node;
		com->node = NULL;
		break;

	case GF_SG_NODE_REPLACE:
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		e = gf_node_replace(com->node, inf->new_node, 0);
		if (inf->new_node) gf_node_register(inf->new_node, NULL);
		break;

	case GF_SG_MULTIPLE_REPLACE:
	case GF_SG_FIELD_REPLACE:
	{
		u32 j;
		GF_ChildNodeItem *list, *cur, *prev;
		j=0;
		while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &j))) {
			e = gf_node_get_field(com->node, inf->fieldIndex, &field);
			if (e) return e;

			switch (field.fieldType) {
			case GF_SG_VRML_SFNODE:
			{
				node = *((GF_Node **) field.far_ptr);
				e = gf_node_unregister(node, com->node);
				*((GF_Node **) field.far_ptr) = inf->new_node;
				if (!e) gf_node_register(inf->new_node, com->node);
				break;
			}
			case GF_SG_VRML_MFNODE:
				gf_node_unregister_children(com->node, * ((GF_ChildNodeItem **) field.far_ptr));
				* ((GF_ChildNodeItem **) field.far_ptr) = NULL;

				list = * ((GF_ChildNodeItem **) inf->field_ptr);
				prev=NULL;
				while (list) {
					cur = malloc(sizeof(GF_ChildNodeItem));
					cur->next = NULL;
					cur->node = list->node;
					if (prev) {
						prev->next = cur;
					} else {
						* ((GF_ChildNodeItem **) field.far_ptr) = cur;
					}
					gf_node_register(list->node, com->node);
					prev = cur;
					list = list->next;
				}
				break;
			default:
				/*this is a regular field, reset it and clone - we cannot switch pointers since the
				original fields are NOT pointers*/
				if (!gf_sg_vrml_is_sf_field(field.fieldType)) {
					e = gf_sg_vrml_mf_reset(field.far_ptr, field.fieldType);
				}
				if (e) return e;
				gf_sg_vrml_field_copy(field.far_ptr, inf->field_ptr, field.fieldType);
				if (field.fieldType==GF_SG_VRML_SFTIME) *(SFTime *)field.far_ptr = *(SFTime *)field.far_ptr + time_offset;
				break;
			}
			SG_CheckFieldChange(com->node, &field);
		}
		break;
	}

	case GF_SG_MULTIPLE_INDEXED_REPLACE:
	case GF_SG_INDEXED_REPLACE:
	{
		u32 sftype, i=0;
		while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &i))) {
			e = gf_node_get_field(com->node, inf->fieldIndex, &field);
			if (e) return e;

			/*if MFNode remove the child and set new node*/
			if (field.fieldType == GF_SG_VRML_MFNODE) {
				/*we must remove the node before in case the new node uses the same ID (not forbidden) and this
				command removes the last instance of the node with the same ID*/
				gf_node_replace_child(com->node, (GF_ChildNodeItem**) field.far_ptr, inf->pos, inf->new_node);
				if (inf->new_node) gf_node_register(inf->new_node, NULL);
			}
			/*erase the field item*/
			else {
				if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) {
					inf->pos = ((GenMFField *)field.far_ptr)->count - 1;
					/*may happen with text and default value*/
					if (inf->pos < 0) {
						inf->pos = 0;
						gf_sg_vrml_mf_alloc(field.far_ptr, field.fieldType, 1);
					}
				}
				e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, & slot_ptr, inf->pos);
				if (e) return e;
				sftype = gf_sg_vrml_get_sf_type(field.fieldType);
				gf_sg_vrml_field_copy(slot_ptr, inf->field_ptr, sftype);
				/*note we don't add time offset, since there's no MFTime*/
			}
			SG_CheckFieldChange(com->node, &field);
		}
		break;
	}
	case GF_SG_ROUTE_REPLACE:
	{
		GF_Route *r;
		char *name;
		r = gf_sg_route_find(graph, com->RouteID);
		def = gf_sg_find_node(graph, com->fromNodeID);
		node = gf_sg_find_node(graph, com->toNodeID);
		if (!node || !def) return GF_SG_UNKNOWN_NODE;
		name = NULL;
		if (r) {
			name = r->name;
			r->name = NULL;
			gf_sg_route_del(r);
		}
		r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex);
		gf_sg_route_set_id(r, com->RouteID);
		if (name) {
			gf_sg_route_set_name(r, name);
			free(name);
		}
		break;
	}
	case GF_SG_NODE_DELETE_EX:
	case GF_SG_NODE_DELETE:
	{
		if (com->node) gf_node_replace(com->node, NULL, (com->tag==GF_SG_NODE_DELETE_EX) ? 1 : 0);
		break;
	}
	case GF_SG_ROUTE_DELETE:
	{
		return gf_sg_route_del_by_id(graph, com->RouteID);
	}
	case GF_SG_INDEXED_DELETE:
	{
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);

		e = gf_node_get_field(com->node, inf->fieldIndex, &field);
		if (e) return e;
		if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM;

		/*then we need special handling in case of a node*/
		if (gf_sg_vrml_get_sf_type(field.fieldType) == GF_SG_VRML_SFNODE) {
			e = gf_node_replace_child(com->node, (GF_ChildNodeItem **) field.far_ptr, inf->pos, NULL);
		} else {
			if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) {
				inf->pos = ((GenMFField *)field.far_ptr)->count - 1;
			}
			/*this is a regular MFField, just remove the item (realloc)*/
			e = gf_sg_vrml_mf_remove(field.far_ptr, field.fieldType, inf->pos);
		}
		/*deletion -> node has changed*/
		if (!e) SG_CheckFieldChange(com->node, &field);
		break;
	}
	case GF_SG_NODE_INSERT:
	{
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);

		e = gf_node_insert_child(com->node, inf->new_node, inf->pos);
		if (!e) gf_node_register(inf->new_node, com->node);
		if (!e) gf_node_event_out(com->node, inf->fieldIndex);
		if (!e) gf_node_changed(com->node, NULL);
		break;
	}
	case GF_SG_ROUTE_INSERT:
	{
		GF_Route *r;
		def = gf_sg_find_node(graph, com->fromNodeID);
		node = gf_sg_find_node(graph, com->toNodeID);
		if (!node || !def) return GF_SG_UNKNOWN_NODE;
		r = gf_sg_route_new(graph, def, com->fromFieldIndex, node, com->toFieldIndex);
		if (com->RouteID) gf_sg_route_set_id(r, com->RouteID);
		if (com->def_name) {
			gf_sg_route_set_name(r, com->def_name);
			free(com->def_name);
			com->def_name = NULL;
		}
		break;
	}
	case GF_SG_INDEXED_INSERT:
	{
		u32 sftype;
		if (!gf_list_count(com->command_fields)) return GF_OK;
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		e = gf_node_get_field(com->node, inf->fieldIndex, &field);
		if (e) return e;

		/*rescale the MFField and parse the SFField*/
		if (field.fieldType != GF_SG_VRML_MFNODE) {
			if (inf->pos == -1) {
				e = gf_sg_vrml_mf_append(field.far_ptr, field.fieldType, & slot_ptr);
			} else {
				e = gf_sg_vrml_mf_insert(field.far_ptr, field.fieldType, & slot_ptr, inf->pos);
			}
			if (e) return e;
			sftype = gf_sg_vrml_get_sf_type(field.fieldType);
			gf_sg_vrml_field_copy(slot_ptr, inf->field_ptr, sftype);
		} else {
			if (inf->new_node) {
				if (inf->pos == -1) {
					gf_node_list_add_child( (GF_ChildNodeItem **) field.far_ptr, inf->new_node);
				} else {
					gf_node_list_insert_child((GF_ChildNodeItem **) field.far_ptr, inf->new_node, inf->pos);
				}
				gf_node_register(inf->new_node, com->node);
			}
		}
		if (!e) SG_CheckFieldChange(com->node, &field);
		break;
	}
	case GF_SG_PROTO_INSERT:
		/*destroy all proto*/
		while (gf_list_count(com->new_proto_list)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0);
			gf_list_rem(com->new_proto_list, 0);
			gf_list_del_item(graph->unregistered_protos, p);
			gf_list_add(graph->protos, p);
		}
		return GF_OK;
	case GF_SG_PROTO_DELETE:
		{
			u32 i;
			for (i=0; i<com->del_proto_list_size; i++) {
				/*note this will check for unregistered protos, but since IDs are unique we are sure we will 
				not destroy an unregistered one*/
				GF_Proto *proto = gf_sg_find_proto(graph, com->del_proto_list[i], NULL);
				if (proto) gf_sg_proto_del(proto);
			}
		}
		return GF_OK;
	case GF_SG_PROTO_DELETE_ALL:
		/*destroy all proto*/
		while (gf_list_count(graph->protos)) {
			GF_Proto *p = (GF_Proto*)gf_list_get(graph->protos, 0);
			gf_list_rem(graph->protos, 0);
			/*this will unregister the proto from the graph, so don't delete the chain entry*/
			gf_sg_proto_del(p);
		}
		/*DO NOT TOUCH UNREGISTERED PROTOS*/
		return GF_OK;
	/*only used by BIFS*/
	case GF_SG_GLOBAL_QUANTIZER:
		return GF_OK;

#ifndef GPAC_DISABLE_SVG
	/*laser commands*/
	case GF_SG_LSR_NEW_SCENE:
		/*DO NOT TOUCH node registry*/

		/*assign new root (no need to register/unregister)*/
		graph->RootNode = com->node;
		com->node = NULL;
		break;
	case GF_SG_LSR_DELETE:
		if (!com->node) return GF_NON_COMPLIANT_BITSTREAM;
		if (!gf_list_count(com->command_fields)) {
			gf_node_replace(com->node, NULL, 0);
			gf_node_deactivate(com->node);
			return GF_OK;
		}
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		node = gf_node_list_get_child(((SVG_Element *)com->node)->children, inf->pos);
		if (node) {
			e = gf_node_replace_child(com->node, &((SVG_Element *)com->node)->children, inf->pos, NULL);
			gf_node_deactivate(node);
		}
		break;
	case GF_SG_LSR_INSERT:
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		if (!com->node || !inf) return GF_NON_COMPLIANT_BITSTREAM;
		if (inf->new_node) {
			if (inf->pos<0) 
				gf_node_list_add_child(& ((SVG_Element *)com->node)->children, inf->new_node);
			else
				gf_node_list_insert_child(& ((SVG_Element *)com->node)->children, inf->new_node, inf->pos);

			gf_node_register(inf->new_node, com->node);
			gf_node_activate(inf->new_node);
			gf_node_changed(com->node, NULL);
		} else {
			/*NOT SUPPORTED*/
			GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[LASeR] VALUE INSERTION NOT SUPPORTED\n"));
		}
		break;
	case GF_SG_LSR_ADD:
	case GF_SG_LSR_REPLACE:
		inf = (GF_CommandField*)gf_list_get(com->command_fields, 0);
		if (!com->node || !inf) return GF_NON_COMPLIANT_BITSTREAM;
		if (inf->new_node) {
			if (inf->pos<0) {
				/*if fieldIndex (eg attributeName) is set, this is children replacement*/
				if (inf->fieldIndex>0) {
					gf_node_unregister_children_deactivate(com->node, ((SVG_Element *)com->node)->children);
					((SVG_Element *)com->node)->children = NULL;
					gf_node_list_add_child(& ((SVG_Element *)com->node)->children, inf->new_node);
					gf_node_register(inf->new_node, com->node);
					gf_node_activate(inf->new_node);
				} else {
					e = gf_node_replace(com->node, inf->new_node, 0);
					gf_node_activate(inf->new_node);
				}
			} else {
				node = gf_node_list_get_child( ((SVG_Element *)com->node)->children, inf->pos);
				gf_node_replace_child(com->node, & ((SVG_Element *)com->node)->children, inf->pos, inf->new_node);
				gf_node_register(inf->new_node, com->node);
				if (node) gf_node_deactivate(node);
				gf_node_activate(inf->new_node);
			}
			/*signal node modif*/
			gf_node_changed(com->node, NULL);
			return e;
		} else if (inf->node_list) {
			GF_ChildNodeItem *child, *cur, *prev;
			gf_node_unregister_children_deactivate(com->node, ((SVG_Element *)com->node)->children);
			((SVG_Element *)com->node)->children = NULL;

			prev = NULL;
			child = inf->node_list;
			while (child) {
				cur = (GF_ChildNodeItem*)malloc(sizeof(GF_ChildNodeItem));
				cur->next = NULL;
				cur->node = child->node;
				gf_node_register(child->node, com->node);
				gf_node_activate(child->node);
				if (prev) prev->next = cur;
				else ((SVG_Element *)com->node)->children = cur;
				prev = cur;
				child = child->next;
			}
			/*signal node modif*/
			gf_node_changed(com->node, NULL);
			return GF_OK;
		}
		/*attribute modif*/
		else if (inf->field_ptr) {
			GF_FieldInfo a, b;
			if (inf->fieldIndex==(u32) -2) {
				GF_Point2D scale, translate;
				Fixed rotate;
				GF_Matrix2D *dest;
				gf_node_get_field_by_name(com->node, "transform", &a);
				dest = (GF_Matrix2D*)a.far_ptr;
				
				if (com->tag==GF_SG_LSR_REPLACE) {
					if (gf_mx2d_decompose(dest, &scale, &rotate, &translate)) {
						gf_mx2d_init(*dest);
						if (inf->fieldType==SVG_TRANSFORM_SCALE) scale = *(GF_Point2D *)inf->field_ptr;
						else if (inf->fieldType==SVG_TRANSFORM_TRANSLATE) translate = *(GF_Point2D *)inf->field_ptr;
						else if (inf->fieldType==SVG_TRANSFORM_ROTATE) rotate = ((SVG_Point_Angle*)inf->field_ptr)->angle;

						gf_mx2d_add_scale(dest, scale.x, scale.y);
						gf_mx2d_add_rotation(dest, 0, 0, rotate);
						gf_mx2d_add_translation(dest, translate.x, translate.y);
					}
				} else {
					GF_Point2D *pt = (GF_Point2D *)inf->field_ptr;
					if (inf->fieldType==SVG_TRANSFORM_SCALE) gf_mx2d_add_scale(dest, pt->x, pt->y);
					else if (inf->fieldType==SVG_TRANSFORM_TRANSLATE) gf_mx2d_add_translation(dest, pt->x, pt->y);
					else if (inf->fieldType == SVG_TRANSFORM_ROTATE) gf_mx2d_add_rotation(dest, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle);
				}
			} else {
				if ((inf->fieldIndex==(u32) -1) && (inf->fieldType==SVG_String_datatype)) {
					char *str = *(SVG_String*)inf->field_ptr;

					if (com->tag == GF_SG_LSR_REPLACE) {
						GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; 
						if (t && (t->sgprivate->tag==TAG_DOMText)) {
							if (t->textContent) free(t->textContent);
							t->textContent = NULL;
							if (str) t->textContent = strdup(str);
						}
					} else {
						if (str) gf_dom_add_text_node(com->node, strdup(str));
					}
				}
				else if ((inf->fieldIndex==TAG_LSR_ATT_scale) 
					|| (inf->fieldIndex==TAG_LSR_ATT_translation)
					|| (inf->fieldIndex==TAG_LSR_ATT_rotation)
				) {
					SVG_Transform *mx;
					gf_svg_get_attribute_by_tag(com->node, TAG_SVG_ATT_transform, 1, 0, &a);
					mx = a.far_ptr;
					if (com->tag == GF_SG_LSR_REPLACE) {
						GF_Point2D scale, translate;
						SVG_Point_Angle rotate;
						if (gf_mx2d_decompose(&mx->mat, &scale, &rotate.angle, &translate)) {
							gf_mx2d_init(mx->mat);
							if (inf->fieldIndex==TAG_LSR_ATT_scale) scale = *(GF_Point2D *)inf->field_ptr;
							else if (inf->fieldIndex==TAG_LSR_ATT_translation) translate = *(GF_Point2D *)inf->field_ptr;
							else if (inf->fieldIndex==TAG_LSR_ATT_rotation) rotate = *(SVG_Point_Angle*)inf->field_ptr;

							gf_mx2d_add_scale(&mx->mat, scale.x, scale.y);
							gf_mx2d_add_rotation(&mx->mat, 0, 0, rotate.angle);
							gf_mx2d_add_translation(&mx->mat, translate.x, translate.y);
						}
					} else {
						if (inf->fieldIndex==TAG_LSR_ATT_scale) gf_mx2d_add_scale(&mx->mat, ((GF_Point2D*)inf->field_ptr)->x, ((GF_Point2D*)inf->field_ptr)->y);
						if (inf->fieldIndex==TAG_LSR_ATT_translation) gf_mx2d_add_translation(&mx->mat, ((GF_Point2D*)inf->field_ptr)->x, ((GF_Point2D*)inf->field_ptr)->y);
						if (inf->fieldIndex==TAG_LSR_ATT_rotation) gf_mx2d_add_rotation(&mx->mat, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle);
					}
				}
				else if (gf_svg_get_attribute_by_tag(com->node, inf->fieldIndex, 1, 0, &a) == GF_OK) {
					b = a;
					b.far_ptr = inf->field_ptr;
					if (com->tag == GF_SG_LSR_REPLACE) {
						gf_svg_attributes_copy(&a, &b, 0);
					} else {
						gf_svg_attributes_add(&a, &b, &a, 0);
					}
				}
				b = a;
				b.far_ptr = inf->field_ptr;
			}
			/*signal node modif*/
			gf_node_changed(com->node, &a);
		} else if (com->fromNodeID) {
			GF_FieldInfo a, b;
			GF_Node *fromNode = gf_sg_find_node(graph, com->fromNodeID);
			if (!fromNode) return GF_NON_COMPLIANT_BITSTREAM;
			if (gf_node_get_field(fromNode, com->fromFieldIndex, &b) != GF_OK) return GF_NON_COMPLIANT_BITSTREAM;

			if ((inf->fieldIndex==(u32) -1) && (inf->fieldType==SVG_String_datatype)) {
				char *str = *(SVG_String*)inf->field_ptr;

				if (com->tag == GF_SG_LSR_REPLACE) {
					GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; 
					if (t && (t->sgprivate->tag==TAG_DOMText)) {
						if (t->textContent) free(t->textContent);
						t->textContent = NULL;
						if (str) t->textContent = strdup(str);
					}
				} else {
					if (str) gf_dom_add_text_node(com->node, strdup(str));
				}
			} else {
				gf_node_get_field(com->node, inf->fieldIndex, &a);
				if (com->tag == GF_SG_LSR_REPLACE) {
					e = gf_svg_attributes_copy(&a, &b, 0);
				} else {
					e = gf_svg_attributes_add(&a, &b, &a, 0);
				}
			}
			gf_node_changed(com->node, &a);
			return e;
		} else {
			return GF_NON_COMPLIANT_BITSTREAM;
		}
		break;
	case GF_SG_LSR_ACTIVATE:
		gf_node_activate(com->node);
		break;
	case GF_SG_LSR_DEACTIVATE:
		gf_node_deactivate(com->node);
		gf_node_changed(com->node, NULL);
		break;
#endif

	default:
		return GF_NOT_SUPPORTED;
	}
	if (e) return e;

	if (com->scripts_to_load) {
		while (gf_list_count(com->scripts_to_load)) {
			GF_Node *script = (GF_Node *)gf_list_get(com->scripts_to_load, 0);
			gf_list_rem(com->scripts_to_load, 0);
			gf_sg_script_load(script);
		}
		gf_list_del(com->scripts_to_load);
		com->scripts_to_load = NULL;
	}
	return GF_OK;
}
コード例 #14
0
static void svg_sani_a_HandleEvent(GF_Node *handler, GF_DOM_Event *event)
{
	GF_Renderer *compositor;
	GF_Event evt;
	SVG_SANI_aElement *a;

	assert(gf_node_get_tag(event->currentTarget)==TAG_SVG_SANI_a);

	a = (SVG_SANI_aElement *) event->currentTarget;
	compositor = (GF_Renderer *)gf_node_get_private(handler);

	if (!compositor->user->EventProc) return;

	evt.type = GF_EVENT_NAVIGATE;
	
	if (a->xlink->href.type == XMLRI_STRING) {
		evt.navigate.to_url = a->xlink->href.iri;
		if (evt.navigate.to_url) {
			evt.navigate.param_count = 1;
			evt.navigate.parameters = (const char **) &a->target;
			compositor->user->EventProc(compositor->user->opaque, &evt);
		}
	} else {
		u32 tag;
		if (!a->xlink->href.target) {
			/* TODO: check if href can be resolved */
			return;
		} 
		tag = gf_node_get_tag((GF_Node *)a->xlink->href.target);
		if (tag == TAG_SVG_SANI_set ||
			tag == TAG_SVG_SANI_animate ||
			tag == TAG_SVG_SANI_animateColor ||
			tag == TAG_SVG_SANI_animateTransform ||
			tag == TAG_SVG_SANI_animateMotion || 
			tag == TAG_SVG_SANI_discard) {
			u32 i, count, found;
			SVG_SANI_setElement *set = (SVG_SANI_setElement *)a->xlink->href.target;
			SMIL_Time *begin;
			GF_SAFEALLOC(begin, SMIL_Time);
			begin->type = GF_SMIL_TIME_EVENT_RESOLVED;
			begin->clock = gf_node_get_scene_time((GF_Node *)set);

			found = 0;
			count = gf_list_count(set->timing->begin);
			for (i=0; i<count; i++) {
				SMIL_Time *first = (SMIL_Time *)gf_list_get(set->timing->begin, i);
				/*remove past instanciations*/
				if ((first->type==GF_SMIL_TIME_EVENT_RESOLVED) && (first->clock < begin->clock)) {
					gf_list_rem(set->timing->begin, i);
					free(first);
					i--;
					count--;
					continue;
				}
				if ( (first->type == GF_SMIL_TIME_INDEFINITE) 
					|| ( (first->type == GF_SMIL_TIME_CLOCK) && (first->clock > begin->clock) ) 
				) {
					gf_list_insert(set->timing->begin, begin, i);
					found = 1;
					break;
				}
			}
			if (!found) gf_list_add(set->timing->begin, begin);
			gf_node_changed((GF_Node *)a->xlink->href.target, NULL);
		}
	}
	return;
}
コード例 #15
0
ファイル: timedtext_dec.c プロジェクト: jnorthrup/gpac
static void TTD_ApplySample(TTDPriv *priv, GF_TextSample *txt, u32 sdi, Bool is_utf_16, u32 sample_duration)
{
	u32 i, nb_lines, start_idx, count;
	s32 *id, thw, thh, tw, th, offset;
	Bool vertical;
	MFInt32 idx;
	SFString *s;
	GF_BoxRecord br;
	M_Material2D *n;
	M_Form *form;
	u16 utf16_text[5000];
	u32 char_offset, char_count;
	GF_List *chunks;
	TTDTextChunk *tc;
	GF_Box *a;
	GF_TextSampleDescriptor *td = NULL;

	/*stop timer sensor*/
	if (gf_list_count(priv->blink_nodes)) {
		priv->ts_blink->stopTime = gf_node_get_scene_time((GF_Node *) priv->ts_blink);
		gf_node_changed((GF_Node *) priv->ts_blink, NULL);
	}
	priv->ts_scroll->stopTime = gf_node_get_scene_time((GF_Node *) priv->ts_scroll);
	gf_node_changed((GF_Node *) priv->ts_scroll, NULL);
	/*flush routes to avoid getting the set_fraction of the scroll sensor deactivation*/
	gf_sg_activate_routes(priv->inlineScene->graph);

	TTD_ResetDisplay(priv);
	if (!sdi || !txt || !txt->len) return;

	i=0;
	while ((td = (GF_TextSampleDescriptor *)gf_list_enum(priv->cfg->sample_descriptions, &i))) {
		if (td->sample_index==sdi) break;
		td = NULL;
	}
	if (!td) return;


	vertical = (td->displayFlags & GF_TXT_VERTICAL) ? 1 : 0;

	/*set back color*/
	/*do we fill the text box or the entire text track region*/
	if (td->displayFlags & GF_TXT_FILL_REGION) {
		priv->mat_box->transparency = FIX_ONE;
		n = priv->mat_track;
	} else {
		priv->mat_track->transparency = FIX_ONE;
		n = priv->mat_box;
	}

	n->transparency = FIX_ONE - INT2FIX((td->back_color>>24) & 0xFF) / 255;
	n->emissiveColor.red = INT2FIX((td->back_color>>16) & 0xFF) / 255;
	n->emissiveColor.green = INT2FIX((td->back_color>>8) & 0xFF) / 255;
	n->emissiveColor.blue = INT2FIX((td->back_color) & 0xFF) / 255;
	gf_node_changed((GF_Node *) n, NULL);

	if (txt->box) {
		br = txt->box->box;
	} else {
		br = td->default_pos;
	}
	if (!br.right || !br.bottom) {
		br.top = br.left = 0;
		br.right = priv->cfg->text_width;
		br.bottom = priv->cfg->text_height;
	}
	thw = br.right - br.left;
	thh = br.bottom - br.top;
	if (!thw || !thh) {
		br.top = br.left = 0;
		thw = priv->cfg->text_width;
		thh = priv->cfg->text_height;
	}

	priv->dlist->size.x = INT2FIX(thw);
	priv->dlist->size.y = INT2FIX(thh);

	/*disable backgrounds if not used*/
	if (priv->mat_track->transparency<FIX_ONE) {
		if (priv->rec_track->size.x != priv->cfg->text_width) {
			priv->rec_track->size.x = priv->cfg->text_width;
			priv->rec_track->size.y = priv->cfg->text_height;
			gf_node_changed((GF_Node *) priv->rec_track, NULL);
		}
	} else if (priv->rec_track->size.x) {
		priv->rec_track->size.x = priv->rec_track->size.y = 0;
		gf_node_changed((GF_Node *) priv->rec_box, NULL);
	}

	if (priv->mat_box->transparency<FIX_ONE) {
		if (priv->rec_box->size.x != priv->dlist->size.x) {
			priv->rec_box->size.x = priv->dlist->size.x;
			priv->rec_box->size.y = priv->dlist->size.y;
			gf_node_changed((GF_Node *) priv->rec_box, NULL);
		}
	} else if (priv->rec_box->size.x) {
		priv->rec_box->size.x = priv->rec_box->size.y = 0;
		gf_node_changed((GF_Node *) priv->rec_box, NULL);
	}

	form = (M_Form *) ttd_create_node(priv, TAG_MPEG4_Form, NULL);
	form->size.x = INT2FIX(thw);
	form->size.y = INT2FIX(thh);

	thw /= 2;
	thh /= 2;
	tw = priv->cfg->text_width;
	th = priv->cfg->text_height;

	/*check translation, we must not get out of scene size - not supported in GPAC*/
	offset = br.left - tw/2 + thw;
	if (offset + thw < - tw/2) offset = - tw/2 + thw;
	else if (offset - thw > tw/2) offset = tw/2 - thw;
	priv->tr_box->translation.x = INT2FIX(offset);

	offset = th/2 - br.top - thh;
	if (offset + thh > th/2) offset = th/2 - thh;
	else if (offset - thh < -th/2) offset = -th/2 + thh;
	priv->tr_box->translation.y = INT2FIX(offset);

	gf_node_dirty_set((GF_Node *)priv->tr_box, 0, 1);


	if (priv->scroll_type) {
		priv->ts_scroll->stopTime = gf_node_get_scene_time((GF_Node *) priv->ts_scroll);
		gf_node_changed((GF_Node *) priv->ts_scroll, NULL);
	}
	priv->scroll_mode = 0;
	if (td->displayFlags & GF_TXT_SCROLL_IN) priv->scroll_mode |= GF_TXT_SCROLL_IN;
	if (td->displayFlags & GF_TXT_SCROLL_OUT) priv->scroll_mode |= GF_TXT_SCROLL_OUT;

	priv->scroll_type = 0;
	if (priv->scroll_mode) {
		priv->scroll_type = (td->displayFlags & GF_TXT_SCROLL_DIRECTION)>>7;
		priv->scroll_type ++;
	}
コード例 #16
0
ファイル: timedtext_dec.c プロジェクト: jnorthrup/gpac
/*the WORST thing about 3GP in MPEG4 is positioning of the text track...*/
static void TTD_UpdateSizeInfo(TTDPriv *priv)
{
	u32 w, h;
	Bool has_size;
	s32 offset, thw, thh, vw, vh;

	has_size = gf_sg_get_scene_size_info(priv->inlineScene->graph, &w, &h);
	/*no size info is given in main scene, override by associated video size if any, or by text track size*/
	if (!has_size) {
		if (priv->cfg->has_vid_info && priv->cfg->video_width && priv->cfg->video_height) {
			gf_sg_set_scene_size_info(priv->sg, priv->cfg->video_width, priv->cfg->video_height, 1);
		} else {
			gf_sg_set_scene_size_info(priv->sg, priv->cfg->text_width, priv->cfg->text_height, 1);
		}
		gf_sg_get_scene_size_info(priv->sg, &w, &h);
		if (!w || !h) return;
		gf_scene_force_size(priv->inlineScene, w, h);
	}

	if (!w || !h) return;
	/*apply*/
	gf_sg_set_scene_size_info(priv->sg, w, h, 1);
	/*make sure the scene size is big enough to contain the text track after positioning. RESULTS ARE UNDEFINED
	if offsets are negative: since MPEG-4 uses centered coord system, we must assume video is aligned to top-left*/
	if (priv->cfg->has_vid_info) {
		Bool set_size = 0;
		vw = priv->cfg->horiz_offset; if (vw<0) vw = 0;
		vh = priv->cfg->vert_offset; if (vh<0) vh = 0;
		if (priv->cfg->text_width + (u32) vw > w) {
			w = priv->cfg->text_width+vw;
			set_size = 1;
		}
		if (priv->cfg->text_height + (u32) vh > h) {
			h = priv->cfg->text_height+vh;
			set_size = 1;
		}
		if (set_size) {
			gf_sg_set_scene_size_info(priv->sg, w, h, 1);
			gf_scene_force_size(priv->inlineScene, w, h);
		}
	} else {
		/*otherwise override (mainly used for SRT & TTXT file direct loading*/
		priv->cfg->text_width = w;
		priv->cfg->text_height = h;
	}

	/*ok override video size with main scene size*/
	priv->cfg->video_width = w;
	priv->cfg->video_height = h;

	vw = (s32) w;
	vh = (s32) h;
	thw = priv->cfg->text_width / 2;
	thh = priv->cfg->text_height / 2;
	/*check translation, we must not get out of scene size - not supported in GPAC*/
	offset = priv->cfg->horiz_offset - vw/2 + thw;
	/*safety checks ?
	if (offset + thw < - vw/2) offset = - vw/2 + thw;
	else if (offset - thw > vw/2) offset = vw/2 - thw;
	*/
	priv->tr_track->translation.x = INT2FIX(offset);

	offset = vh/2 - priv->cfg->vert_offset - thh;
	/*safety checks ?
	if (offset + thh > vh/2) offset = vh/2 - thh;
	else if (offset - thh < -vh/2) offset = -vh/2 + thh;
	*/
	priv->tr_track->translation.y = INT2FIX(offset);

	gf_node_changed((GF_Node *)priv->tr_track, NULL);
}