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); }
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); }
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; }
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(); }
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); }
// 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); }
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); }
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); }
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(); }
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)); } }
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; }
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; }
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; }
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; }
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; }
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"); }
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); }