From 5f34372f2e338d1925addf752980202eb2f8fd9b Mon Sep 17 00:00:00 2001 From: Tom Yan Date: Wed, 25 Jul 2018 01:34:18 +0800 Subject: [PATCH] mpv: remove audio-buffer=0.5 hack from mpv.conf The hack should no longer be necessary, as 0.29.0 includes a few commits from me that makes the opensles output driver work more properly. Also include an extra patch that allows the buffer size to either be increased and decreased (and done more properly). --- packages/mpv/mpv.conf | 10 ++- packages/mpv/sles_enqueue.patch | 115 ++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 packages/mpv/sles_enqueue.patch diff --git a/packages/mpv/mpv.conf b/packages/mpv/mpv.conf index b65a18b005..265ced5c75 100644 --- a/packages/mpv/mpv.conf +++ b/packages/mpv/mpv.conf @@ -3,8 +3,14 @@ # Enable OpenSL ES output, since this should work on all Android devices ao=opensles -# Increase audio buffer to help with stuttering with bluetooth devices. See #1127. -audio-buffer=0.5 +# Use the following option to increase or decrease audio buffer +# when necessary / desired. The default is 250ms (0.25s). + +# opensles-buffer-size-in-ms=250 + +# You can also use the generic audio-buffer option (which takes +# value in second instead), but it will only has effect on the +# opensles ao if the above option is explicitly set to 0. # Disable Video Decode and Output. Termux doesn't support video output (with the exception of "tct"). vid=no diff --git a/packages/mpv/sles_enqueue.patch b/packages/mpv/sles_enqueue.patch new file mode 100644 index 0000000000..121961613c --- /dev/null +++ b/packages/mpv/sles_enqueue.patch @@ -0,0 +1,115 @@ +diff --git a/audio/out/ao_opensles.c b/audio/out/ao_opensles.c +index ea48de892e..9f984bed52 100644 +--- a/audio/out/ao_opensles.c ++++ b/audio/out/ao_opensles.c +@@ -35,12 +35,13 @@ struct priv { + SLBufferQueueItf buffer_queue; + SLEngineItf engine; + SLPlayItf play; +- char *buf; +- size_t buffer_size; ++ void *buf; ++ int bytes_per_enqueue; + pthread_mutex_t buffer_lock; + double audio_latency; + +- int cfg_frames_per_buffer; ++ int frames_per_enqueue; ++ int buffer_size_in_ms; + }; + + static const int fmtmap[][2] = { +@@ -71,7 +72,6 @@ static void uninit(struct ao *ao) + + free(p->buf); + p->buf = NULL; +- p->buffer_size = 0; + } + + #undef DESTROY +@@ -81,26 +81,22 @@ static void buffer_callback(SLBufferQueueItf buffer_queue, void *context) + struct ao *ao = context; + struct priv *p = ao->priv; + SLresult res; +- void *data[1]; + double delay; + + pthread_mutex_lock(&p->buffer_lock); + +- data[0] = p->buf; +- delay = 2 * p->buffer_size / (double)ao->bps; ++ delay = 2 * p->frames_per_enqueue / (double)ao->samplerate; + delay += p->audio_latency; +- ao_read_data(ao, data, p->buffer_size / ao->sstride, ++ ao_read_data(ao, &p->buf, p->frames_per_enqueue, + mp_time_us() + 1000000LL * delay); + +- res = (*buffer_queue)->Enqueue(buffer_queue, p->buf, p->buffer_size); ++ res = (*buffer_queue)->Enqueue(buffer_queue, p->buf, p->bytes_per_enqueue); + if (res != SL_RESULT_SUCCESS) + MP_ERR(ao, "Failed to Enqueue: %d\n", res); + + pthread_mutex_unlock(&p->buffer_lock); + } + +-#define DEFAULT_BUFFER_SIZE_MS 250 +- + #define CHK(stmt) \ + { \ + SLresult res = stmt; \ +@@ -155,17 +151,35 @@ static int init(struct ao *ao) + // samplesPerSec is misnamed, actually it's samples per ms + pcm.samplesPerSec = ao->samplerate * 1000; + +- if (p->cfg_frames_per_buffer) +- ao->device_buffer = p->cfg_frames_per_buffer; +- else +- ao->device_buffer = ao->samplerate * DEFAULT_BUFFER_SIZE_MS / 1000; +- p->buffer_size = ao->device_buffer * ao->channels.num * ++ if (p->buffer_size_in_ms) { ++ ao->device_buffer = ao->samplerate * p->buffer_size_in_ms / 1000; ++ // As the purpose of buffer_size_in_ms is to request a specific ++ // soft buffer size: ++ ao->def_buffer = 0; ++ } ++ ++ // But it does not make sense if it is smaller than the enqueue size: ++ if (p->frames_per_enqueue) { ++ ao->device_buffer = MPMAX(ao->device_buffer, p->frames_per_enqueue); ++ } else { ++ if (ao->device_buffer) { ++ p->frames_per_enqueue = ao->device_buffer; ++ } else if (ao->def_buffer) { ++ p->frames_per_enqueue = ao->def_buffer * ao->samplerate; ++ } else { ++ MP_ERR(ao, "Enqueue size is not set and can neither be derived\n"); ++ goto error; ++ } ++ } ++ ++ p->bytes_per_enqueue = p->frames_per_enqueue * ao->channels.num * + af_fmt_to_bytes(ao->format); +- p->buf = calloc(1, p->buffer_size); ++ p->buf = calloc(1, p->bytes_per_enqueue); + if (!p->buf) { + MP_ERR(ao, "Failed to allocate device buffer\n"); + goto error; + } ++ + int r = pthread_mutex_init(&p->buffer_lock, NULL); + if (r) { + MP_ERR(ao, "Failed to initialize the mutex: %d\n", r); +@@ -248,8 +262,12 @@ const struct ao_driver audio_out_opensles = { + .resume = resume, + + .priv_size = sizeof(struct priv), ++ .priv_defaults = &(const struct priv) { ++ .buffer_size_in_ms = 250, ++ }, + .options = (const struct m_option[]) { +- OPT_INTRANGE("frames-per-buffer", cfg_frames_per_buffer, 0, 1, 96000), ++ OPT_INTRANGE("frames-per-enqueue", frames_per_enqueue, 0, 1, 96000), ++ OPT_INTRANGE("buffer-size-in-ms", buffer_size_in_ms, 0, 0, 500), + {0} + }, + .options_prefix = "opensles",