1 /*
2 * This file is part of mpv.
3 *
4 * mpv is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * mpv is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include <stdlib.h>
19 #include <assert.h>
20
21 #include <libavutil/common.h>
22
23 #include "common/common.h"
24 #include "common/msg.h"
25 #include "chmap.h"
26
27 // Names taken from libavutil/channel_layout.c (Not accessible by API.)
28 // Use of these names is hard-coded in some places (e.g. ao_alsa.c)
29 static const char *const speaker_names[MP_SPEAKER_ID_COUNT][2] = {
30 [MP_SPEAKER_ID_FL] = {"fl", "front left"},
31 [MP_SPEAKER_ID_FR] = {"fr", "front right"},
32 [MP_SPEAKER_ID_FC] = {"fc", "front center"},
33 [MP_SPEAKER_ID_LFE] = {"lfe", "low frequency"},
34 [MP_SPEAKER_ID_BL] = {"bl", "back left"},
35 [MP_SPEAKER_ID_BR] = {"br", "back right"},
36 [MP_SPEAKER_ID_FLC] = {"flc", "front left-of-center"},
37 [MP_SPEAKER_ID_FRC] = {"frc", "front right-of-center"},
38 [MP_SPEAKER_ID_BC] = {"bc", "back center"},
39 [MP_SPEAKER_ID_SL] = {"sl", "side left"},
40 [MP_SPEAKER_ID_SR] = {"sr", "side right"},
41 [MP_SPEAKER_ID_TC] = {"tc", "top center"},
42 [MP_SPEAKER_ID_TFL] = {"tfl", "top front left"},
43 [MP_SPEAKER_ID_TFC] = {"tfc", "top front center"},
44 [MP_SPEAKER_ID_TFR] = {"tfr", "top front right"},
45 [MP_SPEAKER_ID_TBL] = {"tbl", "top back left"},
46 [MP_SPEAKER_ID_TBC] = {"tbc", "top back center"},
47 [MP_SPEAKER_ID_TBR] = {"tbr", "top back right"},
48 [MP_SPEAKER_ID_DL] = {"dl", "downmix left"},
49 [MP_SPEAKER_ID_DR] = {"dr", "downmix right"},
50 [MP_SPEAKER_ID_WL] = {"wl", "wide left"},
51 [MP_SPEAKER_ID_WR] = {"wr", "wide right"},
52 [MP_SPEAKER_ID_SDL] = {"sdl", "surround direct left"},
53 [MP_SPEAKER_ID_SDR] = {"sdr", "surround direct right"},
54 [MP_SPEAKER_ID_LFE2] = {"lfe2", "low frequency 2"},
55 [MP_SPEAKER_ID_NA] = {"na", "not available"},
56 };
57
58 // Names taken from libavutil/channel_layout.c (Not accessible by API.)
59 // Channel order corresponds to lavc/waveex, except for the alsa entries.
60 static const char *const std_layout_names[][2] = {
61 {"empty", ""}, // not in lavc
62 {"mono", "fc"},
63 {"1.0", "fc"}, // not in lavc
64 {"stereo", "fl-fr"},
65 {"2.0", "fl-fr"}, // not in lavc
66 {"2.1", "fl-fr-lfe"},
67 {"3.0", "fl-fr-fc"},
68 {"3.0(back)", "fl-fr-bc"},
69 {"4.0", "fl-fr-fc-bc"},
70 {"quad", "fl-fr-bl-br"},
71 {"quad(side)", "fl-fr-sl-sr"},
72 {"3.1", "fl-fr-fc-lfe"},
73 {"3.1(back)", "fl-fr-lfe-bc"}, // not in lavc
74 {"5.0", "fl-fr-fc-bl-br"},
75 {"5.0(alsa)", "fl-fr-bl-br-fc"}, // not in lavc
76 {"5.0(side)", "fl-fr-fc-sl-sr"},
77 {"4.1", "fl-fr-fc-lfe-bc"},
78 {"4.1(alsa)", "fl-fr-bl-br-lfe"}, // not in lavc
79 {"5.1", "fl-fr-fc-lfe-bl-br"},
80 {"5.1(alsa)", "fl-fr-bl-br-fc-lfe"}, // not in lavc
81 {"5.1(side)", "fl-fr-fc-lfe-sl-sr"},
82 {"6.0", "fl-fr-fc-bc-sl-sr"},
83 {"6.0(front)", "fl-fr-flc-frc-sl-sr"},
84 {"hexagonal", "fl-fr-fc-bl-br-bc"},
85 {"6.1", "fl-fr-fc-lfe-bc-sl-sr"},
86 {"6.1(back)", "fl-fr-fc-lfe-bl-br-bc"}, // lavc calls this "6.1" too
87 {"6.1(top)", "fl-fr-fc-lfe-bl-br-tc"}, // not in lavc
88 {"6.1(front)", "fl-fr-lfe-flc-frc-sl-sr"},
89 {"7.0", "fl-fr-fc-bl-br-sl-sr"},
90 {"7.0(front)", "fl-fr-fc-flc-frc-sl-sr"},
91 {"7.0(rear)", "fl-fr-fc-bl-br-sdl-sdr"}, // not in lavc
92 {"7.1", "fl-fr-fc-lfe-bl-br-sl-sr"},
93 {"7.1(alsa)", "fl-fr-bl-br-fc-lfe-sl-sr"}, // not in lavc
94 {"7.1(wide)", "fl-fr-fc-lfe-bl-br-flc-frc"},
95 {"7.1(wide-side)", "fl-fr-fc-lfe-flc-frc-sl-sr"},
96 {"7.1(rear)", "fl-fr-fc-lfe-bl-br-sdl-sdr"}, // not in lavc
97 {"octagonal", "fl-fr-fc-bl-br-bc-sl-sr"},
98 {"auto", ""}, // not in lavc
99 {0}
100 };
101
102 static const struct mp_chmap default_layouts[] = {
103 {0}, // empty
104 MP_CHMAP_INIT_MONO, // mono
105 MP_CHMAP2(FL, FR), // stereo
106 MP_CHMAP3(FL, FR, LFE), // 2.1
107 MP_CHMAP4(FL, FR, FC, BC), // 4.0
108 MP_CHMAP5(FL, FR, FC, BL, BR), // 5.0
109 MP_CHMAP6(FL, FR, FC, LFE, BL, BR), // 5.1
110 MP_CHMAP7(FL, FR, FC, LFE, BC, SL, SR), // 6.1
111 MP_CHMAP8(FL, FR, FC, LFE, BL, BR, SL, SR), // 7.1
112 };
113
114 // Returns true if speakers are mapped uniquely, and there's at least 1 channel.
mp_chmap_is_valid(const struct mp_chmap * src)115 bool mp_chmap_is_valid(const struct mp_chmap *src)
116 {
117 bool mapped[MP_SPEAKER_ID_COUNT] = {0};
118 for (int n = 0; n < src->num; n++) {
119 int sp = src->speaker[n];
120 if (sp >= MP_SPEAKER_ID_COUNT || mapped[sp])
121 return false;
122 if (sp != MP_SPEAKER_ID_NA)
123 mapped[sp] = true;
124 }
125 return src->num > 0;
126 }
127
mp_chmap_is_empty(const struct mp_chmap * src)128 bool mp_chmap_is_empty(const struct mp_chmap *src)
129 {
130 return src->num == 0;
131 }
132
133 // Return true if the channel map defines the number of the channels only, and
134 // the channels have to meaning associated with them.
mp_chmap_is_unknown(const struct mp_chmap * src)135 bool mp_chmap_is_unknown(const struct mp_chmap *src)
136 {
137 for (int n = 0; n < src->num; n++) {
138 if (src->speaker[n] != MP_SPEAKER_ID_NA)
139 return false;
140 }
141 return mp_chmap_is_valid(src);
142 }
143
144 // Note: empty channel maps compare as equal. Invalid ones can equal too.
mp_chmap_equals(const struct mp_chmap * a,const struct mp_chmap * b)145 bool mp_chmap_equals(const struct mp_chmap *a, const struct mp_chmap *b)
146 {
147 if (a->num != b->num)
148 return false;
149 for (int n = 0; n < a->num; n++) {
150 if (a->speaker[n] != b->speaker[n])
151 return false;
152 }
153 return true;
154 }
155
156 // Whether they use the same speakers (even if in different order).
mp_chmap_equals_reordered(const struct mp_chmap * a,const struct mp_chmap * b)157 bool mp_chmap_equals_reordered(const struct mp_chmap *a, const struct mp_chmap *b)
158 {
159 struct mp_chmap t1 = *a, t2 = *b;
160 mp_chmap_reorder_norm(&t1);
161 mp_chmap_reorder_norm(&t2);
162 return mp_chmap_equals(&t1, &t2);
163 }
164
mp_chmap_is_stereo(const struct mp_chmap * src)165 bool mp_chmap_is_stereo(const struct mp_chmap *src)
166 {
167 static const struct mp_chmap stereo = MP_CHMAP_INIT_STEREO;
168 return mp_chmap_equals(src, &stereo);
169 }
170
comp_uint8(const void * a,const void * b)171 static int comp_uint8(const void *a, const void *b)
172 {
173 return *(const uint8_t *)a - *(const uint8_t *)b;
174 }
175
176 // Reorder channels to normal order, with monotonically increasing speaker IDs.
177 // We define this order as the same order used with waveex.
mp_chmap_reorder_norm(struct mp_chmap * map)178 void mp_chmap_reorder_norm(struct mp_chmap *map)
179 {
180 uint8_t *arr = &map->speaker[0];
181 qsort(arr, map->num, 1, comp_uint8);
182 }
183
184 // Remove silent (NA) channels, if any.
mp_chmap_remove_na(struct mp_chmap * map)185 void mp_chmap_remove_na(struct mp_chmap *map)
186 {
187 struct mp_chmap new = {0};
188 for (int n = 0; n < map->num; n++) {
189 int sp = map->speaker[n];
190 if (sp != MP_SPEAKER_ID_NA)
191 new.speaker[new.num++] = map->speaker[n];
192 }
193 *map = new;
194 }
195
196 // Add silent (NA) channels to map until map->num >= num.
mp_chmap_fill_na(struct mp_chmap * map,int num)197 void mp_chmap_fill_na(struct mp_chmap *map, int num)
198 {
199 assert(num <= MP_NUM_CHANNELS);
200 while (map->num < num)
201 map->speaker[map->num++] = MP_SPEAKER_ID_NA;
202 }
203
204 // Set *dst to a standard layout with the given number of channels.
205 // If the number of channels is invalid, an invalid map is set, and
206 // mp_chmap_is_valid(dst) will return false.
mp_chmap_from_channels(struct mp_chmap * dst,int num_channels)207 void mp_chmap_from_channels(struct mp_chmap *dst, int num_channels)
208 {
209 *dst = (struct mp_chmap) {0};
210 if (num_channels >= 0 && num_channels < MP_ARRAY_SIZE(default_layouts))
211 *dst = default_layouts[num_channels];
212 if (!dst->num)
213 mp_chmap_set_unknown(dst, num_channels);
214 }
215
216 // Set *dst to an unknown layout for the given numbers of channels.
217 // If the number of channels is invalid, an invalid map is set, and
218 // mp_chmap_is_valid(dst) will return false.
219 // A mp_chmap with all entries set to NA is treated specially in some
220 // contexts (watch out for mp_chmap_is_unknown()).
mp_chmap_set_unknown(struct mp_chmap * dst,int num_channels)221 void mp_chmap_set_unknown(struct mp_chmap *dst, int num_channels)
222 {
223 if (num_channels < 0 || num_channels > MP_NUM_CHANNELS) {
224 *dst = (struct mp_chmap) {0};
225 } else {
226 dst->num = num_channels;
227 for (int n = 0; n < dst->num; n++)
228 dst->speaker[n] = MP_SPEAKER_ID_NA;
229 }
230 }
231
232 // Return the ffmpeg/libav channel layout as in <libavutil/channel_layout.h>.
233 // Speakers not representable by ffmpeg/libav are dropped.
234 // Warning: this ignores the order of the channels, and will return a channel
235 // mask even if the order is different from libavcodec's.
236 // Also, "unknown" channel maps are translated to non-sense channel
237 // maps with the same number of channels.
mp_chmap_to_lavc_unchecked(const struct mp_chmap * src)238 uint64_t mp_chmap_to_lavc_unchecked(const struct mp_chmap *src)
239 {
240 struct mp_chmap t = *src;
241 if (t.num > 64)
242 return 0;
243 // lavc has no concept for unknown layouts yet, so pick something that does
244 // the job of signaling the number of channels, even if it makes no sense
245 // as a proper layout.
246 if (mp_chmap_is_unknown(&t))
247 return t.num == 64 ? (uint64_t)-1 : (1ULL << t.num) - 1;
248 uint64_t mask = 0;
249 for (int n = 0; n < t.num; n++) {
250 if (t.speaker[n] < 64) // ignore MP_SPEAKER_ID_NA etc.
251 mask |= 1ULL << t.speaker[n];
252 }
253 return mask;
254 }
255
256 // Return the ffmpeg/libav channel layout as in <libavutil/channel_layout.h>.
257 // Returns 0 if the channel order doesn't match lavc's or if it's invalid.
mp_chmap_to_lavc(const struct mp_chmap * src)258 uint64_t mp_chmap_to_lavc(const struct mp_chmap *src)
259 {
260 if (!mp_chmap_is_lavc(src))
261 return 0;
262 return mp_chmap_to_lavc_unchecked(src);
263 }
264
265 // Set channel map from the ffmpeg/libav channel layout as in
266 // <libavutil/channel_layout.h>.
267 // If the number of channels exceed MP_NUM_CHANNELS, set dst to empty.
mp_chmap_from_lavc(struct mp_chmap * dst,uint64_t src)268 void mp_chmap_from_lavc(struct mp_chmap *dst, uint64_t src)
269 {
270 dst->num = 0;
271 for (int n = 0; n < 64; n++) {
272 if (src & (1ULL << n)) {
273 if (dst->num >= MP_NUM_CHANNELS) {
274 dst->num = 0;
275 return;
276 }
277 dst->speaker[dst->num] = n;
278 dst->num++;
279 }
280 }
281 }
282
mp_chmap_is_lavc(const struct mp_chmap * src)283 bool mp_chmap_is_lavc(const struct mp_chmap *src)
284 {
285 if (!mp_chmap_is_valid(src))
286 return false;
287 if (mp_chmap_is_unknown(src))
288 return true;
289 // lavc's channel layout is a bit mask, and channels are always ordered
290 // from LSB to MSB speaker bits, so speaker IDs have to increase.
291 assert(src->num > 0);
292 for (int n = 1; n < src->num; n++) {
293 if (src->speaker[n - 1] >= src->speaker[n])
294 return false;
295 }
296 for (int n = 0; n < src->num; n++) {
297 if (src->speaker[n] >= 64)
298 return false;
299 }
300 return true;
301 }
302
303 // Warning: for "unknown" channel maps, this returns something that may not
304 // make sense. Invalid channel maps are not changed.
mp_chmap_reorder_to_lavc(struct mp_chmap * map)305 void mp_chmap_reorder_to_lavc(struct mp_chmap *map)
306 {
307 if (!mp_chmap_is_valid(map))
308 return;
309 uint64_t mask = mp_chmap_to_lavc_unchecked(map);
310 mp_chmap_from_lavc(map, mask);
311 }
312
313 // Get reordering array for from->to reordering. from->to must have the same set
314 // of speakers (i.e. same number and speaker IDs, just different order). Then,
315 // for each speaker n, src[n] will be set such that:
316 // to->speaker[n] = from->speaker[src[n]]
317 // (src[n] gives the source channel for destination channel n)
318 // If *from and *to don't contain the same set of speakers, then the above
319 // invariant is not guaranteed. Instead, src[n] can be set to -1 if the channel
320 // at to->speaker[n] is unmapped.
mp_chmap_get_reorder(int src[MP_NUM_CHANNELS],const struct mp_chmap * from,const struct mp_chmap * to)321 void mp_chmap_get_reorder(int src[MP_NUM_CHANNELS], const struct mp_chmap *from,
322 const struct mp_chmap *to)
323 {
324 for (int n = 0; n < MP_NUM_CHANNELS; n++)
325 src[n] = -1;
326
327 if (mp_chmap_is_unknown(from) || mp_chmap_is_unknown(to)) {
328 for (int n = 0; n < to->num; n++)
329 src[n] = n < from->num ? n : -1;
330 return;
331 }
332
333 for (int n = 0; n < to->num; n++) {
334 for (int i = 0; i < from->num; i++) {
335 if (to->speaker[n] == from->speaker[i]) {
336 src[n] = i;
337 break;
338 }
339 }
340 }
341
342 for (int n = 0; n < to->num; n++)
343 assert(src[n] < 0 || (to->speaker[n] == from->speaker[src[n]]));
344 }
345
346 // Return the number of channels only in a.
mp_chmap_diffn(const struct mp_chmap * a,const struct mp_chmap * b)347 int mp_chmap_diffn(const struct mp_chmap *a, const struct mp_chmap *b)
348 {
349 uint64_t a_mask = mp_chmap_to_lavc_unchecked(a);
350 uint64_t b_mask = mp_chmap_to_lavc_unchecked(b);
351 return av_popcount64((a_mask ^ b_mask) & a_mask);
352 }
353
354 // Returns something like "fl-fr-fc". If there's a standard layout in lavc
355 // order, return that, e.g. "3.0" instead of "fl-fr-fc".
356 // Unassigned but valid speakers get names like "sp28".
mp_chmap_to_str_buf(char * buf,size_t buf_size,const struct mp_chmap * src)357 char *mp_chmap_to_str_buf(char *buf, size_t buf_size, const struct mp_chmap *src)
358 {
359 buf[0] = '\0';
360
361 if (mp_chmap_is_unknown(src)) {
362 snprintf(buf, buf_size, "unknown%d", src->num);
363 return buf;
364 }
365
366 for (int n = 0; n < src->num; n++) {
367 int sp = src->speaker[n];
368 const char *s = sp < MP_SPEAKER_ID_COUNT ? speaker_names[sp][0] : NULL;
369 char sp_buf[10];
370 if (!s) {
371 snprintf(sp_buf, sizeof(sp_buf), "sp%d", sp);
372 s = sp_buf;
373 }
374 mp_snprintf_cat(buf, buf_size, "%s%s", n > 0 ? "-" : "", s);
375 }
376
377 // To standard layout name
378 for (int n = 0; std_layout_names[n][0]; n++) {
379 if (strcmp(buf, std_layout_names[n][1]) == 0) {
380 snprintf(buf, buf_size, "%s", std_layout_names[n][0]);
381 break;
382 }
383 }
384
385 return buf;
386 }
387
388 // If src can be parsed as channel map (as produced by mp_chmap_to_str()),
389 // return true and set *dst. Otherwise, return false and don't change *dst.
390 // Note: call mp_chmap_is_valid() to test whether the returned map is valid
391 // the map could be empty, or contain multiply mapped channels
mp_chmap_from_str(struct mp_chmap * dst,bstr src)392 bool mp_chmap_from_str(struct mp_chmap *dst, bstr src)
393 {
394 // Single number corresponds to mp_chmap_from_channels()
395 if (src.len > 0) {
396 bstr t = src;
397 bool unknown = bstr_eatstart0(&t, "unknown");
398 bstr rest;
399 long long count = bstrtoll(t, &rest, 10);
400 if (rest.len == 0) {
401 struct mp_chmap res;
402 if (unknown) {
403 mp_chmap_set_unknown(&res, count);
404 } else {
405 mp_chmap_from_channels(&res, count);
406 }
407 if (mp_chmap_is_valid(&res)) {
408 *dst = res;
409 return true;
410 }
411 }
412 }
413
414 // From standard layout name
415 for (int n = 0; std_layout_names[n][0]; n++) {
416 if (bstr_equals0(src, std_layout_names[n][0])) {
417 src = bstr0(std_layout_names[n][1]);
418 break;
419 }
420 }
421
422 // Explicit speaker list (separated by "-")
423 struct mp_chmap res = {0};
424 while (src.len) {
425 bstr s;
426 bstr_split_tok(src, "-", &s, &src);
427 int speaker = -1;
428 for (int n = 0; n < MP_SPEAKER_ID_COUNT; n++) {
429 const char *name = speaker_names[n][0];
430 if (name && bstr_equals0(s, name)) {
431 speaker = n;
432 break;
433 }
434 }
435 if (speaker < 0) {
436 if (bstr_eatstart0(&s, "sp")) {
437 long long sp = bstrtoll(s, &s, 0);
438 if (s.len == 0 && sp >= 0 && sp < MP_SPEAKER_ID_COUNT)
439 speaker = sp;
440 }
441 if (speaker < 0)
442 return false;
443 }
444 if (res.num >= MP_NUM_CHANNELS)
445 return false;
446 res.speaker[res.num] = speaker;
447 res.num++;
448 }
449
450 *dst = res;
451 return true;
452 }
453
454 // Output a human readable "canonical" channel map string. Converting this from
455 // a string back to a channel map can yield a different map, but the string
456 // looks nicer. E.g. "fc-fl-fr-na" becomes "3.0".
mp_chmap_to_str_hr_buf(char * buf,size_t buf_size,const struct mp_chmap * src)457 char *mp_chmap_to_str_hr_buf(char *buf, size_t buf_size, const struct mp_chmap *src)
458 {
459 struct mp_chmap map = *src;
460 mp_chmap_remove_na(&map);
461 for (int n = 0; std_layout_names[n][0]; n++) {
462 struct mp_chmap s;
463 if (mp_chmap_from_str(&s, bstr0(std_layout_names[n][0])) &&
464 mp_chmap_equals_reordered(&s, &map))
465 {
466 map = s;
467 break;
468 }
469 }
470 return mp_chmap_to_str_buf(buf, buf_size, &map);
471 }
472
mp_chmap_print_help(struct mp_log * log)473 void mp_chmap_print_help(struct mp_log *log)
474 {
475 mp_info(log, "Speakers:\n");
476 for (int n = 0; n < MP_SPEAKER_ID_COUNT; n++) {
477 if (speaker_names[n][0])
478 mp_info(log, " %-16s (%s)\n",
479 speaker_names[n][0], speaker_names[n][1]);
480 }
481 mp_info(log, "Standard layouts:\n");
482 for (int n = 0; std_layout_names[n][0]; n++) {
483 mp_info(log, " %-16s (%s)\n",
484 std_layout_names[n][0], std_layout_names[n][1]);
485 }
486 for (int n = 0; n < MP_NUM_CHANNELS; n++)
487 mp_info(log, " unknown%d\n", n + 1);
488 }
489