/*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; }
void gf_sc_ar_reset(GF_AudioRenderer *ar) { gf_mixer_remove_all(ar->mixer); }