From 47e0f91aa2ca6eb3ea8b7be8aa03cd03a28c3fbe Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 28 Feb 2011 13:00:20 +0530 Subject: sink: Extend API for compressed formats support 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 | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/sink.h | 7 +++++++ 2 files changed, 58 insertions(+) (limited to 'src/pulsecore') diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 839b7d44..345d090c 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -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; +} diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index b61ba333..a96dd90a 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -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); -- cgit