audio: add gst_audio_make_raw_caps()
authorGuillaume Desmottes <guillaume.desmottes@collabora.com>
Wed, 27 May 2020 13:41:43 +0000 (15:41 +0200)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 2 Jun 2020 11:57:42 +0000 (11:57 +0000)
More binding friendly version of GST_AUDIO_CAPS_MAKE().

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/676>

gst-libs/gst/audio/audio-format.c
gst-libs/gst/audio/audio-format.h
gst-libs/gst/audio/audio-info.h
tests/check/libs/audio.c

index 2303495..cc5345e 100644 (file)
@@ -578,3 +578,70 @@ gst_audio_formats_raw (guint * len)
   *len = all->n;
   return all->formats;
 }
+
+/**
+ * gst_audio_make_raw_caps:
+ * @formats: (array length=len) (nullable): an array of raw #GstAudioFormat, or %NULL
+ * @len: the size of @formats
+ * @layout: the layout of audio samples
+ *
+ * Return a generic raw audio caps for formats defined in @formats.
+ * If @formats is %NULL returns a caps for all the supported raw audio formats,
+ * see gst_audio_formats_raw().
+ *
+ * Returns: (transfer full): an audio @GstCaps
+ * Since: 1.18
+ */
+GstCaps *
+gst_audio_make_raw_caps (const GstAudioFormat formats[], guint len,
+    GstAudioLayout layout)
+{
+  GstStructure *s;
+  GValue format = G_VALUE_INIT;
+  GstCaps *caps;
+  const gchar *layout_str;
+
+  g_return_val_if_fail ((formats && len > 0) || (!formats && len == 0), NULL);
+
+  if (!formats) {
+    formats = gst_audio_formats_raw (&len);
+  }
+
+  if (len > 1) {
+    guint i;
+
+    g_value_init (&format, GST_TYPE_LIST);
+
+    for (i = 0; i < len; i++) {
+      GValue v = G_VALUE_INIT;
+
+      g_return_val_if_fail (formats[i] != GST_AUDIO_FORMAT_UNKNOWN
+          && formats[i] != GST_AUDIO_FORMAT_ENCODED, NULL);
+
+      g_value_init (&v, G_TYPE_STRING);
+      g_value_set_static_string (&v, gst_audio_format_to_string (formats[i]));
+      gst_value_list_append_and_take_value (&format, &v);
+    }
+  } else {
+    g_value_init (&format, G_TYPE_STRING);
+
+    g_value_set_static_string (&format,
+        gst_audio_format_to_string (formats[0]));
+  }
+
+  if (layout == GST_AUDIO_LAYOUT_INTERLEAVED)
+    layout_str = "interleaved";
+  else
+    layout_str = "non-interleaved";
+
+  s = gst_structure_new ("audio/x-raw",
+      "rate", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+      "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT,
+      "layout", G_TYPE_STRING, layout_str, NULL);
+
+  gst_structure_take_value (s, "format", &format);
+
+  caps = gst_caps_new_full (s, NULL);
+
+  return caps;
+}
index ed40ee2..b917d15 100644 (file)
@@ -371,6 +371,22 @@ const GstAudioFormat * gst_audio_formats_raw (guint * len);
  */
 #define GST_AUDIO_DEF_FORMAT "S16LE"
 
+/**
+ * GstAudioLayout:
+ * @GST_AUDIO_LAYOUT_INTERLEAVED: interleaved audio
+ * @GST_AUDIO_LAYOUT_NON_INTERLEAVED: non-interleaved audio
+ *
+ * Layout of the audio samples for the different channels.
+ */
+typedef enum {
+  GST_AUDIO_LAYOUT_INTERLEAVED = 0,
+  GST_AUDIO_LAYOUT_NON_INTERLEAVED
+} GstAudioLayout;
+
+GST_AUDIO_API
+GstCaps * gst_audio_make_raw_caps (const GstAudioFormat formats[], guint len,
+                                   GstAudioLayout layout);
+
 G_END_DECLS
 
 #endif /* __GST_AUDIO_FORMAT_H__ */
