[vlc-devel] [PATCH V2 2/4] aout: handle audio filters discontinuity

Thomas Guillem thomas at gllm.fr
Fri Mar 1 12:41:51 CET 2019


In case of a filter discontinuity from aout_filters_t, flush the pipeline and
return vlc_block_discontinuity.
---
 include/vlc_filter.h       |  8 +++++++-
 src/audio_output/dec.c     |  3 +++
 src/audio_output/filters.c | 32 +++++++++++++++++++++++++++++---
 3 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/include/vlc_filter.h b/include/vlc_filter.h
index b2a8f871a4..3e2d8dbe90 100644
--- a/include/vlc_filter.h
+++ b/include/vlc_filter.h
@@ -88,7 +88,13 @@ struct filter_t
         /** Filter a picture (video filter) */
         picture_t * (*pf_video_filter)( filter_t *, picture_t * );
 
-        /** Filter an audio block (audio filter) */
+        /**
+         * Filter an audio block (audio filter)
+         *
+         * @return a valid output block, NULL if the module need more data to
+         * output a block, or vlc_block_discontinuity in case of
+         * discontinuity/error.
+         */
         block_t * (*pf_audio_filter)( filter_t *, block_t * );
 
         /** Blend a subpicture onto a picture (blend) */
diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c
index 0898487668..462ea534e0 100644
--- a/src/audio_output/dec.c
+++ b/src/audio_output/dec.c
@@ -363,6 +363,8 @@ int aout_DecPlay(audio_output_t *aout, block_t *block)
     }
 
     block = aout_FiltersPlay(owner->filters, block, owner->sync.rate);
+    if (unlikely(block == vlc_block_discontinuity))
+        goto lost;
     if (block == NULL)
         return ret;
 
@@ -380,6 +382,7 @@ int aout_DecPlay(audio_output_t *aout, block_t *block)
 drop:
     owner->sync.discontinuity = true;
     block_Release (block);
+lost:
     atomic_fetch_add_explicit(&owner->buffers_lost, 1, memory_order_relaxed);
     return ret;
 }
diff --git a/src/audio_output/filters.c b/src/audio_output/filters.c
index b62cf93f04..54c6282b62 100644
--- a/src/audio_output/filters.c
+++ b/src/audio_output/filters.c
@@ -271,6 +271,13 @@ error:
     return -1;
 }
 
+static inline block_t *
+aout_FiltersOnDiscontinuity(aout_filters_t *filters, block_t *block)
+{
+    aout_FiltersFlush(filters);
+    return block;
+}
+
 /**
  * Filters an audio buffer through a chain of filters.
  */
@@ -285,6 +292,8 @@ static block_t *aout_FiltersPipelinePlay(filter_t *const *filters,
         /* Please note that p_block->i_nb_samples & i_buffer
          * shall be set by the filter plug-in. */
         block = filter->pf_audio_filter (filter, block);
+        if (unlikely(block == vlc_block_discontinuity))
+            return block;
     }
     return block;
 }
@@ -305,11 +314,16 @@ static block_t *aout_FiltersPipelineDrain(filter_t *const *filters,
         block_t *block = filter_DrainAudio (filter);
         if (block)
         {
+            if (unlikely(block == vlc_block_discontinuity))
+                return block;
+
             /* If there is a drained block, filter it through the following
              * chain of filters  */
             if (i + 1 < count)
                 block = aout_FiltersPipelinePlay (&filters[i + 1],
                                                   count - i - 1, block);
+            if (unlikely(block == vlc_block_discontinuity))
+                return block;
             if (block)
                 block_ChainAppend (&chain, block);
         }
@@ -699,7 +713,7 @@ 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 != NULL && block != vlc_block_discontinuity)
     {   /* 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;
@@ -712,6 +726,8 @@ block_t *aout_FiltersPlay(aout_filters_t *filters, block_t *block, float rate)
         assert (filters->rate_filter != NULL);
         filters->rate_filter->fmt_in.audio.i_rate = nominal_rate;
     }
+    if (unlikely(block == vlc_block_discontinuity))
+        return aout_FiltersOnDiscontinuity(filters, block);
     return block;
 
 drop:
@@ -723,6 +739,8 @@ block_t *aout_FiltersDrain (aout_filters_t *filters)
 {
     /* Drain the filters pipeline */
     block_t *block = aout_FiltersPipelineDrain (filters->tab, filters->count);
+    if (unlikely(block == vlc_block_discontinuity))
+        return aout_FiltersOnDiscontinuity(filters, block);
 
     if (filters->resampler != NULL)
     {
@@ -734,17 +752,25 @@ block_t *aout_FiltersDrain (aout_filters_t *filters)
         {
             /* Resample the drained block from the filters pipeline */
             block = aout_FiltersPipelinePlay (&filters->resampler, 1, block);
+            if (unlikely(block == vlc_block_discontinuity))
+            {
+                filters->resampler->fmt_in.audio.i_rate -= filters->resampling;
+                return aout_FiltersOnDiscontinuity(filters, block);
+            }
             if (block)
                 block_ChainAppend (&chain, block);
         }
 
         /* Drain the resampler filter */
         block = aout_FiltersPipelineDrain (&filters->resampler, 1);
+        filters->resampler->fmt_in.audio.i_rate -= filters->resampling;
+
+        if (unlikely(block == vlc_block_discontinuity))
+            return aout_FiltersOnDiscontinuity(filters, block);
+
         if (block)
             block_ChainAppend (&chain, block);
 
-        filters->resampler->fmt_in.audio.i_rate -= filters->resampling;
-
         return chain ? block_ChainGather (chain) : NULL;
     }
     else
-- 
2.20.1



More information about the vlc-devel mailing list