[vlc-commits] [Git][videolan/vlc][master] 4 commits: aout: filters: use an intermediate struct to hold filters

Thomas Guillem (@tguillem) gitlab at videolan.org
Wed Apr 20 12:11:47 UTC 2022



Thomas Guillem pushed to branch master at VideoLAN / VLC


Commits:
278efe44 by Thomas Guillem at 2022-04-19T09:55:04+02:00
aout: filters: use an intermediate struct to hold filters

In order to hold more variables per filter, cf. next commits.

- - - - -
d48a8808 by Thomas Guillem at 2022-04-19T09:55:04+02:00
aout: filters: factorize filter destroy

- - - - -
f834379e by Thomas Guillem at 2022-04-19T09:55:04+02:00
aout: filters: only create a clock when necessary

Only the visualisation aout filters need the clock for the vout (for
now).

Create one slave clock per visualisation aout filter instead of always
creating one for all visualisation aout filters.

- - - - -
38891c2d by Thomas Guillem at 2022-04-19T09:55:04+02:00
aout: filters: move the vout ownership to aout_filters

So that the aout_filters keep a strong reference on the vout it created
in order to control it.

- - - - -


4 changed files:

- include/vlc_aout.h
- modules/visualization/goom.c
- modules/visualization/visual/visual.c
- src/audio_output/filters.c


Changes:

=====================================
include/vlc_aout.h
=====================================
@@ -585,6 +585,14 @@ VLC_API block_t *aout_FiltersDrain(aout_filters_t *);
 VLC_API void     aout_FiltersFlush(aout_filters_t *);
 VLC_API void     aout_FiltersChangeViewpoint(aout_filters_t *, const vlc_viewpoint_t *vp);
 
+/**
+ * Create a vout from an "visualization" audio filter.
+ *
+ * @warning Can only be called once, from the probe function (Open).
+ *
+ * @return a valid vout or NULL in case of error, the returned vout should not
+ * be freed via vout_Close().
+ */
 VLC_API vout_thread_t *aout_filter_GetVout(filter_t *, const video_format_t *);
 
 /** @} */


=====================================
modules/visualization/goom.c
=====================================
@@ -353,8 +353,6 @@ static void Close( filter_t *p_filter )
     vlc_join( p_thread->thread, NULL );
 
     /* Free data */
