GF_EXPORT GF_Err gf_sg_vrml_mf_reset(void *mf, u32 FieldType) { GenMFField *mffield = (GenMFField *)mf; if (!mffield->array) return GF_OK; //field we can't copy if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; if (!gf_sg_vrml_get_sf_size(FieldType)) return GF_BAD_PARAM; switch (FieldType) { case GF_SG_VRML_MFSTRING: gf_sg_mfstring_del( * ((MFString *) mf)); break; case GF_SG_VRML_MFURL: gf_sg_mfurl_del( * ((MFURL *) mf)); break; case GF_SG_VRML_MFSCRIPT: gf_sg_mfscript_del( * ((MFScript *) mf)); break; default: if (mffield->array) gf_free(mffield->array); break; } mffield->array = NULL; mffield->count = 0; return GF_OK; }
static void svg_traverse_updates(GF_Node *node, void *rs, Bool is_destroy) { /*video stack is just an extension of image stack, type-casting is OK*/ SVG_updates_stack *stack = (SVG_updates_stack*)gf_node_get_private(node); GF_TraverseState *tr_state = (GF_TraverseState *)rs; SVGAllAttributes all_atts; SVGPropertiesPointers backup_props; u32 backup_flags, dirty_flags; if (is_destroy) { if (stack->resource) { if (stack->is_open) { gf_mo_set_flag(stack->resource, GF_MO_DISPLAY_REMOVE, GF_TRUE); gf_mo_stop(stack->resource); } gf_mo_unregister(node, stack->resource); } gf_free(stack); return; } if (tr_state->traversing_mode!=TRAVERSE_SORT) return; /*flatten attributes and apply animations + inheritance*/ gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); if (!compositor_svg_traverse_base(node, &all_atts, (GF_TraverseState *)rs, &backup_props, &backup_flags)) return; dirty_flags = gf_node_dirty_get(node); if (dirty_flags) { stack->clipBegin = all_atts.clipBegin ? *all_atts.clipBegin : 0; stack->clipEnd = all_atts.clipEnd ? *all_atts.clipEnd : -1; if (dirty_flags & GF_SG_SVG_XLINK_HREF_DIRTY) { GF_MediaObject *new_res; MFURL url; Bool lock_timeline=GF_FALSE; url.vals = NULL; url.count = 0; if (all_atts.syncBehavior) lock_timeline = (*all_atts.syncBehavior == SMIL_SYNCBEHAVIOR_LOCKED) ? GF_TRUE : GF_FALSE; gf_term_get_mfurl_from_xlink(node, &url); new_res = gf_mo_register(node, &url, lock_timeline, GF_FALSE); gf_sg_mfurl_del(url); if (stack->resource!=new_res) { if (stack->resource) { gf_mo_stop(stack->resource); gf_mo_unregister(node, stack->resource); } stack->resource = new_res; if (stack->resource && stack->is_open) gf_mo_play(stack->resource, stack->clipBegin, stack->clipEnd, GF_FALSE); } } gf_node_dirty_clear(node, 0); } memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers)); tr_state->svg_flags = backup_flags; }
void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType) { GF_Node *node; switch (FieldType) { case GF_SG_VRML_SFBOOL: case GF_SG_VRML_SFFLOAT: case GF_SG_VRML_SFDOUBLE: case GF_SG_VRML_SFTIME: case GF_SG_VRML_SFINT32: case GF_SG_VRML_SFVEC3F: case GF_SG_VRML_SFVEC3D: case GF_SG_VRML_SFVEC2F: case GF_SG_VRML_SFVEC2D: case GF_SG_VRML_SFCOLOR: case GF_SG_VRML_SFCOLORRGBA: case GF_SG_VRML_SFROTATION: case GF_SG_VRML_SFATTRREF: break; case GF_SG_VRML_SFSTRING: if ( ((SFString *)field)->buffer) gf_free(((SFString *)field)->buffer); break; case GF_SG_VRML_SFIMAGE: gf_sg_sfimage_del(* ((SFImage *)field)); break; case GF_SG_VRML_SFNODE: node = *(GF_Node **) field; if (node) gf_node_del(node); return; case GF_SG_VRML_SFCOMMANDBUFFER: gf_sg_sfcommand_del(*(SFCommandBuffer *)field); break; case GF_SG_VRML_MFBOOL: gf_sg_mfbool_del( * ((MFBool *) field)); break; case GF_SG_VRML_MFFLOAT: gf_sg_mffloat_del( * ((MFFloat *) field)); break; case GF_SG_VRML_MFDOUBLE: gf_sg_mfdouble_del( * ((MFDouble *) field)); break; case GF_SG_VRML_MFTIME: gf_sg_mftime_del( * ((MFTime *)field)); break; case GF_SG_VRML_MFINT32: gf_sg_mfint32_del( * ((MFInt32 *)field)); break; case GF_SG_VRML_MFSTRING: gf_sg_mfstring_del( *((MFString *)field)); break; case GF_SG_VRML_MFVEC3F: gf_sg_mfvec3f_del( * ((MFVec3f *)field)); break; case GF_SG_VRML_MFVEC2F: gf_sg_mfvec2f_del( * ((MFVec2f *)field)); break; case GF_SG_VRML_MFVEC3D: gf_sg_mfvec3d_del( * ((MFVec3d *)field)); break; case GF_SG_VRML_MFVEC2D: gf_sg_mfvec2d_del( * ((MFVec2d *)field)); break; case GF_SG_VRML_MFCOLOR: gf_sg_mfcolor_del( * ((MFColor *)field)); break; case GF_SG_VRML_MFCOLORRGBA: gf_sg_mfcolor_rgba_del( * ((MFColorRGBA *)field)); break; case GF_SG_VRML_MFROTATION: case GF_SG_VRML_MFVEC4F: gf_sg_mfrotation_del( * ((MFRotation *)field)); break; case GF_SG_VRML_SFURL: gf_sg_sfurl_del( * ((SFURL *) field)); break; case GF_SG_VRML_MFURL: gf_sg_mfurl_del( * ((MFURL *) field)); break; case GF_SG_VRML_MFATTRREF: gf_sg_mfattrref_del( * ((MFAttrRef *) field)); break; //used only in proto since this field is created by default for regular nodes case GF_SG_VRML_MFNODE: assert(0); return; case GF_SG_VRML_MFSCRIPT: gf_sg_mfscript_del( * ((MFScript *) field)); break; default: assert(0); return; } //free pointer gf_free(field); }
static void svg_traverse_audio_ex(GF_Node *node, void *rs, Bool is_destroy, SVGPropertiesPointers *props) { SVGAllAttributes all_atts; SVGPropertiesPointers backup_props; u32 backup_flags, restore; GF_TraverseState *tr_state = (GF_TraverseState*)rs; SVG_audio_stack *stack = (SVG_audio_stack *)gf_node_get_private(node); if (is_destroy) { gf_sc_audio_predestroy(&stack->input); gf_sg_mfurl_del(stack->aurl); gf_free(stack); return; } if (stack->is_active) { gf_sc_audio_register(&stack->input, (GF_TraverseState*)rs); } restore = 0; if (!props) { restore = 1; gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); if (!compositor_svg_traverse_base(node, &all_atts, (GF_TraverseState *)rs, &backup_props, &backup_flags)) return; props = tr_state->svg_props; } if (gf_node_dirty_get(node) & GF_SG_SVG_XLINK_HREF_DIRTY) { SVGAllAttributes atts; Bool lock_timeline = GF_FALSE; if (stack->is_active) gf_sc_audio_stop(&stack->input); stack->is_error = GF_FALSE; gf_node_dirty_clear(node, GF_SG_SVG_XLINK_HREF_DIRTY); gf_term_get_mfurl_from_xlink(node, &(stack->aurl)); gf_svg_flatten_attributes((SVG_Element*) node, &atts); if (atts.syncBehavior) lock_timeline = (*atts.syncBehavior == SMIL_SYNCBEHAVIOR_LOCKED) ? GF_TRUE : GF_FALSE; if (stack->aurl.count && (gf_sc_audio_open(&stack->input, &stack->aurl, atts.clipBegin ? (*atts.clipBegin) : 0.0, atts.clipEnd ? (*atts.clipEnd) : -1.0, lock_timeline) == GF_OK) ) { gf_mo_set_speed(stack->input.stream, FIX_ONE); stack->is_active = GF_TRUE; } else if (stack->is_active) { gf_sc_audio_unregister(&stack->input); stack->is_active = GF_FALSE; } } /*store mute flag*/ stack->input.is_muted = GF_FALSE; if (tr_state->switched_off || compositor_svg_is_display_off(props) || (*(props->visibility) == SVG_VISIBILITY_HIDDEN) ) { stack->input.is_muted = GF_TRUE; } stack->input.intensity = tr_state->svg_props->computed_audio_level; if (restore) { memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers)); tr_state->svg_flags = backup_flags; } }
static void svg_traverse_bitmap(GF_Node *node, void *rs, Bool is_destroy) { Fixed cx, cy, angle; /*video stack is just an extension of image stack, type-casting is OK*/ SVG_video_stack *stack = (SVG_video_stack*)gf_node_get_private(node); GF_TraverseState *tr_state = (GF_TraverseState *)rs; SVGPropertiesPointers backup_props; u32 backup_flags; GF_Matrix2D backup_matrix; GF_Matrix mx_3d; DrawableContext *ctx; SVGAllAttributes all_atts; if (is_destroy) { gf_sc_texture_destroy(&stack->txh); gf_sg_mfurl_del(stack->txurl); drawable_del(stack->graph); if (stack->audio) { gf_node_unregister(stack->audio, NULL); } gf_free(stack); return; } /*TRAVERSE_DRAW is NEVER called in 3D mode*/ if (tr_state->traversing_mode==TRAVERSE_DRAW_2D) { SVG_Draw_bitmap(tr_state); return; } else if (tr_state->traversing_mode==TRAVERSE_PICK) { svg_drawable_pick(node, stack->graph, tr_state); return; } /*flatten attributes and apply animations + inheritance*/ gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); if (!compositor_svg_traverse_base(node, &all_atts, (GF_TraverseState *)rs, &backup_props, &backup_flags)) return; if (gf_node_dirty_get(node) & GF_SG_SVG_XLINK_HREF_DIRTY) { gf_term_get_mfurl_from_xlink(node, &stack->txurl); stack->txh.width = stack->txh.height = 0; /*remove associated audio if any*/ if (stack->audio) { svg_audio_smil_evaluate_ex(NULL, 0, SMIL_TIMING_EVAL_REMOVE, stack->audio, stack->txh.owner); gf_node_unregister(stack->audio, NULL); stack->audio = NULL; } stack->audio_dirty = GF_TRUE; if (stack->txurl.count) svg_play_texture(stack, &all_atts); gf_node_dirty_clear(node, GF_SG_SVG_XLINK_HREF_DIRTY); } if (gf_node_dirty_get(node)) { /*do not clear dirty state until the image is loaded*/ if (stack->txh.width) { gf_node_dirty_clear(node, 0); SVG_Build_Bitmap_Graph((SVG_video_stack*)gf_node_get_private(node), tr_state); } } if (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS) { if (!compositor_svg_is_display_off(tr_state->svg_props)) { gf_path_get_bounds(stack->graph->path, &tr_state->bounds); compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &mx_3d); if (svg_video_get_transform_behavior(tr_state, &all_atts, &cx, &cy, &angle)) { GF_Matrix2D mx; tr_state->bounds.width = INT2FIX(stack->txh.width); tr_state->bounds.height = INT2FIX(stack->txh.height); tr_state->bounds.x = cx - tr_state->bounds.width/2; tr_state->bounds.y = cy + tr_state->bounds.height/2; gf_mx2d_init(mx); gf_mx2d_add_rotation(&mx, 0, 0, angle); gf_mx2d_apply_rect(&mx, &tr_state->bounds); } else { gf_mx2d_apply_rect(&tr_state->transform, &tr_state->bounds); } compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d); } } else if (tr_state->traversing_mode == TRAVERSE_SORT) { if (!compositor_svg_is_display_off(tr_state->svg_props) && ( *(tr_state->svg_props->visibility) != SVG_VISIBILITY_HIDDEN) ) { GF_Matrix mx_bck; Bool restore_mx = GF_FALSE; compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &mx_3d); ctx = drawable_init_context_svg(stack->graph, tr_state); if (!ctx || !ctx->aspect.fill_texture ) return; if (svg_video_get_transform_behavior(tr_state, &all_atts, &cx, &cy, &angle)) { drawable_reset_path(stack->graph); gf_path_add_rect_center(stack->graph->path, cx, cy, INT2FIX(stack->txh.width), INT2FIX(stack->txh.height)); gf_mx2d_copy(mx_bck, tr_state->transform); restore_mx = GF_TRUE; gf_mx2d_init(tr_state->transform); gf_mx2d_add_rotation(&tr_state->transform, cx, cy, angle); } /*even if set this is not true*/ ctx->aspect.pen_props.width = 0; ctx->flags |= CTX_NO_ANTIALIAS; /*if rotation, transparent*/ ctx->flags &= ~CTX_IS_TRANSPARENT; if (ctx->transform.m[1] || ctx->transform.m[3]) { ctx->flags |= CTX_IS_TRANSPARENT; ctx->flags &= ~CTX_NO_ANTIALIAS; } else if (ctx->aspect.fill_texture->transparent) ctx->flags |= CTX_IS_TRANSPARENT; else if (tr_state->svg_props->opacity && (tr_state->svg_props->opacity->type==SVG_NUMBER_VALUE) && (tr_state->svg_props->opacity->value!=FIX_ONE)) { ctx->flags = CTX_IS_TRANSPARENT; ctx->aspect.fill_color = GF_COL_ARGB(FIX2INT(0xFF * tr_state->svg_props->opacity->value), 0, 0, 0); } #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d) { if (!stack->graph->mesh) { stack->graph->mesh = new_mesh(); mesh_from_path(stack->graph->mesh, stack->graph->path); } compositor_3d_draw_bitmap(stack->graph, &ctx->aspect, tr_state, 0, 0, FIX_ONE, FIX_ONE); ctx->drawable = NULL; } else #endif { drawable_finalize_sort(ctx, tr_state, NULL); } if (restore_mx) gf_mx2d_copy(tr_state->transform, mx_bck); compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d); } } if (stack->audio) svg_traverse_audio_ex(stack->audio, rs, GF_FALSE, tr_state->svg_props); memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers)); tr_state->svg_flags = backup_flags; }