diff options
Diffstat (limited to 'src/modules/module-protocol-pulse/format.h')
-rw-r--r-- | src/modules/module-protocol-pulse/format.h | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/src/modules/module-protocol-pulse/format.h b/src/modules/module-protocol-pulse/format.h new file mode 100644 index 0000000..4300fc0 --- /dev/null +++ b/src/modules/module-protocol-pulse/format.h @@ -0,0 +1,233 @@ +/* PipeWire + * + * Copyright © 2020 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef PULSE_SERVER_FORMAT_H +#define PULSE_SERVER_FORMAT_H + +#include <spa/utils/defs.h> +#include <pipewire/properties.h> + +struct spa_pod; +struct spa_pod_builder; + +#define RATE_MAX (48000u*8u) +#define CHANNELS_MAX (64u) + +enum sample_format { + SAMPLE_U8, + SAMPLE_ALAW, + SAMPLE_ULAW, + SAMPLE_S16LE, + SAMPLE_S16BE, + SAMPLE_FLOAT32LE, + SAMPLE_FLOAT32BE, + SAMPLE_S32LE, + SAMPLE_S32BE, + SAMPLE_S24LE, + SAMPLE_S24BE, + SAMPLE_S24_32LE, + SAMPLE_S24_32BE, + SAMPLE_MAX, + SAMPLE_INVALID = -1 +}; + +#if __BYTE_ORDER == __BIG_ENDIAN +#define SAMPLE_S16NE SAMPLE_S16BE +#define SAMPLE_FLOAT32NE SAMPLE_FLOAT32BE +#define SAMPLE_S32NE SAMPLE_S32BE +#define SAMPLE_S24NE SAMPLE_S24BE +#define SAMPLE_S24_32NE SAMPLE_S24_32BE +#elif __BYTE_ORDER == __LITTLE_ENDIAN +#define SAMPLE_S16NE SAMPLE_S16LE +#define SAMPLE_FLOAT32NE SAMPLE_FLOAT32LE +#define SAMPLE_S32NE SAMPLE_S32LE +#define SAMPLE_S24NE SAMPLE_S24LE +#define SAMPLE_S24_32NE SAMPLE_S24_32LE +#endif + +struct format { + uint32_t pa; + uint32_t id; + const char *name; + uint32_t size; +}; + +struct sample_spec { + uint32_t format; + uint32_t rate; + uint8_t channels; +}; +#define SAMPLE_SPEC_INIT \ + (struct sample_spec) { \ + .format = SPA_AUDIO_FORMAT_UNKNOWN, \ + .rate = 0, \ + .channels = 0, \ + } + +enum channel_position { + CHANNEL_POSITION_INVALID = -1, + CHANNEL_POSITION_MONO = 0, + CHANNEL_POSITION_FRONT_LEFT, + CHANNEL_POSITION_FRONT_RIGHT, + CHANNEL_POSITION_FRONT_CENTER, + + CHANNEL_POSITION_REAR_CENTER, + CHANNEL_POSITION_REAR_LEFT, + CHANNEL_POSITION_REAR_RIGHT, + + CHANNEL_POSITION_LFE, + CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, + CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, + + CHANNEL_POSITION_SIDE_LEFT, + CHANNEL_POSITION_SIDE_RIGHT, + CHANNEL_POSITION_AUX0, + CHANNEL_POSITION_AUX1, + CHANNEL_POSITION_AUX2, + CHANNEL_POSITION_AUX3, + CHANNEL_POSITION_AUX4, + CHANNEL_POSITION_AUX5, + CHANNEL_POSITION_AUX6, + CHANNEL_POSITION_AUX7, + CHANNEL_POSITION_AUX8, + CHANNEL_POSITION_AUX9, + CHANNEL_POSITION_AUX10, + CHANNEL_POSITION_AUX11, + CHANNEL_POSITION_AUX12, + CHANNEL_POSITION_AUX13, + CHANNEL_POSITION_AUX14, + CHANNEL_POSITION_AUX15, + CHANNEL_POSITION_AUX16, + CHANNEL_POSITION_AUX17, + CHANNEL_POSITION_AUX18, + CHANNEL_POSITION_AUX19, + CHANNEL_POSITION_AUX20, + CHANNEL_POSITION_AUX21, + CHANNEL_POSITION_AUX22, + CHANNEL_POSITION_AUX23, + CHANNEL_POSITION_AUX24, + CHANNEL_POSITION_AUX25, + CHANNEL_POSITION_AUX26, + CHANNEL_POSITION_AUX27, + CHANNEL_POSITION_AUX28, + CHANNEL_POSITION_AUX29, + CHANNEL_POSITION_AUX30, + CHANNEL_POSITION_AUX31, + + CHANNEL_POSITION_TOP_CENTER, + + CHANNEL_POSITION_TOP_FRONT_LEFT, + CHANNEL_POSITION_TOP_FRONT_RIGHT, + CHANNEL_POSITION_TOP_FRONT_CENTER, + + CHANNEL_POSITION_TOP_REAR_LEFT, + CHANNEL_POSITION_TOP_REAR_RIGHT, + CHANNEL_POSITION_TOP_REAR_CENTER, + + CHANNEL_POSITION_MAX +}; + +struct channel { + uint32_t channel; + const char *name; +}; + +struct channel_map { + uint8_t channels; + uint32_t map[CHANNELS_MAX]; +}; + +#define CHANNEL_MAP_INIT \ + (struct channel_map) { \ + .channels = 0, \ + } + +enum encoding { + ENCODING_ANY, + ENCODING_PCM, + ENCODING_AC3_IEC61937, + ENCODING_EAC3_IEC61937, + ENCODING_MPEG_IEC61937, + ENCODING_DTS_IEC61937, + ENCODING_MPEG2_AAC_IEC61937, + ENCODING_TRUEHD_IEC61937, + ENCODING_DTSHD_IEC61937, + ENCODING_MAX, + ENCODING_INVALID = -1, +}; + +struct format_info { + enum encoding encoding; + struct pw_properties *props; +}; + +uint32_t format_pa2id(enum sample_format format); +const char *format_id2name(uint32_t format); +uint32_t format_name2id(const char *name); +uint32_t format_paname2id(const char *name, size_t size); +enum sample_format format_id2pa(uint32_t id); +const char *format_id2paname(uint32_t id); +const char *format_encoding2name(enum encoding enc); +uint32_t format_encoding2id(enum encoding enc); + +uint32_t sample_spec_frame_size(const struct sample_spec *ss); +bool sample_spec_valid(const struct sample_spec *ss); + +uint32_t channel_pa2id(enum channel_position channel); +const char *channel_id2name(uint32_t channel); +uint32_t channel_name2id(const char *name); +enum channel_position channel_id2pa(uint32_t id, uint32_t *aux); +const char *channel_id2paname(uint32_t id, uint32_t *aux); +uint32_t channel_paname2id(const char *name, size_t size); + +void channel_map_to_positions(const struct channel_map *map, uint32_t *pos); +void channel_map_parse(const char *str, struct channel_map *map); +bool channel_map_valid(const struct channel_map *map); + +int format_parse_param(const struct spa_pod *param, bool collect, struct sample_spec *ss, + struct channel_map *map, const struct sample_spec *def_ss, + const struct channel_map *def_map); + +const struct spa_pod *format_build_param(struct spa_pod_builder *b, uint32_t id, + const struct sample_spec *spec, const struct channel_map *map); + +int format_info_from_spec(struct format_info *info, const struct sample_spec *ss, + const struct channel_map *map); +int format_info_from_param(struct format_info *info, struct spa_pod *param, uint32_t index); + +const struct spa_pod *format_info_build_param(struct spa_pod_builder *b, uint32_t id, + const struct format_info *info, uint32_t *rate); + +int format_info_from_spec(struct format_info *info, const struct sample_spec *ss, + const struct channel_map *map); +int format_info_to_spec(const struct format_info *info, struct sample_spec *ss, + struct channel_map *map); + +static inline void format_info_clear(struct format_info *info) +{ + pw_properties_free(info->props); + spa_zero(*info); +} + +#endif |