mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 14:36:24 +00:00
sdpdemux: replace duplicated codes to call new base sdp apis
https://bugzilla.gnome.org/show_bug.cgi?id=745880
This commit is contained in:
parent
8c78a79c67
commit
1e5eb72532
1 changed files with 1 additions and 248 deletions
|
@ -94,9 +94,6 @@ static void gst_sdp_demux_set_property (GObject * object, guint prop_id,
|
||||||
static void gst_sdp_demux_get_property (GObject * object, guint prop_id,
|
static void gst_sdp_demux_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
static GstCaps *gst_sdp_demux_media_to_caps (gint pt,
|
|
||||||
const GstSDPMedia * media);
|
|
||||||
|
|
||||||
static GstStateChangeReturn gst_sdp_demux_change_state (GstElement * element,
|
static GstStateChangeReturn gst_sdp_demux_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
static void gst_sdp_demux_handle_message (GstBin * bin, GstMessage * message);
|
static void gst_sdp_demux_handle_message (GstBin * bin, GstMessage * message);
|
||||||
|
@ -398,7 +395,7 @@ gst_sdp_demux_create_stream (GstSDPDemux * demux, GstSDPMessage * sdp, gint idx)
|
||||||
if ((payload = gst_sdp_media_get_format (media, 0))) {
|
if ((payload = gst_sdp_media_get_format (media, 0))) {
|
||||||
stream->pt = atoi (payload);
|
stream->pt = atoi (payload);
|
||||||
/* convert caps */
|
/* convert caps */
|
||||||
stream->caps = gst_sdp_demux_media_to_caps (stream->pt, media);
|
stream->caps = gst_sdp_media_get_caps_from_media (media, stream->pt);
|
||||||
|
|
||||||
if (stream->pt >= 96) {
|
if (stream->pt >= 96) {
|
||||||
/* If we have a dynamic payload type, see if we have a stream with the
|
/* If we have a dynamic payload type, see if we have a stream with the
|
||||||
|
@ -482,250 +479,6 @@ gst_sdp_demux_cleanup (GstSDPDemux * demux)
|
||||||
demux->numstreams = 0;
|
demux->numstreams = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PARSE_INT(p, del, res) \
|
|
||||||
G_STMT_START { \
|
|
||||||
gchar *t = p; \
|
|
||||||
p = strstr (p, del); \
|
|
||||||
if (p == NULL) \
|
|
||||||
res = -1; \
|
|
||||||
else { \
|
|
||||||
*p = '\0'; \
|
|
||||||
p++; \
|
|
||||||
res = atoi (t); \
|
|
||||||
} \
|
|
||||||
} G_STMT_END
|
|
||||||
|
|
||||||
#define PARSE_STRING(p, del, res) \
|
|
||||||
G_STMT_START { \
|
|
||||||
gchar *t = p; \
|
|
||||||
p = strstr (p, del); \
|
|
||||||
if (p == NULL) { \
|
|
||||||
res = NULL; \
|
|
||||||
p = t; \
|
|
||||||
} \
|
|
||||||
else { \
|
|
||||||
*p = '\0'; \
|
|
||||||
p++; \
|
|
||||||
res = t; \
|
|
||||||
} \
|
|
||||||
} G_STMT_END
|
|
||||||
|
|
||||||
#define SKIP_SPACES(p) \
|
|
||||||
while (*p && g_ascii_isspace (*p)) \
|
|
||||||
p++;
|
|
||||||
|
|
||||||
/* rtpmap contains:
|
|
||||||
*
|
|
||||||
* <payload> <encoding_name>/<clock_rate>[/<encoding_params>]
|
|
||||||
*/
|
|
||||||
static gboolean
|
|
||||||
gst_sdp_demux_parse_rtpmap (const gchar * rtpmap, gint * payload, gchar ** name,
|
|
||||||
gint * rate, gchar ** params)
|
|
||||||
{
|
|
||||||
gchar *p, *t;
|
|
||||||
|
|
||||||
p = (gchar *) rtpmap;
|
|
||||||
|
|
||||||
PARSE_INT (p, " ", *payload);
|
|
||||||
if (*payload == -1)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
SKIP_SPACES (p);
|
|
||||||
if (*p == '\0')
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
PARSE_STRING (p, "/", *name);
|
|
||||||
if (*name == NULL) {
|
|
||||||
GST_DEBUG ("no rate, name %s", p);
|
|
||||||
/* no rate, assume -1 then */
|
|
||||||
*name = p;
|
|
||||||
*rate = -1;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
t = p;
|
|
||||||
p = strstr (p, "/");
|
|
||||||
if (p == NULL) {
|
|
||||||
*rate = atoi (t);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
p++;
|
|
||||||
*rate = atoi (t);
|
|
||||||
|
|
||||||
t = p;
|
|
||||||
if (*p == '\0')
|
|
||||||
return TRUE;
|
|
||||||
*params = t;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Mapping of caps to and from SDP fields:
|
|
||||||
*
|
|
||||||
* m=<media> <UDP port> RTP/AVP <payload>
|
|
||||||
* a=rtpmap:<payload> <encoding_name>/<clock_rate>[/<encoding_params>]
|
|
||||||
* a=fmtp:<payload> <param>[=<value>];...
|
|
||||||
*/
|
|
||||||
static GstCaps *
|
|
||||||
gst_sdp_demux_media_to_caps (gint pt, const GstSDPMedia * media)
|
|
||||||
{
|
|
||||||
GstCaps *caps;
|
|
||||||
const gchar *rtpmap;
|
|
||||||
const gchar *fmtp;
|
|
||||||
gchar *name = NULL;
|
|
||||||
gint rate = -1;
|
|
||||||
gchar *params = NULL;
|
|
||||||
gchar *tmp;
|
|
||||||
GstStructure *s;
|
|
||||||
gint payload = 0;
|
|
||||||
gboolean ret;
|
|
||||||
|
|
||||||
/* get and parse rtpmap */
|
|
||||||
if ((rtpmap = gst_sdp_media_get_attribute_val (media, "rtpmap"))) {
|
|
||||||
ret = gst_sdp_demux_parse_rtpmap (rtpmap, &payload, &name, &rate, ¶ms);
|
|
||||||
if (ret) {
|
|
||||||
if (payload != pt) {
|
|
||||||
/* we ignore the rtpmap if the payload type is different. */
|
|
||||||
g_warning ("rtpmap of wrong payload type, ignoring");
|
|
||||||
name = NULL;
|
|
||||||
rate = -1;
|
|
||||||
params = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* if we failed to parse the rtpmap for a dynamic payload type, we have an
|
|
||||||
* error */
|
|
||||||
if (pt >= 96)
|
|
||||||
goto no_rtpmap;
|
|
||||||
/* else we can ignore */
|
|
||||||
g_warning ("error parsing rtpmap, ignoring");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* dynamic payloads need rtpmap or we fail */
|
|
||||||
if (pt >= 96)
|
|
||||||
goto no_rtpmap;
|
|
||||||
}
|
|
||||||
/* check if we have a rate, if not, we need to look up the rate from the
|
|
||||||
* default rates based on the payload types. */
|
|
||||||
if (rate == -1) {
|
|
||||||
const GstRTPPayloadInfo *info;
|
|
||||||
|
|
||||||
if (GST_RTP_PAYLOAD_IS_DYNAMIC (pt)) {
|
|
||||||
/* dynamic types, use media and encoding_name */
|
|
||||||
tmp = g_ascii_strdown (media->media, -1);
|
|
||||||
info = gst_rtp_payload_info_for_name (tmp, name);
|
|
||||||
g_free (tmp);
|
|
||||||
} else {
|
|
||||||
/* static types, use payload type */
|
|
||||||
info = gst_rtp_payload_info_for_pt (pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info) {
|
|
||||||
if ((rate = info->clock_rate) == 0)
|
|
||||||
rate = -1;
|
|
||||||
}
|
|
||||||
/* we fail if we cannot find one */
|
|
||||||
if (rate == -1)
|
|
||||||
goto no_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = g_ascii_strdown (media->media, -1);
|
|
||||||
caps = gst_caps_new_simple ("application/x-rtp",
|
|
||||||
"media", G_TYPE_STRING, tmp, "payload", G_TYPE_INT, pt, NULL);
|
|
||||||
g_free (tmp);
|
|
||||||
s = gst_caps_get_structure (caps, 0);
|
|
||||||
|
|
||||||
gst_structure_set (s, "clock-rate", G_TYPE_INT, rate, NULL);
|
|
||||||
|
|
||||||
/* encoding name must be upper case */
|
|
||||||
if (name != NULL) {
|
|
||||||
tmp = g_ascii_strup (name, -1);
|
|
||||||
gst_structure_set (s, "encoding-name", G_TYPE_STRING, tmp, NULL);
|
|
||||||
g_free (tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* params must be lower case */
|
|
||||||
if (params != NULL) {
|
|
||||||
tmp = g_ascii_strdown (params, -1);
|
|
||||||
gst_structure_set (s, "encoding-params", G_TYPE_STRING, tmp, NULL);
|
|
||||||
g_free (tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* parse optional fmtp: field */
|
|
||||||
if ((fmtp = gst_sdp_media_get_attribute_val (media, "fmtp"))) {
|
|
||||||
gchar *p;
|
|
||||||
gint payload = 0;
|
|
||||||
|
|
||||||
p = (gchar *) fmtp;
|
|
||||||
|
|
||||||
/* p is now of the format <payload> <param>[=<value>];... */
|
|
||||||
PARSE_INT (p, " ", payload);
|
|
||||||
if (payload != -1 && payload == pt) {
|
|
||||||
gchar **pairs;
|
|
||||||
gint i;
|
|
||||||
|
|
||||||
/* <param>[=<value>] are separated with ';' */
|
|
||||||
pairs = g_strsplit (p, ";", 0);
|
|
||||||
for (i = 0; pairs[i]; i++) {
|
|
||||||
gchar *valpos;
|
|
||||||
const gchar *key, *val;
|
|
||||||
gint j;
|
|
||||||
const gchar *reserved_keys[] =
|
|
||||||
{ "media", "payload", "clock-rate", "encoding-name",
|
|
||||||
"encoding-params"
|
|
||||||
};
|
|
||||||
|
|
||||||
/* the key may not have a '=', the value can have other '='s */
|
|
||||||
valpos = strstr (pairs[i], "=");
|
|
||||||
if (valpos) {
|
|
||||||
/* we have a '=' and thus a value, remove the '=' with \0 */
|
|
||||||
*valpos = '\0';
|
|
||||||
/* value is everything between '=' and ';'. FIXME, strip? */
|
|
||||||
val = g_strstrip (valpos + 1);
|
|
||||||
} else {
|
|
||||||
/* simple <param>;.. is translated into <param>=1;... */
|
|
||||||
val = "1";
|
|
||||||
}
|
|
||||||
/* strip the key of spaces, convert key to lowercase but not the value. */
|
|
||||||
key = g_strstrip (pairs[i]);
|
|
||||||
|
|
||||||
/* skip keys from the fmtp, which we already use ourselves for the
|
|
||||||
* caps. Some software is adding random things like clock-rate into
|
|
||||||
* the fmtp, and we would otherwise here set a string-typed clock-rate
|
|
||||||
* in the caps... and thus fail to create valid RTP caps
|
|
||||||
*/
|
|
||||||
for (j = 0; j < G_N_ELEMENTS (reserved_keys); j++) {
|
|
||||||
if (g_ascii_strcasecmp (reserved_keys[j], key) == 0) {
|
|
||||||
key = "";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen (key) > 1) {
|
|
||||||
tmp = g_ascii_strdown (key, -1);
|
|
||||||
gst_structure_set (s, tmp, G_TYPE_STRING, val, NULL);
|
|
||||||
g_free (tmp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_strfreev (pairs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return caps;
|
|
||||||
|
|
||||||
/* ERRORS */
|
|
||||||
no_rtpmap:
|
|
||||||
{
|
|
||||||
g_warning ("rtpmap type not given for dynamic payload %d", pt);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
no_rate:
|
|
||||||
{
|
|
||||||
g_warning ("rate unknown for payload type %d", pt);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this callback is called when the session manager generated a new src pad with
|
/* this callback is called when the session manager generated a new src pad with
|
||||||
* payloaded RTP packets. We simply ghost the pad here. */
|
* payloaded RTP packets. We simply ghost the pad here. */
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue