From 2049d408765d5f0209444025c21833624935ca37 Mon Sep 17 00:00:00 2001 From: Thomas Guillem <thomas@gllm.fr> Date: Tue, 12 Mar 2019 14:42:08 +0100 Subject: [PATCH] aout: use a separate drain callback This callback is not mandatory. If it is NULL, the core will wait for the delay returned by time_get(). This was already the case for most aout plugins: PulseAudio, coreaudio, Android, DirectSound, Wasapi, and Jack. --- include/vlc_aout.h | 12 ++++++-- modules/audio_output/adummy.c | 4 +-- modules/audio_output/alsa.c | 24 ++++++++++------ modules/audio_output/amem.c | 17 +++++++++--- modules/audio_output/audiotrack.c | 25 ++++------------- modules/audio_output/audiounit_ios.m | 13 ++------- modules/audio_output/coreaudio_common.c | 37 ++++++------------------- modules/audio_output/coreaudio_common.h | 2 +- modules/audio_output/directsound.c | 13 ++------- modules/audio_output/file.c | 5 ++-- modules/audio_output/jack.c | 12 ++------ modules/audio_output/kai.c | 16 +++-------- modules/audio_output/mmdevice.c | 4 +-- modules/audio_output/mmdevice.h | 14 ++-------- modules/audio_output/opensles_android.c | 32 +++++++++------------ modules/audio_output/oss.c | 8 ++---- modules/audio_output/pulse.c | 35 +++++++++++++---------- modules/audio_output/sndio.c | 5 ++-- modules/audio_output/waveout.c | 36 ++++++++++++------------ modules/audio_output/winstore.c | 4 +-- src/audio_output/dec.c | 19 +++++++++++-- 21 files changed, 146 insertions(+), 191 deletions(-) diff --git a/include/vlc_aout.h b/include/vlc_aout.h index a4ae6bc49893..a6b80691515b 100644 --- a/include/vlc_aout.h +++ b/include/vlc_aout.h @@ -212,14 +212,20 @@ struct audio_output * \note This callback cannot be called in stopped state. */ - void (*flush)( audio_output_t *, bool wait); - /**< Flushes or drains the playback buffers (mandatory, cannot be NULL). + void (*flush)( audio_output_t *); + /**< Flushes the playback buffers (mandatory, cannot be NULL). * * \param wait true to wait for playback of pending buffers (drain), * false to discard pending buffers (flush) * * \note This callback cannot be called in stopped state. */ + void (*drain)(audio_output_t *); + /**< Drain the playback buffers (can be NULL). + * + * If NULL, the caller will wait for the delay returned by time_get before + * calling stop(). + */ int (*volume_set)(audio_output_t *, float volume); /**< Changes playback volume (optional, may be NULL). @@ -456,7 +462,7 @@ static inline void aout_PauseDefault(audio_output_t *aout, bool paused, vlc_tick_t date) { if (paused && aout->flush != NULL) - aout->flush(aout, false); + aout->flush(aout); (void) date; } diff --git a/modules/audio_output/adummy.c b/modules/audio_output/adummy.c index 657aed2bc9e6..0a804b9eb0ed 100644 --- a/modules/audio_output/adummy.c +++ b/modules/audio_output/adummy.c @@ -52,9 +52,9 @@ static void Pause(audio_output_t *aout, bool paused, vlc_tick_t date) (void) aout; (void) paused; (void) date; } -static void Flush(audio_output_t *aout, bool wait) +static void Flush(audio_output_t *aout) { - (void) aout; (void) wait; + (void) aout; } static int Start(audio_output_t *aout, audio_sample_format_t *restrict fmt) diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c index e507f78241a7..ccf9435b1d3a 100644 --- a/modules/audio_output/alsa.c +++ b/modules/audio_output/alsa.c @@ -294,7 +294,8 @@ static int TimeGet (audio_output_t *aout, vlc_tick_t *); static void Play(audio_output_t *, block_t *, vlc_tick_t); static void Pause (audio_output_t *, bool, vlc_tick_t); static void PauseDummy (audio_output_t *, bool, vlc_tick_t); -static void Flush (audio_output_t *, bool); +static void Flush (audio_output_t *); +static void Drain (audio_output_t *); /** Initializes an ALSA playback stream */ static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt) @@ -714,20 +715,26 @@ static void PauseDummy (audio_output_t *aout, bool pause, vlc_tick_t date) } /** - * Flushes/drains the audio playback buffer. + * Flushes the audio playback buffer. */ -static void Flush (audio_output_t *aout, bool wait) +static void Flush (audio_output_t *aout) { aout_sys_t *p_sys = aout->sys; snd_pcm_t *pcm = p_sys->pcm; - - if (wait) - snd_pcm_drain (pcm); - else - snd_pcm_drop (pcm); + snd_pcm_drop (pcm); snd_pcm_prepare (pcm); } +/** + * Drains the audio playback buffer. + */ +static void Drain (audio_output_t *aout) +{ + aout_sys_t *p_sys = aout->sys; + snd_pcm_t *pcm = p_sys->pcm; + snd_pcm_drain (pcm); + snd_pcm_prepare (pcm); +} /** * Releases the audio output. @@ -851,6 +858,7 @@ static int Open(vlc_object_t *obj) aout->time_get = TimeGet; aout->play = Play; aout->flush = Flush; + aout->drain = Drain; return VLC_SUCCESS; error: diff --git a/modules/audio_output/amem.c b/modules/audio_output/amem.c index dcba84c32dc7..f859a4b10a73 100644 --- a/modules/audio_output/amem.c +++ b/modules/audio_output/amem.c @@ -104,19 +104,27 @@ static void Pause (audio_output_t *aout, bool paused, vlc_tick_t date) } } -static void Flush (audio_output_t *aout, bool wait) +static void Flush (audio_output_t *aout) { aout_sys_t *sys = aout->sys; - void (*cb) (void *) = wait ? sys->drain : sys->flush; - if (cb != NULL) + if (sys->flush != NULL) { vlc_mutex_lock(&sys->lock); - cb (sys->opaque); + sys->flush (sys->opaque); vlc_mutex_unlock(&sys->lock); } } +static void Drain (audio_output_t *aout) +{ + aout_sys_t *sys = aout->sys; + + vlc_mutex_lock(&sys->lock); + sys->drain (sys->opaque); + vlc_mutex_unlock(&sys->lock); +} + static int VolumeSet (audio_output_t *aout, float vol) { aout_sys_t *sys = aout->sys; @@ -313,6 +321,7 @@ static int Open (vlc_object_t *obj) aout->play = Play; aout->pause = Pause; aout->flush = Flush; + aout->drain = sys->drain ? Drain : NULL; if (sys->set_volume != NULL) { aout->volume_set = VolumeSet; diff --git a/modules/audio_output/audiotrack.c b/modules/audio_output/audiotrack.c index 2dcababe47c5..1d398523430b 100644 --- a/modules/audio_output/audiotrack.c +++ b/modules/audio_output/audiotrack.c @@ -2040,7 +2040,7 @@ bailout: } static void -Flush( audio_output_t *p_aout, bool b_wait ) +Flush( audio_output_t *p_aout ) { aout_sys_t *p_sys = p_aout->sys; JNIEnv *env; @@ -2061,25 +2061,10 @@ Flush( audio_output_t *p_aout, bool b_wait ) * that has not been played back will be discarded. No-op if not stopped * or paused, or if the track's creation mode is not MODE_STREAM. */ - if( b_wait ) - { - /* Wait for the thread to process the circular buffer */ - while( !p_sys->b_error - && p_sys->circular.i_read != p_sys->circular.i_write ) - vlc_cond_wait( &p_sys->aout_cond, &p_sys->lock ); - if( p_sys->b_error ) - goto bailout; - - JNI_AT_CALL_VOID( stop ); - if( CHECK_AT_EXCEPTION( "stop" ) ) - goto bailout; - } else - { - JNI_AT_CALL_VOID( pause ); - if( CHECK_AT_EXCEPTION( "pause" ) ) - goto bailout; - JNI_AT_CALL_VOID( flush ); - } + JNI_AT_CALL_VOID( pause ); + if( CHECK_AT_EXCEPTION( "pause" ) ) + goto bailout; + JNI_AT_CALL_VOID( flush ); p_sys->circular.i_read = p_sys->circular.i_write = 0; /* HACK: Before Android 4.4, the head position is not reset to zero and is diff --git a/modules/audio_output/audiounit_ios.m b/modules/audio_output/audiounit_ios.m index e449f6e2eb0c..ea555c0c14cb 100644 --- a/modules/audio_output/audiounit_ios.m +++ b/modules/audio_output/audiounit_ios.m @@ -409,15 +409,7 @@ Pause (audio_output_t *p_aout, bool pause, vlc_tick_t date) * that we loose 1-2 sec of audio when resuming. The order is important * here, ca_Flush need to be called when paused. */ if (pause) - ca_Flush(p_aout, false); -} - -static void -Flush(audio_output_t *p_aout, bool wait) -{ - aout_sys_t * p_sys = p_aout->sys; - - ca_Flush(p_aout, wait); + ca_Flush(p_aout); } static int @@ -430,7 +422,7 @@ MuteSet(audio_output_t *p_aout, bool mute) { Pause(p_aout, mute, 0); if (mute) - ca_Flush(p_aout, false); + ca_Flush(p_aout); } return VLC_SUCCESS; @@ -562,7 +554,6 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt) fmt->channel_type = AUDIO_CHANNEL_TYPE_BITMAP; p_aout->mute_set = MuteSet; p_aout->pause = Pause; - p_aout->flush = Flush; aout_SoftVolumeStart( p_aout ); diff --git a/modules/audio_output/coreaudio_common.c b/modules/audio_output/coreaudio_common.c index d790daf1cbe1..4a714f5411d1 100644 --- a/modules/audio_output/coreaudio_common.c +++ b/modules/audio_output/coreaudio_common.c @@ -230,42 +230,21 @@ ca_TimeGet(audio_output_t *p_aout, vlc_tick_t *delay) } void -ca_Flush(audio_output_t *p_aout, bool wait) +ca_Flush(audio_output_t *p_aout) { struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys; lock_lock(p_sys); - if (wait) - { - while (p_sys->i_out_size > 0) - { - if (p_sys->b_paused) - { - ca_ClearOutBuffers(p_aout); - break; - } - /* Calculate the duration of the circular buffer, in order to wait - * for the render thread to play it all */ - const vlc_tick_t i_frame_us = - FramesToUs(p_sys, BytesToFrames(p_sys, p_sys->i_out_size)) + VLC_TICK_FROM_MS(10); - lock_unlock(p_sys); - vlc_tick_sleep(i_frame_us); - lock_lock(p_sys); - } - } + assert(!p_sys->b_do_flush); + if (p_sys->b_paused) + ca_ClearOutBuffers(p_aout); else { - assert(!p_sys->b_do_flush); - if (p_sys->b_paused) - ca_ClearOutBuffers(p_aout); - else - { - p_sys->b_do_flush = true; - lock_unlock(p_sys); - vlc_sem_wait(&p_sys->flush_sem); - lock_lock(p_sys); - } + p_sys->b_do_flush = true; + lock_unlock(p_sys); + vlc_sem_wait(&p_sys->flush_sem); + lock_lock(p_sys); } p_sys->i_render_host_time = 0; diff --git a/modules/audio_output/coreaudio_common.h b/modules/audio_output/coreaudio_common.h index ead0c34e9e2d..a860a9aa5166 100644 --- a/modules/audio_output/coreaudio_common.h +++ b/modules/audio_output/coreaudio_common.h @@ -89,7 +89,7 @@ void ca_Render(audio_output_t *p_aout, uint32_t i_nb_samples, uint64_t i_host_ti int ca_TimeGet(audio_output_t *p_aout, vlc_tick_t *delay); -void ca_Flush(audio_output_t *p_aout, bool wait); +void ca_Flush(audio_output_t *p_aout); void ca_Pause(audio_output_t * p_aout, bool pause, vlc_tick_t date); diff --git a/modules/audio_output/directsound.c b/modules/audio_output/directsound.c index fb4fe75e328b..f93237a93a17 100644 --- a/modules/audio_output/directsound.c +++ b/modules/audio_output/directsound.c @@ -360,19 +360,10 @@ static HRESULT StreamFlush( aout_stream_t *s ) return Flush( s->sys ); } -static void OutputFlush( audio_output_t *aout, bool drain ) +static void OutputFlush( audio_output_t *aout ) { aout_sys_t *sys = aout->sys; - if (drain) - { /* Loosy drain emulation */ - vlc_tick_t delay; - - if( OutputTimeGet( aout, &delay ) == 0 && - delay <= VLC_TICK_FROM_SEC( 5 ) ) - Sleep( MS_FROM_VLC_TICK( delay ) + 1 ); - } - else - Flush( &sys->s ); + Flush( &sys->s ); } /** diff --git a/modules/audio_output/file.c b/modules/audio_output/file.c index fbdf35fcb123..906b2285480d 100644 --- a/modules/audio_output/file.c +++ b/modules/audio_output/file.c @@ -75,7 +75,7 @@ static const int pi_channels_maps[CHANNELS_MAX+1] = static int Open ( vlc_object_t * ); static void Play ( audio_output_t *, block_t *, vlc_tick_t ); static void Pause ( audio_output_t *, bool, vlc_tick_t ); -static void Flush ( audio_output_t *, bool ); +static void Flush ( audio_output_t * ); /***************************************************************************** * Module descriptor @@ -339,12 +339,11 @@ static void Pause( audio_output_t *aout, bool paused, vlc_tick_t date ) (void) aout; (void) paused; (void) date; } -static void Flush( audio_output_t *aout, bool wait ) +static void Flush( audio_output_t *aout ) { aout_sys_t *p_sys = aout->sys; if( fflush( p_sys->p_file ) ) msg_Err( aout, "flush error: %s", vlc_strerror_c(errno) ); - (void) wait; } static int Open(vlc_object_t *obj) diff --git a/modules/audio_output/jack.c b/modules/audio_output/jack.c index 59ad013b2fbe..d21150f2a41c 100644 --- a/modules/audio_output/jack.c +++ b/modules/audio_output/jack.c @@ -71,7 +71,7 @@ static int Open ( vlc_object_t * ); static void Close ( vlc_object_t * ); static void Play ( audio_output_t * p_aout, block_t *, vlc_tick_t ); static void Pause ( audio_output_t *aout, bool paused, vlc_tick_t date ); -static void Flush ( audio_output_t *p_aout, bool wait ); +static void Flush ( audio_output_t *p_aout ); static int TimeGet ( audio_output_t *, vlc_tick_t * ); static int Process ( jack_nframes_t i_frames, void *p_arg ); static int GraphChange ( void *p_arg ); @@ -328,19 +328,11 @@ static void Pause(audio_output_t *aout, bool paused, vlc_tick_t date) } } -static void Flush(audio_output_t *p_aout, bool wait) +static void Flush(audio_output_t *p_aout) { aout_sys_t * p_sys = p_aout->sys; jack_ringbuffer_t *rb = p_sys->p_jack_ringbuffer; - /* Sleep if wait was requested */ - if( wait ) - { - vlc_tick_t delay; - if (!TimeGet(p_aout, &delay)) - vlc_tick_sleep(delay); - } - /* reset ringbuffer read and write pointers */ jack_ringbuffer_reset(rb); } diff --git a/modules/audio_output/kai.c b/modules/audio_output/kai.c index 98a21823942d..dd75e367d8a5 100644 --- a/modules/audio_output/kai.c +++ b/modules/audio_output/kai.c @@ -74,7 +74,7 @@ static int Open ( vlc_object_t * ); static void Close ( vlc_object_t * ); static void Play ( audio_output_t *_p_aout, block_t *block, vlc_tick_t ); static void Pause ( audio_output_t *, bool, vlc_tick_t ); -static void Flush ( audio_output_t *, bool ); +static void Flush ( audio_output_t * ); static int TimeGet ( audio_output_t *, vlc_tick_t *restrict ); static ULONG APIENTRY KaiCallback ( PVOID, PVOID, ULONG ); @@ -310,23 +310,15 @@ static void Pause( audio_output_t *aout, bool pause, vlc_tick_t date ) kaiResume( sys->hkai ); } -static void Flush( audio_output_t *aout, bool drain ) +static void Flush( audio_output_t *aout ) { aout_sys_t *sys = aout->sys; audio_buffer_t *buffer = sys->buffer; vlc_mutex_lock( &buffer->mutex ); - if( drain ) - { - while( buffer->length > 0 ) - vlc_cond_wait( &buffer->cond, &buffer->mutex ); - } - else - { - buffer->read_pos = buffer->write_pos; - buffer->length = 0; - } + buffer->read_pos = buffer->write_pos; + buffer->length = 0; vlc_mutex_unlock( &buffer->mutex ); } diff --git a/modules/audio_output/mmdevice.c b/modules/audio_output/mmdevice.c index 162c8350b793..4c79cabf1d89 100644 --- a/modules/audio_output/mmdevice.c +++ b/modules/audio_output/mmdevice.c @@ -162,13 +162,13 @@ static void Pause(audio_output_t *aout, bool paused, vlc_tick_t date) (void) date; } -static void Flush(audio_output_t *aout, bool wait) +static void Flush(audio_output_t *aout) { aout_sys_t *sys = aout->sys; HRESULT hr; EnterMTA(); - hr = aout_stream_Flush(sys->stream, wait); + hr = aout_stream_Flush(sys->stream); LeaveMTA(); vlc_FromHR(aout, hr); diff --git a/modules/audio_output/mmdevice.h b/modules/audio_output/mmdevice.h index d671f450d34b..2e131ab01f4e 100644 --- a/modules/audio_output/mmdevice.h +++ b/modules/audio_output/mmdevice.h @@ -77,19 +77,9 @@ static inline HRESULT aout_stream_Pause(aout_stream_t *s, bool paused) return (s->pause)(s, paused); } -static inline HRESULT aout_stream_Flush(aout_stream_t *s, bool wait) +static inline HRESULT aout_stream_Flush(aout_stream_t *s) { - if (wait) - { /* Loosy drain emulation */ - vlc_tick_t delay; - - if (SUCCEEDED(aout_stream_TimeGet(s, &delay)) && - delay <= VLC_TICK_FROM_SEC(5)) - Sleep(MS_FROM_VLC_TICK( delay ) + 1); - return S_OK; - } - else - return (s->flush)(s); + return (s->flush)(s); } static inline diff --git a/modules/audio_output/opensles_android.c b/modules/audio_output/opensles_android.c index f0d7360397d6..b1c2a0d98518 100644 --- a/modules/audio_output/opensles_android.c +++ b/modules/audio_output/opensles_android.c @@ -177,30 +177,24 @@ static int TimeGet(audio_output_t* aout, vlc_tick_t* restrict drift) return 0; } -static void Flush(audio_output_t *aout, bool drain) +static void Flush(audio_output_t *aout) { aout_sys_t *sys = aout->sys; - if (drain) { - vlc_tick_t delay; - if (!TimeGet(aout, &delay)) - vlc_tick_sleep(delay); - } else { - vlc_mutex_lock(&sys->lock); - SetPlayState(sys->playerPlay, SL_PLAYSTATE_STOPPED); - Clear(sys->playerBufferQueue); - SetPlayState(sys->playerPlay, SL_PLAYSTATE_PLAYING); - - /* release audio data not yet written to opensles */ - block_ChainRelease(sys->p_buffer_chain); - sys->p_buffer_chain = NULL; - sys->pp_buffer_last = &sys->p_buffer_chain; + vlc_mutex_lock(&sys->lock); + SetPlayState(sys->playerPlay, SL_PLAYSTATE_STOPPED); + Clear(sys->playerBufferQueue); + SetPlayState(sys->playerPlay, SL_PLAYSTATE_PLAYING); - sys->samples = 0; - sys->started = false; + /* release audio data not yet written to opensles */ + block_ChainRelease(sys->p_buffer_chain); + sys->p_buffer_chain = NULL; + sys->pp_buffer_last = &sys->p_buffer_chain; - vlc_mutex_unlock(&sys->lock); - } + sys->samples = 0; + sys->started = false; + + vlc_mutex_unlock(&sys->lock); } static int VolumeSet(audio_output_t *aout, float vol) diff --git a/modules/audio_output/oss.c b/modules/audio_output/oss.c index 5e16255798e2..5bada6857d5f 100644 --- a/modules/audio_output/oss.c +++ b/modules/audio_output/oss.c @@ -90,7 +90,7 @@ vlc_module_end () static int TimeGet (audio_output_t *, vlc_tick_t *); static void Play(audio_output_t *, block_t *, vlc_tick_t); static void Pause (audio_output_t *, bool, vlc_tick_t); -static void Flush (audio_output_t *, bool); +static void Flush (audio_output_t *); static int Start (audio_output_t *aout, audio_sample_format_t *restrict fmt) { @@ -302,15 +302,13 @@ static void Pause (audio_output_t *aout, bool pause, vlc_tick_t date) } /** - * Flushes/drains the audio playback buffer. + * Flushes the audio playback buffer. */ -static void Flush (audio_output_t *aout, bool wait) +static void Flush (audio_output_t *aout) { aout_sys_t *sys = aout->sys; int fd = sys->fd; - if (wait) - return; /* drain is implicit with OSS */ ioctl (fd, SNDCTL_DSP_HALT, NULL); } diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c index a76fd6c65760..cc4af1e8c0d9 100644 --- a/modules/audio_output/pulse.c +++ b/modules/audio_output/pulse.c @@ -533,26 +533,14 @@ static void Pause(audio_output_t *aout, bool paused, vlc_tick_t date) /** * Flush or drain the playback stream */ -static void Flush(audio_output_t *aout, bool wait) +static void Flush(audio_output_t *aout) { aout_sys_t *sys = aout->sys; pa_stream *s = sys->stream; - pa_operation *op; pa_threaded_mainloop_lock(sys->mainloop); - if (wait) - { - op = pa_stream_drain(s, NULL, NULL); - - /* XXX: Loosy drain emulation. - * See #18141: drain callback is never received */ - vlc_tick_t delay; - if (TimeGet(aout, &delay) == 0 && delay <= VLC_TICK_FROM_SEC(5)) - vlc_tick_sleep(delay); - } - else - op = pa_stream_flush(s, NULL, NULL); + pa_operation *op = pa_stream_flush(s, NULL, NULL); if (op != NULL) pa_operation_unref(op); sys->last_date = VLC_TICK_INVALID; @@ -561,6 +549,24 @@ static void Flush(audio_output_t *aout, bool wait) pa_threaded_mainloop_unlock(sys->mainloop); } +static void Drain(audio_output_t *aout) +{ + aout_sys_t *sys = aout->sys; + pa_stream *s = sys->stream; + + pa_threaded_mainloop_lock(sys->mainloop); + pa_operation *op = pa_stream_drain(s, NULL, NULL); + if (op != NULL) + pa_operation_unref(op); + pa_threaded_mainloop_unlock(sys->mainloop); + + /* XXX: Loosy drain emulation. + * See #18141: drain callback is never received */ + vlc_tick_t delay; + if (TimeGet(aout, &delay) == 0 && delay <= VLC_TICK_FROM_SEC(5)) + vlc_tick_sleep(delay); +} + static int VolumeSet(audio_output_t *aout, float vol) { aout_sys_t *sys = aout->sys; @@ -1006,6 +1012,7 @@ static int Open(vlc_object_t *obj) aout->play = Play; aout->pause = Pause; aout->flush = Flush; + aout->drain = Drain; aout->volume_set = VolumeSet; aout->mute_set = MuteSet; aout->device_select = StreamMove; diff --git a/modules/audio_output/sndio.c b/modules/audio_output/sndio.c index 6b28772817ca..642113a48726 100644 --- a/modules/audio_output/sndio.c +++ b/modules/audio_output/sndio.c @@ -45,7 +45,7 @@ vlc_module_end () static int TimeGet (audio_output_t *, vlc_tick_t *); static void Play(audio_output_t *, block_t *, vlc_tick_t); -static void Flush (audio_output_t *, bool); +static void Flush (audio_output_t *); static int VolumeSet (audio_output_t *, float); static int MuteSet (audio_output_t *, bool); static void VolumeChanged (void *, unsigned); @@ -240,7 +240,7 @@ static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date) (void) date; } -static void Flush (audio_output_t *aout, bool wait) +static void Flush (audio_output_t *aout) { aout_sys_t *sys = aout->sys; @@ -248,7 +248,6 @@ static void Flush (audio_output_t *aout, bool wait) sys->started = 0; sys->delay = 0; sio_start (sys->hdl); - (void)wait; } static void VolumeChanged (void *arg, unsigned volume) diff --git a/modules/audio_output/waveout.c b/modules/audio_output/waveout.c index f2ddf42f7aab..736a5f016cad 100644 --- a/modules/audio_output/waveout.c +++ b/modules/audio_output/waveout.c @@ -79,7 +79,8 @@ static void WaveOutClearBuffer( HWAVEOUT, WAVEHDR *); static int ReloadWaveoutDevices( const char *, char ***, char *** ); static uint32_t findDeviceID(char *); static int WaveOutTimeGet(audio_output_t * , vlc_tick_t *); -static void WaveOutFlush( audio_output_t *, bool); +static void WaveOutFlush( audio_output_t *); +static void WaveOutDrain( audio_output_t *); static void WaveOutPause( audio_output_t *, bool, vlc_tick_t); static int WaveoutVolumeSet(audio_output_t * p_aout, float volume); static int WaveoutMuteSet(audio_output_t * p_aout, bool mute); @@ -177,6 +178,7 @@ static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt ) p_aout->play = Play; p_aout->pause = WaveOutPause; p_aout->flush = WaveOutFlush; + p_aout->drain = WaveOutDrain; aout_sys_t *sys = p_aout->sys; @@ -393,7 +395,7 @@ static void Stop( audio_output_t *p_aout ) waveOutReset( p_sys->h_waveout ); /* wait for the frames to be queued in cleaning list */ - WaveOutFlush( p_aout, true ); + WaveOutDrain( p_aout ); WaveOutClean( p_sys ); /* now we can Close the device */ @@ -848,27 +850,27 @@ static int WaveOutTimeGet(audio_output_t * p_aout, vlc_tick_t *delay) return 0; } -static void WaveOutFlush( audio_output_t *p_aout, bool wait) +static void WaveOutFlush( audio_output_t *p_aout) { MMRESULT res; aout_sys_t *sys = p_aout->sys; - if( !wait ) - { - res = waveOutReset( sys->h_waveout ); - sys->i_played_length = 0; - if( res != MMSYSERR_NOERROR ) - msg_Err( p_aout, "waveOutReset failed"); - } - else + res = waveOutReset( sys->h_waveout ); + sys->i_played_length = 0; + if( res != MMSYSERR_NOERROR ) + msg_Err( p_aout, "waveOutReset failed"); +} + +static void WaveOutDrain( audio_output_t *p_aout) +{ + aout_sys_t *sys = p_aout->sys; + + vlc_mutex_lock( &sys->lock ); + while( sys->i_frames ) { - vlc_mutex_lock( &sys->lock ); - while( sys->i_frames ) - { - vlc_cond_wait( &sys->cond, &sys->lock ); - } - vlc_mutex_unlock( &sys->lock ); + vlc_cond_wait( &sys->cond, &sys->lock ); } + vlc_mutex_unlock( &sys->lock ); } static void WaveOutPause( audio_output_t * p_aout, bool pause, vlc_tick_t date) diff --git a/modules/audio_output/winstore.c b/modules/audio_output/winstore.c index 5205c9e5a43f..8ad1fa431f44 100644 --- a/modules/audio_output/winstore.c +++ b/modules/audio_output/winstore.c @@ -178,14 +178,14 @@ static void Pause(audio_output_t *aout, bool paused, vlc_tick_t date) vlc_FromHR(aout, hr); } -static void Flush(audio_output_t *aout, bool wait) +static void Flush(audio_output_t *aout) { aout_sys_t *sys = aout->sys; if( unlikely( sys->client == NULL ) ) return; EnterMTA(); - HRESULT hr = aout_stream_Flush(sys->stream, wait); + HRESULT hr = aout_stream_Flush(sys->stream); LeaveMTA(); vlc_FromHR(aout, hr); diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c index 39f87f1c9ac4..91f9ccf2fe46 100644 --- a/src/audio_output/dec.c +++ b/src/audio_output/dec.c @@ -38,6 +38,18 @@ #include "clock/clock.h" #include "libvlc.h" +static void aout_Drain(audio_output_t *aout) +{ + if (aout->drain) + aout->drain(aout); + else + { + vlc_tick_t delay; + if (aout->time_get(aout, &delay) == 0) + vlc_tick_sleep(delay); + } +} + /** * Creates an audio output */ @@ -481,7 +493,7 @@ void aout_DecChangePause (audio_output_t *aout, bool paused, vlc_tick_t date) if (aout->pause != NULL) aout->pause(aout, paused, date); else if (paused) - aout->flush(aout, false); + aout->flush(aout); } } @@ -507,7 +519,7 @@ void aout_DecFlush(audio_output_t *aout) { aout_FiltersFlush (owner->filters); - aout->flush(aout, false); + aout->flush(aout); vlc_clock_Reset(owner->sync.clock); aout_FiltersResetClock(owner->filters); @@ -539,7 +551,8 @@ void aout_DecDrain(audio_output_t *aout) block_t *block = aout_FiltersDrain (owner->filters); if (block) aout->play(aout, block, vlc_tick_now()); - aout->flush(aout, true); + + aout_Drain(aout); vlc_clock_Reset(owner->sync.clock); aout_FiltersResetClock(owner->filters); -- GitLab