[vlc-devel] [PATCH V2 2/4] aout: handle audio filters discontinuity
Thomas Guillem
thomas at gllm.fr
Fri Mar 1 13:08:21 CET 2019
On Fri, Mar 1, 2019, at 12:42, Thomas Guillem wrote:
> 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);
> +
I think it's better to return NULL from aout_FiltersDrain in case of discontinuity.
> 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
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list