sink-input: Kill passthrough streams if moving to an unsupported sink
authorArun Raghavan <arun.raghavan@collabora.co.uk>
Wed, 2 Mar 2011 06:08:01 +0000 (11:38 +0530)
committerArun Raghavan <arun.raghavan@collabora.co.uk>
Mon, 2 May 2011 06:24:48 +0000 (11:54 +0530)
This will eventually be replaced by a hook to let clients know that the
stream has moved so that they can gracefully reconnect and renegotiate a
supported format.

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

index 0f34e65..6e1b81f 100644 (file)
@@ -1552,6 +1552,11 @@ int pa_sink_input_finish_move(pa_sink_input *i, pa_sink *dest, pa_bool_t save) {
     if (!pa_sink_input_may_move_to(i, dest))
         return -PA_ERR_NOTSUPPORTED;
 
+    if (!pa_format_info_is_pcm(i->format) && !pa_sink_check_format(dest, i->format)) {
+        /* FIXME: Fire a message here so the client can renegotiate */
+        return -PA_ERR_NOTSUPPORTED;
+    }
+
     if (i->thread_info.resampler &&
         pa_sample_spec_equal(pa_resampler_output_sample_spec(i->thread_info.resampler), &dest->sample_spec) &&
         pa_channel_map_equal(pa_resampler_output_channel_map(i->thread_info.resampler), &dest->channel_map))
index 2b9402a..626c727 100644 (file)
@@ -3292,6 +3292,33 @@ pa_idxset* pa_sink_get_formats(pa_sink *s) {
 }
 
 /* Called from the main thread */
+/* Checks if the sink can accept this format */
+pa_bool_t pa_sink_check_format(pa_sink *s, pa_format_info *f)
+{
+    pa_idxset *sink_formats = NULL;
+    pa_format_info *f_sink;
+    uint32_t i;
+    pa_bool_t ret = FALSE;
+
+    pa_assert(s);
+    pa_assert(f);
+
+    sink_formats = pa_sink_get_formats(s);
+
+    PA_IDXSET_FOREACH(f_sink, sink_formats, i) {
+        if (pa_format_info_is_compatible(f_sink, f)) {
+            ret = TRUE;
+            break;
+        }
+    }
+
+    if (sink_formats)
+        pa_idxset_free(sink_formats, (pa_free2_cb_t) pa_format_info_free2, NULL);
+
+    return ret;
+}
+
+/* Called from the main thread */
 /* Calculates the intersection between formats supported by the sink and
  * in_formats, and returns these, in the order of the sink's formats. */
 pa_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats) {
index 492abf6..cbff5ca 100644 (file)
@@ -407,6 +407,7 @@ void pa_sink_move_all_finish(pa_sink *s, pa_queue *q, pa_bool_t save);
 void pa_sink_move_all_fail(pa_queue *q);
 
 pa_idxset* pa_sink_get_formats(pa_sink *s);
+pa_bool_t pa_sink_check_format(pa_sink *s, pa_format_info *f);
 pa_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats);
 
 /*** To be called exclusively by the sink driver, from IO context */