index b939013..cc9e972 100644 (file)
@@ -44,18 +44,6 @@ typedef enum {
 } GstAudioFlags;
 
 /**
- * GstAudioLayout:
- * @GST_AUDIO_LAYOUT_INTERLEAVED: interleaved audio
- * @GST_AUDIO_LAYOUT_NON_INTERLEAVED: non-interleaved audio
- *
- * Layout of the audio samples for the different channels.
- */
-typedef enum {
-  GST_AUDIO_LAYOUT_INTERLEAVED = 0,
-  GST_AUDIO_LAYOUT_NON_INTERLEAVED
-} GstAudioLayout;
-
-/**
  * GstAudioInfo:
  * @finfo: the format info of the audio
  * @flags: additional audio flags
index 5e5ca47..400dbc8 100644 (file)
@@ -1491,6 +1491,43 @@ GST_START_TEST (test_audio_info_from_caps)
 
 GST_END_TEST;
 
+GST_START_TEST (test_audio_make_raw_caps)
+{
+  GstCaps *caps, *expected;
+  GstAudioFormat f1[] = { GST_AUDIO_FORMAT_U8 };
+  GstAudioFormat f2[] = { GST_AUDIO_FORMAT_U8, GST_AUDIO_FORMAT_S8 };
+
+  caps =
+      gst_audio_make_raw_caps (f1, G_N_ELEMENTS (f1),
+      GST_AUDIO_LAYOUT_INTERLEAVED);
+  expected =
+      gst_caps_from_string
+      ("audio/x-raw, format = (string) U8, rate = (int) [ 1, max ], channels = (int) [ 1, max ], layout = (string) interleaved");
+  fail_unless (gst_caps_is_equal (caps, expected));
+  gst_caps_unref (caps);
+  gst_caps_unref (expected);
+
+  caps =
+      gst_audio_make_raw_caps (f2, G_N_ELEMENTS (f2),
+      GST_AUDIO_LAYOUT_NON_INTERLEAVED);
+  expected =
+      gst_caps_from_string
+      ("audio/x-raw, format = (string) { U8, S8 }, rate = (int) [ 1, max ], channels = (int) [ 1, max ], layout = (string) non-interleaved");
+  fail_unless (gst_caps_is_equal (caps, expected));
+  gst_caps_unref (caps);
+  gst_caps_unref (expected);
+
+  caps = gst_audio_make_raw_caps (NULL, 0, GST_AUDIO_LAYOUT_INTERLEAVED);
+  expected =
+      gst_caps_from_string
+      ("audio/x-raw, format = (string) { S8, U8, S16LE, S16BE, U16LE, U16BE, S24_32LE, S24_32BE, U24_32LE, U24_32BE, S32LE, S32BE, U32LE, U32BE, S24LE, S24BE, U24LE, U24BE, S20LE, S20BE, U20LE, U20BE, S18LE, S18BE, U18LE, U18BE, F32LE, F32BE, F64LE, F64BE }, rate = (int) [ 1, max ], channels = (int) [ 1, max ], layout = (string) interleaved");
+  fail_unless (gst_caps_is_equal (caps, expected));
+  gst_caps_unref (caps);
+  gst_caps_unref (expected);
+}
+
+GST_END_TEST;
+
 static Suite *
 audio_suite (void)
 {
@@ -1526,6 +1563,7 @@ audio_suite (void)
   tcase_add_test (tc_chain, test_stream_align_reverse);
   tcase_add_test (tc_chain, test_audio_buffer_and_audio_meta);
   tcase_add_test (tc_chain, test_audio_info_from_caps);
+  tcase_add_test (tc_chain, test_audio_make_raw_caps);
 
   return s;
 }