Ejemplo n.º 1
0
void MC_Modified(GF_Node *node)
{
	MediaControlStack *stack =(MediaControlStack *) gf_node_get_private(node);
	if (!stack) return;
	if (stack->changed!=2) {
		/*check URL*/
		if (MC_URLChanged(&stack->url, &stack->control->url))
			stack->changed = 2;
		/*check speed (play/pause)*/
		else if (stack->media_speed != stack->control->mediaSpeed)
			stack->changed = 1;
		/*check mediaStartTime (seek)*/
		else if (stack->media_start != stack->control->mediaStartTime) {
			/*do not reevaluate if mediaStartTime is reset to -1 (current time)*/
			if (stack->control->mediaStartTime!=-1.0)
				stack->changed = 2;
			/*check mediaStopTime <0 (timeshift buffer control)*/
		} else if (stack->media_stop != stack->control->mediaStopTime) {
			if (stack->control->mediaStopTime<=0)
				stack->changed = 2;
		}
//		else stack->changed = 1;
	}

	gf_node_dirty_set( gf_sg_get_root_node(gf_node_get_graph(node)), 0, 1);
	/*invalidate scene, we recompute MC state in render*/
	gf_term_invalidate_compositor(stack->parent->root_od->term);
}
Ejemplo n.º 2
0
static void svg_a_set_view(GF_Node *handler, GF_Compositor *compositor, const char *url)
{
	gf_scene_set_fragment_uri(handler, url);
	/*force recompute viewbox of root SVG - FIXME in full this should be the parent svg*/
	gf_node_dirty_set(gf_sg_get_root_node(gf_node_get_graph(handler)), 0, 0);

	compositor->trans_x = compositor->trans_y = 0;
	compositor->rotation = 0;
	compositor->zoom = FIX_ONE;
	compositor_2d_set_user_transform(compositor, FIX_ONE, 0, 0, 0); 				
	gf_sc_invalidate(compositor, NULL);
}
Ejemplo n.º 3
0
GF_Node *compositor_svg_get_xlink_resource_node(GF_Node *node, XMLRI *xlink)
{
	SVGlinkStack *stack;
	switch (gf_node_get_tag(node)) {
	case TAG_SVG_animation:
		stack = gf_node_get_private(node);
		return gf_sg_get_root_node(stack->inline_sg);
	case TAG_SVG_use:
		stack = gf_node_get_private(node);
		if (stack && stack->fragment_id)
			return gf_sg_find_node_by_name(stack->inline_sg, (char *) stack->fragment_id+1);
		return xlink ? xlink->target : NULL;
	}
	return NULL;
}
Ejemplo n.º 4
0
void V4SceneManager::LoadFile(const char *path) 
{	
	LoadCommon();
	GF_Terminal *term = m_gpac_panel->GetMPEG4Terminal();

	/* Loading of a file (BT, MP4 ...) and modification of the SceneManager */
	GF_SceneLoader load;
	memset(&load, 0, sizeof(GF_SceneLoader));
	load.fileName = path;
	load.ctx = m_pSm;
	if (strstr(path, ".mp4") || strstr(path, ".MP4") ) load.isom = gf_isom_open(path, GF_ISOM_OPEN_READ, NULL);
	gf_sm_load_init(&load);
	gf_sm_load_run(&load);
	gf_sm_load_done(&load);
	if (load.isom) gf_isom_delete(load.isom);

	/* SceneManager should be initialized  and filled correctly */

	gf_sg_set_scene_size_info(m_pIs->graph, m_pSm->scene_width, m_pSm->scene_height, m_pSm->is_pixel_metrics);

	// TODO : replace with GetBifsStream
	GF_StreamContext *sc = (GF_StreamContext *) gf_list_get(m_pSm->streams,0);

	if (sc->streamType == 3) {
		GF_AUContext *au = (GF_AUContext *) gf_list_get(sc->AUs,0);
		GF_Command *c = (GF_Command *) gf_list_get(au->commands,0);
		//gf_sg_command_apply(m_pIs->graph, c, 0);
		/* This is a patch to solve the save pb:
		    When ApplyCommand is made on a Scene Replace Command
		    The command node is set to NULL
		    When we save a BIFS stream whose first command is of this kind,
		    the file saver thinks the bifs commands should come from an NHNT file 
		   This is a temporary patch */
		if (c->tag == GF_SG_SCENE_REPLACE) { c->node = m_pIs->graph->RootNode; }
	}

	gf_sc_set_scene(term->compositor, m_pIs->graph);
	m_pIs->graph_attached = 1;

	// TODO : read actual values from file
	SetLength(50);
	SetFrameRate(25);

	// retrieves all the node from the tree and adds them to the node pool
	GF_Node * root = gf_sg_get_root_node(m_pIs->graph);
//	CreateDictionnary();
}
Ejemplo n.º 5
0
void compositor_init_svg_svg(GF_Compositor *compositor, GF_Node *node)
{
	GF_Node *root;
	SVGsvgStack *stack;

	GF_SAFEALLOC(stack, SVGsvgStack);

	root = gf_sg_get_root_node(gf_node_get_graph(node));
	stack->root_svg = (root==node) ? 1 : 0;
	if (stack->root_svg) {
		GF_SAFEALLOC(stack->svg_props, SVGPropertiesPointers);
		gf_svg_properties_init_pointers(stack->svg_props);
	}
	gf_mx2d_init(stack->viewbox_mx);

	gf_node_set_private(node, stack);
	gf_node_set_callback_function(node, svg_traverse_svg);
}
Ejemplo n.º 6
0
// CreateDictionnary -- Create the root node of the dictionnary and populates it
void V4SceneManager::CreateDictionnary() {
  GF_Node * root = gf_sg_get_root_node(m_pIs->graph);
  dictionnary = NewNode(TAG_MPEG4_Switch);

  // Insert the dictionnary in the scene and gives it a name
  gf_node_insert_child(root, dictionnary, 0);
  gf_node_register(dictionnary, root);
  gf_node_set_id(dictionnary, gf_sg_get_next_available_node_id(m_pIs->graph), DICTNAME);

  // makes the dictionnary invisible
  // the number 1 field is the "whichChoice", setting it to -1 makes it display nothing
  GF_FieldInfo field;
  gf_node_get_field(dictionnary, 1, &field);
  frame->GetFieldView()->SetFieldValue(field, &wxString("-1"), -1);  // TODO : maybe put the method SetFieldValue somewhere more accessible

  // populates dictionnary with the root node of the scene
  AddToDictionnary(root);
}
Ejemplo n.º 7
0
void VTT_UpdateSizeInfo(VTTDec *vttdec)
{
	u32 w, h;
	GF_FieldInfo info;
	char szVB[100];
	GF_Node *root = gf_sg_get_root_node(vttdec->sg);
	if (!root) return;
	w = vttdec->scene->root_od->term->compositor->display_width;
	h = vttdec->scene->root_od->term->compositor->display_height;

	w=1280;
	h=720;
	/*apply*/
	gf_sg_set_scene_size_info(vttdec->sg, w, h, GF_TRUE);

	sprintf(szVB, "0 0 %d %d", w, h);
	gf_node_get_attribute_by_tag(root, TAG_SVG_ATT_viewBox, GF_TRUE, GF_FALSE, &info);
	gf_svg_parse_attribute(root, &info, szVB, 0);

}
Ejemplo n.º 8
0
void visual_2d_pick_node(GF_VisualManager *visual, GF_TraverseState *tr_state, GF_Event *ev, GF_ChildNodeItem *children)
{
	GF_Matrix2D backup;
	visual->bounds_tracker_modif_flag = DRAWABLE_HAS_CHANGED_IN_LAST_TRAVERSE;

	gf_mx2d_copy(backup, tr_state->transform);

	visual_2d_setup_projection(visual, tr_state);

	visual->compositor->hit_node = NULL;
	tr_state->ray.orig.x = INT2FIX(ev->mouse.x);
	tr_state->ray.orig.y = INT2FIX(ev->mouse.y);
	tr_state->ray.orig.z = 0;
	tr_state->ray.dir.x = 0;
	tr_state->ray.dir.y = 0;
	tr_state->ray.dir.z = -FIX_ONE;

	visual->compositor->hit_world_point = tr_state->ray.orig;
	visual->compositor->hit_world_ray = tr_state->ray;
	visual->compositor->hit_square_dist = 0;

	gf_list_reset(visual->compositor->sensors);
	tr_state->traversing_mode = TRAVERSE_PICK;

	/*not the root scene, use children list*/
	if (visual->compositor->visual != visual) {
		while (children) {
			gf_node_traverse(children->node, tr_state);
			children = children->next;
		}
	} else {
		u32 i = 0;
		GF_SceneGraph *sg = visual->compositor->scene;
		GF_Node *root = gf_sg_get_root_node(sg);
		gf_node_traverse(root, tr_state);
		while ((sg = (GF_SceneGraph*)gf_list_enum(visual->compositor->extra_scenes, &i))) {
			gf_sc_traverse_subscene(visual->compositor, root, sg, tr_state);
		}
	}
	gf_mx2d_copy(tr_state->transform, backup);
}
Ejemplo n.º 9
0
void V4SceneGraph::LoadFile(const char *path) 
{
	GF_SceneLoader load;
	if (m_pSm) {
		gf_sr_set_scene(m_pSr, NULL);
		gf_sm_del(m_pSm);
		gf_sg_del(m_pSg);
	}
	
	// initializes a new scene
	// We need an GF_InlineScene, a SceneManager and an GF_ObjectManager
	m_pIs = gf_is_new(NULL);
	m_pSg = m_pIs->graph;
	m_pSm = gf_sm_new(m_pSg);

	m_pIs->root_od = gf_odm_new();

	m_pIs->root_od->parentscene = NULL;
	m_pIs->root_od->subscene = m_pIs;
	m_pIs->root_od->term = m_term;

	m_term->root_scene = m_pIs;
	
	// TODO : what's the use of this ?
	if (m_pOriginal_mp4) gf_free(m_pOriginal_mp4);
	m_pOriginal_mp4 = NULL;

	/* Loading of a file (BT, MP4 ...) and modification of the SceneManager */
	memset(&load, 0, sizeof(GF_SceneLoader));
	load.fileName = path;
	load.ctx = m_pSm;
	load.cbk = this;
	if (strstr(path, ".mp4") || strstr(path, ".MP4") ) load.isom = gf_isom_open(path, GF_ISOM_OPEN_READ, NULL);
	gf_sm_load_init(&load);
	gf_sm_load_run(&load);
	gf_sm_load_done(&load);
	if (load.isom) gf_isom_delete(load.isom);

	/* SceneManager should be initialized  and filled correctly */

	gf_sg_set_scene_size_info(m_pSg, m_pSm->scene_width, m_pSm->scene_height, m_pSm->is_pixel_metrics);

	// TODO : replace with GetBifsStream
	GF_StreamContext *sc = (GF_StreamContext *) gf_list_get(m_pSm->streams,0);

	if (sc->streamType == 3) {
		GF_AUContext *au = (GF_AUContext *) gf_list_get(sc->AUs,0);
		GF_Command *c = (GF_Command *) gf_list_get(au->commands,0);
		gf_sg_command_apply(m_pSg, c, 0);
		/* This is a patch to solve the save pb:
		    When ApplyCommand is made on a Scene Replace Command
		    The command node is set to NULL
		    When we save a BIFS stream whose first command is of this kind,
		    the file saver thinks the bifs commands should come from an NHNT file 
		   This is a temporary patch */
		if (c->tag == GF_SG_SCENE_REPLACE) { c->node = m_pSg->RootNode; }
	}
	gf_sr_set_scene(m_pSr, m_pSg);

	// retrieves all the node from the tree and adds them to the node pool
	GF_Node * root = gf_sg_get_root_node(m_pSg);
	CreateDictionnary();
}
Ejemplo n.º 10
0
static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes)
{
	u32 i;
	SVG_SANI_BIFS_Converter *converter = (SVG_SANI_BIFS_Converter *)sax_cbck;
	SVGPropertiesPointers *backup_props;
	char *id_string = NULL;

	u32	tag = gf_svg_get_element_tag(name);
	SVG_Element *elt = (SVG_Element*)gf_node_new(converter->svg_sg, tag);
	if (!gf_sg_get_root_node(converter->svg_sg)) {
		gf_node_register((GF_Node *)elt, NULL);
		gf_sg_set_root_node(converter->svg_sg, (GF_Node *)elt);
	} else {
		gf_node_register((GF_Node *)elt, converter->svg_parent);	
		//gf_node_list_add_child(&((GF_ParentNode*)converter->svg_parent)->children, (GF_Node *)elt);
	}
	converter->svg_parent = (GF_Node *)elt;
	
//	fprintf(stdout, "Converting %s\n", gf_node_get_class_name((GF_Node *)elt));
//	if (converter->bifs_parent) fprintf(stdout, "%s\n", gf_node_get_class_name(converter->bifs_parent));

	for (i=0; i<nb_attributes; i++) {
		GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i];
		if (!att->value || !strlen(att->value)) continue;

		if (!stricmp(att->name, "style")) {
			gf_svg_parse_style((GF_Node *)elt, att->value);
		} else if (!stricmp(att->name, "id") || !stricmp(att->name, "xml:id")) {
			gf_svg_parse_element_id((GF_Node *)elt, att->value, 0);
			id_string = att->value;
		} else {
			GF_FieldInfo info;
			if (gf_node_get_field_by_name((GF_Node *)elt, att->name, &info)==GF_OK) {
				gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0);
			} else {
				fprintf(stdout, "Skipping attribute %s\n", att->name);
			}
		}
	}

	memset(&converter->all_atts, 0, sizeof(SVGAllAttributes));
	gf_svg_flatten_attributes(elt, &converter->all_atts);
	
	backup_props = gf_malloc(sizeof(SVGPropertiesPointers));
	memcpy(backup_props, &converter->svg_props, sizeof(SVGPropertiesPointers));
	gf_node_set_private((GF_Node *)elt, backup_props);

	gf_svg_apply_inheritance(&converter->all_atts, &converter->svg_props);

	if (!gf_sg_get_root_node(converter->bifs_sg)) {
		if (tag == TAG_SVG_svg) {
			GF_Node *node, *child;

			converter->bifs_sg->usePixelMetrics = 1;
			if (converter->all_atts.width && converter->all_atts.width->type == SVG_NUMBER_VALUE) {
				converter->bifs_sg->width = FIX2INT(converter->all_atts.width->value);
			} else {
				converter->bifs_sg->width = 320;
			}
			if (converter->all_atts.height && converter->all_atts.height->type == SVG_NUMBER_VALUE) {
				converter->bifs_sg->height = FIX2INT(converter->all_atts.height->value);
			} else {
				converter->bifs_sg->height = 200;
			}

			node = gf_node_new(converter->bifs_sg, TAG_MPEG4_OrderedGroup);
			gf_node_register(node, NULL);
			gf_sg_set_root_node(converter->bifs_sg, node);

			/* SVG to BIFS coordinate transformation */
			child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Viewport);
			gf_node_register(child, node);
			gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
			if (converter->all_atts.viewBox) {
				M_Viewport *vp = (M_Viewport*)child;
				vp->size.x = converter->all_atts.viewBox->width;
				vp->size.y = converter->all_atts.viewBox->height;
				vp->position.x = converter->all_atts.viewBox->x+converter->all_atts.viewBox->width/2;
				vp->position.y = -(converter->all_atts.viewBox->y+converter->all_atts.viewBox->height/2);
			} else {
				M_Viewport *vp = (M_Viewport*)child;
				vp->size.x = INT2FIX(converter->bifs_sg->width);
				vp->size.y = INT2FIX(converter->bifs_sg->height);
				vp->position.x = INT2FIX(converter->bifs_sg->width)/2;
				vp->position.y = -INT2FIX(converter->bifs_sg->height)/2;
			}

			child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Background2D);
			gf_node_register(child, node);
			gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
			{
				M_Background2D *b = (M_Background2D *)child;
				b->backColor.red = FIX_ONE;
				b->backColor.green = FIX_ONE;				
				b->backColor.blue = FIX_ONE;
			}

			child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
			gf_node_register(child, node);
			gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
			node = child;
			child = NULL;
			{
				M_Transform2D *tr = (M_Transform2D *)node;
				tr->scale.y = -FIX_ONE;
			}
			converter->bifs_parent = node;
		}
	} else {
		GF_Node *node, *child;
		
		node = converter->bifs_parent;

		switch(tag) {
		case TAG_SVG_g:
			{
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
				} else {
					M_Group *g = (M_Group*)gf_node_new(converter->bifs_sg, TAG_MPEG4_Group);
					gf_node_register((GF_Node *)g, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, (GF_Node *)g);
					node = (GF_Node *)g;
					converter->bifs_parent = node;
				}
			}
			break;
		case TAG_SVG_rect:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				} 
				if (converter->all_atts.x || converter->all_atts.y) {
					child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
					gf_node_register(child, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
					node = child;
					child = NULL;
					if (!is_parent_set) {
						converter->bifs_parent = node;
						is_parent_set = 1;
					}
					{
						M_Transform2D *tr = (M_Transform2D *)node;
						if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value + (converter->all_atts.width?converter->all_atts.width->value/2:0);
						if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value + (converter->all_atts.height?converter->all_atts.height->value/2:0);
					}
				} 
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_Rectangle);
					gf_node_register(shape->geometry, (GF_Node *)shape);
					{
						M_Rectangle *rect = (M_Rectangle *)shape->geometry;
						if (converter->all_atts.width) rect->size.x = converter->all_atts.width->value;
						if (converter->all_atts.height) rect->size.y = converter->all_atts.height->value;					
					}			
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_path:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				} 
				if (converter->all_atts.x || converter->all_atts.y) {
					child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
					gf_node_register(child, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
					node = child;
					child = NULL;
					if (!is_parent_set) {
						converter->bifs_parent = node;
						is_parent_set = 1;
					}
					{
						M_Transform2D *tr = (M_Transform2D *)node;
						if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value;
						if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value;
					}
				} 
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_XCurve2D);
					gf_node_register(shape->geometry, (GF_Node *)shape);
					if (converter->all_atts.d) {
						M_Coordinate2D *c2d;
						M_XCurve2D *xc = (M_XCurve2D *)shape->geometry;
						u32 i, j, c;

						xc->point = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
						c2d = (M_Coordinate2D *)xc->point;
						gf_node_register(xc->point, (GF_Node *)xc);
						
						gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, converter->all_atts.d->n_points);
						j= 0;
						for (i = 0; i < converter->all_atts.d->n_points; i++) {
							if (converter->all_atts.d->tags[i] != GF_PATH_CLOSE || i == converter->all_atts.d->n_points-1) {
								c2d->point.vals[j] = converter->all_atts.d->points[i];
								j++;
							}
						}
						c2d->point.count = j;

						gf_sg_vrml_mf_alloc(&xc->type, GF_SG_VRML_MFINT32, converter->all_atts.d->n_points);
						c = 0;
						j = 0;
						xc->type.vals[0] = 0;
						for (i = 1; i < converter->all_atts.d->n_points; i++) {
							switch(converter->all_atts.d->tags[i]) {
							case GF_PATH_CURVE_ON:
								if (c < converter->all_atts.d->n_contours &&
									i-1 == converter->all_atts.d->contours[c]) {
									xc->type.vals[j] = 0;
									c++;
								} else {
									xc->type.vals[j] = 1;
								}
								break;
							case GF_PATH_CURVE_CUBIC:
								xc->type.vals[j] = 2;
								i+=2;
								break;
							case GF_PATH_CLOSE:
								xc->type.vals[j] = 6;
								break;
							case GF_PATH_CURVE_CONIC:
								xc->type.vals[j] = 7;
								i++;
								break;
							}
							j++;
						}
						xc->type.count = j;
					}			
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_polyline:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				} 

				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_IndexedFaceSet2D);
					gf_node_register(shape->geometry, (GF_Node *)shape);
					if (converter->all_atts.points) {
						M_Coordinate2D *c2d;
						M_IndexedFaceSet2D *ifs = (M_IndexedFaceSet2D *)shape->geometry;
						u32 i;

						ifs->coord = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
						c2d = (M_Coordinate2D *)ifs->coord;
						gf_node_register(ifs->coord, (GF_Node *)ifs);
						
						gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, gf_list_count(*converter->all_atts.points));
						for (i = 0; i < gf_list_count(*converter->all_atts.points); i++) {
							SVG_Point *p = (SVG_Point *)gf_list_get(*converter->all_atts.points, i);
							c2d->point.vals[i].x = p->x;
							c2d->point.vals[i].y = p->y;
						}						
					}			
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_text:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				}

				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				{
					M_Transform2D *tr = (M_Transform2D *)child;
					if (converter->all_atts.text_x) tr->translation.x = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_x, 0))->value;
					if (converter->all_atts.text_y) tr->translation.y = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_y, 0))->value;
					tr->scale.y = -FIX_ONE;
				}
				node = child;
				child = NULL;
				if (!is_parent_set) {
					converter->bifs_parent = node;
					is_parent_set = 1;
				}

				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_FontStyle *fs;
					M_Text *text; 
					M_Shape *shape = (M_Shape *)node;
					text = (M_Text *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Text);
					shape->geometry = (GF_Node *)text;
					converter->bifs_text_node = shape->geometry;
					gf_node_register(shape->geometry, (GF_Node *)shape);
					
					fs = (M_FontStyle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_XFontStyle);
					gf_node_register((GF_Node *)fs, (GF_Node*)text);
					text->fontStyle = (GF_Node *)fs;

					gf_sg_vrml_mf_alloc(&fs->family, GF_SG_VRML_MFSTRING, 1);				
					fs->family.vals[0] = strdup(converter->svg_props.font_family->value);				
					fs->size = converter->svg_props.font_size->value;

					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_ellipse:
		case TAG_SVG_circle:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				}
				if (converter->all_atts.cx || converter->all_atts.cy) {
					child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
					gf_node_register(child, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
					{
						M_Transform2D *tr = (M_Transform2D *)child;
						if (converter->all_atts.cx) tr->translation.x = converter->all_atts.cx->value;
						if (converter->all_atts.cy) tr->translation.y = converter->all_atts.cy->value;
					}
					node = child;
					child = NULL;
					if (!is_parent_set) {
						converter->bifs_parent = node;
						is_parent_set = 1;
					}
				} 
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					if (tag == TAG_SVG_ellipse) {
						M_Ellipse *e = (M_Ellipse *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Ellipse);
						shape->geometry = (GF_Node *)e;
						e->radius.x = converter->all_atts.rx->value;
						e->radius.y = converter->all_atts.ry->value;
					} else {
						M_Circle *c = (M_Circle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Circle);
						shape->geometry = (GF_Node *)c;
						c->radius = converter->all_atts.r->value;
					}
					gf_node_register(shape->geometry, (GF_Node *)shape);
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;

		case TAG_SVG_defs:
			{
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Switch);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				{
					M_Switch *sw = (M_Switch *)node;
					sw->whichChoice = -1;
				}
				converter->bifs_parent = node;
			}
			break;
		case TAG_SVG_solidColor:
			{
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				converter->bifs_parent = node;
			}
			break;
		default:
			{
				fprintf(stdout, "Warning: element %s not supported \n", gf_node_get_class_name((GF_Node *)elt));
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				converter->bifs_parent = node;
			}
			break;
		}

		if (id_string) 
			gf_node_set_id(converter->bifs_parent, gf_node_get_id((GF_Node *)elt), gf_node_get_name((GF_Node *)elt));
	}
}
Ejemplo n.º 11
0
static Bool gf_sm_check_for_modif(GF_SceneEngine *seng, GF_AUContext *au)
{
	GF_Command *com;
	Bool modified=0;
	u32 i=0;
	/*au is marked as modified - this happens when commands are concatenated into the au*/
	if (au->flags & GF_SM_AU_MODIFIED) {
		au->flags &= ~GF_SM_AU_MODIFIED;
		modified=1;
	}
	/*check each command*/
	while (NULL != (com = gf_list_enum(au->commands, &i))) {
		u32 j=0;
		GF_CommandField *field;
		if (!com->node) continue;
		/*check root node (for SCENE_REPLACE) */
		if (gf_node_dirty_get(com->node)) {
			modified=1;
			gf_node_dirty_reset(com->node, 1);
		}
		/*check all command fields of type SFNODE or MFNODE*/
		while (NULL != (field = gf_list_enum(com->command_fields, &j))) {
			switch (field->fieldType) {
			case GF_SG_VRML_SFNODE:
				if (field->new_node) {
					if (gf_node_dirty_get(field->new_node)) {
						modified=1;
						gf_node_dirty_reset(field->new_node, 1);
					}
				}
				break;
			case GF_SG_VRML_MFNODE:
				if (field->field_ptr) {
					GF_ChildNodeItem *child;
					child = field->node_list;
					while (child) {
						if (gf_node_dirty_get(child->node)) {
							modified=1;
							gf_node_dirty_reset(child->node, 1);
						}
						child = child->next;
					}
				}
				break;
			}
		}
	}

	if (!seng->first_dims_sent) {
		if (au->owner->objectType==GPAC_OTI_SCENE_DIMS) {
			GF_Node *root = gf_sg_get_root_node(seng->ctx->scene_graph);
			if (gf_node_dirty_get(root)) {
				modified=1;
				gf_node_dirty_reset(root, 1);
			}
		} else {
		}
		seng->first_dims_sent = 1;
	}
	return modified;
}
Ejemplo n.º 12
0
Bool gf_sc_fit_world_to_screen(GF_Compositor *compositor)
{
	GF_TraverseState tr_state;
	SFVec3f pos, diff;
	Fixed dist, d;
	GF_Camera *cam;
	GF_Node *top;

#ifndef GPAC_DISABLE_VRML
//	if (gf_list_count(compositor->visual->back_stack)) return;
	if (gf_list_count(compositor->visual->view_stack)) return 0;
#endif

	gf_mx_p(compositor->mx);
	top = gf_sg_get_root_node(compositor->scene);
	if (!top) {
		gf_mx_v(compositor->mx);
		return 0;
	}
	memset(&tr_state, 0, sizeof(GF_TraverseState));
	gf_mx_init(tr_state.model_matrix);
	tr_state.traversing_mode = TRAVERSE_GET_BOUNDS;
	tr_state.visual = compositor->visual;
	gf_node_traverse(top, &tr_state);
	if (gf_node_dirty_get(top)) {
		tr_state.bbox.is_set = 0;
	}

	if (!tr_state.bbox.is_set) {
		gf_mx_v(compositor->mx);
		/*empty world ...*/
		if (tr_state.bbox.radius==-1) return 1;
		/*2D world with 3D camera forced*/
		if (tr_state.bounds.width&&tr_state.bounds.height) return 1;
		return 0;
	}

	cam = &compositor->visual->camera;

	cam->world_bbox = tr_state.bbox;
	/*fit is based on bounding sphere*/
	dist = gf_divfix(tr_state.bbox.radius, gf_sin(cam->fieldOfView/2) );
	gf_vec_diff(diff, cam->center, tr_state.bbox.center);
	/*do not update if camera is outside the scene bounding sphere and dist is too close*/
	if (gf_vec_len(diff) > tr_state.bbox.radius + cam->radius) {
		gf_vec_diff(diff, cam->vp_position, tr_state.bbox.center);
		d = gf_vec_len(diff);
		if (d<dist) {
			gf_mx_v(compositor->mx);
			return 1;
		}
	}

	diff = gf_vec_scale(camera_get_pos_dir(cam), dist);
	gf_vec_add(pos, tr_state.bbox.center, diff);
	diff = cam->position;
	camera_set_vectors(cam, pos, cam->vp_orientation, cam->fieldOfView);
	cam->position = diff;
	camera_move_to(cam, pos, cam->target, cam->up);
	cam->examine_center = tr_state.bbox.center;
	cam->flags |= CF_STORE_VP;
	if (cam->z_far < dist) cam->z_far = 10*dist;
	camera_changed(compositor, cam);
	gf_mx_v(compositor->mx);
	return 1;
}
Ejemplo n.º 13
0
GF_Err gf_sr_set_scene(GF_Renderer *sr, GF_SceneGraph *scene_graph)
{
	u32 width, height;
	Bool do_notif;

	if (!sr) return GF_BAD_PARAM;

	gf_sr_lock(sr, 1);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, (scene_graph ? "[Render] Attaching new scene\n" : "[Render] Detaching scene\n"));

	if (sr->audio_renderer && (sr->scene != scene_graph)) {
		GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Reseting audio render\n"));
		gf_sr_ar_reset(sr->audio_renderer);
	}

