[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