mirror of
https://code.videolan.org/videolan/vlc
synced 2024-07-21 07:24:15 +02:00
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.
This commit is contained in:
parent
9bfddfd1eb
commit
2049d40876
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
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;
|
||||
/* 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;
|
||||
|
||||
sys->samples = 0;
|
||||
sys->started = false;
|
||||
sys->samples = 0;
|
||||
sys->started = false;
|
||||
|
||||
vlc_mutex_unlock(&sys->lock);
|
||||
}
|
||||
vlc_mutex_unlock(&sys->lock);
|
||||
}
|
||||
|
||||
static int VolumeSet(audio_output_t *aout, float vol)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
static void WaveOutDrain( audio_output_t *p_aout)
|
||||
{
|
||||
aout_sys_t *sys = p_aout->sys;
|
||||
|
||||
vlc_mutex_lock( &sys->lock );
|
||||
while( sys->i_frames )
|
||||
{
|
||||
res = waveOutReset( sys->h_waveout );
|
||||
sys->i_played_length = 0;
|
||||
if( res != MMSYSERR_NOERROR )
|
||||
msg_Err( p_aout, "waveOutReset failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user