#ifdef GF_SR_EVENT_QUEUE
	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Reseting event queue\n"));
	gf_mx_p(sr->ev_mx);
	while (gf_list_count(sr->events)) {
		GF_Event *ev = (GF_Event*)gf_list_get(sr->events, 0);
		gf_list_rem(sr->events, 0);
		free(ev);
	}
#endif
	
	GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Reseting render module\n"));
	/*reset main surface*/
	sr->visual_renderer->SceneReset(sr->visual_renderer);

	/*set current graph*/
	sr->scene = scene_graph;
	do_notif = 0;
	if (scene_graph) {
#ifndef GPAC_DISABLE_SVG
		SVG_Length *w, *h;
#endif
		const char *opt;
		Bool is_svg = 0;
		u32 tag;
		GF_Node *top_node;
		Bool had_size_info = sr->has_size_info;
		/*get pixel size if any*/
		gf_sg_get_scene_size_info(sr->scene, &width, &height);
		sr->has_size_info = (width && height) ? 1 : 0;
		if (sr->has_size_info != had_size_info) sr->scene_width = sr->scene_height = 0;

		/*default back color is black*/
		if (! (sr->user->init_flags & GF_TERM_WINDOWLESS)) sr->back_color = 0xFF000000;

		top_node = gf_sg_get_root_node(sr->scene);
		tag = 0;
		if (top_node) tag = gf_node_get_tag(top_node);

#ifndef GPAC_DISABLE_SVG
		w = h = NULL;
		if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) {
			GF_FieldInfo info;
			is_svg = 1;
			if (gf_svg_get_attribute_by_tag(top_node, TAG_SVG_ATT_width, 0, 0, &info)==GF_OK) 
				w = info.far_ptr;
			if (gf_svg_get_attribute_by_tag(top_node, TAG_SVG_ATT_height, 0, 0, &info)==GF_OK) 
				h = info.far_ptr;
		}
