diff --git a/gst-libs/gst/audio/audio-format.c b/gst-libs/gst/audio/audio-format.c index 2303495db6..cc5345e5da 100644 --- a/gst-libs/gst/audio/audio-format.c +++ b/gst-libs/gst/audio/audio-format.c @@ -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; +} diff --git a/gst-libs/gst/audio/audio-format.h b/gst-libs/gst/audio/audio-format.h index ed40ee2e31..b917d15435 100644 --- a/gst-libs/gst/audio/audio-format.h +++ b/gst-libs/gst/audio/audio-format.h @@ -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__ */ diff --git a/gst-libs/gst/audio/audio-info.h b/gst-libs/gst/audio/audio-info.h index b939013175..cc9e972220 100644 --- a/gst-libs/gst/audio/audio-info.h +++ b/gst-libs/gst/audio/audio-info.h @@ -43,18 +43,6 @@ typedef enum { GST_AUDIO_FLAG_UNPOSITIONED = (1 << 0) } 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 diff --git a/tests/check/libs/audio.c b/tests/check/libs/audio.c index 5e5ca475a8..400dbc89cf 100644 --- a/tests/check/libs/audio.c +++ b/tests/check/libs/audio.c @@ -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; }