]> code.delx.au - pulseaudio/blobdiff - src/pulse/format.c
format: Expose pa_format_info<->pa_sample_spec conversion functions
[pulseaudio] / src / pulse / format.c
index 112b103c802c22c28368daf36de02b1cb5790365..6e8e70795f4bae5af922398f3c8b78f8f7dd9306 100644 (file)
 
 static int pa_format_info_prop_compatible(const char *one, const char *two);
 
-const char *pa_encoding_to_string(pa_encoding_t e) {
-    static const char* const table[]= {
-        [PA_ENCODING_PCM] = "pcm",
-        [PA_ENCODING_AC3_IEC61937] = "ac3-iec61937",
-        [PA_ENCODING_EAC3_IEC61937] = "eac3-iec61937",
-        [PA_ENCODING_MPEG_IEC61937] = "mpeg-iec61937",
-        [PA_ENCODING_DTS_IEC61937] = "dts-iec61937",
-        [PA_ENCODING_ANY] = "any",
-    };
+static const char* const _encoding_str_table[]= {
+    [PA_ENCODING_PCM] = "pcm",
+    [PA_ENCODING_AC3_IEC61937] = "ac3-iec61937",
+    [PA_ENCODING_EAC3_IEC61937] = "eac3-iec61937",
+    [PA_ENCODING_MPEG_IEC61937] = "mpeg-iec61937",
+    [PA_ENCODING_DTS_IEC61937] = "dts-iec61937",
+    [PA_ENCODING_ANY] = "any",
+};
 
+const char *pa_encoding_to_string(pa_encoding_t e) {
     if (e < 0 || e >= PA_ENCODING_MAX)
         return NULL;
 
-    return table[e];
+    return _encoding_str_table[e];
+}
+
+pa_encoding_t pa_encoding_from_string(const char *encoding) {
+    pa_encoding_t e;
+
+    for (e = PA_ENCODING_ANY; e < PA_ENCODING_MAX; e++)
+        if (pa_streq(_encoding_str_table[e], encoding))
+            return e;
+
+    return PA_ENCODING_INVALID;
 }
 
 pa_format_info* pa_format_info_new(void) {
@@ -125,6 +135,44 @@ char *pa_format_info_snprint(char *s, size_t l, const pa_format_info *f) {
     return s;
 }
 
+pa_format_info* pa_format_info_from_string(const char *str) {
+    pa_format_info *f = pa_format_info_new();
+    char *encoding = NULL, *properties = NULL;
+    size_t pos;
+
+    pos = strcspn(str, ",");
+
+    encoding = pa_xstrndup(str, pos);
+    f->encoding = pa_encoding_from_string(pa_strip(encoding));
+    if (f->encoding == PA_ENCODING_INVALID)
+        goto error;
+
+    if (pos != strlen(str)) {
+        pa_proplist *plist;
+
+        properties = pa_xstrdup(&str[pos+1]);
+        plist = pa_proplist_from_string(properties);
+
+        if (!plist)
+            goto error;
+
+        pa_proplist_free(f->plist);
+        f->plist = plist;
+    }
+
+out:
+    if (encoding)
+        pa_xfree(encoding);
+    if (properties)
+        pa_xfree(properties);
+    return f;
+
+error:
+    pa_format_info_free(f);
+    f = NULL;
+    goto out;
+}
+
 int pa_format_info_is_compatible(pa_format_info *first, pa_format_info *second) {
     const char *key;
     void *state = NULL;
@@ -171,20 +219,20 @@ pa_format_info* pa_format_info_from_sample_spec(pa_sample_spec *ss, pa_channel_m
 }
 
 /* For PCM streams */
-pa_bool_t pa_format_info_to_sample_spec(pa_format_info *f, pa_sample_spec *ss, pa_channel_map *map) {
+int pa_format_info_to_sample_spec(pa_format_info *f, pa_sample_spec *ss, pa_channel_map *map) {
     char *sf = NULL, *m = NULL;
     int rate, channels;
-    pa_bool_t ret = FALSE;
+    int ret = -PA_ERR_INVALID;
 
     pa_assert(f);
     pa_assert(ss);
     pa_return_val_if_fail(f->encoding == PA_ENCODING_PCM, FALSE);
 
-    if (!pa_format_info_get_prop_string(f, PA_PROP_FORMAT_SAMPLE_FORMAT, &sf))
+    if (pa_format_info_get_prop_string(f, PA_PROP_FORMAT_SAMPLE_FORMAT, &sf))
         goto out;
-    if (!pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate))
+    if (pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate))
         goto out;
-    if (!pa_format_info_get_prop_int(f, PA_PROP_FORMAT_CHANNELS, &channels))
+    if (pa_format_info_get_prop_int(f, PA_PROP_FORMAT_CHANNELS, &channels))
         goto out;
 
     if ((ss->format = pa_parse_sample_format(sf)) == PA_SAMPLE_INVALID)
@@ -196,12 +244,12 @@ pa_bool_t pa_format_info_to_sample_spec(pa_format_info *f, pa_sample_spec *ss, p
     if (map) {
         pa_channel_map_init(map);
 
-        if (pa_format_info_get_prop_string(f, PA_PROP_FORMAT_CHANNEL_MAP, &m))
+        if (pa_format_info_get_prop_string(f, PA_PROP_FORMAT_CHANNEL_MAP, &m) == 0)
             if (pa_channel_map_parse(map, m) == NULL)
                 goto out;
     }
 
-    ret = TRUE;
+    ret = 0;
 
 out:
     if (sf)
@@ -213,23 +261,23 @@ out:
 }
 
 /* For compressed streams */
-pa_bool_t pa_format_info_to_sample_spec_fake(pa_format_info *f, pa_sample_spec *ss) {
+int pa_format_info_to_sample_spec_fake(pa_format_info *f, pa_sample_spec *ss) {
     int rate;
 
     pa_assert(f);
     pa_assert(ss);
-    pa_return_val_if_fail(f->encoding != PA_ENCODING_PCM, FALSE);
+    pa_return_val_if_fail(f->encoding != PA_ENCODING_PCM, -PA_ERR_INVALID);
 
     ss->format = PA_SAMPLE_S16LE;
     ss->channels = 2;
 
-    pa_return_val_if_fail(pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate), FALSE);
+    pa_return_val_if_fail(pa_format_info_get_prop_int(f, PA_PROP_FORMAT_RATE, &rate) == 0, -PA_ERR_INVALID);
     ss->rate = (uint32_t) rate;
 
     if (f->encoding == PA_ENCODING_EAC3_IEC61937)
         ss->rate *= 4;
 
-    return TRUE;
+    return 0;
 }
 
 void pa_format_info_set_sample_format(pa_format_info *f, pa_sample_format_t sf) {
@@ -252,7 +300,7 @@ void pa_format_info_set_channel_map(pa_format_info *f, const pa_channel_map *map
     pa_format_info_set_prop_string(f, PA_PROP_FORMAT_CHANNEL_MAP, map_str);
 }
 
-pa_bool_t pa_format_info_get_prop_int(pa_format_info *f, const char *key, int *v) {
+int pa_format_info_get_prop_int(pa_format_info *f, const char *key, int *v) {
     const char *str;
     json_object *o;
 
@@ -260,21 +308,26 @@ pa_bool_t pa_format_info_get_prop_int(pa_format_info *f, const char *key, int *v
     pa_assert(key);
     pa_assert(v);
 
-    pa_return_val_if_fail(str = pa_proplist_gets(f->plist, key), FALSE);
+    str = pa_proplist_gets(f->plist, key);
+    if (!str)
+        return -PA_ERR_NOENTITY;
+
     o = json_tokener_parse(str);
-    pa_return_val_if_fail(!is_error(o), FALSE);
+    if (is_error(o))
+        return -PA_ERR_INVALID;
+
     if (json_object_get_type(o) != json_type_int) {
         json_object_put(o);
-        return FALSE;
+        return -PA_ERR_INVALID;
     }
 
     *v = json_object_get_int(o);
     json_object_put(o);
 
-    return TRUE;
+    return 0;
 }
 
-pa_bool_t pa_format_info_get_prop_string(pa_format_info *f, const char *key, char **v) {
+int pa_format_info_get_prop_string(pa_format_info *f, const char *key, char **v) {
     const char *str = NULL;
     json_object *o;
 
@@ -282,21 +335,23 @@ pa_bool_t pa_format_info_get_prop_string(pa_format_info *f, const char *key, cha
     pa_assert(key);
     pa_assert(v);
 
-    str = pa_proplist_gets(f->plist, key), FALSE;
+    str = pa_proplist_gets(f->plist, key);
     if (!str)
-        return FALSE;
+        return -PA_ERR_NOENTITY;
 
     o = json_tokener_parse(str);
-    pa_return_val_if_fail(!is_error(o), FALSE);
+    if (is_error(o))
+        return -PA_ERR_INVALID;
+
     if (json_object_get_type(o) != json_type_string) {
         json_object_put(o);
-        return FALSE;
+        return -PA_ERR_INVALID;
     }
 
     *v = pa_xstrdup(json_object_get_string(o));
     json_object_put(o);
 
-    return TRUE;
+    return 0;
 }
 
 void pa_format_info_set_prop_int(pa_format_info *f, const char *key, int value) {