#ifdef GPAC_ENABLE_SVG_SA
		else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SA) && (tag<=GF_NODE_RANGE_LAST_SVG_SA)) {
			SVG_SA_svgElement *root = (SVG_SA_svgElement *) top_node;
			is_svg = 1;
			w = &root->width;
			h = &root->height;
		}
#endif
#ifdef GPAC_ENABLE_SVG_SANI
		else if ((tag>=GF_NODE_RANGE_FIRST_SVG_SANI) && (tag<=GF_NODE_RANGE_LAST_SVG_SANI)) {
			SVG_SANI_svgElement *root = (SVG_SANI_svgElement*) top_node;
			is_svg = 1;
			w = &root->width;
			h = &root->height;
		}
#endif
		/*default back color is white*/
		if (is_svg && ! (sr->user->init_flags & GF_TERM_WINDOWLESS)) sr->back_color = 0xFFFFFFFF;

		/*hack for SVG where size is set in %*/
		if (!sr->has_size_info && w && h) {
			sr->has_size_info = 1;
			sr->aspect_ratio = GF_ASPECT_RATIO_FILL_SCREEN;
			if (w->type!=SVG_NUMBER_PERCENTAGE) {
				width = FIX2INT(convert_svg_length_to_user(sr, w) );
			} else {
				width = 320; //FIX2INT(root->viewBox.width);
			}
			if (h->type!=SVG_NUMBER_PERCENTAGE) {
				height = FIX2INT(convert_svg_length_to_user(sr, h) );
			} else {
				height = 240; //FIX2INT(root->viewBox.height);
			}
		}
