+ if (aout_ChangeFilterString (obj, obj, "audio-filter", "equalizer", *val))
+ aout_InputRequestRestart ((audio_output_t *)obj); /* <- That sucks! */
+
+ (void) var; (void) oldval; (void) data;
+ return VLC_SUCCESS;
+}
+
+static vout_thread_t *RequestVout (void *data, vout_thread_t *vout,
+ video_format_t *fmt, bool recycle)
+{
+ audio_output_t *aout = data;
+ vout_configuration_t cfg = {
+ .vout = vout,
+ .input = NULL,
+ .change_fmt = true,
+ .fmt = fmt,
+ .dpb_size = 1,
+ };
+
+ (void) recycle;
+ return vout_Request (aout, &cfg);
+}
+
+vout_thread_t *aout_filter_RequestVout (filter_t *filter, vout_thread_t *vout,
+ video_format_t *fmt)
+{
+ /* NOTE: This only works from audio output.
+ * If you want to use visualization filters from another place, you will
+ * need to add a new pf_aout_request_vout callback or store a pointer
+ * to aout_request_vout_t inside filter_t (i.e. a level of indirection). */
+ aout_owner_t *owner = aout_owner ((audio_output_t *)filter->p_parent);
+ aout_request_vout_t *req = &owner->request_vout;
+
+ return req->pf_request_vout (req->p_private, vout, fmt,
+ owner->recycle_vout);
+}
+
+static filter_t *CreateFilter (vlc_object_t *parent, const char *name,
+ const audio_sample_format_t *restrict infmt,
+ const audio_sample_format_t *restrict outfmt,
+ bool visu)
+{
+ filter_t *filter = vlc_custom_create (parent, sizeof (*filter),
+ "audio filter");
+ if (unlikely(filter == NULL))
+ return NULL;
+
+ /*filter->p_owner = NOT NEEDED;*/
+ filter->fmt_in.i_codec = infmt->i_format;
+ filter->fmt_in.audio = *infmt;
+ filter->fmt_out.i_codec = outfmt->i_format;
+ filter->fmt_out.audio = *outfmt;
+
+ if (!visu)