add support for MPEG-2 AAC pass-through
[platform/upstream/pulseaudio.git] / src / pulse / format.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2011 Intel Corporation
5   Copyright 2011 Collabora Multimedia
6   Copyright 2011 Arun Raghavan <arun.raghavan@collabora.co.uk>
7
8   PulseAudio is free software; you can redistribute it and/or modify
9   it under the terms of the GNU Lesser General Public License as published
10   by the Free Software Foundation; either version 2.1 of the License,
11   or (at your option) any later version.
12
13   PulseAudio is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with PulseAudio; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21   USA.
22 ***/
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <json.h>
29
30 #include <pulse/internal.h>
31 #include <pulse/xmalloc.h>
32
33 #include <pulsecore/core-util.h>
34 #include <pulsecore/i18n.h>
35 #include <pulsecore/macro.h>
36
37 #include "format.h"
38
39 #define PA_JSON_MIN_KEY "min"
40 #define PA_JSON_MAX_KEY "max"
41
42 static int pa_format_info_prop_compatible(const char *one, const char *two);
43
44 static const char* const _encoding_str_table[]= {
45     [PA_ENCODING_PCM] = "pcm",
46     [PA_ENCODING_AC3_IEC61937] = "ac3-iec61937",
47     [PA_ENCODING_EAC3_IEC61937] = "eac3-iec61937",
48     [PA_ENCODING_MPEG_IEC61937] = "mpeg-iec61937",
49     [PA_ENCODING_DTS_IEC61937] = "dts-iec61937",
50     [PA_ENCODING_MPEG2_AAC_IEC61937] = "mpeg2-aac-iec61937",
51     [PA_ENCODING_ANY] = "any",
52 };
53
54 const char *pa_encoding_to_string(pa_encoding_t e) {
55     if (e < 0 || e >= PA_ENCODING_MAX)
56         return NULL;
57
58     return _encoding_str_table[e];
59 }
60
61 pa_encoding_t pa_encoding_from_string(const char *encoding) {
62     pa_encoding_t e;
63
64     for (e = PA_ENCODING_ANY; e < PA_ENCODING_MAX; e++)
65         if (pa_streq(_encoding_str_table[e], encoding))
66             return e;
67
68     return PA_ENCODING_INVALID;
69 }
70
71 pa_format_info* pa_format_info_new(void) {
72     pa_format_info *f = pa_xnew(pa_format_info, 1);
73
74     f->encoding = PA_ENCODING_INVALID;
75     f->plist = pa_proplist_new();
76
77     return f;
78 }
79
80 pa_format_info* pa_format_info_copy(const pa_format_info *src) {
81     pa_format_info *dest;
82
83     pa_assert(src);
84
85     dest = pa_xnew(pa_format_info, 1);
86
87     dest->encoding = src->encoding;
88
89     if (src->plist)
90         dest->plist = pa_proplist_copy(src->plist);
91     else
92         dest->plist = NULL;
93
94     return dest;
95 }
96
97 void pa_format_info_free(pa_format_info *f) {
98     pa_assert(f);
99
100     pa_proplist_free(f->plist);
101     pa_xfree(f);
102 }
103
104 int pa_format_info_valid(const pa_format_info *f) {
105     return (f->encoding >= 0 && f->encoding < PA_ENCODING_MAX && f->plist != NULL);
106 }
107
108 int pa_format_info_is_pcm(const pa_format_info *f) {
109     return f->encoding == PA_ENCODING_PCM;
110 }
111
112 char *pa_format_info_snprint(char *s, size_t l, const pa_format_info *f) {
113     char *tmp;
114
115     pa_assert(s);
116     pa_assert(l > 0);
117     pa_assert(f);
118
119     pa_init_i18n();
120
121     if (!pa_format_info_valid(f))
122         pa_snprintf(s, l, _("(invalid)"));
123     else {
124         tmp = pa_proplist_to_string_sep(f->plist, "  ");
125         if (tmp[0])
126             pa_snprintf(s, l, "%s, %s", pa_encoding_to_string(f->encoding), tmp);
127         else
128             pa_snprintf(s, l, "%s", pa_encoding_to_string(f->encoding));
129         pa_xfree(tmp);
130     }
131
132     return s;
133 }
134
135 pa_format_info* pa_format_info_from_string(const char *str) {
136     pa_format_info *f = pa_format_info_new();
137     char *encoding = NULL, *properties = NULL;
138     size_t pos;
139
140     pos = strcspn(str, ",");
141
142     encoding = pa_xstrndup(str, pos);
143     f->encoding = pa_encoding_from_string(pa_strip(encoding));
144     if (f->encoding == PA_ENCODING_INVALID)
145         goto error;
146
147     if (pos != strlen(str)) {
148         pa_proplist *plist;
149
150         properties = pa_xstrdup(&str[pos+1]);
151         plist = pa_proplist_from_string(properties);
152
153         if (!plist)
154             goto error;
155
156         pa_proplist_free(f->plist);
157         f->plist = plist;
158     }
159
160 out:
161     if (encoding)
162         pa_xfree(encoding);
163     if (properties)
164         pa_xfree(properties);
165     return f;
166
167 error:
168     pa_format_info_free(f);
169     f = NULL;
170     goto out;
171 }
172
173 int pa_format_info_is_compatible(pa_format_info *first, pa_format_info *second) {
174     const char *key;
175     void *state = NULL;
176
177     pa_assert(first);
178     pa_assert(second);
179
180     if (first->encoding != second->encoding)
181         return FALSE;
182
183     while ((key = pa_proplist_iterate(first->plist, &state))) {
184         const char *value_one, *value_two;
185
186         value_one = pa_proplist_gets(first->plist, key);
187         value_two = pa_proplist_gets(second->plist, key);
188
189         if (!value_two || !pa_format_info_prop_compatible(value_one, value_two))
190             return FALSE;
191     }
192
193     return TRUE;
194 }
195
196 pa_format_info* pa_format_info_from_sample_spec(pa_sample_spec *ss, pa_channel_map *map) {
197     char cm[PA_CHANNEL_MAP_SNPRINT_MAX];
198     pa_format_info *f;
199
200     pa_assert(ss && pa_sample_spec_valid(ss));
201     pa_assert(!map || pa_channel_map_valid(map));
202
203     f = pa_format_info_new();
204     f->encoding = PA_ENCODING_PCM;
205
206     pa_format_info_set_sample_format(f, ss->format);
207     pa_format_info_set_rate(f, ss->rate);
208     pa_format_info_set_channels(f, ss->channels);
209
210     if (map) {
211         pa_channel_map_snprint(cm, sizeof(cm), map);
212         pa_format_info_set_prop_string(f, PA_PROP_FORMAT_CHANNEL_MAP, cm);
213     }
214
215     return f;
216 }
217
218 /* For compressed streams */
219 static int pa_format_info_to_sample_spec_fake(pa_format_info *f, pa_sample_spec *ss) {
220     int rate;
221
222     pa_assert(f);
223     pa_assert(ss);
224
225     /* Note: When we add support for non-IEC61937 encapsulated compressed
226      * formats, this function should return a non-zero values for these. */
227
228     ss->format = PA_SAMPLE_S16LE;
229     ss->channels = 2;
230
231     pa_return_val_if_fail(pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate) == 0, -PA_ERR_INVALID);
232     ss->rate = (uint32_t) rate;
233
234     if (f->encoding == PA_ENCODING_EAC3_IEC61937)
235         ss->rate *= 4;
236
237     return 0;
238 }
239
240 /* For PCM streams */
241 int pa_format_info_to_sample_spec(pa_format_info *f, pa_sample_spec *ss, pa_channel_map *map) {
242     char *sf = NULL, *m = NULL;
243     int rate, channels;
244     int ret = -PA_ERR_INVALID;
245
246     pa_assert(f);
247     pa_assert(ss);
248
249     if (!pa_format_info_is_pcm(f))
250         return pa_format_info_to_sample_spec_fake(f, ss);
251
252     if (pa_format_info_get_prop_string(f, PA_PROP_FORMAT_SAMPLE_FORMAT, &sf))
253         goto out;
254     if (pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate))
255         goto out;
256     if (pa_format_info_get_prop_int(f, PA_PROP_FORMAT_CHANNELS, &channels))
257         goto out;
258
259     if ((ss->format = pa_parse_sample_format(sf)) == PA_SAMPLE_INVALID)
260         goto out;
261
262     ss->rate = (uint32_t) rate;
263     ss->channels = (uint8_t) channels;
264
265     if (map) {
266         pa_channel_map_init(map);
267
268         if (pa_format_info_get_prop_string(f, PA_PROP_FORMAT_CHANNEL_MAP, &m) == 0)
269             if (pa_channel_map_parse(map, m) == NULL)
270                 goto out;
271     }
272
273     ret = 0;
274
275 out:
276     if (sf)
277         pa_xfree(sf);
278     if (m)
279         pa_xfree(m);
280
281     return ret;
282 }
283
284 pa_prop_type_t pa_format_info_get_prop_type(pa_format_info *f, const char *key) {
285     const char *str;
286     json_object *o, *o1;
287     pa_prop_type_t type;
288
289     pa_assert(f);
290     pa_assert(key);
291
292     str = pa_proplist_gets(f->plist, key);
293     if (!str)
294         return PA_PROP_TYPE_INVALID;
295
296     o = json_tokener_parse(str);
297     if (is_error(o))
298         return PA_PROP_TYPE_INVALID;
299
300     switch (json_object_get_type(o)) {
301         case json_type_int:
302             type = PA_PROP_TYPE_INT;
303             break;
304
305         case json_type_string:
306             type = PA_PROP_TYPE_STRING;
307             break;
308
309         case json_type_array:
310             if (json_object_array_length(o) == 0) {
311                 /* Unlikely, but let's account for this anyway. We need at
312                  * least one element to figure out the array type. */
313                 type = PA_PROP_TYPE_INVALID;
314                 break;
315             }
316
317             o1 = json_object_array_get_idx(o, 1);
318
319             if (json_object_get_type(o1) == json_type_int)
320                 type = PA_PROP_TYPE_INT_ARRAY;
321             else if (json_object_get_type(o1) == json_type_string)
322                 type = PA_PROP_TYPE_STRING_ARRAY;
323             else
324                 type = PA_PROP_TYPE_INVALID;
325
326             json_object_put(o1);
327             break;
328
329         case json_type_object:
330             /* We actually know at this point that it's a int range, but let's
331              * confirm. */
332             o1 = json_object_object_get(o, PA_JSON_MIN_KEY);
333             if (!o1) {
334                 type = PA_PROP_TYPE_INVALID;
335                 break;
336             }
337             json_object_put(o1);
338
339             o1 = json_object_object_get(o, PA_JSON_MAX_KEY);
340             if (!o1) {
341                 type = PA_PROP_TYPE_INVALID;
342                 break;
343             }
344             json_object_put(o1);
345
346             type = PA_PROP_TYPE_INT_RANGE;
347             break;
348
349         default:
350             type = PA_PROP_TYPE_INVALID;
351             break;
352     }
353
354     json_object_put(o);
355     return type;
356 }
357
358 int pa_format_info_get_prop_int(pa_format_info *f, const char *key, int *v) {
359     const char *str;
360     json_object *o;
361
362     pa_assert(f);
363     pa_assert(key);
364     pa_assert(v);
365
366     str = pa_proplist_gets(f->plist, key);
367     if (!str)
368         return -PA_ERR_NOENTITY;
369
370     o = json_tokener_parse(str);
371     if (is_error(o))
372         return -PA_ERR_INVALID;
373
374     if (json_object_get_type(o) != json_type_int) {
375         json_object_put(o);
376         return -PA_ERR_INVALID;
377     }
378
379     *v = json_object_get_int(o);
380     json_object_put(o);
381
382     return 0;
383 }
384
385 int pa_format_info_get_prop_int_range(pa_format_info *f, const char *key, int *min, int *max) {
386     const char *str;
387     json_object *o, *o1;
388     int ret = -PA_ERR_INVALID;
389
390     pa_assert(f);
391     pa_assert(key);
392     pa_assert(min);
393     pa_assert(max);
394
395     str = pa_proplist_gets(f->plist, key);
396     if (!str)
397         return -PA_ERR_NOENTITY;
398
399     o = json_tokener_parse(str);
400     if (is_error(o))
401         return -PA_ERR_INVALID;
402
403     if (json_object_get_type(o) != json_type_object)
404         goto out;
405
406     if (!(o1 = json_object_object_get(o, PA_JSON_MIN_KEY)))
407         goto out;
408
409     *min = json_object_get_int(o1);
410     json_object_put(o1);
411
412     if (!(o1 = json_object_object_get(o, PA_JSON_MAX_KEY)))
413         goto out;
414
415     *max = json_object_get_int(o1);
416     json_object_put(o1);
417
418     ret = 0;
419
420 out:
421     json_object_put(o);
422     return ret;
423 }
424
425 int pa_format_info_get_prop_int_array(pa_format_info *f, const char *key, int **values, int *n_values)
426 {
427     const char *str;
428     json_object *o, *o1;
429     int i, ret = -PA_ERR_INVALID;
430
431     pa_assert(f);
432     pa_assert(key);
433     pa_assert(values);
434     pa_assert(n_values);
435
436     str = pa_proplist_gets(f->plist, key);
437     if (!str)
438         return -PA_ERR_NOENTITY;
439
440     o = json_tokener_parse(str);
441     if (is_error(o))
442         return -PA_ERR_INVALID;
443
444     if (json_object_get_type(o) != json_type_array)
445         goto out;
446
447     *n_values = json_object_array_length(o);
448     *values = pa_xnew(int, *n_values);
449
450     for (i = 0; i < *n_values; i++) {
451         o1 = json_object_array_get_idx(o, i);
452
453         if (json_object_get_type(o1) != json_type_int) {
454             json_object_put(o1);
455             goto out;
456         }
457
458         (*values)[i] = json_object_get_int(o1);
459         json_object_put(o1);
460     }
461
462     ret = 0;
463
464 out:
465     json_object_put(o);
466     return ret;
467 }
468
469 int pa_format_info_get_prop_string(pa_format_info *f, const char *key, char **v) {
470     const char *str = NULL;
471     json_object *o;
472
473     pa_assert(f);
474     pa_assert(key);
475     pa_assert(v);
476
477     str = pa_proplist_gets(f->plist, key);
478     if (!str)
479         return -PA_ERR_NOENTITY;
480
481     o = json_tokener_parse(str);
482     if (is_error(o))
483         return -PA_ERR_INVALID;
484
485     if (json_object_get_type(o) != json_type_string) {
486         json_object_put(o);
487         return -PA_ERR_INVALID;
488     }
489
490     *v = pa_xstrdup(json_object_get_string(o));
491     json_object_put(o);
492
493     return 0;
494 }
495
496 int pa_format_info_get_prop_string_array(pa_format_info *f, const char *key, char ***values, int *n_values)
497 {
498     const char *str;
499     json_object *o, *o1;
500     int i, ret = -PA_ERR_INVALID;
501
502     pa_assert(f);
503     pa_assert(key);
504     pa_assert(values);
505     pa_assert(n_values);
506
507     str = pa_proplist_gets(f->plist, key);
508     if (!str)
509         return -PA_ERR_NOENTITY;
510
511     o = json_tokener_parse(str);
512     if (is_error(o))
513         return -PA_ERR_INVALID;
514
515     if (json_object_get_type(o) != json_type_array)
516         goto out;
517
518     *n_values = json_object_array_length(o);
519     *values = pa_xnew(char *, *n_values);
520
521     for (i = 0; i < *n_values; i++) {
522         o1 = json_object_array_get_idx(o, i);
523
524         if (json_object_get_type(o1) != json_type_string) {
525             json_object_put(o1);
526             goto out;
527         }
528
529         (*values)[i] = pa_xstrdup(json_object_get_string(o1));
530         json_object_put(o1);
531     }
532
533     ret = 0;
534
535 out:
536     json_object_put(o);
537     return ret;
538 }
539
540 void pa_format_info_free_string_array(char **values, int n_values) {
541     int i;
542
543     for (i = 0; i < n_values; i++)
544         pa_xfree(values[i]);
545
546     pa_xfree(values);
547 }
548
549 void pa_format_info_set_sample_format(pa_format_info *f, pa_sample_format_t sf) {
550     pa_format_info_set_prop_string(f, PA_PROP_FORMAT_SAMPLE_FORMAT, pa_sample_format_to_string(sf));
551 }
552
553 void pa_format_info_set_rate(pa_format_info *f, int rate) {
554     pa_format_info_set_prop_int(f, PA_PROP_FORMAT_RATE, rate);
555 }
556
557 void pa_format_info_set_channels(pa_format_info *f, int channels) {
558     pa_format_info_set_prop_int(f, PA_PROP_FORMAT_CHANNELS, channels);
559 }
560
561 void pa_format_info_set_channel_map(pa_format_info *f, const pa_channel_map *map) {
562     char map_str[PA_CHANNEL_MAP_SNPRINT_MAX];
563
564     pa_channel_map_snprint(map_str, sizeof(map_str), map);
565
566     pa_format_info_set_prop_string(f, PA_PROP_FORMAT_CHANNEL_MAP, map_str);
567 }
568
569 void pa_format_info_set_prop_int(pa_format_info *f, const char *key, int value) {
570     json_object *o;
571
572     pa_assert(f);
573     pa_assert(key);
574
575     o = json_object_new_int(value);
576
577     pa_proplist_sets(f->plist, key, json_object_to_json_string(o));
578
579     json_object_put(o);
580 }
581
582 void pa_format_info_set_prop_int_array(pa_format_info *f, const char *key, const int *values, int n_values) {
583     json_object *o;
584     int i;
585
586     pa_assert(f);
587     pa_assert(key);
588
589     o = json_object_new_array();
590
591     for (i = 0; i < n_values; i++)
592         json_object_array_add(o, json_object_new_int(values[i]));
593
594     pa_proplist_sets(f->plist, key, json_object_to_json_string(o));
595
596     json_object_put(o);
597 }
598
599 void pa_format_info_set_prop_int_range(pa_format_info *f, const char *key, int min, int max) {
600     json_object *o;
601
602     pa_assert(f);
603     pa_assert(key);
604
605     o = json_object_new_object();
606
607     json_object_object_add(o, PA_JSON_MIN_KEY, json_object_new_int(min));
608     json_object_object_add(o, PA_JSON_MAX_KEY, json_object_new_int(max));
609
610     pa_proplist_sets(f->plist, key, json_object_to_json_string(o));
611
612     json_object_put(o);
613 }
614
615 void pa_format_info_set_prop_string(pa_format_info *f, const char *key, const char *value) {
616     json_object *o;
617
618     pa_assert(f);
619     pa_assert(key);
620
621     o = json_object_new_string(value);
622
623     pa_proplist_sets(f->plist, key, json_object_to_json_string(o));
624
625     json_object_put(o);
626 }
627
628 void pa_format_info_set_prop_string_array(pa_format_info *f, const char *key, const char **values, int n_values) {
629     json_object *o;
630     int i;
631
632     pa_assert(f);
633     pa_assert(key);
634
635     o = json_object_new_array();
636
637     for (i = 0; i < n_values; i++)
638         json_object_array_add(o, json_object_new_string(values[i]));
639
640     pa_proplist_sets(f->plist, key, json_object_to_json_string(o));
641
642     json_object_put(o);
643 }
644
645 static pa_bool_t pa_json_is_fixed_type(json_object *o)
646 {
647     switch(json_object_get_type(o)) {
648         case json_type_object:
649         case json_type_array:
650             return FALSE;
651
652         default:
653             return TRUE;
654     }
655 }
656
657 static int pa_json_value_equal(json_object *o1, json_object *o2) {
658     return (json_object_get_type(o1) == json_object_get_type(o2)) &&
659         pa_streq(json_object_to_json_string(o1), json_object_to_json_string(o2));
660 }
661
662 static int pa_format_info_prop_compatible(const char *one, const char *two) {
663     json_object *o1 = NULL, *o2 = NULL;
664     int i, ret = 0;
665
666     o1 = json_tokener_parse(one);
667     if (is_error(o1))
668         goto out;
669
670     o2 = json_tokener_parse(two);
671     if (is_error(o2))
672         goto out;
673
674     /* We don't deal with both values being non-fixed - just because there is no immediate need (FIXME) */
675     pa_return_val_if_fail(pa_json_is_fixed_type(o1) || pa_json_is_fixed_type(o2), FALSE);
676
677     if (pa_json_is_fixed_type(o1) && pa_json_is_fixed_type(o2)) {
678         ret = pa_json_value_equal(o1, o2);
679         goto out;
680     }
681
682     if (pa_json_is_fixed_type(o1)) {
683         json_object *tmp = o2;
684         o2 = o1;
685         o1 = tmp;
686     }
687
688     /* o2 is now a fixed type, and o1 is not */
689
690     if (json_object_get_type(o1) == json_type_array) {
691         for (i = 0; i < json_object_array_length(o1); i++) {
692             if (pa_json_value_equal(json_object_array_get_idx(o1, i), o2)) {
693                 ret = 1;
694                 break;
695             }
696         }
697     } else if (json_object_get_type(o1) == json_type_object) {
698         /* o1 should be a range type */
699         int min, max, v;
700         json_object *o_min = NULL, *o_max = NULL;
701
702         if (json_object_get_type(o2) != json_type_int) {
703             /* We don't support non-integer ranges */
704             goto out;
705         }
706
707         o_min = json_object_object_get(o1, PA_JSON_MIN_KEY);
708         if (!o_min || json_object_get_type(o_min) != json_type_int)
709             goto out;
710
711         o_max = json_object_object_get(o1, PA_JSON_MAX_KEY);
712         if (!o_max || json_object_get_type(o_max) != json_type_int)
713             goto out;
714
715         v = json_object_get_int(o2);
716         min = json_object_get_int(o_min);
717         max = json_object_get_int(o_max);
718
719         ret = v >= min && v <= max;
720     } else {
721         pa_log_warn("Got a format type that we don't support");
722     }
723
724 out:
725     if (o1)
726         json_object_put(o1);
727     if (o2)
728         json_object_put(o2);
729
730     return ret;
731 }