#endif
		/*default back color is key color*/
		if (sr->user->init_flags & GF_TERM_WINDOWLESS) {
			opt = gf_cfg_get_key(sr->user->config, "Rendering", "ColorKey");
			if (opt) {
				u32 r, g, b, a;
				sscanf(opt, "%02X%02X%02X%02X", &a, &r, &g, &b);
				sr->back_color = GF_COL_ARGB(0xFF, r, g, b);
			}
		}

		/*set scene size only if different, otherwise keep scaling/FS*/
		if ( !width || (sr->scene_width!=width) || !height || (sr->scene_height!=height)) {
			do_notif = sr->has_size_info || (!sr->scene_width && !sr->scene_height);
			SR_SetSceneSize(sr, width, height);

			/*get actual size in pixels*/
			width = sr->scene_width;
			height = sr->scene_height;

			if (!sr->user->os_window_handler) {
				/*only notify user if we are attached to a window*/
				do_notif = 0;
				if (sr->video_out->max_screen_width && (width > sr->video_out->max_screen_width))
					width = sr->video_out->max_screen_width;
				if (sr->video_out->max_screen_height && (height > sr->video_out->max_screen_height))
					height = sr->video_out->max_screen_height;

				gf_sr_set_size(sr,width, height);
			}
		}
	}

	SR_ResetFrameRate(sr);	
#ifdef GF_SR_EVENT_QUEUE
	gf_mx_v(sr->ev_mx);
