1 /* PipeWire
2  *
3  * Copyright © 2020 Wim Taymans
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24 
25 #ifndef PULSE_SERVER_FORMAT_H
26 #define PULSE_SERVER_FORMAT_H
27 
28 #include <spa/utils/defs.h>
29 #include <pipewire/properties.h>
30 
31 struct spa_pod;
32 struct spa_pod_builder;
33 
34 #define RATE_MAX	(48000u*8u)
35 #define CHANNELS_MAX	(64u)
36 
37 enum sample_format {
38 	SAMPLE_U8,
39 	SAMPLE_ALAW,
40 	SAMPLE_ULAW,
41 	SAMPLE_S16LE,
42 	SAMPLE_S16BE,
43 	SAMPLE_FLOAT32LE,
44 	SAMPLE_FLOAT32BE,
45 	SAMPLE_S32LE,
46 	SAMPLE_S32BE,
47 	SAMPLE_S24LE,
48 	SAMPLE_S24BE,
49 	SAMPLE_S24_32LE,
50 	SAMPLE_S24_32BE,
51 	SAMPLE_MAX,
52 	SAMPLE_INVALID = -1
53 };
54 
55 #if __BYTE_ORDER == __BIG_ENDIAN
56 #define SAMPLE_S16NE		SAMPLE_S16BE
57 #define SAMPLE_FLOAT32NE	SAMPLE_FLOAT32BE
58 #define SAMPLE_S32NE		SAMPLE_S32BE
59 #define	SAMPLE_S24NE		SAMPLE_S24BE
60 #define SAMPLE_S24_32NE		SAMPLE_S24_32BE
61 #elif __BYTE_ORDER == __LITTLE_ENDIAN
62 #define SAMPLE_S16NE		SAMPLE_S16LE
63 #define SAMPLE_FLOAT32NE	SAMPLE_FLOAT32LE
64 #define SAMPLE_S32NE		SAMPLE_S32LE
65 #define	SAMPLE_S24NE		SAMPLE_S24LE
66 #define SAMPLE_S24_32NE		SAMPLE_S24_32LE
67 #endif
68 
69 struct format {
70 	uint32_t pa;
71 	uint32_t id;
72 	const char *name;
73 	uint32_t size;
74 };
75 
76 struct sample_spec {
77 	uint32_t format;
78 	uint32_t rate;
79 	uint8_t channels;
80 };
81 #define SAMPLE_SPEC_INIT				\
82 	(struct sample_spec) {				\
83 		.format = SPA_AUDIO_FORMAT_UNKNOWN,	\
84 		.rate = 0,				\
85 		.channels = 0,				\
86 	}
87 
88 enum channel_position {
89 	CHANNEL_POSITION_INVALID = -1,
90 	CHANNEL_POSITION_MONO = 0,
91 	CHANNEL_POSITION_FRONT_LEFT,
92 	CHANNEL_POSITION_FRONT_RIGHT,
93 	CHANNEL_POSITION_FRONT_CENTER,
94 
95 	CHANNEL_POSITION_REAR_CENTER,
96 	CHANNEL_POSITION_REAR_LEFT,
97 	CHANNEL_POSITION_REAR_RIGHT,
98 
99 	CHANNEL_POSITION_LFE,
100 	CHANNEL_POSITION_FRONT_LEFT_OF_CENTER,
101 	CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER,
102 
103 	CHANNEL_POSITION_SIDE_LEFT,
104 	CHANNEL_POSITION_SIDE_RIGHT,
105 	CHANNEL_POSITION_AUX0,
106 	CHANNEL_POSITION_AUX1,
107 	CHANNEL_POSITION_AUX2,
108 	CHANNEL_POSITION_AUX3,
109 	CHANNEL_POSITION_AUX4,
110 	CHANNEL_POSITION_AUX5,
111 	CHANNEL_POSITION_AUX6,
112 	CHANNEL_POSITION_AUX7,
113 	CHANNEL_POSITION_AUX8,
114 	CHANNEL_POSITION_AUX9,
115 	CHANNEL_POSITION_AUX10,
116 	CHANNEL_POSITION_AUX11,
117 	CHANNEL_POSITION_AUX12,
118 	CHANNEL_POSITION_AUX13,
119 	CHANNEL_POSITION_AUX14,
120 	CHANNEL_POSITION_AUX15,
121 	CHANNEL_POSITION_AUX16,
122 	CHANNEL_POSITION_AUX17,
123 	CHANNEL_POSITION_AUX18,
124 	CHANNEL_POSITION_AUX19,
125 	CHANNEL_POSITION_AUX20,
126 	CHANNEL_POSITION_AUX21,
127 	CHANNEL_POSITION_AUX22,
128 	CHANNEL_POSITION_AUX23,
129 	CHANNEL_POSITION_AUX24,
130 	CHANNEL_POSITION_AUX25,
131 	CHANNEL_POSITION_AUX26,
132 	CHANNEL_POSITION_AUX27,
133 	CHANNEL_POSITION_AUX28,
134 	CHANNEL_POSITION_AUX29,
135 	CHANNEL_POSITION_AUX30,
136 	CHANNEL_POSITION_AUX31,
137 
138 	CHANNEL_POSITION_TOP_CENTER,
139 
140 	CHANNEL_POSITION_TOP_FRONT_LEFT,
141 	CHANNEL_POSITION_TOP_FRONT_RIGHT,
142 	CHANNEL_POSITION_TOP_FRONT_CENTER,
143 
144 	CHANNEL_POSITION_TOP_REAR_LEFT,
145 	CHANNEL_POSITION_TOP_REAR_RIGHT,
146 	CHANNEL_POSITION_TOP_REAR_CENTER,
147 
148 	CHANNEL_POSITION_MAX
149 };
150 
151 struct channel {
152 	uint32_t channel;
153 	const char *name;
154 };
155 
156 struct channel_map {
157 	uint8_t channels;
158 	uint32_t map[CHANNELS_MAX];
159 };
160 
161 #define CHANNEL_MAP_INIT 	\
162 	(struct channel_map) {	\
163 		.channels = 0,	\
164 	}
165 
166 enum encoding {
167 	ENCODING_ANY,
168 	ENCODING_PCM,
169 	ENCODING_AC3_IEC61937,
170 	ENCODING_EAC3_IEC61937,
171 	ENCODING_MPEG_IEC61937,
172 	ENCODING_DTS_IEC61937,
173 	ENCODING_MPEG2_AAC_IEC61937,
174 	ENCODING_TRUEHD_IEC61937,
175 	ENCODING_DTSHD_IEC61937,
176 	ENCODING_MAX,
177 	ENCODING_INVALID = -1,
178 };
179 
180 struct format_info {
181 	enum encoding encoding;
182 	struct pw_properties *props;
183 };
184 
185 uint32_t format_pa2id(enum sample_format format);
186 const char *format_id2name(uint32_t format);
187 uint32_t format_name2id(const char *name);
188 uint32_t format_paname2id(const char *name, size_t size);
189 enum sample_format format_id2pa(uint32_t id);
190 const char *format_id2paname(uint32_t id);
191 const char *format_encoding2name(enum encoding enc);
192 uint32_t format_encoding2id(enum encoding enc);
193 
194 uint32_t sample_spec_frame_size(const struct sample_spec *ss);
195 bool sample_spec_valid(const struct sample_spec *ss);
196 
197 uint32_t channel_pa2id(enum channel_position channel);
198 const char *channel_id2name(uint32_t channel);
199 uint32_t channel_name2id(const char *name);
200 enum channel_position channel_id2pa(uint32_t id, uint32_t *aux);
201 const char *channel_id2paname(uint32_t id, uint32_t *aux);
202 uint32_t channel_paname2id(const char *name, size_t size);
203 
204 void channel_map_to_positions(const struct channel_map *map, uint32_t *pos);
205 void channel_map_parse(const char *str, struct channel_map *map);
206 bool channel_map_valid(const struct channel_map *map);
207 
208 int format_parse_param(const struct spa_pod *param, struct sample_spec *ss,
209 		struct channel_map *map, const struct sample_spec *def_ss,
210 		const struct channel_map *def_map);
211 
212 const struct spa_pod *format_build_param(struct spa_pod_builder *b, uint32_t id,
213 		const struct sample_spec *spec, const struct channel_map *map);
214 
215 int format_info_from_spec(struct format_info *info, const struct sample_spec *ss,
216 			  const struct channel_map *map);
217 int format_info_from_param(struct format_info *info, struct spa_pod *param, uint32_t index);
218 
219 const struct spa_pod *format_info_build_param(struct spa_pod_builder *b, uint32_t id,
220 		const struct format_info *info, uint32_t *rate);
221 
222 int format_info_from_spec(struct format_info *info, const struct sample_spec *ss,
223 		const struct channel_map *map);
224 int format_info_to_spec(const struct format_info *info, struct sample_spec *ss,
225 		struct channel_map *map);
226 
format_info_clear(struct format_info * info)227 static inline void format_info_clear(struct format_info *info)
228 {
229 	pw_properties_free(info->props);
230 	spa_zero(*info);
231 }
232 
233 #endif
234