sdp: Add media_add_media_from_structure API

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/9117>
This commit is contained in:
Philippe Normand 2025-06-09 13:04:55 +01:00 committed by GStreamer Marge Bot
parent d2cd810b07
commit fb43941e92
4 changed files with 202 additions and 44 deletions

View File

@ -2458,6 +2458,35 @@ stack and initialized with gst_sdp_media_init().</doc>
</instance-parameter>
</parameters>
</method>
<function name="add_media_from_structure" c:identifier="gst_sdp_media_add_media_from_structure" version="1.28">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">Mapping of structure fields to SDP attributes:
a=rtpmap:(payload) (encoding_name) or (clock_rate)[or (encoding_params)]
a=framesize:(payload) (width)-(height)
a=fmtp:(payload) (param)[=(value)];...
a=rtcp-fb:(payload) (param1) [param2]...
a=extmap:(id)[/direction] (extensionname) (extensionattributes)</doc>
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.h"/>
<return-value transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">a #GstSDPResult.</doc>
<type name="SDPResult" c:type="GstSDPResult"/>
</return-value>
<parameters>
<parameter name="structure" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">a #GstStructure belonging to a #GstCaps SDP mapping, see also
`gst_sdp_media_get_caps_from_media()`</doc>
<type name="Gst.Structure" c:type="const GstStructure*"/>
</parameter>
<parameter name="media" direction="out" caller-allocates="1" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">a #GstSDPMedia</doc>
<type name="SDPMedia" c:type="GstSDPMedia*"/>
</parameter>
</parameters>
</function>
<function name="init" c:identifier="gst_sdp_media_init">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">Initialize @media so that its contents are as if it was freshly allocated
with gst_sdp_media_new(). This function is mostly used to initialize a media
@ -2502,7 +2531,9 @@ a=fmtp:(payload) (param)[=(value)];...
a=rtcp-fb:(payload) (param1) [param2]...
a=extmap:(id)[/direction] (extensionname) (extensionattributes)</doc>
a=extmap:(id)[/direction] (extensionname) (extensionattributes)
Only the first #GstStructure of the @caps is used.</doc>
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.h"/>
<return-value transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">a #GstSDPResult.</doc>
@ -4161,6 +4192,35 @@ messages.</doc>
</parameter>
</parameters>
</function>
<function name="sdp_media_add_media_from_structure" c:identifier="gst_sdp_media_add_media_from_structure" moved-to="SDPMedia.add_media_from_structure" version="1.28">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">Mapping of structure fields to SDP attributes:
a=rtpmap:(payload) (encoding_name) or (clock_rate)[or (encoding_params)]
a=framesize:(payload) (width)-(height)
a=fmtp:(payload) (param)[=(value)];...
a=rtcp-fb:(payload) (param1) [param2]...
a=extmap:(id)[/direction] (extensionname) (extensionattributes)</doc>
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.h"/>
<return-value transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">a #GstSDPResult.</doc>
<type name="SDPResult" c:type="GstSDPResult"/>
</return-value>
<parameters>
<parameter name="structure" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">a #GstStructure belonging to a #GstCaps SDP mapping, see also
`gst_sdp_media_get_caps_from_media()`</doc>
<type name="Gst.Structure" c:type="const GstStructure*"/>
</parameter>
<parameter name="media" direction="out" caller-allocates="1" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">a #GstSDPMedia</doc>
<type name="SDPMedia" c:type="GstSDPMedia*"/>
</parameter>
</parameters>
</function>
<function name="sdp_media_init" c:identifier="gst_sdp_media_init" moved-to="SDPMedia.init">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">Initialize @media so that its contents are as if it was freshly allocated
with gst_sdp_media_new(). This function is mostly used to initialize a media
@ -4205,7 +4265,9 @@ a=fmtp:(payload) (param)[=(value)];...
a=rtcp-fb:(payload) (param1) [param2]...
a=extmap:(id)[/direction] (extensionname) (extensionattributes)</doc>
a=extmap:(id)[/direction] (extensionname) (extensionattributes)
Only the first #GstStructure of the @caps is used.</doc>
<source-position filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.h"/>
<return-value transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c">a #GstSDPResult.</doc>