#endif
	
	gf_sr_lock(sr, 0);
	/*here's a nasty trick: the app may respond to this by calling a gf_sr_set_size from a different
	thread, but in an atomic way (typically happen on Win32 when changing the window size). WE MUST
	NOTIFY THE SIZE CHANGE AFTER RELEASING THE RENDERER MUTEX*/
	if (do_notif && sr->user->EventProc) {
		GF_Event evt;
		evt.type = GF_EVENT_SCENE_SIZE;
		evt.size.width = width;
		evt.size.height = height;
		sr->user->EventProc(sr->user->opaque, &evt);
	}
	if (scene_graph)
		sr->draw_next_frame = 1;
	return GF_OK;
}
Ejemplo n.º 14
0
static void svg_traverse_resource(GF_Node *node, void *rs, Bool is_destroy, Bool is_foreign_object)
{
	GF_Matrix2D backup_matrix;
	GF_Matrix mx_3d;
  	GF_Matrix2D translate;
	SVGPropertiesPointers backup_props;
	u32 backup_flags, dirty;
	Bool is_fragment;
	GF_Node *used_node;
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;
	SVGAllAttributes all_atts;
	SVGlinkStack *stack = gf_node_get_private(node);
	SFVec2f prev_vp;
	SVG_Number *prev_opacity;

	if (is_destroy) {
		if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource);
		gf_free(stack);
		return;
	}


	gf_svg_flatten_attributes((SVG_Element *)node, &all_atts);
	if (!all_atts.xlink_href) return;

	if (!compositor_svg_traverse_base(node, &all_atts, tr_state, &backup_props, &backup_flags))
		return;

	dirty = gf_node_dirty_get(node);
	if (dirty & GF_SG_CHILD_DIRTY) drawable_reset_group_highlight(tr_state, node);

	if (dirty & GF_SG_SVG_XLINK_HREF_DIRTY) {
		stack->fragment_id = NULL;
		stack->inline_sg = NULL;
		if (all_atts.xlink_href->string && (all_atts.xlink_href->string[0]=='#')) {
			stack->fragment_id = all_atts.xlink_href->string;
			stack->inline_sg = gf_node_get_graph(node);
		} else {
			GF_MediaObject *new_res = gf_mo_load_xlink_resource(node, is_foreign_object, 0, -1);
			if (new_res != stack->resource) {
				if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource);
				stack->resource = new_res;
			}
		}
	}
	gf_node_dirty_clear(node, 0);

	/*locate the used node - this is done at each step to handle progressive loading*/
	is_fragment = 0;
	used_node = NULL;
	if (!stack->inline_sg && !stack->fragment_id && all_atts.xlink_href) {
		if (all_atts.xlink_href->type == XMLRI_ELEMENTID) {
			used_node = all_atts.xlink_href->target;
			is_fragment = 1;
		} else if (stack->resource) {
			stack->inline_sg = gf_mo_get_scenegraph(stack->resource);
			if (!is_foreign_object) {
				stack->fragment_id = strchr(all_atts.xlink_href->string, '#');
			}
		}
	}
	if (!used_node && stack->inline_sg) {
		if (stack->fragment_id) {
			used_node = gf_sg_find_node_by_name(stack->inline_sg, (char *) stack->fragment_id+1);
			is_fragment = 1;
		} else if (is_foreign_object) {
			used_node = gf_sg_get_root_node(stack->inline_sg);
		}
	}
	if (!used_node) goto end;

	/*stack use nodes for picking*/
	gf_list_add(tr_state->use_stack, used_node);
	gf_list_add(tr_state->use_stack, node);

	gf_mx2d_init(translate);
	translate.m[2] = (all_atts.x ? all_atts.x->value : 0);
	translate.m[5] = (all_atts.y ? all_atts.y->value : 0);

	/*update VP size (SVG 1.1)*/
	prev_vp = tr_state->vp_size;
	if (all_atts.width && all_atts.height) {
		tr_state->vp_size.x = gf_sc_svg_convert_length_to_display(tr_state->visual->compositor, all_atts.width);
		tr_state->vp_size.y = gf_sc_svg_convert_length_to_display(tr_state->visual->compositor, all_atts.height);
	}

	prev_opacity = tr_state->parent_use_opacity;
	tr_state->parent_use_opacity = all_atts.opacity;

	if (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS) {
		compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &mx_3d);
		if (!compositor_svg_is_display_off(tr_state->svg_props)) {
			gf_node_traverse(used_node, tr_state);
			gf_mx2d_apply_rect(&translate, &tr_state->bounds);
		} 
		compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d);
	}
	/*SORT mode and visible, traverse*/
	else if (!compositor_svg_is_display_off(tr_state->svg_props) 
		&& (*(tr_state->svg_props->visibility) != SVG_VISIBILITY_HIDDEN)) {

		compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &mx_3d);

#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) {
			gf_mx_add_matrix_2d(&tr_state->model_matrix, &translate);

			if (tr_state->traversing_mode==TRAVERSE_SORT) {
				GF_Matrix tmp;
				gf_mx_from_mx2d(&tmp, &translate);
				visual_3d_matrix_add(tr_state->visual, tmp.m);
			}
		} else 
#endif
			gf_mx2d_pre_multiply(&tr_state->transform, &translate);


		drawable_check_focus_highlight(node, tr_state, NULL);
		if (is_fragment) {
			gf_node_traverse(used_node, tr_state);
		} else {
			gf_sc_traverse_subscene(tr_state->visual->compositor, node, stack->inline_sg, tr_state);
		}
		compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d);  

	}
	gf_list_rem_last(tr_state->use_stack);
	gf_list_rem_last(tr_state->use_stack);
	tr_state->vp_size = prev_vp;

	tr_state->parent_use_opacity = prev_opacity;

