The function will be used in pa_sink_input_new() and pa_source_output_new() to convert the sample spec given by the client to a format info object. The set_format, set_rate and set_channels will be set according to the stream flags (PA_SINK_INPUT_FIX_FORMAT etc.). --- src/pulsecore/core-format.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ src/pulsecore/core-format.h | 18 +++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/src/pulsecore/core-format.c b/src/pulsecore/core-format.c index ec90988..34976b7 100644 --- a/src/pulsecore/core-format.c +++ b/src/pulsecore/core-format.c @@ -113,6 +113,55 @@ int pa_format_info_get_channel_map(pa_format_info *f, pa_channel_map *map) { return 0; } +pa_format_info *pa_format_info_from_sample_spec2(const pa_sample_spec *ss, const pa_channel_map *map, bool set_format, + bool set_rate, bool set_channels) { + pa_format_info *format; + + pa_assert(ss); + + format = pa_format_info_new(); + format->encoding = PA_ENCODING_PCM; + + if (set_format) { + if (!pa_sample_format_valid(ss->format)) + goto fail; + + pa_format_info_set_sample_format(format, ss->format); + } + + if (set_rate) { + if (!pa_sample_rate_valid(ss->rate)) + goto fail; + + pa_format_info_set_rate(format, ss->rate); + } + + if (set_channels) { + if (!pa_channels_valid(ss->channels)) + goto fail; + + pa_format_info_set_channels(format, ss->channels); + + if (map) { + if (!pa_channel_map_valid(map)) + goto fail; + + if (map->channels != ss->channels) + goto fail; + + pa_format_info_set_channel_map(format, map); + } + } + + return format; + +fail: + if (format) + pa_format_info_free(format); + + return NULL; +} + int pa_format_info_to_sample_spec2(pa_format_info *f, pa_sample_spec *ss, pa_channel_map *map, pa_sample_spec *fallback_ss, pa_channel_map *fallback_map) { int r, r2; diff --git a/src/pulsecore/core-format.h b/src/pulsecore/core-format.h index 9342acc..ce3923e 100644 --- a/src/pulsecore/core-format.h +++ b/src/pulsecore/core-format.h @@ -22,6 +22,8 @@ #include <pulse/format.h> +#include <stdbool.h> + /* Gets the sample format stored in the format info. Returns a negative error * code on failure. If the sample format property is not set at all, returns * -PA_ERR_NOENTITY. */ @@ -42,6 +44,22 @@ int pa_format_info_get_channels(pa_format_info *f, uint8_t *channels); * -PA_ERR_NOENTITY. */ int pa_format_info_get_channel_map(pa_format_info *f, pa_channel_map *map); +/* Convert a sample spec and an optional channel map to a new PCM format info + * object (remember to free it). If map is NULL, then the channel map will be + * left unspecified. If some fields of the sample spec should be ignored, pass + * false for set_format, set_rate and set_channels as appropriate, then those + * fields will be left unspecified. This function returns NULL if the input is + * invalid (for example, setting the sample rate was requested, but the rate + * in ss is invalid). + * + * pa_format_info_from_sample_spec() exists too. This "version 2" was created, + * because the original function doesn't provide the possibility of ignoring + * some of the sample spec fields. That functionality can't be added to the + * original function, because the function is a part of the public API and + * adding parameters to it would break the API. */ +pa_format_info *pa_format_info_from_sample_spec2(const pa_sample_spec *ss, const pa_channel_map *map, bool set_format, + bool set_rate, bool set_channels); + /* Convert the format info into a sample spec and a channel map. If the format * info doesn't contain some information, the fallback sample spec and channel * map are used to populate the output. -- 1.8.3.1