]> code.delx.au - pulseaudio/commitdiff
core: Suspend monitor when a sink enters passthrough mode
authorArun Raghavan <arun.raghavan@collabora.co.uk>
Thu, 3 Mar 2011 13:32:45 +0000 (19:02 +0530)
committerArun Raghavan <arun.raghavan@collabora.co.uk>
Mon, 2 May 2011 06:25:38 +0000 (11:55 +0530)
In most cases it is expected that clients cannot consume compressed
data from monitor sources, so we suspend the monitor source when the
sink goes into passthrough mode.

Eventually, when the extended API includes client notifications for
changed formats, we should emit a notification on the monitor so that
clients can decide what they want to do when this happens (disconnect or
consume the data anyway).

src/pulsecore/core.h
src/pulsecore/sink-input.c
src/pulsecore/source.c

index 358b98d7e8a211cfc3cc91c9062dcf9a850d3242..6b25fbad0d4e7e48914a571b93a56ebfc58e2191 100644 (file)
@@ -35,6 +35,7 @@ typedef enum pa_suspend_cause {
     PA_SUSPEND_APPLICATION = 2,  /* Used by the device reservation logic */
     PA_SUSPEND_IDLE = 4,         /* Used by module-suspend-on-idle */
     PA_SUSPEND_SESSION = 8,      /* Used by module-hal for mark inactive sessions */
+    PA_SUSPEND_PASSTHROUGH = 16, /* Used to suspend monitor sources when the sink is in passthrough mode */
     PA_SUSPEND_ALL = 0xFFFF      /* Magic cause that can be used to resume forcibly */
 } pa_suspend_cause_t;
 
index 6e1b81f44bffd3cfb502f94391df1ed2018c7c9d..d77eb2cae4678632ee05b372a542c305e15d589f 100644 (file)
@@ -599,6 +599,10 @@ void pa_sink_input_unlink(pa_sink_input *i) {
 
         if (i->sink->asyncmsgq)
             pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_REMOVE_INPUT, i, 0, NULL) == 0);
+
+        /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
+        if (!pa_format_info_is_pcm(i->format) && i->sink->monitor_source)
+            pa_source_suspend(i->sink->monitor_source, FALSE, PA_SUSPEND_PASSTHROUGH);
     }
 
     reset_callbacks(i);
@@ -689,6 +693,10 @@ void pa_sink_input_put(pa_sink_input *i) {
         set_real_ratio(i, &i->volume);
     }
 
+    /* If we're entering passthrough mode, disable the monitor */
+    if (!pa_format_info_is_pcm(i->format) && i->sink->monitor_source)
+        pa_source_suspend(i->sink->monitor_source, TRUE, PA_SUSPEND_PASSTHROUGH);
+
     i->thread_info.soft_volume = i->soft_volume;
     i->thread_info.muted = i->muted;
 
@@ -1380,6 +1388,10 @@ int pa_sink_input_start_move(pa_sink_input *i) {
 
     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_START_MOVE, i, 0, NULL) == 0);
 
+    /* We suspend the monitor if there was a passthrough sink, unsuspend now if required */
+    if (!pa_format_info_is_pcm(i->format) && i->sink->monitor_source)
+        pa_source_suspend(i->sink->monitor_source, FALSE, PA_SUSPEND_PASSTHROUGH);
+
     pa_sink_update_status(i->sink);
     pa_cvolume_remap(&i->volume_factor_sink, &i->sink->channel_map, &i->channel_map);
     i->sink = NULL;
@@ -1621,6 +1633,10 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
 
     pa_assert_se(pa_asyncmsgq_send(i->sink->asyncmsgq, PA_MSGOBJECT(i->sink), PA_SINK_MESSAGE_FINISH_MOVE, i, 0, NULL) == 0);
 
+    /* If we're entering passthrough mode, disable the monitor */
+    if (!pa_format_info_is_pcm(i->format) && i->sink->monitor_source)
+        pa_source_suspend(i->sink->monitor_source, TRUE, PA_SUSPEND_PASSTHROUGH);
+
     pa_log_debug("Successfully moved sink input %i to %s.", i->index, dest->name);
 
     /* Notify everyone */
index 92fb80e0995bdd3ffd155af1f0703800f680aaeb..15a5b8d9c9cb828955a9eaab9fc9bd4288b5d373 100644 (file)
@@ -514,7 +514,7 @@ int pa_source_suspend(pa_source *s, pa_bool_t suspend, pa_suspend_cause_t cause)
     pa_assert(PA_SOURCE_IS_LINKED(s->state));
     pa_assert(cause != 0);
 
-    if (s->monitor_of)
+    if (s->monitor_of && cause != PA_SUSPEND_PASSTHROUGH)
         return -PA_ERR_NOTSUPPORTED;
 
     if (suspend)