-    vout_Close( p_thread->p_vout );
-
     while( p_thread->i_blocks-- )
     {
         block_Release( p_thread->pp_blocks[p_thread->i_blocks] );


=====================================
modules/visualization/visual/visual.c
=====================================
@@ -405,7 +405,6 @@ static void Close( filter_t * p_filter )
 
     vlc_queue_Kill(&p_sys->queue, &p_sys->dead);
     vlc_join( p_sys->thread, NULL );
-    vout_Close( p_sys->p_vout );
 
     /* Free the list */
     for( int i = 0; i < p_sys->i_effect; i++ )


=====================================
src/audio_output/filters.c
=====================================
@@ -40,6 +40,20 @@
 #include "aout_internal.h"
 #include "../video_output/vout_internal.h" /* for vout_Request */
 
+struct aout_filter
+{
+    filter_t *f;
+    vlc_clock_t *clock;
+    vout_thread_t *vout;
+};
+
+static inline void aout_filter_Init(struct aout_filter *tab, filter_t *f)
+{
+    tab->f = f;
+    tab->clock = NULL;
+    tab->vout = NULL;
+}
+
 filter_t *aout_filter_Create(vlc_object_t *obj, const filter_owner_t *restrict owner,
                              const char *type, const char *name,
                              const audio_sample_format_t *infmt,
@@ -109,18 +123,27 @@ static filter_t *FindResampler (vlc_object_t *obj,
     return filter;
 }
 
+static void aout_FilterDestroy(filter_t *filter)
+{
+    filter_Close(filter);
+    module_unneed(filter, filter->p_module);
+    vlc_object_delete(filter);
+}
+
 /**
  * Destroys a chain of audio filters.
  */
-static void aout_FiltersPipelineDestroy(filter_t *const *filters, unsigned n)
+static void aout_FiltersPipelineDestroy(struct aout_filter *tab, unsigned n)
 {
     for( unsigned i = 0; i < n; i++ )
     {
-        filter_t *p_filter = filters[i];
+        filter_t *p_filter = tab[i].f;
 
-        filter_Close( p_filter );
-        module_unneed( p_filter, p_filter->p_module );
-        vlc_object_delete(p_filter);
+        aout_FilterDestroy(p_filter);
+        if (tab[i].vout != NULL)
+            vout_Close(tab[i].vout);
+        if (tab[i].clock != NULL)
+            vlc_clock_Delete(tab[i].clock);
     }
 }
 
@@ -149,14 +172,14 @@ static filter_t *TryFormat (vlc_object_t *obj, vlc_fourcc_t codec,
  * @param outfmt output audio format
  * @return 0 on success, -1 on failure
  */
-static int aout_FiltersPipelineCreate(vlc_object_t *obj, filter_t **filters,
+static int aout_FiltersPipelineCreate(vlc_object_t *obj, struct aout_filter *tab,
                                       unsigned *count, unsigned max,
                                  const audio_sample_format_t *restrict infmt,
                                  const audio_sample_format_t *restrict outfmt)
 {
     aout_FormatsPrint (obj, "conversion:", infmt, outfmt);
     max -= *count;
-    filters += *count;
+    tab += *count;
 
     /* There is a lot of second guessing on what the conversion plugins can
      * and cannot do. This seems hardly avoidable, the conversion problem need
@@ -188,7 +211,7 @@ static int aout_FiltersPipelineCreate(vlc_object_t *obj, filter_t **filters,
                 goto error;
             }
 
-            filters[n++] = f;
+            aout_filter_Init(&tab[n++], f);
         }
 
         if (n == max)
@@ -217,7 +240,7 @@ static int aout_FiltersPipelineCreate(vlc_object_t *obj, filter_t **filters,
         }
 
         input = output;
-        filters[n++] = f;
+        aout_filter_Init(&tab[n++], f);
     }
 
     /* Resample */
@@ -238,7 +261,7 @@ static int aout_FiltersPipelineCreate(vlc_object_t *obj, filter_t **filters,
         }
 
         input = output;
-        filters[n++] = f;
+        aout_filter_Init(&tab[n++], f);
     }
 
     /* Format */
@@ -254,7 +277,7 @@ static int aout_FiltersPipelineCreate(vlc_object_t *obj, filter_t **filters,
                      "post-mix converter");
             goto error;
         }
-        filters[n++] = f;
+        aout_filter_Init(&tab[n++], f);
     }
 
     msg_Dbg (obj, "conversion pipeline complete");
@@ -266,20 +289,20 @@ overflow:
     vlc_dialog_display_error (obj, _("Audio filtering failed"),
         _("The maximum number of filters (%u) was reached."), max);
 error:
-    aout_FiltersPipelineDestroy (filters, n);
+    aout_FiltersPipelineDestroy (tab, n);
     return -1;
 }
 
 /**
  * Filters an audio buffer through a chain of filters.
  */
-static block_t *aout_FiltersPipelinePlay(filter_t *const *filters,
+static block_t *aout_FiltersPipelinePlay(const struct aout_filter *tab,
                                          unsigned count, block_t *block)
 {
     /* TODO: use filter chain */
     for (unsigned i = 0; (i < count) && (block != NULL); i++)
     {
-        filter_t *filter = filters[i];
+        filter_t *filter = tab[i].f;
 
         /* Please note that p_block->i_nb_samples & i_buffer
          * shall be set by the filter plug-in. */
@@ -292,14 +315,14 @@ static block_t *aout_FiltersPipelinePlay(filter_t *const *filters,
 /**
  * Drain the chain of filters.
  */
-static block_t *aout_FiltersPipelineDrain(filter_t *const *filters,
+static block_t *aout_FiltersPipelineDrain(const struct aout_filter *tab,
                                           unsigned count)
 {
     block_t *chain = NULL;
 
     for (unsigned i = 0; i < count; i++)
     {
-        filter_t *filter = filters[i];
+        filter_t *filter = tab[i].f;
 
         block_t *block = filter_DrainAudio (filter);
         if (block)
@@ -307,7 +330,7 @@ static block_t *aout_FiltersPipelineDrain(filter_t *const *filters,
             /* If there is a drained block, filter it through the following
              * chain of filters  */
             if (i + 1 < count)
-                block = aout_FiltersPipelinePlay (&filters[i + 1],
+                block = aout_FiltersPipelinePlay (&tab[i + 1],
                                                   count - i - 1, block);
             if (block)
                 block_ChainAppend (&chain, block);
@@ -323,19 +346,19 @@ static block_t *aout_FiltersPipelineDrain(filter_t *const *filters,
 /**
  * Flush the chain of filters.
  */
-static void aout_FiltersPipelineFlush(filter_t *const *filters,
+static void aout_FiltersPipelineFlush(const struct aout_filter *tab,
                                       unsigned count)
 {
     for (unsigned i = 0; i < count; i++)
-        filter_Flush (filters[i]);
+        filter_Flush (tab[i].f);
 }
 
-static void aout_FiltersPipelineChangeViewpoint(filter_t *const *filters,
+static void aout_FiltersPipelineChangeViewpoint(const struct aout_filter *tab,
                                                 unsigned count,
                                                 const vlc_viewpoint_t *vp)
 {
     for (unsigned i = 0; i < count; i++)
-        filter_ChangeViewpoint (filters[i], vp);
+        filter_ChangeViewpoint (tab[i].f, vp);
 }
 
 #define AOUT_MAX_FILTERS 10
@@ -344,12 +367,12 @@ struct aout_filters
 {
     filter_t *rate_filter; /**< The filter adjusting samples count
         (either the scaletempo filter or a resampler) */
-    filter_t *resampler; /**< The resampler */
+    struct aout_filter resampler; /**< The resampler */
     int resampling; /**< Current resampling (Hz) */
-    vlc_clock_t *clock;
+    const vlc_clock_t *clock_source;
 
     unsigned count; /**< Number of filters */
-    filter_t *tab[AOUT_MAX_FILTERS]; /**< Configured user filters
+    struct aout_filter tab[AOUT_MAX_FILTERS]; /**< Configured user filters
         (e.g. equalization) and their conversions */
 };
 
@@ -380,15 +403,34 @@ static int VisualizationCallback (vlc_object_t *obj, const char *var,
     return VLC_SUCCESS;
 }
 
+struct filter_owner_sys
+{
+    const vlc_clock_t *clock_source;
+    vlc_clock_t *clock;
+    vout_thread_t *vout;
+};
+
 vout_thread_t *aout_filter_GetVout(filter_t *filter, const video_format_t *fmt)
 {
+    struct filter_owner_sys *owner_sys = filter->owner.sys;
+    assert(owner_sys->clock_source != NULL);
+    assert(owner_sys->clock == NULL);
+    assert(owner_sys->vout == NULL);
+
+    vlc_clock_t *clock = vlc_clock_CreateSlave(owner_sys->clock_source, AUDIO_ES);
+    if (clock == NULL)
+        return NULL;
+
     vout_thread_t *vout = vout_Create(VLC_OBJECT(filter));
     if (unlikely(vout == NULL))
+    {
+        vlc_clock_Delete(clock);
         return NULL;
+    }
 
     video_format_t adj_fmt = *fmt;
     vout_configuration_t cfg = {
-        .vout = vout, .clock = filter->owner.sys, .fmt = &adj_fmt,
+        .vout = vout, .clock = clock, .fmt = &adj_fmt,
     };
 
     video_format_AdjustColorSpace(&adj_fmt);
@@ -396,7 +438,11 @@ vout_thread_t *aout_filter_GetVout(filter_t *filter, const video_format_t *fmt)
     if (vout_Request(&cfg, NULL, NULL)) {
         vout_Close(vout);
         vout = NULL;
+        vlc_clock_Delete(clock);
     }
+
+    owner_sys->clock = clock;
+    owner_sys->vout = vout;
     return vout;
 }
 
@@ -413,7 +459,12 @@ static int AppendFilter(vlc_object_t *obj, const char *type, const char *name,
         return -1;
     }
 
-    const filter_owner_t owner = { .sys = filters->clock };
+    struct filter_owner_sys owner_sys = {
+        .clock_source = filters->clock_source,
+        .clock = NULL,
+        .vout = NULL,
+    };
+    const filter_owner_t owner = { .sys = &owner_sys };
     filter_t *filter = aout_filter_Create(obj, &owner, type, name,
                                           infmt, outfmt, cfg, false);
     if (filter == NULL)
@@ -427,14 +478,18 @@ static int AppendFilter(vlc_object_t *obj, const char *type, const char *name,
                                     max - 1, infmt, &filter->fmt_in.audio))
     {
         msg_Err (filter, "cannot add user %s \"%s\" (skipped)", type, name);
-        filter_Close( filter );
-        module_unneed (filter, filter->p_module);
-        vlc_object_delete(filter);
+        aout_FilterDestroy(filter);
+        if (owner_sys.vout != NULL)
+            vout_Close(owner_sys.vout);
+        if (owner_sys.clock != NULL)
+            vlc_clock_Delete(owner_sys.clock);
         return -1;
     }
 
     assert (filters->count < max);
-    filters->tab[filters->count] = filter;
+    aout_filter_Init(&filters->tab[filters->count], filter);
+    filters->tab[filters->count].clock = owner_sys.clock;
+    filters->tab[filters->count].vout = owner_sys.vout;
     filters->count++;
     *infmt = filter->fmt_out.audio;
     return 0;
@@ -496,17 +551,10 @@ aout_filters_t *aout_FiltersNewWithClock(vlc_object_t *obj, const vlc_clock_t *c
         return NULL;
 
     filters->rate_filter = NULL;
-    filters->resampler = NULL;
+    aout_filter_Init(&filters->resampler, NULL);
     filters->resampling = 0;
     filters->count = 0;
-    if (clock)
-    {
-        filters->clock = vlc_clock_CreateSlave(clock, AUDIO_ES);
-        if (!filters->clock)
-            goto error;
-    }
-    else
-        filters->clock = NULL;
+    filters->clock_source = clock;
 
     /* Prepare format structure */
     aout_FormatPrint (obj, "input", infmt);
@@ -521,13 +569,13 @@ aout_filters_t *aout_FiltersNewWithClock(vlc_object_t *obj, const vlc_clock_t *c
         if (!AOUT_FMTS_IDENTICAL(infmt, outfmt))
         {
             aout_FormatsPrint (obj, "pass-through:", infmt, outfmt);
-            filters->tab[0] = FindConverter(obj, infmt, outfmt);
-            if (filters->tab[0] == NULL)
+            filter_t *f = FindConverter(obj, infmt, outfmt);
+            if (f == NULL)
             {
                 msg_Err (obj, "cannot setup pass-through");
                 goto error;
             }
-            filters->count++;
+            aout_filter_Init(&filters->tab[filters->count++], f);
         }
         return filters;
     }
@@ -576,7 +624,7 @@ aout_filters_t *aout_FiltersNewWithClock(vlc_object_t *obj, const vlc_clock_t *c
         }
 
         input_format = input_phys_format;
-        filters->tab[filters->count++] = f;
+        aout_filter_Init(&filters->tab[filters->count++], f);
     }
 
     assert(input_format.channel_type == AUDIO_CHANNEL_TYPE_BITMAP);
@@ -586,7 +634,7 @@ aout_filters_t *aout_FiltersNewWithClock(vlc_object_t *obj, const vlc_clock_t *c
     {
         if (AppendFilter(obj, "audio filter", "scaletempo",
                          filters, &input_format, &output_format, NULL) == 0)
-            filters->rate_filter = filters->tab[filters->count - 1];
+            filters->rate_filter = filters->tab[filters->count - 1].f;
     }
 
     if (cfg != NULL)
@@ -625,37 +673,57 @@ aout_filters_t *aout_FiltersNewWithClock(vlc_object_t *obj, const vlc_clock_t *c
     /* insert the resampler */
     output_format.i_rate = outfmt->i_rate;
     assert (AOUT_FMTS_IDENTICAL(&output_format, outfmt));
-    filters->resampler = FindResampler (obj, &input_format,
-                                        &output_format);
-    if (filters->resampler == NULL && input_format.i_rate != outfmt->i_rate)
+    filters->resampler.f = FindResampler(obj, &input_format,
+                                         &output_format);
+    if (filters->resampler.f == NULL && input_format.i_rate != outfmt->i_rate)
     {
         msg_Err (obj, "cannot setup a resampler");
         goto error;
     }
     if (filters->rate_filter == NULL)
-        filters->rate_filter = filters->resampler;
+        filters->rate_filter = filters->resampler.f;
 
     return filters;
 
 error:
     aout_FiltersPipelineDestroy (filters->tab, filters->count);
     var_DelCallback(obj, "visual", VisualizationCallback, NULL);
-    if (filters->clock)
-        vlc_clock_Delete(filters->clock);
     free (filters);
     return NULL;
 }
 
+static void aout_FiltersPipelineResetClock(const struct aout_filter *tab,
+                                           unsigned count)
+{
+    for (unsigned i = 0; i < count; i++)
+    {
+        vlc_clock_t *clock = tab[i].clock;
+        if (clock != NULL)
+            vlc_clock_Reset(clock);
+    }
+}
+
 void aout_FiltersResetClock(aout_filters_t *filters)
 {
-    assert(filters->clock);
-    vlc_clock_Reset(filters->clock);
+    assert(filters->clock_source);
+    aout_FiltersPipelineResetClock(filters->tab, filters->count);
+}
+
+static void aout_FiltersPipelineSetClockDelay(const struct aout_filter *tab,
+                                              unsigned count, vlc_tick_t delay)
+{
+    for (unsigned i = 0; i < count; i++)
+    {
+        vlc_clock_t *clock = tab[i].clock;
+        if (clock != NULL)
+            vlc_clock_SetDelay(clock, delay);
+    }
 }
 
 void aout_FiltersSetClockDelay(aout_filters_t *filters, vlc_tick_t delay)
 {
-    assert(filters->clock);
-    vlc_clock_SetDelay(filters->clock, delay);
+    assert(filters->clock_source);
+    aout_FiltersPipelineSetClockDelay(filters->tab, filters->count, delay);
 }
 
 #undef aout_FiltersNew
@@ -683,23 +751,21 @@ aout_filters_t *aout_FiltersNew(vlc_object_t *obj,
  */
 void aout_FiltersDelete (vlc_object_t *obj, aout_filters_t *filters)
 {
-    if (filters->resampler != NULL)
-        aout_FiltersPipelineDestroy (&filters->resampler, 1);
+    if (filters->resampler.f != NULL)
+        aout_FiltersPipelineDestroy(&filters->resampler, 1);
     aout_FiltersPipelineDestroy (filters->tab, filters->count);
     var_DelCallback(obj, "visual", VisualizationCallback, NULL);
-    if (filters->clock)
-        vlc_clock_Delete(filters->clock);
     free (filters);
 }
 
 bool aout_FiltersCanResample (aout_filters_t *filters)
 {
-    return (filters->resampler != NULL);
+    return (filters->resampler.f != NULL);
 }
 
 bool aout_FiltersAdjustResampling (aout_filters_t *filters, int adjust)
 {
-    if (filters->resampler == NULL)
+    if (filters->resampler.f == NULL)
         return false;
 
     if (adjust)
@@ -726,12 +792,12 @@ block_t *aout_FiltersPlay(aout_filters_t *filters, block_t *block, float rate)
     }
 
     block = aout_FiltersPipelinePlay (filters->tab, filters->count, block);
-    if (filters->resampler != NULL)
+    if (filters->resampler.f != NULL)
     {   /* NOTE: the resampler needs to run even if resampling is 0.
          * The decoder and output rates can still be different. */
-        filters->resampler->fmt_in.audio.i_rate += filters->resampling;
+        filters->resampler.f->fmt_in.audio.i_rate += filters->resampling;
         block = aout_FiltersPipelinePlay (&filters->resampler, 1, block);
-        filters->resampler->fmt_in.audio.i_rate -= filters->resampling;
+        filters->resampler.f->fmt_in.audio.i_rate -= filters->resampling;
     }
 
     if (nominal_rate != 0)
@@ -751,11 +817,11 @@ block_t *aout_FiltersDrain (aout_filters_t *filters)
     /* Drain the filters pipeline */
     block_t *block = aout_FiltersPipelineDrain (filters->tab, filters->count);
 
-    if (filters->resampler != NULL)
+    if (filters->resampler.f != NULL)
     {
         block_t *chain = NULL;
 
-        filters->resampler->fmt_in.audio.i_rate += filters->resampling;
+        filters->resampler.f->fmt_in.audio.i_rate += filters->resampling;
 
         if (block)
         {
@@ -770,7 +836,7 @@ block_t *aout_FiltersDrain (aout_filters_t *filters)
         if (block)
             block_ChainAppend (&chain, block);
 
-        filters->resampler->fmt_in.audio.i_rate -= filters->resampling;
+        filters->resampler.f->fmt_in.audio.i_rate -= filters->resampling;
 
         return chain ? block_ChainGather (chain) : NULL;
     }
@@ -782,7 +848,7 @@ void aout_FiltersFlush (aout_filters_t *filters)
 {
     aout_FiltersPipelineFlush (filters->tab, filters->count);
 
-    if (filters->resampler != NULL)
+    if (filters->resampler.f != NULL)
         aout_FiltersPipelineFlush (&filters->resampler, 1);
 }
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b7b5fd49c888fbe054973b7635404f35029e9f55...38891c2dc35b7903c39cef2f43730da3a2a50a42

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/b7b5fd49c888fbe054973b7635404f35029e9f55...38891c2dc35b7903c39cef2f43730da3a2a50a42
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list