]> code.delx.au - pulseaudio/commitdiff
sink: Extend API for compressed formats support
authorArun Raghavan <arun.raghavan@collabora.co.uk>
Mon, 28 Feb 2011 07:30:20 +0000 (13:00 +0530)
committerArun Raghavan <arun.raghavan@collabora.co.uk>
Mon, 2 May 2011 04:47:20 +0000 (10:17 +0530)
This adds a get_formats() vfunc for sinks to provide a list of formats
they can support. pa_sink_check_formats() can be used during or after
routing to determine what formats from a stream the sink can support.

src/pulsecore/sink.c
src/pulsecore/sink.h

index 839b7d44c1024bb54aa5bf7530fd69caab2eddd2..345d090c1dd43cf831e6ff3ec415eda5724b2d75 100644 (file)
@@ -35,6 +35,7 @@
 #include <pulse/util.h>
 #include <pulse/i18n.h>
 #include <pulse/rtclock.h>
+#include <pulse/internal.h>
 
 #include <pulsecore/sink-input.h>
 #include <pulsecore/namereg.h>
@@ -177,6 +178,7 @@ static void reset_callbacks(pa_sink *s) {
     s->request_rewind = NULL;
     s->update_requested_latency = NULL;
     s->set_port = NULL;
+    s->get_formats = NULL;
 }
 
 /* Called from main context */
@@ -3258,3 +3260,52 @@ static void pa_sink_volume_change_rewind(pa_sink *s, size_t nbytes) {
     }
     pa_sink_volume_change_apply(s, NULL);
 }
+
+/* Called from the main thread */
+/* Gets the list of formats supported by the sink. The members and idxset must
+ * be freed by the caller. */
+pa_idxset* pa_sink_get_formats(pa_sink *s) {
+    pa_idxset *ret;
+
+    pa_assert(s);
+
+    if (s->get_formats) {
+        /* Sink supports format query, all is good */
+        ret = s->get_formats(s);
+    } else {
+        /* Sink doesn't support format query, so assume it does PCM */
+        pa_format_info *f = pa_format_info_new();
+        f->encoding = PA_ENCODING_PCM;
+
+        ret = pa_idxset_new(NULL, NULL);
+        pa_idxset_put(ret, f, 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) {
+    pa_idxset *out_formats = pa_idxset_new(NULL, NULL), *sink_formats;
+    pa_format_info *f_sink, *f_in;
+    uint32_t i, j;
+
+    pa_assert(s);
+
+    if (!in_formats || pa_idxset_isempty(in_formats))
+        goto done;
+
+    sink_formats = pa_sink_get_formats(s);
+
+    PA_IDXSET_FOREACH(f_sink, sink_formats, i) {
+        PA_IDXSET_FOREACH(f_in, in_formats, j) {
+            if (pa_format_info_is_compatible(f_sink, f_in))
+                pa_idxset_put(out_formats, pa_format_info_copy(f_in), NULL);
+        }
+    }
+
+done:
+    return out_formats;
+}
index b61ba333d577e0afe45f44417cace7a8bbf3ec01..a96dd90a69560cda93d897f1aa6cba4bb709cdaa 100644 (file)
@@ -199,6 +199,10 @@ struct pa_sink {
      * thread. */
     int (*set_port)(pa_sink *s, pa_device_port *port); /* ditto */
 
+    /* Called to get the list of formats supported by the sink, sorted
+     * in descending order of preference. */
+    pa_idxset* (*get_formats)(pa_sink *s); /* ditto */
+
     /* Contains copies of the above data so that the real-time worker
      * thread can work without access locking */
     struct {
@@ -398,6 +402,9 @@ pa_queue *pa_sink_move_all_start(pa_sink *s, pa_queue *q);
 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_idxset* pa_sink_check_formats(pa_sink *s, pa_idxset *in_formats);
+
 /*** To be called exclusively by the sink driver, from IO context */
 
 void pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result);