From 40db06de5f49c3fa50599e746e63aca00f07c889 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 21 Nov 2007 22:55:28 +0000 Subject: when speaking to a client with a version < 12, hide S32 sample specs, and make them appaear as FLOAT32 git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@2069 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/pulsecore/protocol-native.c | 77 +++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 48d5cd70..46405f10 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -1899,16 +1899,38 @@ static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED pa_pstream_send_simple_ack(c->pstream, tag); } -static void sink_fill_tagstruct(pa_tagstruct *t, pa_sink *sink) { +static void fixup_sample_spec(connection *c, pa_sample_spec *fixed, const pa_sample_spec *original) { + pa_assert(c); + pa_assert(fixed); + pa_assert(original); + + *fixed = *original; + + if (c->version < 12) { + /* Before protocol version 12 we didn't support S32 samples, + * so we need to lie about this to the client */ + + if (fixed->format == PA_SAMPLE_S32LE) + fixed->format = PA_SAMPLE_FLOAT32LE; + if (fixed->format == PA_SAMPLE_S32BE) + fixed->format = PA_SAMPLE_FLOAT32BE; + } +} + +static void sink_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink *sink) { + pa_sample_spec fixed_ss; + pa_assert(t); pa_sink_assert_ref(sink); + fixup_sample_spec(c, &fixed_ss, &sink->sample_spec); + pa_tagstruct_put( t, PA_TAG_U32, sink->index, PA_TAG_STRING, sink->name, PA_TAG_STRING, sink->description, - PA_TAG_SAMPLE_SPEC, &sink->sample_spec, + PA_TAG_SAMPLE_SPEC, &fixed_ss, PA_TAG_CHANNEL_MAP, &sink->channel_map, PA_TAG_U32, sink->module ? sink->module->index : PA_INVALID_INDEX, PA_TAG_CVOLUME, pa_sink_get_volume(sink), @@ -1921,16 +1943,20 @@ static void sink_fill_tagstruct(pa_tagstruct *t, pa_sink *sink) { PA_TAG_INVALID); } -static void source_fill_tagstruct(pa_tagstruct *t, pa_source *source) { +static void source_fill_tagstruct(connection *c, pa_tagstruct *t, pa_source *source) { + pa_sample_spec fixed_ss; + pa_assert(t); pa_source_assert_ref(source); + fixup_sample_spec(c, &fixed_ss, &source->sample_spec); + pa_tagstruct_put( t, PA_TAG_U32, source->index, PA_TAG_STRING, source->name, PA_TAG_STRING, source->description, - PA_TAG_SAMPLE_SPEC, &source->sample_spec, + PA_TAG_SAMPLE_SPEC, &fixed_ss, PA_TAG_CHANNEL_MAP, &source->channel_map, PA_TAG_U32, source->module ? source->module->index : PA_INVALID_INDEX, PA_TAG_CVOLUME, pa_source_get_volume(source), @@ -1965,15 +1991,19 @@ static void module_fill_tagstruct(pa_tagstruct *t, pa_module *module) { } static void sink_input_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink_input *s) { + pa_sample_spec fixed_ss; + pa_assert(t); pa_sink_input_assert_ref(s); + fixup_sample_spec(c, &fixed_ss, &s->sample_spec); + pa_tagstruct_putu32(t, s->index); pa_tagstruct_puts(t, s->name); pa_tagstruct_putu32(t, s->module ? s->module->index : PA_INVALID_INDEX); pa_tagstruct_putu32(t, s->client ? s->client->index : PA_INVALID_INDEX); pa_tagstruct_putu32(t, s->sink->index); - pa_tagstruct_put_sample_spec(t, &s->sample_spec); + pa_tagstruct_put_sample_spec(t, &fixed_ss); pa_tagstruct_put_channel_map(t, &s->channel_map); pa_tagstruct_put_cvolume(t, &s->volume); pa_tagstruct_put_usec(t, pa_sink_input_get_latency(s)); @@ -1984,16 +2014,20 @@ static void sink_input_fill_tagstruct(connection *c, pa_tagstruct *t, pa_sink_in pa_tagstruct_put_boolean(t, pa_sink_input_get_mute(s)); } -static void source_output_fill_tagstruct(pa_tagstruct *t, pa_source_output *s) { +static void source_output_fill_tagstruct(connection *c, pa_tagstruct *t, pa_source_output *s) { + pa_sample_spec fixed_ss; + pa_assert(t); pa_source_output_assert_ref(s); + fixup_sample_spec(c, &fixed_ss, &s->sample_spec); + pa_tagstruct_putu32(t, s->index); pa_tagstruct_puts(t, s->name); pa_tagstruct_putu32(t, s->module ? s->module->index : PA_INVALID_INDEX); pa_tagstruct_putu32(t, s->client ? s->client->index : PA_INVALID_INDEX); pa_tagstruct_putu32(t, s->source->index); - pa_tagstruct_put_sample_spec(t, &s->sample_spec); + pa_tagstruct_put_sample_spec(t, &fixed_ss); pa_tagstruct_put_channel_map(t, &s->channel_map); pa_tagstruct_put_usec(t, pa_source_output_get_latency(s)); pa_tagstruct_put_usec(t, pa_source_get_latency(s->source)); @@ -2001,15 +2035,19 @@ static void source_output_fill_tagstruct(pa_tagstruct *t, pa_source_output *s) { pa_tagstruct_puts(t, s->driver); } -static void scache_fill_tagstruct(pa_tagstruct *t, pa_scache_entry *e) { +static void scache_fill_tagstruct(connection *c, pa_tagstruct *t, pa_scache_entry *e) { + pa_sample_spec fixed_ss; + pa_assert(t); pa_assert(e); + fixup_sample_spec(c, &fixed_ss, &e->sample_spec); + pa_tagstruct_putu32(t, e->index); pa_tagstruct_puts(t, e->name); pa_tagstruct_put_cvolume(t, &e->volume); pa_tagstruct_put_usec(t, pa_bytes_to_usec(e->memchunk.length, &e->sample_spec)); - pa_tagstruct_put_sample_spec(t, &e->sample_spec); + pa_tagstruct_put_sample_spec(t, &fixed_ss); pa_tagstruct_put_channel_map(t, &e->channel_map); pa_tagstruct_putu32(t, e->memchunk.length); pa_tagstruct_put_boolean(t, e->lazy); @@ -2079,9 +2117,9 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u reply = reply_new(tag); if (sink) - sink_fill_tagstruct(reply, sink); + sink_fill_tagstruct(c, reply, sink); else if (source) - source_fill_tagstruct(reply, source); + source_fill_tagstruct(c, reply, source); else if (client) client_fill_tagstruct(reply, client); else if (module) @@ -2089,9 +2127,9 @@ static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, u else if (si) sink_input_fill_tagstruct(c, reply, si); else if (so) - source_output_fill_tagstruct(reply, so); + source_output_fill_tagstruct(c, reply, so); else - scache_fill_tagstruct(reply, sce); + scache_fill_tagstruct(c, reply, sce); pa_pstream_send_tagstruct(c->pstream, reply); } @@ -2134,9 +2172,9 @@ static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma if (i) { for (p = pa_idxset_first(i, &idx); p; p = pa_idxset_next(i, &idx)) { if (command == PA_COMMAND_GET_SINK_INFO_LIST) - sink_fill_tagstruct(reply, p); + sink_fill_tagstruct(c, reply, p); else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST) - source_fill_tagstruct(reply, p); + source_fill_tagstruct(c, reply, p); else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST) client_fill_tagstruct(reply, p); else if (command == PA_COMMAND_GET_MODULE_INFO_LIST) @@ -2144,10 +2182,10 @@ static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t comma else if (command == PA_COMMAND_GET_SINK_INPUT_INFO_LIST) sink_input_fill_tagstruct(c, reply, p); else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST) - source_output_fill_tagstruct(reply, p); + source_output_fill_tagstruct(c, reply, p); else { pa_assert(command == PA_COMMAND_GET_SAMPLE_INFO_LIST); - scache_fill_tagstruct(reply, p); + scache_fill_tagstruct(c, reply, p); } } } @@ -2160,6 +2198,7 @@ static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSE pa_tagstruct *reply; char txt[256]; const char *n; + pa_sample_spec fixed_ss; connection_assert_ref(c); pa_assert(t); @@ -2176,7 +2215,9 @@ static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSE pa_tagstruct_puts(reply, PACKAGE_VERSION); pa_tagstruct_puts(reply, pa_get_user_name(txt, sizeof(txt))); pa_tagstruct_puts(reply, pa_get_fqdn(txt, sizeof(txt))); - pa_tagstruct_put_sample_spec(reply, &c->protocol->core->default_sample_spec); + + fixup_sample_spec(c, &fixed_ss, &c->protocol->core->default_sample_spec); + pa_tagstruct_put_sample_spec(reply, &fixed_ss); n = pa_namereg_get_default_sink_name(c->protocol->core); pa_tagstruct_puts(reply, n); -- cgit