static void audiosource_traverse(GF_Node *node, void *rs, Bool is_destroy) { GF_TraverseState*tr_state = (GF_TraverseState*)rs; M_AudioSource *as = (M_AudioSource *)node; AudioSourceStack *st = (AudioSourceStack *)gf_node_get_private(node); if (is_destroy) { gf_sc_audio_predestroy(&st->input); if (st->time_handle.is_registered) { gf_sc_unregister_time_node(st->input.compositor, &st->time_handle); } gf_free(st); return; } /*check end of stream*/ if (st->input.stream && st->input.stream_finished) { if (gf_mo_get_loop(st->input.stream, 0)) { gf_sc_audio_restart(&st->input); } else if (st->is_active && gf_mo_should_deactivate(st->input.stream)) { /*deactivate*/ audiosource_deactivate(st, as); } } if (st->is_active) { gf_sc_audio_register(&st->input, (GF_TraverseState*)rs); } /*store mute flag*/ st->input.is_muted = tr_state->switched_off; }
static void movietexture_destroy(GF_Node *node, void *rs, Bool is_destroy) { if (is_destroy) { MovieTextureStack *st = (MovieTextureStack *) gf_node_get_private(node); gf_sc_texture_destroy(&st->txh); if (st->time_handle.is_registered) gf_sc_unregister_time_node(st->txh.compositor, &st->time_handle); gf_free(st); } }
static void timesensor_destroy(GF_Node *ts, void *rs, Bool is_destroy) { if (is_destroy) { TimeSensorStack *st = (TimeSensorStack *)gf_node_get_private(ts); if (st->time_handle.is_registered) { gf_sc_unregister_time_node(st->compositor, &st->time_handle); } gf_free(st); } }
static void animationstream_destroy(GF_Node *node, void *rs, Bool is_destroy) { if (is_destroy) { M_AnimationStream *as = (M_AnimationStream *)node; AnimationStreamStack *st = (AnimationStreamStack *) gf_node_get_private(node); if (st->time_handle.is_registered) { gf_sc_unregister_time_node(st->compositor, &st->time_handle); } if (st->stream && as->isActive) { gf_mo_set_flag(st->stream, GF_MO_DISPLAY_REMOVE, 1); gf_mo_stop(st->stream); } gf_sg_vrml_mf_reset(&st->current_url, GF_SG_VRML_MFURL); gf_free(st); } }
static void audioclip_traverse(GF_Node *node, void *rs, Bool is_destroy) { GF_TraverseState *tr_state = (GF_TraverseState *)rs; M_AudioClip *ac = (M_AudioClip *)node; AudioClipStack *st = (AudioClipStack *)gf_node_get_private(node); if (is_destroy) { gf_sc_audio_predestroy(&st->input); if (st->time_handle.is_registered) { gf_sc_unregister_time_node(st->input.compositor, &st->time_handle); } gf_free(st); return; } if (st->failure) return; /*check end of stream*/ if (st->input.stream && st->input.stream_finished) { if (gf_mo_get_loop(st->input.stream, ac->loop)) { gf_sc_audio_restart(&st->input); } else if (ac->isActive && gf_mo_should_deactivate(st->input.stream)) { /*deactivate*/ audioclip_deactivate(st, ac); } } if (ac->isActive) { gf_sc_audio_register(&st->input, (GF_TraverseState*)rs); } if (st->set_duration && st->input.stream) { ac->duration_changed = gf_mo_get_duration(st->input.stream); gf_node_event_out_str(node, "duration_changed"); st->set_duration = 0; } /*store mute flag*/ st->input.is_muted = tr_state->switched_off; }
/*we have no choice but always browsing the children, since a src can be replaced by a new one without the parent being modified. We just collect the src and check against the current mixer inputs to reset the mixer or not - the spec is not clear about that btw, shall rebuffering happen if a source is modified or not ...*/ static void audiobuffer_traverse(GF_Node *node, void *rs, Bool is_destroy) { u32 j; Bool update_mixer; GF_ChildNodeItem *l; GF_AudioGroup *parent; AudioBufferStack *st = (AudioBufferStack *)gf_node_get_private(node); M_AudioBuffer *ab = (M_AudioBuffer *)node; GF_TraverseState*tr_state = (GF_TraverseState*) rs; if (is_destroy) { gf_sc_audio_unregister(&st->output); if (st->time_handle.is_registered) gf_sc_unregister_time_node(st->output.compositor, &st->time_handle); gf_mixer_del(st->am); if (st->buffer) gf_free(st->buffer); gf_list_del(st->new_inputs); gf_free(st); return; } parent = tr_state->audio_parent; tr_state->audio_parent = (GF_AudioGroup *) st; l = ab->children; while (l) { gf_node_traverse(l->node, tr_state); l = l->next; } gf_mixer_lock(st->am, 1); /*if no new inputs don't change mixer config*/ update_mixer = gf_list_count(st->new_inputs) ? 1 : 0; if (gf_mixer_get_src_count(st->am) == gf_list_count(st->new_inputs)) { u32 count = gf_list_count(st->new_inputs); update_mixer = 0; for (j=0; j<count; j++) { GF_AudioInput *cur = (GF_AudioInput *)gf_list_get(st->new_inputs, j); if (!gf_mixer_is_src_present(st->am, &cur->input_ifce)) { update_mixer = 1; break; } } } if (update_mixer) { gf_mixer_remove_all(st->am); gf_mixer_force_chanel_out(st->am, ab->numChan); } while (gf_list_count(st->new_inputs)) { GF_AudioInput *src = (GF_AudioInput *)gf_list_get(st->new_inputs, 0); gf_list_rem(st->new_inputs, 0); if (update_mixer) gf_mixer_add_input(st->am, &src->input_ifce); } gf_mixer_lock(st->am, 0); tr_state->audio_parent = parent; /*Note the audio buffer is ALWAYS registered untill destroyed since buffer filling shall happen even when inactive*/ if (!st->output.register_with_parent || !st->output.register_with_renderer) gf_sc_audio_register(&st->output, tr_state); /*store mute flag*/ st->is_muted = tr_state->switched_off; }