Currently format negotiation is done in pa_sink_input_new_data_set_sink(), but the new data won't be available when a router module needs to connect a sink input node to some other node, so a different function is needed. It would probably otherwise be possible to convert also pa_sink_input_new_data_set_sink() to use pa_format_info_negotiate() internally, but pa_sink_input_new_data_set_sink() doesn't currently choose the final format, which pa_format_info_negotiate() does. The reason is probably to allow policy modules to choose the format if there are multiple alternatives, but I don't know if we really need that possibility (AFAIK the possibility is not currently used), so perhaps that conversion should be done to get rid of the duplicated code? --- src/Makefile.am | 1 + src/pulsecore/core-format.c | 51 +++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/core-format.h | 44 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 src/pulsecore/core-format.c create mode 100644 src/pulsecore/core-format.h diff --git a/src/Makefile.am b/src/Makefile.am index 4efd4c4..168415e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -871,6 +871,7 @@ libpulsecore_ at PA_MAJORMINOR@_la_SOURCES = \ pulsecore/cli-text.c pulsecore/cli-text.h \ pulsecore/client.c pulsecore/client.h \ pulsecore/card.c pulsecore/card.h \ + pulsecore/core-format.c pulsecore/core-format.h \ pulsecore/core-scache.c pulsecore/core-scache.h \ pulsecore/core-subscribe.c pulsecore/core-subscribe.h \ pulsecore/core.c pulsecore/core.h \ diff --git a/src/pulsecore/core-format.c b/src/pulsecore/core-format.c new file mode 100644 index 0000000..6e534f4 --- /dev/null +++ b/src/pulsecore/core-format.c @@ -0,0 +1,51 @@ +/*** + This file is part of PulseAudio. + + Copyright 2013 Intel Corporation + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "core-format.h" + +int pa_format_info_negotiate(pa_idxset *formats_a, pa_idxset *formats_b, const pa_format_info **format) { + pa_format_info *a; + uint32_t idx_a; + pa_format_info *b; + uint32_t idx_b; + + pa_assert(formats_a); + pa_assert(formats_b); + pa_assert(format); + + PA_IDXSET_FOREACH(a, formats_a, idx_a) { + PA_IDXSET_FOREACH(b, formats_b, idx_b) { + /* pa_format_info_is_compatible() succeeds if the first parameter + * is a subset of the second parameter, so b must be the first + * parameter. */ + if (pa_format_info_is_compatible(b, a)) { + *format = a; + return 0; + } + } + } + + return -PA_ERR_NOTSUPPORTED; +} diff --git a/src/pulsecore/core-format.h b/src/pulsecore/core-format.h new file mode 100644 index 0000000..f492c19 --- /dev/null +++ b/src/pulsecore/core-format.h @@ -0,0 +1,44 @@ +#ifndef foocoreformathfoo +#define foocoreformathfoo + +/*** + This file is part of PulseAudio. + + Copyright 2013 Intel Corporation + + PulseAudio is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 of the License, + or (at your option) any later version. + + PulseAudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with PulseAudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#include <pulse/format.h> + +#include <pulsecore/idxset.h> + +/* Selects the first format in formats_a that is compatible with some format in + * formats_b, and stores the result in format. Returns a negative error code if + * no compatible format can be found. + * + * Being "compatible" means that format a is a superset of format b (internally + * this function uses pa_format_info_compatible(), which defines what + * "compatible" means). If you have two format sets, how do you know which one + * is going to contain supersets of the other? Currently (as of 2013-11-17) + * things are designed so that formats_a should represent stream formats and + * formats_b should represent device formats. Hopefully the definition of + * "compatible" will change at some point so that it would actually mean that + * there's a valid intersection of a and b, because then it wouldn't matter if + * the formats are stream or device formats. */ +int pa_format_info_negotiate(pa_idxset *formats_a, pa_idxset *formats_b, const pa_format_info **format); + +#endif -- 1.8.3.1