void gf_sc_ar_del(GF_AudioRenderer *ar) { if (!ar) return; GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Destroying compositor\n")); /*resume if paused (might cause deadlock otherwise)*/ if (ar->Frozen) gf_sc_ar_control(ar, GF_SC_AR_RESUME); /*stop and shutdown*/ if (ar->audio_out) { /*kill audio thread*/ if (!ar->audio_out->SelfThreaded) { GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] stopping audio thread\n")); ar->audio_th_state = 2; while (ar->audio_th_state != 3) { gf_sleep(33); } GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] audio thread stopped\n")); gf_th_del(ar->th); GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] audio thread destroyed\n")); } /*lock access before shutdown and emulate a reconfig (avoids mixer lock from self-threaded modules)*/ ar->need_reconfig = GF_TRUE; gf_mixer_lock(ar->mixer, GF_TRUE); if (ar->audio_out->SelfThreaded) ar->audio_out->Shutdown(ar->audio_out); gf_modules_close_interface((GF_BaseInterface *)ar->audio_out); ar->audio_out = NULL; gf_mixer_lock(ar->mixer, GF_FALSE); } gf_mixer_del(ar->mixer); if (ar->audio_listeners) gf_list_del(ar->audio_listeners); gf_afc_unload(&ar->filter_chain); gf_free(ar); GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Renderer destroyed\n")); }
GF_EXPORT void gf_sc_reload_audio_filters(GF_Compositor *compositor) { GF_AudioRenderer *ar = compositor->audio_renderer; if (!ar) return; gf_mixer_lock(ar->mixer, GF_TRUE); gf_afc_unload(&ar->filter_chain); gf_afc_load(&ar->filter_chain, ar->user, (char*)gf_cfg_get_key(ar->user->config, "Audio", "Filter")); gf_ar_pause(ar, GF_TRUE, GF_TRUE, GF_FALSE); ar->need_reconfig = GF_FALSE; gf_ar_setup_output_format(ar); gf_ar_pause(ar, GF_FALSE, GF_TRUE, GF_FALSE); gf_mixer_lock(ar->mixer, GF_FALSE); }
void gf_af_del(GF_AudioFilterItem *af) { gf_afc_unload(&af->filter_chain); gf_free(af); }