mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
sdp: Handle level-asymmetry-allowed for H264 streams
The ["level-asymmetry-allowed"] field states that the peer wants the profile specified in the "profile-level-id" fields but doesn't care about the level. To express this in GStreamer caps term, we add a "profile" field in the caps, which reuses the usual "profile" semantics for H.264 streams and, and remove "profile-level-id" and "level-asymmetry-allowed" fields. ["level-asymmetry-allowed"]: https://www.iana.org/assignments/media-types/video/H264 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1410>
This commit is contained in:
parent
f10867dfb5
commit
9ac502c21d
4 changed files with 83 additions and 2 deletions
|
@ -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')
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include <gio/gio.h>
|
||||
|
||||
#include <gst/rtp/gstrtppayloads.h>
|
||||
#include <gst/pbutils/pbutils.h>
|
||||
#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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue