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; }
static void animationstream_check_url(AnimationStreamStack *stack, M_AnimationStream *as) { if (!stack->stream) { gf_sg_vrml_mf_reset(&stack->current_url, GF_SG_VRML_MFURL); gf_sg_vrml_field_copy(&stack->current_url, &as->url, GF_SG_VRML_MFURL); stack->stream = gf_mo_register((GF_Node *)as, &as->url, 0, 0); gf_sc_invalidate(stack->compositor, NULL); /*if changed while playing trigger*/ if (as->isActive) { gf_mo_play(stack->stream, 0, -1, 0); gf_mo_set_speed(stack->stream, as->speed); } return; } /*check change*/ if (gf_mo_url_changed(stack->stream, &as->url)) { gf_sg_vrml_mf_reset(&stack->current_url, GF_SG_VRML_MFURL); gf_sg_vrml_field_copy(&stack->current_url, &as->url, GF_SG_VRML_MFURL); /*if changed while playing stop old source*/ if (as->isActive) { gf_mo_set_flag(stack->stream, GF_MO_DISPLAY_REMOVE, 1); gf_mo_stop(stack->stream); } gf_mo_unregister((GF_Node *)as, stack->stream); stack->stream = gf_mo_register((GF_Node *)as, &as->url, 0, 0); /*if changed while playing play new source*/ if (as->isActive) { gf_mo_play(stack->stream, 0, -1, 0); gf_mo_set_speed(stack->stream, as->speed); } gf_sc_invalidate(stack->compositor, NULL); } }
/* input sensor node handling */ static void IS_Unregister(GF_Node *node, ISStack *st) { u32 i; GF_ObjectManager *odm; ISPriv *is_dec; gf_mo_unregister(node, st->mo); odm = st->mo->odm; if (!odm) return; assert(odm->codec && (odm->codec->type == GF_STREAM_INTERACT)); /*get IS dec*/ is_dec = (ISPriv*)odm->codec->decio->privateStack; for (i=0; i<gf_list_count(is_dec->is_nodes); i++) { ISStack *tmp = (ISStack *)gf_list_get(is_dec->is_nodes, i); if (tmp == st) { gf_list_rem(is_dec->is_nodes, i); i--; } } /*stop stream*/ if (st->mo->num_open) gf_mo_stop(st->mo); st->mo = NULL; if (st->registered) { st->registered = 0; if (is_dec->io_dev && is_dec->io_dev->Stop) is_dec->io_dev->Stop(is_dec->io_dev); } }
GF_EXPORT void gf_sc_texture_stop(GF_TextureHandler *txh) { if (!txh->is_open) return; /*release texture WITHOUT droping frame*/ if (txh->needs_release) { gf_mo_release_data(txh->stream, 0xFFFFFFFF, -1); txh->needs_release = 0; } gf_sc_invalidate(txh->compositor, NULL); if (gf_mo_stop(txh->stream)) { txh->data = NULL; } txh->is_open = 0; /*and deassociate object*/ gf_mo_unregister(txh->owner, txh->stream); txh->stream = NULL; }
GF_EXPORT void gf_sc_audio_stop(GF_AudioInput *ai) { if (!ai->is_open) return; /*we must make sure audio mixer is not using the stream otherwise we may leave it dirty (with unrelease frame)*/ gf_mixer_lock(ai->compositor->audio_renderer->mixer, 1); assert(!ai->need_release); gf_mo_stop(ai->stream); ai->is_open = 0; gf_mo_unregister(ai->owner, ai->stream); ai->stream = NULL; if (ai->filter) gf_af_del(ai->filter); ai->filter = NULL; gf_mixer_lock(ai->compositor->audio_renderer->mixer, 0); }
/*only URL can be changed, so reset and get new URL*/ void MS_Modified(GF_Node *node) { MediaSensorStack *st = (MediaSensorStack *)gf_node_get_private(node); if (!st) return; while (gf_list_count(st->seg)) gf_list_rem(st->seg, 0); if (st->stream) { /*unlink from OD*/ if (st->stream->odm && st->stream->odm->ms_stack) gf_list_del_item(st->stream->odm->ms_stack, st); gf_mo_unregister(node, st->stream); if (st->sensor->isActive) { st->sensor->isActive = 0; gf_node_event_out((GF_Node *) st->sensor, 4/*"isActive"*/); } } st->stream = NULL; st->is_init = 0; gf_term_invalidate_compositor(st->parent->root_od->term); }