[vlc-devel] [PATCH] aout: play the silence buffer on most modules
Thomas Guillem
thomas at gllm.fr
Thu Aug 15 13:01:46 CEST 2019
Add a new capability: aout->module_info.can_play_at_date, only set by Pulse
(for now) since it is the only module that can handle a play_date != system_now.
This capability is checked by the aout core in order to tell if it should first
play a silence buffer (that has the same length than the jitter delay).
Before this commit, I assumed that a module could need a silence buffer only if
it returned a valid delay before the first play. This assumption is now false,
cf. the coreaudio case here: bdd96900164739b72220334bdbda511aff708caa. I plan
do to the same for the Android aout module: return a delay only when it is
really known but don't handle play_date.
For info: returning a delay before the first play could trigger frame drops (or
audio flush/resampling if audio is not the master) once the delay is really
known (and too far from the first returned delay).
---
include/vlc_aout.h | 9 ++++++++-
modules/audio_output/pulse.c | 1 +
src/audio_output/dec.c | 18 +++++++++++++-----
src/audio_output/output.c | 1 +
4 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/include/vlc_aout.h b/include/vlc_aout.h
index 43fbf2f120..74d51c2335 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -190,7 +190,8 @@ struct audio_output
/**< Queues a block of samples for playback (mandatory, cannot be NULL).
*
* \param block block of audio samples
- * \param date intended system time to render the first sample
+ * \param date intended system time to render the first sample. Should be
+ * used only if module_info.can_play_at_date is true
*
* \note This callback cannot be called in stopped state.
*/
@@ -257,6 +258,12 @@ struct audio_output
* \warning The same constraints apply as with volume_set().
*/
+ struct {
+ bool can_play_at_date;
+ /**< Default to false, set it to true if the module can play an audio
+ * buffer at a given date (in the future) */
+ } module_info;
+
struct {
bool headphones; /**< Default to false, set it to true if the current
sink is using headphones */
diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c
index fba8fd6840..e7f95fd5da 100644
--- a/modules/audio_output/pulse.c
+++ b/modules/audio_output/pulse.c
@@ -1038,6 +1038,7 @@ static int Open(vlc_object_t *obj)
aout->volume_set = VolumeSet;
aout->mute_set = MuteSet;
aout->device_select = StreamMove;
+ aout->module_info.can_play_at_date = true;
pa_threaded_mainloop_lock(sys->mainloop);
/* Sinks (output devices) list */
diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c
index e0c9f32b7e..7ebfedb746 100644
--- a/src/audio_output/dec.c
+++ b/src/audio_output/dec.c
@@ -268,12 +268,18 @@ static void aout_DecSynchronize(audio_output_t *aout, vlc_tick_t system_now,
* pts = vlc_tick_now() + delay
*/
aout_owner_t *owner = aout_owner (aout);
+ bool delay_valid;
vlc_tick_t delay;
- if (aout->time_get(aout, &delay) != 0)
- return; /* nothing can be done if timing is unknown */
+ if (aout->time_get(aout, &delay) == 0)
+ delay_valid = true;
+ else
+ {
+ delay_valid = false;
+ delay = 0;
+ }
- if (owner->sync.discontinuity)
+ if (owner->sync.discontinuity && !aout->module_info.can_play_at_date)
{
/* Chicken-egg situation for most aout modules that can't be started
* deferred (all except PulseAudio). These modules will start to play
@@ -291,11 +297,13 @@ static void aout_DecSynchronize(audio_output_t *aout, vlc_tick_t system_now,
if (jitter > 0)
{
aout_DecSilence (aout, jitter, dec_pts - delay);
- if (aout->time_get(aout, &delay) != 0)
- return;
+ delay_valid = aout->time_get(aout, &delay) == 0;
}
}
+ if (!delay_valid)
+ return; /* nothing can be done if timing is unknown */
+
aout_RequestRetiming(aout, system_now + delay, dec_pts);
}
diff --git a/src/audio_output/output.c b/src/audio_output/output.c
index 5c378dbb31..212164f7bf 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -242,6 +242,7 @@ audio_output_t *aout_New (vlc_object_t *parent)
aout->volume_set = NULL;
aout->mute_set = NULL;
aout->device_select = NULL;
+ aout->module_info.can_play_at_date = false;
owner->module = module_need_var(aout, "audio output", "aout");
if (owner->module == NULL)
{
--
2.20.1
More information about the vlc-devel
mailing list