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