summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao.c2
-rw-r--r--audio/out/ao.h3
-rw-r--r--audio/out/ao_lavc.c10
-rw-r--r--audio/out/internal.h4
-rw-r--r--audio/out/push.c17
5 files changed, 33 insertions, 3 deletions
diff --git a/audio/out/ao.c b/audio/out/ao.c
index 8f6fc8ea3c..8fd24c2439 100644
--- a/audio/out/ao.c
+++ b/audio/out/ao.c
@@ -422,7 +422,7 @@ int ao_query_and_reset_events(struct ao *ao, int events)
return atomic_fetch_and(&ao->events_, ~(unsigned)events) & events;
}
-static void ao_add_events(struct ao *ao, int events)
+void ao_add_events(struct ao *ao, int events)
{
atomic_fetch_or(&ao->events_, events);
ao->wakeup_cb(ao->wakeup_ctx);
diff --git a/audio/out/ao.h b/audio/out/ao.h
index b9df4ebb00..99a3d0fae0 100644
--- a/audio/out/ao.h
+++ b/audio/out/ao.h
@@ -48,6 +48,7 @@ enum aocontrol {
enum {
AO_EVENT_RELOAD = 1,
AO_EVENT_HOTPLUG = 2,
+ AO_EVENT_INITIAL_UNBLOCK = 4,
};
enum {
@@ -104,6 +105,8 @@ void ao_resume(struct ao *ao);
void ao_drain(struct ao *ao);
bool ao_eof_reached(struct ao *ao);
int ao_query_and_reset_events(struct ao *ao, int events);
+void ao_add_events(struct ao *ao, int events);
+void ao_unblock(struct ao *ao);
void ao_request_reload(struct ao *ao);
void ao_hotplug_event(struct ao *ao);
diff --git a/audio/out/ao_lavc.c b/audio/out/ao_lavc.c
index bb86224229..974d9d0b63 100644
--- a/audio/out/ao_lavc.c
+++ b/audio/out/ao_lavc.c
@@ -84,6 +84,13 @@ static void select_format(struct ao *ao, const AVCodec *codec)
}
}
+static void on_ready(void *ptr)
+{
+ struct ao *ao = ptr;
+
+ ao_add_events(ao, AO_EVENT_INITIAL_UNBLOCK);
+}
+
// open & setup audio device
static int init(struct ao *ao)
{
@@ -123,7 +130,7 @@ static int init(struct ao *ao)
encoder->sample_fmt = af_to_avformat(ao->format);
encoder->bits_per_raw_sample = ac->sample_size * 8;
- if (!encoder_init_codec_and_muxer(ac->enc))
+ if (!encoder_init_codec_and_muxer(ac->enc, on_ready, ao))
goto fail;
ac->pcmhack = 0;
@@ -342,6 +349,7 @@ const struct ao_driver audio_out_lavc = {
.encode = true,
.description = "audio encoding using libavcodec",
.name = "lavc",
+ .initially_blocked = true,
.priv_size = sizeof(struct priv),
.init = init,
.uninit = uninit,
diff --git a/audio/out/internal.h b/audio/out/internal.h
index 33e8a8c6a9..bf769d7e1c 100644
--- a/audio/out/internal.h
+++ b/audio/out/internal.h
@@ -130,6 +130,10 @@ struct ao_driver {
const char *name;
// Description shown with --ao=help.
const char *description;
+ // This requires waiting for a AO_EVENT_INITIAL_UNBLOCK event before the
+ // first play() call is done. Encode mode uses this, and push mode
+ // respects it automatically (don't use with pull mode).
+ bool initially_blocked;
// Init the device using ao->format/ao->channels/ao->samplerate. If the
// device doesn't accept these parameters, you can attempt to negotiate
// fallback parameters, and set the ao format fields accordingly.
diff --git a/audio/out/push.c b/audio/out/push.c
index b198afef91..470f521c68 100644
--- a/audio/out/push.c
+++ b/audio/out/push.c
@@ -56,6 +56,7 @@ struct ao_push_state {
bool still_playing;
bool need_wakeup;
bool paused;
+ bool initial_unblocked;
// Whether the current buffer contains the complete audio.
bool final_chunk;
@@ -357,7 +358,8 @@ static void *playthread(void *arg)
mpthread_set_name("ao");
pthread_mutex_lock(&p->lock);
while (!p->terminate) {
- bool playing = !p->paused || ao->stream_silence;
+ bool blocked = ao->driver->initially_blocked && !p->initial_unblocked;
+ bool playing = (!p->paused || ao->stream_silence) && !blocked;
if (playing)
ao_play_data(ao);
@@ -502,6 +504,19 @@ int ao_play_silence(struct ao *ao, int samples)
return ao->driver->play(ao, (void **)p->silence, samples, 0);
}
+void ao_unblock(struct ao *ao)
+{
+ if (ao->api == &ao_api_push) {
+ struct ao_push_state *p = ao->api_priv;
+ pthread_mutex_lock(&p->lock);
+ p->need_wakeup = true;
+ p->initial_unblocked = true;
+ wakeup_playthread(ao);
+ pthread_cond_signal(&p->wakeup);
+ pthread_mutex_unlock(&p->lock);
+ }
+}
+
#ifndef __MINGW32__
#include <poll.h>