From b6fa6aa4ee9fc1c58d7ca43033d77663f2ceda83 Mon Sep 17 00:00:00 2001 From: Tom Yan Date: Wed, 25 Jul 2018 20:00:01 +0800 Subject: [PATCH] libpulseaudio: support suspend on idle Turns out it's pretty easy to implement. Now the buffer queue will stop requesting for data once the sink is suspended on idle. No more power wasted. Note that it is natural that there would be a bit of extra delay when resume playback after the sink is suspended. In case it is wanted to be avoided, make sure the module-suspend-on-idle is not loaded. --- packages/libpulseaudio/module-sles-sink.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/packages/libpulseaudio/module-sles-sink.c b/packages/libpulseaudio/module-sles-sink.c index b4295b3890..ed26e2fabc 100644 --- a/packages/libpulseaudio/module-sles-sink.c +++ b/packages/libpulseaudio/module-sles-sink.c @@ -261,6 +261,20 @@ finish: pa_log_debug("Thread shutting down"); } +static int state_func(pa_sink *s, pa_sink_state_t state, pa_suspend_cause_t suspend_cause) { + struct userdata *u = s->userdata; + int r = 0; + + if (PA_SINK_IS_OPENED(s->state) && state == PA_SINK_SUSPENDED) { + r = (*u->bqPlayerPlay)->SetPlayState(u->bqPlayerPlay, SL_PLAYSTATE_STOPPED); + //pa_log_debug("Suspended on idle\n"); + } else if (s->state == PA_SINK_SUSPENDED && PA_SINK_IS_OPENED(state)) { + r = (*u->bqPlayerPlay)->SetPlayState(u->bqPlayerPlay, SL_PLAYSTATE_PLAYING); + //pa_log_debug("Resume from suspension\n"); + } + return r; +} + int pa__init(pa_module*m) { struct userdata *u = NULL; pa_sample_spec ss; @@ -320,6 +334,7 @@ int pa__init(pa_module*m) { } u->sink->parent.process_msg = pa_sink_process_msg; + u->sink->set_state_in_main_thread = state_func; u->sink->userdata = u; pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);