[vlc-devel] [RFC PATCH 1/2] aout: make the play() API non blocking
Thomas Guillem
thomas at gllm.fr
Tue Mar 12 18:18:42 CET 2019
TODO: implement it on all modules.
---
include/vlc_aout.h | 33 +++++++++++++++++++++++--
modules/audio_output/adummy.c | 3 ++-
modules/audio_output/alsa.c | 6 ++---
modules/audio_output/amem.c | 3 ++-
modules/audio_output/audiotrack.c | 6 ++---
modules/audio_output/audiounit_ios.m | 7 ++++--
modules/audio_output/coreaudio_common.c | 7 +++---
modules/audio_output/coreaudio_common.h | 2 +-
modules/audio_output/directsound.c | 21 ++++++++++------
modules/audio_output/file.c | 5 ++--
modules/audio_output/jack.c | 5 ++--
modules/audio_output/kai.c | 5 ++--
modules/audio_output/mmdevice.c | 5 ++--
modules/audio_output/mmdevice.h | 5 ++--
modules/audio_output/opensles_android.c | 3 ++-
modules/audio_output/oss.c | 5 ++--
modules/audio_output/pulse.c | 3 ++-
modules/audio_output/sndio.c | 5 ++--
modules/audio_output/wasapi.c | 5 ++--
modules/audio_output/waveout.c | 7 +++---
modules/audio_output/winstore.c | 6 +++--
src/audio_output/aout_internal.h | 1 +
src/audio_output/dec.c | 27 +++++++++++++++++++-
src/audio_output/output.c | 1 +
24 files changed, 128 insertions(+), 48 deletions(-)
diff --git a/include/vlc_aout.h b/include/vlc_aout.h
index 4441a42a82..770c2b7025 100644
--- a/include/vlc_aout.h
+++ b/include/vlc_aout.h
@@ -112,6 +112,7 @@
#include <vlc_block.h>
struct vlc_audio_output_events {
+ void (*more_data_report)(audio_output_t *);
void (*drained_report)(audio_output_t *);
void (*timing_report)(audio_output_t *, vlc_tick_t system_now, vlc_tick_t pts);
void (*volume_report)(audio_output_t *, float);
@@ -123,6 +124,7 @@ struct vlc_audio_output_events {
int (*gain_request)(audio_output_t *, float);
};
+
/** Audio output object
*
* The audio output object is the abstraction for rendering decoded
@@ -187,11 +189,27 @@ struct audio_output
* \note This callback cannot be called in stopped state.
*/
- void (*play)(audio_output_t *, block_t *block, vlc_tick_t date);
+#define AOUT_PLAY_WAIT_REPORT (-1)
+#define AOUT_PLAY_DONE (0)
+ vlc_tick_t (*play)(audio_output_t *, block_t *block, vlc_tick_t date);
/**< Queues a block of samples for playback (mandatory, cannot be NULL).
*
- * \param block block of audio samples
+ * As the play implementation must be non-blocking, the implementation is
+ * allowed to return prematurely if is internal buffer is full. In that
+ * case, the implementation must modify the block offset since the same
+ * block will be given in a successive call and return one of the 3
+ * possibles values:
+ * AOUT_PLAY_DONE: the block is fully written
+ * AOUT_PLAY_WAIT_REPORT: aout_MoreDataReport() must be called
+ * asynchronously from the implementation to notify the core that new data
+ * can be written.
+ * > 0: The core will wait for that positive delay before calling play()
+ * again.
+ *
+ * \param block block of audio samples, must be released when returning
+ * AOUT_PLAY_DONE
* \param date intended system time to render the first sample
+ * \return AOUT_PLAY_WAIT_REPORT, AOUT_PLAY_DONE or a positive delay
*
* \note This callback cannot be called in stopped state.
*/
@@ -460,6 +478,17 @@ static inline void aout_DrainedReport(audio_output_t *aout)
aout->events->drained_report(aout);
}
+/**
+ * Report that more data can be played
+ *
+ * This function can only be called after aout->play() returned
+ * AOUT_PLAY_WAIT_REPORT.
+ */
+static inline void aout_MoreDataReport(audio_output_t *aout)
+{
+ aout->events->more_data_report(aout);
+}
+
/**
* Default implementation for audio_output_t.time_get
*/
diff --git a/modules/audio_output/adummy.c b/modules/audio_output/adummy.c
index e81a9cb0c8..c410a295f4 100644
--- a/modules/audio_output/adummy.c
+++ b/modules/audio_output/adummy.c
@@ -41,10 +41,11 @@ vlc_module_end ()
#define A52_FRAME_NB 1536
-static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
+static vlc_tick_t Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
{
block_Release( block );
(void) aout; (void) date;
+ return AOUT_PLAY_DONE;
}
static void Pause(audio_output_t *aout, bool paused, vlc_tick_t date)
diff --git a/modules/audio_output/alsa.c b/modules/audio_output/alsa.c
index cdbfd44d41..5d30d05af9 100644
--- a/modules/audio_output/alsa.c
+++ b/modules/audio_output/alsa.c
@@ -291,7 +291,7 @@ out:
#endif
static int TimeGet (audio_output_t *aout, vlc_tick_t *);
-static void Play(audio_output_t *, block_t *, vlc_tick_t);
+static vlc_tick_t 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 *);
@@ -647,7 +647,7 @@ static int TimeGet (audio_output_t *aout, vlc_tick_t *restrict delay)
/**
* Queues one audio buffer to the hardware.
*/
-static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
+static vlc_tick_t Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
{
aout_sys_t *sys = aout->sys;
@@ -687,7 +687,7 @@ static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
}
}
block_Release (block);
- (void) date;
+ return AOUT_PLAY_DONE;
}
/**
diff --git a/modules/audio_output/amem.c b/modules/audio_output/amem.c
index f859a4b10a..036818769d 100644
--- a/modules/audio_output/amem.c
+++ b/modules/audio_output/amem.c
@@ -81,7 +81,7 @@ typedef struct
vlc_mutex_t lock;
} aout_sys_t;
-static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
+static vlc_tick_t Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
{
aout_sys_t *sys = aout->sys;
@@ -89,6 +89,7 @@ static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
sys->play(sys->opaque, block->p_buffer, block->i_nb_samples, date);
vlc_mutex_unlock(&sys->lock);
block_Release (block);
+ return AOUT_PLAY_DONE;
}
static void Pause (audio_output_t *aout, bool paused, vlc_tick_t date)
diff --git a/modules/audio_output/audiotrack.c b/modules/audio_output/audiotrack.c
index 1d39852343..0bb5e3e9fd 100644
--- a/modules/audio_output/audiotrack.c
+++ b/modules/audio_output/audiotrack.c
@@ -1923,7 +1923,7 @@ ConvertFromIEC61937( audio_output_t *p_aout, block_t *p_buffer )
return 0;
}
-static void
+static vlc_tick_t
Play( audio_output_t *p_aout, block_t *p_buffer, vlc_tick_t i_date )
{
JNIEnv *env = NULL;
@@ -1934,7 +1934,7 @@ Play( audio_output_t *p_aout, block_t *p_buffer, vlc_tick_t i_date )
&& ConvertFromIEC61937( p_aout, p_buffer ) != 0 )
{
block_Release(p_buffer);
- return;
+ return AOUT_PLAY_DONE;
}
vlc_mutex_lock( &p_sys->lock );
@@ -2007,7 +2007,7 @@ Play( audio_output_t *p_aout, block_t *p_buffer, vlc_tick_t i_date )
bailout:
vlc_mutex_unlock( &p_sys->lock );
block_Release( p_buffer );
- (void) i_date;
+ return AOUT_PLAY_DONE;
}
static void
diff --git a/modules/audio_output/audiounit_ios.m b/modules/audio_output/audiounit_ios.m
index ea555c0c14..d8590a456e 100644
--- a/modules/audio_output/audiounit_ios.m
+++ b/modules/audio_output/audiounit_ios.m
@@ -428,15 +428,18 @@ MuteSet(audio_output_t *p_aout, bool mute)
return VLC_SUCCESS;
}
-static void
+static vlc_tick_t
Play(audio_output_t * p_aout, block_t * p_block, vlc_tick_t date)
{
aout_sys_t * p_sys = p_aout->sys;
if (p_sys->b_muted)
+ {
block_Release(p_block);
+ return AOUT_PLAY_DONE;
+ }
else
- ca_Play(p_aout, p_block, date);
+ return ca_Play(p_aout, p_block, date);
}
#pragma mark initialization
diff --git a/modules/audio_output/coreaudio_common.c b/modules/audio_output/coreaudio_common.c
index 4a714f5411..7bcccd6c2c 100644
--- a/modules/audio_output/coreaudio_common.c
+++ b/modules/audio_output/coreaudio_common.c
@@ -263,7 +263,7 @@ ca_Pause(audio_output_t * p_aout, bool pause, vlc_tick_t date)
lock_unlock(p_sys);
}
-void
+vlc_tick_t
ca_Play(audio_output_t * p_aout, block_t * p_block, vlc_tick_t date)
{
struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys;
@@ -290,7 +290,7 @@ ca_Play(audio_output_t * p_aout, block_t * p_block, vlc_tick_t date)
if (!p_new)
{
block_Release(p_block);
- return;
+ return AOUT_PLAY_DONE;
}
memcpy(p_new->p_buffer, p_block->p_buffer, i_avalaible_bytes);
@@ -307,7 +307,7 @@ ca_Play(audio_output_t * p_aout, block_t * p_block, vlc_tick_t date)
{
lock_unlock(p_sys);
block_Release(p_block);
- return;
+ return AOUT_PLAY_DONE;
}
const vlc_tick_t i_frame_us =
@@ -334,6 +334,7 @@ ca_Play(audio_output_t * p_aout, block_t * p_block, vlc_tick_t date)
if (i_underrun_size > 0)
msg_Warn(p_aout, "underrun of %zu bytes", i_underrun_size);
+ return AOUT_PLAY_DONE;
(void) date;
}
diff --git a/modules/audio_output/coreaudio_common.h b/modules/audio_output/coreaudio_common.h
index a860a9aa51..248c1dee91 100644
--- a/modules/audio_output/coreaudio_common.h
+++ b/modules/audio_output/coreaudio_common.h
@@ -93,7 +93,7 @@ void ca_Flush(audio_output_t *p_aout);
void ca_Pause(audio_output_t * p_aout, bool pause, vlc_tick_t date);
-void ca_Play(audio_output_t * p_aout, block_t * p_block, vlc_tick_t date);
+vlc_tick_t ca_Play(audio_output_t * p_aout, block_t * p_block, vlc_tick_t date);
int ca_Initialize(audio_output_t *p_aout, const audio_sample_format_t *fmt,
vlc_tick_t i_dev_latency_us);
diff --git a/modules/audio_output/directsound.c b/modules/audio_output/directsound.c
index f93237a93a..3f0dbc8c16 100644
--- a/modules/audio_output/directsound.c
+++ b/modules/audio_output/directsound.c
@@ -267,13 +267,16 @@ static HRESULT FillBuffer( vlc_object_t *obj, aout_stream_sys_t *p_sys,
return DS_OK;
}
-static HRESULT Play( vlc_object_t *obj, aout_stream_sys_t *sys,
- block_t *p_buffer )
+static vlc_tick_t Play( vlc_object_t *obj, aout_stream_sys_t *sys,
+ block_t *p_buffer, HRESULT *hr )
{
HRESULT dsresult;
dsresult = FillBuffer( obj, sys, p_buffer );
if( dsresult != DS_OK )
- return dsresult;
+ {
+ *hr = dsresult;
+ return AOUT_PLAY_DONE;
+ }
/* start playing the buffer */
dsresult = IDirectSoundBuffer_Play( sys->p_dsbuffer, 0, 0,
@@ -294,18 +297,20 @@ static HRESULT Play( vlc_object_t *obj, aout_stream_sys_t *sys,
vlc_mutex_unlock( &sys->lock );
}
- return dsresult;
+ *hr = dsresult;
+ return AOUT_PLAY_DONE;
}
-static HRESULT StreamPlay( aout_stream_t *s, block_t *block )
+static vlc_tick_t StreamPlay( aout_stream_t *s, block_t *block, HRESULT *hr )
{
- return Play( VLC_OBJECT(s), s->sys, block );
+ return Play( VLC_OBJECT(s), s->sys, block, hr );
}
-static void OutputPlay( audio_output_t *aout, block_t *block, vlc_tick_t date )
+static vlc_tick_t OutputPlay( audio_output_t *aout, block_t *block, vlc_tick_t date )
{
aout_sys_t *sys = aout->sys;
- Play( VLC_OBJECT(aout), &sys->s, block );
+ HRESULT ignored;
+ return Play( VLC_OBJECT(aout), &sys->s, block, &ignored );
(void) date;
}
diff --git a/modules/audio_output/file.c b/modules/audio_output/file.c
index 906b228548..28c1866895 100644
--- a/modules/audio_output/file.c
+++ b/modules/audio_output/file.c
@@ -73,7 +73,7 @@ static const int pi_channels_maps[CHANNELS_MAX+1] =
* Local prototypes.
*****************************************************************************/
static int Open ( vlc_object_t * );
-static void Play ( audio_output_t *, block_t *, vlc_tick_t );
+static vlc_tick_t 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 * );
@@ -315,7 +315,7 @@ static void Stop( audio_output_t *p_aout )
/*****************************************************************************
* Play: pretend to play a sound
*****************************************************************************/
-static void Play( audio_output_t * p_aout, block_t *p_buffer, vlc_tick_t date )
+static vlc_tick_t Play( audio_output_t * p_aout, block_t *p_buffer, vlc_tick_t date )
{
aout_sys_t *p_sys = p_aout->sys;
if( fwrite( p_buffer->p_buffer, p_buffer->i_buffer, 1,
@@ -331,6 +331,7 @@ static void Play( audio_output_t * p_aout, block_t *p_buffer, vlc_tick_t date )
}
block_Release( p_buffer );
+ return AOUT_PLAY_DONE;
(void) date;
}
diff --git a/modules/audio_output/jack.c b/modules/audio_output/jack.c
index d21150f2a4..c5daab6fe5 100644
--- a/modules/audio_output/jack.c
+++ b/modules/audio_output/jack.c
@@ -69,7 +69,7 @@ typedef struct
*****************************************************************************/
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 vlc_tick_t 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 );
static int TimeGet ( audio_output_t *, vlc_tick_t * );
@@ -282,7 +282,7 @@ error_out:
return status;
}
-static void Play(audio_output_t * p_aout, block_t * p_block, vlc_tick_t date)
+static vlc_tick_t Play(audio_output_t * p_aout, block_t * p_block, vlc_tick_t date)
{
aout_sys_t *p_sys = p_aout->sys;
jack_ringbuffer_t *rb = p_sys->p_jack_ringbuffer;
@@ -309,6 +309,7 @@ static void Play(audio_output_t * p_aout, block_t * p_block, vlc_tick_t date)
}
block_Release(p_block);
+ return AOUT_PLAY_DONE;
(void) date;
}
diff --git a/modules/audio_output/kai.c b/modules/audio_output/kai.c
index dd75e367d8..aecc95e42d 100644
--- a/modules/audio_output/kai.c
+++ b/modules/audio_output/kai.c
@@ -72,7 +72,7 @@ typedef struct
*****************************************************************************/
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 vlc_tick_t 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 * );
static int TimeGet ( audio_output_t *, vlc_tick_t *restrict );
@@ -233,7 +233,7 @@ exit_kai_done :
/*****************************************************************************
* Play: play a sound samples buffer
*****************************************************************************/
-static void Play(audio_output_t *p_aout, block_t *block, vlc_tick_t date)
+static vlc_tick_t Play(audio_output_t *p_aout, block_t *block, vlc_tick_t date)
{
aout_sys_t *p_sys = p_aout->sys;
@@ -242,6 +242,7 @@ static void Play(audio_output_t *p_aout, block_t *block, vlc_tick_t date)
WriteBuffer( p_aout, block->p_buffer, block->i_buffer );
block_Release( block );
+ return AOUT_PLAY_DONE;
(void) date;
}
diff --git a/modules/audio_output/mmdevice.c b/modules/audio_output/mmdevice.c
index 4c79cabf1d..abffe3ddb5 100644
--- a/modules/audio_output/mmdevice.c
+++ b/modules/audio_output/mmdevice.c
@@ -136,16 +136,17 @@ static int TimeGet(audio_output_t *aout, vlc_tick_t *restrict delay)
return SUCCEEDED(hr) ? 0 : -1;
}
-static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
+static vlc_tick_t Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
{
aout_sys_t *sys = aout->sys;
HRESULT hr;
EnterMTA();
- hr = aout_stream_Play(sys->stream, block);
+ vlc_tick_t wait = aout_stream_Play(sys->stream, block, &hr);
LeaveMTA();
vlc_FromHR(aout, hr);
+ return wait;
(void) date;
}
diff --git a/modules/audio_output/mmdevice.h b/modules/audio_output/mmdevice.h
index 2e131ab01f..5b2e610ea3 100644
--- a/modules/audio_output/mmdevice.h
+++ b/modules/audio_output/mmdevice.h
@@ -67,9 +67,10 @@ static inline HRESULT aout_stream_TimeGet(aout_stream_t *s, vlc_tick_t *delay)
return (s->time_get)(s, delay);
}
-static inline HRESULT aout_stream_Play(aout_stream_t *s, block_t *block)
+static inline vlc_tick_t aout_stream_Play(aout_stream_t *s, block_t *block,
+ HRESULT *hr)
{
- return (s->play)(s, block);
+ return (s->play)(s, block, hr);
}
static inline HRESULT aout_stream_Pause(aout_stream_t *s, bool paused)
diff --git a/modules/audio_output/opensles_android.c b/modules/audio_output/opensles_android.c
index b1c2a0d985..64747c13e1 100644
--- a/modules/audio_output/opensles_android.c
+++ b/modules/audio_output/opensles_android.c
@@ -317,7 +317,7 @@ static int WriteBuffer(audio_output_t *aout)
/*****************************************************************************
* Play: play a sound
*****************************************************************************/
-static void Play(audio_output_t *aout, block_t *p_buffer, vlc_tick_t date)
+static vlc_tick_t Play(audio_output_t *aout, block_t *p_buffer, vlc_tick_t date)
{
aout_sys_t *sys = aout->sys;
@@ -334,6 +334,7 @@ static void Play(audio_output_t *aout, block_t *p_buffer, vlc_tick_t date)
;
vlc_mutex_unlock(&sys->lock);
+ return AOUT_PLAY_DONE;
(void) date;
}
diff --git a/modules/audio_output/oss.c b/modules/audio_output/oss.c
index 5bada6857d..c5399c7747 100644
--- a/modules/audio_output/oss.c
+++ b/modules/audio_output/oss.c
@@ -88,7 +88,7 @@ vlc_module_begin ()
vlc_module_end ()
static int TimeGet (audio_output_t *, vlc_tick_t *);
-static void Play(audio_output_t *, block_t *, vlc_tick_t);
+static vlc_tick_t 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 *);
@@ -269,7 +269,7 @@ static int TimeGet (audio_output_t *aout, vlc_tick_t *restrict pts)
/**
* Queues one audio buffer to the hardware.
*/
-static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
+static vlc_tick_t Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
{
aout_sys_t *sys = aout->sys;
int fd = sys->fd;
@@ -286,6 +286,7 @@ static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
msg_Err (aout, "cannot write samples: %s", vlc_strerror_c(errno));
}
block_Release (block);
+ return AOUT_PLAY_DONE;
(void) date;
}
diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c
index 4ec20cfdd5..f51d521952 100644
--- a/modules/audio_output/pulse.c
+++ b/modules/audio_output/pulse.c
@@ -461,7 +461,7 @@ static int TimeGet(audio_output_t *aout, vlc_tick_t *restrict delay)
/**
* Queue one audio frame to the playback stream
*/
-static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
+static vlc_tick_t Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
{
aout_sys_t *sys = aout->sys;
pa_stream *s = sys->stream;
@@ -505,6 +505,7 @@ static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
block_Release(block);
pa_threaded_mainloop_unlock(sys->mainloop);
+ return AOUT_PLAY_DONE;
}
/**
diff --git a/modules/audio_output/sndio.c b/modules/audio_output/sndio.c
index 642113a487..26b8c989ec 100644
--- a/modules/audio_output/sndio.c
+++ b/modules/audio_output/sndio.c
@@ -44,7 +44,7 @@ vlc_module_begin ()
vlc_module_end ()
static int TimeGet (audio_output_t *, vlc_tick_t *);
-static void Play(audio_output_t *, block_t *, vlc_tick_t);
+static vlc_tick_t Play(audio_output_t *, block_t *, vlc_tick_t);
static void Flush (audio_output_t *);
static int VolumeSet (audio_output_t *, float);
static int MuteSet (audio_output_t *, bool);
@@ -230,13 +230,14 @@ static int TimeGet (audio_output_t *aout, vlc_tick_t *restrict delay)
return 0;
}
-static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
+static vlc_tick_t Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
{
aout_sys_t *sys = aout->sys;
sio_write (sys->hdl, block->p_buffer, block->i_buffer);
sys->delay += block->i_nb_samples;
block_Release (block);
+ return AOUT_PLAY_DONE;
(void) date;
}
diff --git a/modules/audio_output/wasapi.c b/modules/audio_output/wasapi.c
index 74d5239bd7..470868b9ec 100644
--- a/modules/audio_output/wasapi.c
+++ b/modules/audio_output/wasapi.c
@@ -140,7 +140,7 @@ static HRESULT TimeGet(aout_stream_t *s, vlc_tick_t *restrict delay)
return hr;
}
-static HRESULT Play(aout_stream_t *s, block_t *block)
+static vlc_tick_t Play(aout_stream_t *s, block_t *block, HRESULT *phr)
{
aout_stream_sys_t *sys = s->sys;
void *pv;
@@ -206,7 +206,8 @@ static HRESULT Play(aout_stream_t *s, block_t *block)
out:
block_Release(block);
- return hr;
+ *phr = hr;
+ return AOUT_PLAY_DONE;
}
static HRESULT Pause(aout_stream_t *s, bool paused)
diff --git a/modules/audio_output/waveout.c b/modules/audio_output/waveout.c
index 495fe519bc..8331f31231 100644
--- a/modules/audio_output/waveout.c
+++ b/modules/audio_output/waveout.c
@@ -48,7 +48,7 @@
*****************************************************************************/
static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * );
-static void Play ( audio_output_t *, block_t *, vlc_tick_t );
+static vlc_tick_t Play ( audio_output_t *, block_t *, vlc_tick_t );
/*****************************************************************************
* notification_thread_t: waveOut event thread
@@ -347,7 +347,7 @@ static int Start( audio_output_t *p_aout, audio_sample_format_t *restrict fmt )
* This doesn't actually play the buffer. This just stores the buffer so it
* can be played by the callback thread.
*****************************************************************************/
-static void Play( audio_output_t *p_aout, block_t *block, vlc_tick_t date )
+static vlc_tick_t Play( audio_output_t *p_aout, block_t *block, vlc_tick_t date )
{
aout_sys_t *sys = p_aout->sys;
@@ -358,7 +358,7 @@ static void Play( audio_output_t *p_aout, block_t *block, vlc_tick_t date )
msg_Err(p_aout, "Couldn't alloc WAVEHDR");
if( block )
block_Release( block );
- return;
+ return AOUT_PLAY_DONE;
}
p_waveheader->p_next = NULL;
@@ -384,6 +384,7 @@ static void Play( audio_output_t *p_aout, block_t *block, vlc_tick_t date )
sys->i_frames++;
sys->i_played_length += block->i_length;
vlc_mutex_unlock( &sys->lock );
+ return AOUT_PLAY_DONE;
(void) date;
}
diff --git a/modules/audio_output/winstore.c b/modules/audio_output/winstore.c
index 8ad1fa431f..edabb52400 100644
--- a/modules/audio_output/winstore.c
+++ b/modules/audio_output/winstore.c
@@ -150,17 +150,19 @@ static int TimeGet(audio_output_t *aout, vlc_tick_t *restrict delay)
return SUCCEEDED(hr) ? 0 : -1;
}
-static void Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
+static vlc_tick_t Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
{
aout_sys_t *sys = aout->sys;
if( unlikely( sys->client == NULL ) )
return;
EnterMTA();
- HRESULT hr = aout_stream_Play(sys->stream, block);
+ HRESULT hr;
+ vlc_tick_t wait = aout_stream_Play(sys->stream, block, &hr);
LeaveMTA();
vlc_FromHR(aout, hr);
+ return wait;
(void) date;
}
diff --git a/src/audio_output/aout_internal.h b/src/audio_output/aout_internal.h
index 5e37e70f72..2905b46faf 100644
--- a/src/audio_output/aout_internal.h
+++ b/src/audio_output/aout_internal.h
@@ -152,6 +152,7 @@ void aout_RequestRestart (audio_output_t *, unsigned);
void aout_RequestRetiming(audio_output_t *aout, vlc_tick_t system_ts,
vlc_tick_t audio_ts);
void aout_Drained(audio_output_t *);
+void aout_MoreData(audio_output_t *);
static inline void aout_InputRequestRestart(audio_output_t *aout)
{
diff --git a/src/audio_output/dec.c b/src/audio_output/dec.c
index 4c24ea307e..88559873ea 100644
--- a/src/audio_output/dec.c
+++ b/src/audio_output/dec.c
@@ -209,9 +209,34 @@ static void aout_StopResampling (audio_output_t *aout)
aout_FiltersAdjustResampling (owner->filters, 0);
}
+void aout_MoreData(audio_output_t *aout)
+{
+ aout_owner_t *owner = aout_owner (aout);
+
+ assert(atomic_fetch_add(&owner->report_count, 1) == 0);
+ vlc_sem_post(&owner->report_sem);
+}
+
static void aout_Play(audio_output_t *aout, block_t *block, vlc_tick_t date)
{
- aout->play(aout, block, date);
+ aout_owner_t *owner = aout_owner (aout);
+ for (;;)
+ {
+ vlc_tick_t status = aout->play(aout, block, date);
+ switch (status)
+ {
+ case AOUT_PLAY_WAIT_REPORT:
+ vlc_sem_wait(&owner->report_sem);
+ assert(atomic_fetch_sub(&owner->report_count, 1) == 1);
+ break;
+ case AOUT_PLAY_DONE:
+ return;
+ default:
+ assert(status > 0);
+ vlc_tick_sleep(status);
+ break;
+ }
+ }
}
static void aout_DecSynchronize(audio_output_t *aout, vlc_tick_t system_now,
diff --git a/src/audio_output/output.c b/src/audio_output/output.c
index 6bb54a2012..717bf6b8e5 100644
--- a/src/audio_output/output.c
+++ b/src/audio_output/output.c
@@ -165,6 +165,7 @@ static int aout_GainNotify (audio_output_t *aout, float gain)
}
static const struct vlc_audio_output_events aout_events = {
+ aout_MoreData,
aout_Drained,
aout_TimingNotify,
aout_VolumeNotify,
--
2.20.1
More information about the vlc-devel
mailing list