summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>2017-08-28 17:49:16 -0500
committerTanu Kaskinen <tanuk@iki.fi>2017-09-05 13:46:27 +0300
commit15d28f21b4c00bd38a3797461b28bb6f90709aae (patch)
tree07cdfecb21d6f5c2e57c5877cac547f801c42174
parentb4d2443249c2ab31f58ed97a968db41c1fe61b49 (diff)
downloadpulseaudio-15d28f21b4c00bd38a3797461b28bb6f90709aae.tar.gz
sink: force suspend/resume on passthrough transitions
A race condition prevents the AES non-audio bit from being set when enabling IEC61937 passthrough on resume with no sink-input connected (pa_sink_is_passthrough returns false). The non-audio bit should really be set when opening the sink. Force the sink to suspend/resume when actually entering passthrough mode, and likewise force a suspend-resume on leaving passthrough mode. Tested with E-AC3 streams which do need the AES bit set for my Onkyon receiver to detect the format instead of playing it as PCM. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
-rw-r--r--src/pulsecore/sink.c24
-rw-r--r--src/pulsecore/sink.h1
2 files changed, 25 insertions, 0 deletions
diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c
index a8b4cd3da..0cc765144 100644
--- a/src/pulsecore/sink.c
+++ b/src/pulsecore/sink.c
@@ -1626,6 +1626,11 @@ bool pa_sink_is_passthrough(pa_sink *s) {
void pa_sink_enter_passthrough(pa_sink *s) {
pa_cvolume volume;
+ if (s->is_passthrough_set) {
+ pa_log_debug("Sink %s is already in passthrough mode, nothing to do", s->name);
+ return;
+ }
+
/* disable the monitor in passthrough mode */
if (s->monitor_source) {
pa_log_debug("Suspending monitor source %s, because the sink is entering the passthrough mode.", s->monitor_source->name);
@@ -1638,10 +1643,23 @@ void pa_sink_enter_passthrough(pa_sink *s) {
pa_cvolume_set(&volume, s->sample_spec.channels, PA_MIN(s->base_volume, PA_VOLUME_NORM));
pa_sink_set_volume(s, &volume, true, false);
+
+ pa_log_debug("Suspending/Restarting sink %s to enter passthrough mode", s->name);
+
+ /* force sink to be resumed in passthrough mode */
+ pa_sink_suspend(s, true, PA_SUSPEND_INTERNAL);
+ s->is_passthrough_set = true;
+ pa_sink_suspend(s, false, PA_SUSPEND_INTERNAL);
}
/* Called from main context */
void pa_sink_leave_passthrough(pa_sink *s) {
+
+ if (!s->is_passthrough_set) {
+ pa_log_debug("Sink %s is not in passthrough mode, nothing to do", s->name);
+ return;
+ }
+
/* Unsuspend monitor */
if (s->monitor_source) {
pa_log_debug("Resuming monitor source %s, because the sink is leaving the passthrough mode.", s->monitor_source->name);
@@ -1653,6 +1671,12 @@ void pa_sink_leave_passthrough(pa_sink *s) {
pa_cvolume_init(&s->saved_volume);
s->saved_save_volume = false;
+
+ /* force sink to be resumed in non-passthrough mode */
+ pa_sink_suspend(s, true, PA_SUSPEND_INTERNAL);
+ s->is_passthrough_set = false;
+ pa_sink_suspend(s, false, PA_SUSPEND_INTERNAL);
+
}
/* Called from main context. */
diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h
index 0e79cf369..7deafdd85 100644
--- a/src/pulsecore/sink.h
+++ b/src/pulsecore/sink.h
@@ -108,6 +108,7 @@ struct pa_sink {
/* Saved volume state while we're in passthrough mode */
pa_cvolume saved_volume;
bool saved_save_volume:1;
+ bool is_passthrough_set:1;
pa_asyncmsgq *asyncmsgq;