end:
	memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers));
	tr_state->svg_flags = backup_flags;
}
Ejemplo n.º 15
0
static GF_Err SVG_ProcessData(GF_SceneDecoder *plug, const char *inBuffer, u32 inBufferLength,
                              u16 ES_ID, u32 stream_time, u32 mmlevel)
{
	GF_Err e = GF_OK;
	SVGIn *svgin = (SVGIn *)plug->privateStack;

	if (stream_time==(u32)-1) {
		if (svgin->src) gzclose(svgin->src);
		svgin->src = NULL;
		gf_sm_load_done(&svgin->loader);
		svgin->loader.fileName = NULL;
		svgin->file_pos = 0;
		gf_sg_reset(svgin->scene->graph);
		return GF_OK;
	}

	switch (svgin->oti) {
	/*!OTI for SVG dummy stream (dsi = file name) - GPAC internal*/
	case GPAC_OTI_PRIVATE_SCENE_SVG:
		/*full doc parsing*/
		if ((svgin->sax_max_duration==(u32) -1) && svgin->file_size) {
			/*init step*/
			if (!svgin->loader.fileName) {
				/*not done yet*/
				if (!svg_check_download(svgin)) return GF_OK;
				svgin->loader.fileName = svgin->file_name;
				e = gf_sm_load_init(&svgin->loader);
			} else {
				e = gf_sm_load_run(&svgin->loader);
			}
		}
		/*chunk parsing*/
		else {
			u32 entry_time;
			char file_buf[SVG_PROGRESSIVE_BUFFER_SIZE+2];
			/*initial load*/
			if (!svgin->src && !svgin->file_pos) {
				svgin->src = gzopen(svgin->file_name, "rb");
				if (!svgin->src) return GF_URL_ERROR;
				svgin->loader.fileName = svgin->file_name;
				gf_sm_load_init(&svgin->loader);
			}
			e = GF_OK;
			entry_time = gf_sys_clock();

			while (1) {
				u32 diff;
				s32 nb_read;
				nb_read = gzread(svgin->src, file_buf, SVG_PROGRESSIVE_BUFFER_SIZE);
				/*we may have read nothing but we still need to call parse in case the parser got suspended*/
				if (nb_read<=0) {
					nb_read = 0;
					if ((e==GF_EOS) && gzeof(svgin->src)) {
						gf_set_progress("SVG Parsing", svgin->file_pos, svgin->file_size);
						gzclose(svgin->src);
						svgin->src = NULL;
						gf_sm_load_done(&svgin->loader);
					}
					goto exit;
				}

				file_buf[nb_read] = file_buf[nb_read+1] = 0;

				e = gf_sm_load_string(&svgin->loader, file_buf, 0);
				svgin->file_pos += nb_read;



				/*handle decompression*/
				if (svgin->file_pos > svgin->file_size) svgin->file_size = svgin->file_pos + 1;
				if (e) break;

				gf_set_progress("SVG Parsing", svgin->file_pos, svgin->file_size);
				diff = gf_sys_clock() - entry_time;
				if (diff > svgin->sax_max_duration) {
					break;
				}
			}
		}
		break;

	/*!OTI for streaming SVG - GPAC internal*/
	case GPAC_OTI_SCENE_SVG:
		e = gf_sm_load_string(&svgin->loader, inBuffer, 0);
		break;

	/*!OTI for streaming SVG + gz - GPAC internal*/
	case GPAC_OTI_SCENE_SVG_GZ:
		e = svgin_deflate(svgin, inBuffer, inBufferLength);
		break;

	/*!OTI for DIMS (dsi = 3GPP DIMS configuration) - GPAC internal*/
	case GPAC_OTI_SCENE_DIMS:
	{
		u8 prev, dims_hdr;
		u32 nb_bytes, size;
		u64 pos;
		char * buf2 = gf_malloc(inBufferLength);
		GF_BitStream *bs = gf_bs_new(inBuffer, inBufferLength, GF_BITSTREAM_READ);
		memcpy(buf2, inBuffer, inBufferLength);
//			FILE *f = gf_f64_open("dump.svg", "wb");
//
		while (gf_bs_available(bs)) {
			pos = gf_bs_get_position(bs);
			size = gf_bs_read_u16(bs);
			nb_bytes = 2;
			/*GPAC internal hack*/
			if (!size) {
				size = gf_bs_read_u32(bs);
				nb_bytes = 6;
			}
//	            gf_fwrite( inBuffer + pos + nb_bytes + 1, 1, size - 1, f );

			dims_hdr = gf_bs_read_u8(bs);
			prev = buf2[pos + nb_bytes + size];

			buf2[pos + nb_bytes + size] = 0;
			if (dims_hdr & GF_DIMS_UNIT_C) {
				e = svgin_deflate(svgin, buf2 + pos + nb_bytes + 1, size - 1);
			} else {
				e = gf_sm_load_string(&svgin->loader, buf2 + pos + nb_bytes + 1, 0);
			}
			buf2[pos + nb_bytes + size] = prev;
			gf_bs_skip_bytes(bs, size-1);

		}
//          fclose(f);
		gf_bs_del(bs);
	}
	break;

	default:
		return GF_BAD_PARAM;
	}

exit:
	if ((e>=GF_OK) && (svgin->scene->graph_attached!=1) && (gf_sg_get_root_node(svgin->loader.scene_graph)!=NULL) ) {
		gf_scene_attach_to_compositor(svgin->scene);
	}
	/*prepare for next playback*/
	if (e) {
		gf_sm_load_done(&svgin->loader);
		svgin->loader.fileName = NULL;
		e = GF_EOS;
	}
	return e;
}
Ejemplo n.º 16
0
static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes)
{
    u32 i;
    SVG2BIFS_Converter *converter = (SVG2BIFS_Converter *)sax_cbck;
    SVGPropertiesPointers *backup_props;
    char *id_string = NULL;
    u32	tag;
    SVG_Element *elt;
    SVG_DeferedAnimation *anim = NULL;

    tag = gf_xml_get_element_tag(name, 0);
    elt = (SVG_Element*)gf_node_new(converter->svg_sg, tag);
    if (!gf_sg_get_root_node(converter->svg_sg)) {
        gf_node_register((GF_Node *)elt, NULL);
        gf_sg_set_root_node(converter->svg_sg, (GF_Node *)elt);
    } else {
        gf_node_register((GF_Node *)elt, converter->svg_parent);
        //gf_node_list_add_child(&((GF_ParentNode*)converter->svg_parent)->children, (GF_Node *)elt);
    }

//	fprintf(stdout, "Converting %s\n", gf_node_get_class_name((GF_Node *)elt));
//	if (converter->bifs_parent) fprintf(stdout, "%s\n", gf_node_get_class_name(converter->bifs_parent));

    if (gf_svg_is_animation_tag(tag)) {
        GF_SAFEALLOC(anim, SVG_DeferedAnimation);
        /*default anim target is parent node*/
        anim->animation_elt = elt;
        if (converter->svg_parent) {
            anim->target = anim->anim_parent = (SVG_Element*) converter->svg_parent;
        }
    }

    for (i=0; i<nb_attributes; i++) {
        GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i];
        if (!att->value || !strlen(att->value)) continue;

        if (!stricmp(att->name, "style")) {
            gf_svg_parse_style((GF_Node *)elt, att->value);
        } else if (!stricmp(att->name, "id") || !stricmp(att->name, "xml:id")) {
            gf_svg_parse_element_id((GF_Node *)elt, att->value, 0);
            id_string = att->value;
        } else if (anim && !stricmp(att->name, "to")) {
            anim->to = gf_strdup(att->value);
        } else if (anim && !stricmp(att->name, "from")) {
            anim->from = gf_strdup(att->value);
        } else if (anim && !stricmp(att->name, "by")) {
            anim->by = gf_strdup(att->value);
        } else if (anim && !stricmp(att->name, "values")) {
            anim->values = gf_strdup(att->value);
        } else if (anim && (tag == TAG_SVG_animateTransform) && !stricmp(att->name, "type")) {
            anim->type = gf_strdup(att->value);
        } else {
            GF_FieldInfo info;
            if (gf_node_get_field_by_name((GF_Node *)elt, att->name, &info)==GF_OK) {
                gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0);
            } else {
                fprintf(stdout, "Skipping attribute %s\n", att->name);
            }
        }
    }

    if (anim) {
        svg_parse_animation(converter->svg_sg, anim);
    }

    memset(&converter->all_atts, 0, sizeof(SVGAllAttributes));
    gf_svg_flatten_attributes(elt, &converter->all_atts);

    backup_props = gf_malloc(sizeof(SVGPropertiesPointers));
    memcpy(backup_props, &converter->svg_props, sizeof(SVGPropertiesPointers));
    gf_node_set_private((GF_Node *)elt, backup_props);

    gf_svg_apply_inheritance(&converter->all_atts, &converter->svg_props);

    fprintf(stdout, "START\t%s\t%s\t%s", converter->svg_parent ? gf_node_get_class_name(converter->svg_parent) : "none", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none", name);
    converter->svg_parent = (GF_Node *)elt;
    if (!gf_sg_get_root_node(converter->bifs_sg)) {
        if (tag == TAG_SVG_svg) {
            GF_Node *node, *child;

            converter->bifs_sg->usePixelMetrics = 1;
            if (converter->all_atts.width && converter->all_atts.width->type == SVG_NUMBER_VALUE) {
                converter->bifs_sg->width = FIX2INT(converter->all_atts.width->value);
            } else {
                converter->bifs_sg->width = 320;
            }
            if (converter->all_atts.height && converter->all_atts.height->type == SVG_NUMBER_VALUE) {
                converter->bifs_sg->height = FIX2INT(converter->all_atts.height->value);
            } else {
                converter->bifs_sg->height = 200;
            }

            node = gf_node_new(converter->bifs_sg, TAG_MPEG4_OrderedGroup);
            gf_node_register(node, NULL);
            gf_sg_set_root_node(converter->bifs_sg, node);

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_QuantizationParameter);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_QuantizationParameter *qp = (M_QuantizationParameter *)child;
                qp->useEfficientCoding = 1;
            }

            /* SVG to BIFS coordinate transformation */
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Viewport);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_Viewport *vp = (M_Viewport*)child;
                if (converter->all_atts.viewBox) {
                    vp->size.x = converter->all_atts.viewBox->width;
                    vp->size.y = converter->all_atts.viewBox->height;
                    vp->position.x = converter->all_atts.viewBox->x+converter->all_atts.viewBox->width/2;
                    vp->position.y = -(converter->all_atts.viewBox->y+converter->all_atts.viewBox->height/2);
                } else {
                    vp->size.x = INT2FIX(converter->bifs_sg->width);
                    vp->size.y = INT2FIX(converter->bifs_sg->height);
                    vp->position.x = INT2FIX(converter->bifs_sg->width)/2;
                    vp->position.y = -INT2FIX(converter->bifs_sg->height)/2;
                }
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Background2D);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_Background2D *b = (M_Background2D *)child;
                b->backColor.red = FIX_ONE;
                b->backColor.green = FIX_ONE;
                b->backColor.blue = FIX_ONE;
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            {
                M_Transform2D *tr = (M_Transform2D *)node;
                tr->scale.y = -FIX_ONE;
            }
            converter->bifs_parent = node;
        }
    } else {
        GF_Node *node, *child;

        node = converter->bifs_parent;

        switch(tag) {
        case TAG_SVG_g:
        {
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
            } else {
                M_Group *g = (M_Group*)gf_node_new(converter->bifs_sg, TAG_MPEG4_Group);
                gf_node_register((GF_Node *)g, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, (GF_Node *)g);
                node = (GF_Node *)g;
                converter->bifs_parent = node;
            }
        }
        break;
        case TAG_SVG_rect:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            if (converter->all_atts.x || converter->all_atts.y) {
                child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
                gf_node_register(child, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
                node = child;
                child = NULL;
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
                {
                    M_Transform2D *tr = (M_Transform2D *)node;
                    if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value + (converter->all_atts.width?converter->all_atts.width->value/2:0);
                    if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value + (converter->all_atts.height?converter->all_atts.height->value/2:0);
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_Rectangle);
                gf_node_register(shape->geometry, (GF_Node *)shape);
                {
                    M_Rectangle *rect = (M_Rectangle *)shape->geometry;
                    if (converter->all_atts.width) rect->size.x = converter->all_atts.width->value;
                    if (converter->all_atts.height) rect->size.y = converter->all_atts.height->value;
                }

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_path:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            if (converter->all_atts.x || converter->all_atts.y) {
                child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
                gf_node_register(child, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
                node = child;
                child = NULL;
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
                {
                    M_Transform2D *tr = (M_Transform2D *)node;
                    if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value;
                    if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value;
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_XCurve2D);
                gf_node_register(shape->geometry, (GF_Node *)shape);
                if (converter->all_atts.d) {
                    M_Coordinate2D *c2d;
                    M_XCurve2D *xc = (M_XCurve2D *)shape->geometry;
                    u32 i, j, c, k;

                    xc->point = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
                    c2d = (M_Coordinate2D *)xc->point;
                    gf_node_register(xc->point, (GF_Node *)xc);

                    gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, converter->all_atts.d->n_points);
                    gf_sg_vrml_mf_alloc(&xc->type, GF_SG_VRML_MFINT32, converter->all_atts.d->n_points);

                    c = 0;
                    k = 0;
                    j = 0;
                    c2d->point.vals[k] = converter->all_atts.d->points[0];
                    k++;
                    xc->type.vals[0] = 0;
                    for (i = 1; i < converter->all_atts.d->n_points; ) {
                        switch(converter->all_atts.d->tags[i]) {
                        case GF_PATH_CURVE_ON:
                            c2d->point.vals[k] = converter->all_atts.d->points[i];
                            k++;

                            if (i-1 == converter->all_atts.d->contours[c]) {
                                xc->type.vals[j] = 0;
                                c++;
                            } else {
                                xc->type.vals[j] = 1;
                            }
                            i++;
                            break;
                        case GF_PATH_CURVE_CUBIC:
                            c2d->point.vals[k] = converter->all_atts.d->points[i];
                            c2d->point.vals[k+1] = converter->all_atts.d->points[i+1];
                            c2d->point.vals[k+2] = converter->all_atts.d->points[i+2];
                            k+=3;

                            xc->type.vals[j] = 2;
                            if (converter->all_atts.d->tags[i+2]==GF_PATH_CLOSE)  {
                                j++;
                                xc->type.vals[j] = 6;
                            }
                            i+=3;
                            break;
                        case GF_PATH_CLOSE:
                            xc->type.vals[j] = 6;
                            i++;
                            break;
                        case GF_PATH_CURVE_CONIC:
                            c2d->point.vals[k] = converter->all_atts.d->points[i];
                            c2d->point.vals[k+1] = converter->all_atts.d->points[i+1];
                            k+=2;

                            xc->type.vals[j] = 7;
                            if (converter->all_atts.d->tags[i+1]==GF_PATH_CLOSE)  {
                                j++;
                                xc->type.vals[j] = 6;
                            }
                            i+=2;
                            break;
                        }
                        j++;
                    }
                    xc->type.count = j;
                    c2d->point.count = k;
                }

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_polyline:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_IndexedFaceSet2D);
                gf_node_register(shape->geometry, (GF_Node *)shape);
                if (converter->all_atts.points) {
                    M_Coordinate2D *c2d;
                    M_IndexedFaceSet2D *ifs = (M_IndexedFaceSet2D *)shape->geometry;
                    u32 i;

                    ifs->coord = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
                    c2d = (M_Coordinate2D *)ifs->coord;
                    gf_node_register(ifs->coord, (GF_Node *)ifs);

                    gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, gf_list_count(*converter->all_atts.points));
                    for (i = 0; i < gf_list_count(*converter->all_atts.points); i++) {
                        SVG_Point *p = (SVG_Point *)gf_list_get(*converter->all_atts.points, i);
                        c2d->point.vals[i].x = p->x;
                        c2d->point.vals[i].y = p->y;
                    }
                }

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_text:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_Transform2D *tr = (M_Transform2D *)child;
                if (converter->all_atts.text_x) tr->translation.x = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_x, 0))->value;
                if (converter->all_atts.text_y) tr->translation.y = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_y, 0))->value;
                tr->scale.y = -FIX_ONE;
            }
            node = child;
            child = NULL;
            if (!is_parent_set) {
                converter->bifs_parent = node;
                is_parent_set = 1;
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_FontStyle *fs;
                M_Text *text;
                M_Shape *shape = (M_Shape *)node;
                text = (M_Text *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Text);
                shape->geometry = (GF_Node *)text;
                converter->bifs_text_node = shape->geometry;
                gf_node_register(shape->geometry, (GF_Node *)shape);

                fs = (M_FontStyle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_XFontStyle);
                gf_node_register((GF_Node *)fs, (GF_Node*)text);
                text->fontStyle = (GF_Node *)fs;

                gf_sg_vrml_mf_alloc(&fs->family, GF_SG_VRML_MFSTRING, 1);
                fs->family.vals[0] = gf_strdup(converter->svg_props.font_family->value);
                fs->size = converter->svg_props.font_size->value;

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_ellipse:
        case TAG_SVG_circle:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            if (converter->all_atts.cx || converter->all_atts.cy) {
                child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
                gf_node_register(child, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
                {
                    M_Transform2D *tr = (M_Transform2D *)child;
                    if (converter->all_atts.cx) tr->translation.x = converter->all_atts.cx->value;
                    if (converter->all_atts.cy) tr->translation.y = converter->all_atts.cy->value;
                }
                node = child;
                child = NULL;
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                if (tag == TAG_SVG_ellipse) {
                    M_Ellipse *e = (M_Ellipse *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Ellipse);
                    shape->geometry = (GF_Node *)e;
                    e->radius.x = converter->all_atts.rx->value;
                    e->radius.y = converter->all_atts.ry->value;
                } else {
                    M_Circle *c = (M_Circle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Circle);
                    shape->geometry = (GF_Node *)c;
                    c->radius = converter->all_atts.r->value;
                }
                gf_node_register(shape->geometry, (GF_Node *)shape);

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;

        case TAG_SVG_defs:
        {
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Switch);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            {
                M_Switch *sw = (M_Switch *)node;
                sw->whichChoice = -1;
            }
            converter->bifs_parent = node;
        }
        break;
        case TAG_SVG_solidColor:
        {
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            converter->bifs_parent = node;
        }
        break;
        case TAG_SVG_animateTransform:
        {
            GF_Node *child_ts;
            if (!gf_node_get_id(node)) {
                gf_node_set_id(node, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
            }

            child_ts = gf_node_new(converter->bifs_sg, TAG_MPEG4_TimeSensor);
            if (!gf_node_get_id(child_ts)) {
                gf_node_set_id(child_ts, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
            }
            gf_node_register(child_ts, node);
            gf_node_list_add_child(&((GF_ParentNode *)node)->children, child_ts);
            {
                M_TimeSensor *ts = (M_TimeSensor *)child_ts;
                if (converter->all_atts.dur) {
                    ts->cycleInterval = converter->all_atts.dur->clock_value;
                }
                if (converter->all_atts.repeatCount && converter->all_atts.repeatCount->type == SMIL_REPEATCOUNT_INDEFINITE) {
                    ts->loop = 1;
                }
            }

            if (converter->all_atts.transform_type) {
                GF_FieldInfo fromField, toField;

                switch (*converter->all_atts.transform_type) {
                case SVG_TRANSFORM_ROTATE:
                    child = gf_node_new(converter->bifs_sg, TAG_MPEG4_PositionInterpolator2D);
                    if (!gf_node_get_id(child)) {
                        gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
                    }
                    gf_node_register(child, node);
                    gf_node_list_add_child(&((GF_ParentNode *)node)->children, child);

                    gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField);
                    gf_node_get_field_by_name(child, "set_fraction", &toField);
                    gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex);

                    gf_node_get_field_by_name(child, "value_changed", &fromField);
                    gf_node_get_field_by_name(node, "rotationAngle", &toField);
                    gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex);
                    {
                        M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child;
                        if (converter->all_atts.keyTimes) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(*converter->all_atts.keyTimes);
                            for (i = 0; i < count; i++) {
                                Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i);
                                gf_sg_vrml_mf_append(&pi2d->key, GF_SG_VRML_MFFLOAT, &g);
                                *g = *f;
                            }
                        }
                        if (converter->all_atts.values) {
                            SFVec2f *g;
                            u32 count, i;
                            count = gf_list_count(converter->all_atts.values->values);
                            for (i = 0; i < count; i++) {
                                SVG_Point_Angle *p;
                                p = gf_list_get(converter->all_atts.values->values, i);
                                gf_sg_vrml_mf_append(&pi2d->keyValue, GF_SG_VRML_MFVEC2F, &g);
                                g->x = p->x;
                                g->y = p->y;
                            }
                        }
                    }


                    child = gf_node_new(converter->bifs_sg, TAG_MPEG4_ScalarInterpolator);
                    if (!gf_node_get_id(child)) {
                        gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
                    }
                    gf_node_register(child, node);
                    gf_node_list_add_child(&((GF_ParentNode *)node)->children, child);

                    gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField);
                    gf_node_get_field_by_name(child, "set_fraction", &toField);
                    gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex);

                    gf_node_get_field_by_name(child, "value_changed", &fromField);
                    gf_node_get_field_by_name(node, "center", &toField);
                    gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex);

                    {
                        M_ScalarInterpolator *si = (M_ScalarInterpolator *)child;
                        if (converter->all_atts.keyTimes) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(*converter->all_atts.keyTimes);
                            for (i = 0; i < count; i++) {
                                Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i);
                                gf_sg_vrml_mf_append(&si->key, GF_SG_VRML_MFFLOAT, &g);
                                *g = *f;
                            }
                        }
                        if (converter->all_atts.values) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(converter->all_atts.values->values);
                            for (i = 0; i < count; i++) {
                                SVG_Point_Angle *p;
                                p = gf_list_get(converter->all_atts.values->values, i);
                                gf_sg_vrml_mf_append(&si->keyValue, GF_SG_VRML_MFFLOAT, &g);
                                *g = p->angle;
                            }
                        }
                    }

                    break;

                case SVG_TRANSFORM_SCALE:
                case SVG_TRANSFORM_TRANSLATE:
                    child = gf_node_new(converter->bifs_sg, TAG_MPEG4_PositionInterpolator2D);
                    if (!gf_node_get_id(child)) {
                        gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
                    }
                    gf_node_register(child, node);
                    gf_node_list_add_child(&((GF_ParentNode *)node)->children, child);

                    gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField);
                    gf_node_get_field_by_name(child, "set_fraction", &toField);
                    gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex);

                    gf_node_get_field_by_name(child, "value_changed", &fromField);
                    if (*converter->all_atts.transform_type == SVG_TRANSFORM_SCALE)
                        gf_node_get_field_by_name(node, "scale", &toField);
                    else
                        gf_node_get_field_by_name(node, "translation", &toField);

                    gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex);
                    {
                        M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child;
                        if (converter->all_atts.keyTimes) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(*converter->all_atts.keyTimes);
                            for (i = 0; i < count; i++) {
                                Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i);
                                gf_sg_vrml_mf_append(&pi2d->key, GF_SG_VRML_MFFLOAT, &g);
                                *g = *f;
                            }
                        }
                        if (converter->all_atts.values) {
                            SFVec2f *g;
                            u32 count, i;
                            count = gf_list_count(converter->all_atts.values->values);
                            for (i = 0; i < count; i++) {
                                SVG_Point *p;
                                p = gf_list_get(converter->all_atts.values->values, i);
                                gf_sg_vrml_mf_append(&pi2d->keyValue, GF_SG_VRML_MFVEC2F, &g);
                                g->x = p->x;
                                g->y = p->y;
                            }
                        }
                    }
                    break;
                default:
                    fprintf(stdout, "Warning: transformation type not supported \n");
                }
            }
            //converter->bifs_parent = node;
        }
        break;
        default:
        {
            fprintf(stdout, "Warning: element %s not supported \n", gf_node_get_class_name((GF_Node *)elt));
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
            gf_node_register(child, node);
            //gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            converter->bifs_parent = node;
        }
        break;
        }

        if (id_string)
            gf_node_set_id(converter->bifs_parent, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);//gf_node_get_name((GF_Node *)elt));

    }
    fprintf(stdout, "\t%s\n", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none");
}
Ejemplo n.º 17
0
void gf_sr_simulation_tick(GF_Renderer *sr)
{	
	u32 in_time, end_time, i, count;

	/*lock renderer for the whole render cycle*/
	gf_sr_lock(sr, 1);

	/*first thing to do, let the video output handle user event if it is not threaded*/
	sr->video_out->ProcessEvent(sr->video_out, NULL);

	if (sr->freeze_display) {
		gf_sr_lock(sr, 0);
		gf_sleep(sr->frame_duration);
		return;
	}

	gf_sr_reconfig_task(sr);

	/* if there is no scene, we draw a black screen to flush the screen */
	if (!sr->scene) {
		sr->visual_renderer->DrawScene(sr->visual_renderer);
		gf_sr_lock(sr, 0);
		gf_sleep(sr->frame_duration);
		return;
	}

//	GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[General] Time %f - Composing new frame #%d\n", gf_node_get_scene_time(gf_sg_get_root_node(sr->scene)), sr->frame_number));

	in_time = gf_sys_clock();
	if (sr->reset_graphics) sr->draw_next_frame = 1;

#ifdef GF_SR_EVENT_QUEUE
	/*process pending user events*/
	gf_mx_p(sr->ev_mx);
	while (gf_list_count(sr->events)) {
		GF_Event *ev = (GF_Event*)gf_list_get(sr->events, 0);
		gf_list_rem(sr->events, 0);
		if (!sr->visual_renderer->ExecuteEvent(sr->visual_renderer, ev)) {
			SR_ForwardUserEvent(sr, ev);
		}
		free(ev);
	}
	gf_mx_v(sr->ev_mx);
#endif


#if 0
	if (sr->frame_number == 0 && sr->user->EventProc) {
		GF_Event evt;
		evt.type = GF_EVENT_UPDATE_RTI;
		evt.caption.caption = "UPDATE - Before first call to draw scene";
		sr->user->EventProc(sr->user->opaque, &evt);
	}
#endif

	/*execute all routes before updating textures, otherwise nodes inside composite texture may never see their
	dirty flag set*/
	gf_sg_activate_routes(sr->scene);

#ifndef GPAC_DISABLE_SVG
#if SVG_FIXME
	{ /* Experimental (Not SVG compliant system events (i.e. battery, cpu ...) triggered to the root node)*/
		GF_Node *root = gf_sg_get_root_node(sr->scene);
		GF_DOM_Event evt;
		if (gf_dom_listener_count(root)) {
			u32 i, count;
			count = gf_dom_listener_count(root);
			for (i=0;i<count; i++) {
				SVG_SA_listenerElement *l = gf_dom_listener_get(root, i);
				if (l->event.type == GF_EVENT_CPU) {
					GF_SystemRTInfo sys_rti;
					if (gf_sys_get_rti(500, &sys_rti, GF_RTI_ALL_PROCESSES_TIMES)) {
						evt.type = GF_EVENT_CPU;
						evt.cpu_percentage = sys_rti.total_cpu_usage;
						//printf("%d\n",sys_rti.total_cpu_usage);
						gf_dom_event_fire(root, NULL, &evt);
					} 
				} else if (l->event.type == GF_EVENT_BATTERY) { //&& l->observer.target == (SVG_SA_Element *)node) {
					evt.type = GF_EVENT_BATTERY;
					gf_sys_get_battery_state(&evt.onBattery, &evt.batteryState, &evt.batteryLevel);
					gf_dom_event_fire(root, NULL, &evt);
				}
			}
		}
	}
#endif

	if (gf_smil_notify_timed_elements(sr->scene)) {
		sr->draw_next_frame = 1;
	}
#if 0
	for (i=0; i<gf_list_count(sr->secondary_scenes); i++) {
		if (gf_smil_notify_timed_elements(gf_list_get(sr->secondary_scenes, i))) {
			sr->draw_next_frame = 1;
		}
	}
#endif

#endif

	/*update all textures*/
	count = gf_list_count(sr->textures);
	for (i=0; i<count; i++) {
		GF_TextureHandler *st = (GF_TextureHandler *)gf_list_get(sr->textures, i);
		/*signal graphics reset before updating*/
		if (sr->reset_graphics && st->hwtx) sr->visual_renderer->TextureHWReset(st);
		st->update_texture_fcnt(st);
	}

	/*if invalidated, draw*/
	if (sr->draw_next_frame) {
		/*video flush only*/
		if (sr->draw_next_frame==2) {
			GF_Window rc;
			rc.x = rc.y = 0; 
			rc.w = sr->width;	
			rc.h = sr->height;		
			sr->draw_next_frame = 0;
			sr->video_out->Flush(sr->video_out, &rc);
		} else {
			sr->draw_next_frame = 0;
			GF_LOG(GF_LOG_DEBUG, GF_LOG_RENDER, ("[Render] Redrawing scene\n"));
			sr->visual_renderer->DrawScene(sr->visual_renderer);
#if 0
			if (sr->frame_number == 0 && sr->user->EventProc) {
				GF_Event evt;
				evt.type = GF_EVENT_UPDATE_RTI;
				evt.caption.caption = "Before first call to draw scene";
				sr->user->EventProc(sr->user->opaque, &evt);
			}
#endif
		}
		sr->reset_graphics = 0;

		GF_LOG(GF_LOG_INFO, GF_LOG_RENDER, ("[Render] Scene drawn in %d ms\n", gf_sys_clock() - in_time));

		if (sr->stress_mode) {
			sr->draw_next_frame = 1;
			sr->reset_graphics = 1;
		}
	}

	/*release all textures - we must release them to handle a same OD being used by several textures*/
	count = gf_list_count(sr->textures);
	for (i=0; i<count; i++) {
		GF_TextureHandler *st = (GF_TextureHandler *)gf_list_get(sr->textures, i);
		gf_sr_texture_release_stream(st);
	}

	/*update all timed nodes */
	for (i=0; i<gf_list_count(sr->time_nodes); i++) {
		GF_TimeNode *tn = (GF_TimeNode *)gf_list_get(sr->time_nodes, i);
		if (!tn->needs_unregister) tn->UpdateTimeNode(tn);
		if (tn->needs_unregister) {
			tn->is_registered = 0;
			tn->needs_unregister = 0;
			gf_list_rem(sr->time_nodes, i);
			i--;
			continue;
		}
	}

	end_time = gf_sys_clock() - in_time;

	gf_sr_lock(sr, 0);

	sr->current_frame = (sr->current_frame+1) % GF_SR_FPS_COMPUTE_SIZE;
	sr->frame_time[sr->current_frame] = end_time;

	sr->frame_number++;
#if 0
	if (sr->user->EventProc) {
		char legend[100];
		GF_Event evt;
		evt.type = GF_EVENT_UPDATE_RTI;
		sprintf(legend, "After rendering of frame %d", sr->frame_number);
		evt.caption.caption = legend;
		sr->user->EventProc(sr->user->opaque, &evt);
	}
#endif

	/*step mode on, pause and return*/
	if (sr->step_mode) {
		sr->step_mode = 0;
		if (sr->term) gf_term_set_option(sr->term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED);
		return;
	}
	/*not threaded, let the owner decide*/
	if ((sr->user->init_flags & GF_TERM_NO_VISUAL_THREAD) || !sr->frame_duration) return;

	/*compute sleep time till next frame, otherwise we'll kill the CPU*/
	i=1;
	while (i * sr->frame_duration < end_time) i++;
	in_time = i * sr->frame_duration - end_time;
	gf_sleep(in_time);
}