diff --git a/subprojects/gst-plugins-base/gst-libs/gst/meson.build b/subprojects/gst-plugins-base/gst-libs/gst/meson.build index cd3b5b0436..42c0a6fcab 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/meson.build +++ b/subprojects/gst-plugins-base/gst-libs/gst/meson.build @@ -3,9 +3,9 @@ subdir('fft') subdir('video') subdir('audio') subdir('rtp') +subdir('pbutils') subdir('sdp') subdir('rtsp') -subdir('pbutils') subdir('riff') subdir('app') subdir('allocators') diff --git a/subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c b/subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c index 04c27b9d74..59f0c5c888 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/sdp/gstsdpmessage.c @@ -61,6 +61,7 @@ #include #include +#include #include "gstsdpmessage.h" #define FREE_STRING(field) g_free (field); (field) = NULL @@ -3540,6 +3541,35 @@ gst_sdp_media_add_rtcp_fb_attributes_from_media (const GstSDPMedia * media, return GST_SDP_OK; } +static void +gst_sdp_media_caps_adjust_h264 (GstCaps * caps) +{ + long int spsint; + guint8 sps[2]; + const gchar *profile_level_id; + GstStructure *s = gst_caps_get_structure (caps, 0); + + if (g_strcmp0 (gst_structure_get_string (s, "encoding-name"), "H264") || + g_strcmp0 (gst_structure_get_string (s, "level-asymmetry-allowed"), "1")) + return; + + profile_level_id = gst_structure_get_string (s, "profile-level-id"); + if (!profile_level_id) + return; + + spsint = strtol (profile_level_id, NULL, 16); + sps[0] = spsint >> 16; + sps[1] = spsint >> 8; + + GST_DEBUG ("'level-asymmetry-allowed' is set so we shouldn't care about " + "'profile-level-id' and only set a 'profile' instead"); + gst_structure_set (s, "profile", G_TYPE_STRING, + gst_codec_utils_h264_get_profile (sps, 2), NULL); + + gst_structure_remove_fields (s, "level-asymmetry-allowed", "profile-level-id", + NULL); +} + /** * gst_sdp_media_get_caps_from_media: * @media: a #GstSDPMedia @@ -3714,6 +3744,8 @@ gst_sdp_media_get_caps_from_media (const GstSDPMedia * media, gint pt) } } + gst_sdp_media_caps_adjust_h264 (caps); + /* parse rtcp-fb: field */ gst_sdp_media_add_rtcp_fb_attributes_from_media (media, pt, caps); @@ -3960,6 +3992,16 @@ gst_sdp_media_set_media_from_caps (const GstCaps * caps, GstSDPMedia * media) } if ((fval = gst_structure_get_string (s, fname))) { + + /* "profile" is our internal representation of the notion of + * "level-asymmetry-allowed" with caps, convert it back to the SDP + * representation */ + if (!g_strcmp0 (gst_structure_get_string (s, "encoding-name"), "H264") + && !g_strcmp0 (fname, "profile")) { + fname = "level-asymmetry-allowed"; + fval = "1"; + } + g_string_append_printf (fmtp, "%s%s=%s", first ? "" : ";", fname, fval); first = FALSE; } diff --git a/subprojects/gst-plugins-base/gst-libs/gst/sdp/meson.build b/subprojects/gst-plugins-base/gst-libs/gst/sdp/meson.build index 53d695af43..746004f291 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/sdp/meson.build +++ b/subprojects/gst-plugins-base/gst-libs/gst/sdp/meson.build @@ -7,7 +7,7 @@ gst_sdp_headers = files([ ]) install_headers(gst_sdp_headers, subdir : 'gstreamer-1.0/gst/sdp/') -sdp_deps = [rtp_dep, gst_dep, gio_dep] +sdp_deps = [rtp_dep, gst_dep, gio_dep, pbutils_dep] gst_sdp_sources = files(['gstsdpmessage.c', 'gstmikey.c']) gstsdp = library('gstsdp-@0@'.format(api_version), gst_sdp_sources, diff --git a/subprojects/gst-plugins-base/tests/check/libs/sdp.c b/subprojects/gst-plugins-base/tests/check/libs/sdp.c index d93b96f53d..40c3c8a7cf 100644 --- a/subprojects/gst-plugins-base/tests/check/libs/sdp.c +++ b/subprojects/gst-plugins-base/tests/check/libs/sdp.c @@ -47,6 +47,16 @@ static const gchar *sdp = "v=0\r\n" "a=sendrecv\r\n" "m=audio 1010 TCP 14\r\n"; +static const gchar *h264_sdp = "v=0\r\n" + "o=- 992782775729845470 2 IN IP4 127.0.0.1\r\n" + "s=TestH264\r\n" + "t=0 0\r\n" + "m=video 9 UDP/TLS/RTP/SAVPF 96\r\n" + "c=IN IP4 0.0.0.0\r\n" + "a=recvonly\r\n" + "a=rtpmap:96 H264/90000\r\n" + "a=fmtp:96 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\n"; + static const gchar caps_video_string1[] = "application/x-unknown, media=(string)video, payload=(int)96, " "clock-rate=(int)90000, encoding-name=(string)MP4V-ES"; @@ -657,6 +667,33 @@ GST_START_TEST (caps_from_media_really_const) gst_sdp_message_free (message); } +GST_END_TEST +GST_START_TEST (media_from_caps_h264_with_profile_asymmetry_allowed) +{ + GstSDPMessage *message; + glong length = -1; + const GstSDPMedia *result_video; + GstStructure *s_video; + GstCaps *caps_video; + + gst_sdp_message_new (&message); + gst_sdp_message_parse_buffer ((guint8 *) h264_sdp, length, message); + + + result_video = gst_sdp_message_get_media (message, 0); + fail_unless (result_video != NULL); + caps_video = gst_sdp_media_get_caps_from_media (result_video, 96); + + s_video = gst_caps_get_structure (caps_video, 0); + fail_if (gst_structure_has_field (s_video, "level-asymmetry-allowed")); + fail_if (gst_structure_has_field (s_video, "profile-level-id")); + fail_unless_equals_string (gst_structure_get_string (s_video, "profile"), + "constrained-baseline"); + + gst_caps_unref (caps_video); + gst_sdp_message_free (message); +} + GST_END_TEST /* * End of test cases @@ -681,6 +718,8 @@ sdp_suite (void) tcase_add_test (tc_chain, media_from_caps_rtcp_fb_pt_100); tcase_add_test (tc_chain, media_from_caps_rtcp_fb_pt_101); tcase_add_test (tc_chain, media_from_caps_extmap_pt_100); + tcase_add_test (tc_chain, + media_from_caps_h264_with_profile_asymmetry_allowed); return s; }