View File

@ -3813,54 +3813,18 @@ no_rate:
}
}
/**
* gst_sdp_media_set_media_from_caps:
* @caps: a #GstCaps
* @media: (out caller-allocates): a #GstSDPMedia
*
* Mapping of caps to SDP fields:
*
* a=rtpmap:(payload) (encoding_name) or (clock_rate)[or (encoding_params)]
*
* a=framesize:(payload) (width)-(height)
*
* a=fmtp:(payload) (param)[=(value)];...
*
* a=rtcp-fb:(payload) (param1) [param2]...
*
* a=extmap:(id)[/direction] (extensionname) (extensionattributes)
*
* Returns: a #GstSDPResult.
*
* Since: 1.8
*/
GstSDPResult
gst_sdp_media_set_media_from_caps (const GstCaps * caps, GstSDPMedia * media)
static GstSDPResult
_add_media_format_from_structure (const GstStructure * s, GstSDPMedia * media)
{
const gchar *caps_str, *caps_enc, *caps_params;
const gchar *caps_enc, *caps_params;
gchar *tmp;
gint caps_pt, caps_rate;
guint n_fields, j;
gboolean first, nack, nack_pli, ccm_fir, transport_cc;
GString *fmtp;
GstStructure *s;
g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
g_return_val_if_fail (caps != NULL && GST_IS_CAPS (caps), GST_SDP_EINVAL);
s = gst_caps_get_structure (caps, 0);
if (s == NULL) {
GST_ERROR ("ignoring stream without media type");
goto error;
}
/* get media type and payload for the m= line */
caps_str = gst_structure_get_string (s, "media");
if (!caps_str) {
GST_ERROR ("ignoring stream without media type");
goto error;
}
gst_sdp_media_set_media (media, caps_str);
g_return_val_if_fail (s != NULL, GST_SDP_EINVAL);
if (!gst_structure_get_int (s, "payload", &caps_pt)) {
GST_ERROR ("ignoring stream without payload type");
@ -4118,8 +4082,93 @@ gst_sdp_media_set_media_from_caps (const GstCaps * caps, GstSDPMedia * media)
return GST_SDP_OK;
/* ERRORS */
error:
{
error:{
GST_DEBUG ("ignoring stream");
return GST_SDP_EINVAL;
}
}
/**
* gst_sdp_media_set_media_from_caps:
* @caps: a #GstCaps
* @media: (out caller-allocates): a #GstSDPMedia
*
* Mapping of caps to SDP fields:
*
* a=rtpmap:(payload) (encoding_name) or (clock_rate)[or (encoding_params)]
*
* a=framesize:(payload) (width)-(height)
*
* a=fmtp:(payload) (param)[=(value)];...
*
* a=rtcp-fb:(payload) (param1) [param2]...
*
* a=extmap:(id)[/direction] (extensionname) (extensionattributes)
*
* Only the first #GstStructure of the @caps is used.
*
* Returns: a #GstSDPResult.
*
* Since: 1.8
*/
GstSDPResult
gst_sdp_media_set_media_from_caps (const GstCaps * caps, GstSDPMedia * media)
{
g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
g_return_val_if_fail (caps != NULL && GST_IS_CAPS (caps), GST_SDP_EINVAL);
return gst_sdp_media_add_media_from_structure (gst_caps_get_structure (caps,
0), media);
}
/**
* gst_sdp_media_add_media_from_structure:
* @structure: a #GstStructure belonging to a #GstCaps SDP mapping, see also
* `gst_sdp_media_get_caps_from_media()`
* @media: (out caller-allocates): a #GstSDPMedia
*
* Mapping of structure fields to SDP attributes:
*
* a=rtpmap:(payload) (encoding_name) or (clock_rate)[or (encoding_params)]
*
* a=framesize:(payload) (width)-(height)
*
* a=fmtp:(payload) (param)[=(value)];...
*
* a=rtcp-fb:(payload) (param1) [param2]...
*
* a=extmap:(id)[/direction] (extensionname) (extensionattributes)
*
* Returns: a #GstSDPResult.
*
* Since: 1.28
*/
GstSDPResult
gst_sdp_media_add_media_from_structure (const GstStructure * structure,
GstSDPMedia * media)
{
const gchar *caps_str;
g_return_val_if_fail (media != NULL, GST_SDP_EINVAL);
g_return_val_if_fail (structure != NULL
&& GST_IS_STRUCTURE (structure), GST_SDP_EINVAL);
if (structure == NULL) {
GST_ERROR ("ignoring stream without media type");
goto error;
}
/* get media type and payload for the m= line */
caps_str = gst_structure_get_string (structure, "media");
if (!caps_str) {
GST_ERROR ("ignoring stream without media type");
goto error;
}
gst_sdp_media_set_media (media, caps_str);
return _add_media_format_from_structure (structure, media);
/* ERRORS */
error:{
GST_DEBUG ("ignoring stream");
return GST_SDP_EINVAL;
}

View File

@ -743,6 +743,10 @@ GstCaps* gst_sdp_media_get_caps_from_media (const GstSDPMedia *
GST_SDP_API
GstSDPResult gst_sdp_media_set_media_from_caps (const GstCaps* caps, GstSDPMedia *media);
GST_SDP_API
GstSDPResult gst_sdp_media_add_media_from_structure (const GstStructure *structure,
GstSDPMedia *media);
GST_SDP_API
gchar * gst_sdp_make_keymgmt (const gchar *uri, const gchar *base64);

View File

@ -80,6 +80,17 @@ static const gchar caps_audio_string[] =
"application/x-unknown, media=(string)audio, payload=(int)14, "
"clock-rate=(int)90000";
static const gchar caps_opus_dtmf[] =
"application/x-unknown, media=(string)audio, payload=(int)98, "
"clock-rate=(int)48000, encoding-name=(string)OPUS; "
"application/x-unknown, media=(string)audio, payload=(int)110, "
"clock-rate=(int)48000, encoding-name=(string)TELEPHONE-EVENT;";
static const gchar *sdp_opus_dtmf =
"m=audio 0 (null) 98 110\r\n"
"a=rtpmap:98 OPUS/48000\r\n"
"a=rtpmap:110 TELEPHONE-EVENT/48000\r\n";
static const gchar * sdp_rtcp_fb = "v=0\r\n"
"o=- 123456 2 IN IP4 127.0.0.1 \r\n"
"s=-\r\n"
@ -983,6 +994,37 @@ GST_START_TEST (media_remove)
gst_sdp_message_free (message);
}
GST_END_TEST
GST_START_TEST (media_from_all_caps)
{
GstSDPResult ret = GST_SDP_OK;
GstCaps *caps = gst_caps_from_string (caps_opus_dtmf);
GstSDPMedia *media;
gchar *sdp;
guint caps_size = gst_caps_get_size (caps);
gst_sdp_media_new (&media);
fail_unless (media != NULL);
for (guint i = 0; i < caps_size; i++) {
const GstStructure *s = gst_caps_get_structure (caps, i);
ret = gst_sdp_media_add_media_from_structure (s, media);
fail_unless (ret == GST_SDP_OK);
}
gst_caps_unref (caps);
fail_unless_equals_int (gst_sdp_media_formats_len (media), 2);
fail_unless_equals_string (gst_sdp_media_get_format (media, 0), "98");
fail_unless_equals_string (gst_sdp_media_get_format (media, 1), "110");
sdp = gst_sdp_media_as_text (media);
fail_unless_equals_string (sdp, sdp_opus_dtmf);
g_free (sdp);
gst_sdp_media_free (media);
}
GST_END_TEST
/*
* End of test cases
@ -1014,6 +1056,7 @@ sdp_suite (void)
tcase_add_test (tc_chain, caps_multiple_rid_parse_with_params);
tcase_add_test (tc_chain, media_from_caps_with_source_filters);
tcase_add_test (tc_chain, media_remove);
tcase_add_test (tc_chain, media_from_all_caps);
return s;
}