#define DEFAULT_DO_RETRANSMISSION TRUE
#define DEFAULT_NTP_TIME_SOURCE NTP_TIME_SOURCE_NTP
#define DEFAULT_USER_AGENT "GStreamer/" PACKAGE_VERSION
+#define DEFAULT_MAX_RTCP_RTP_TIME_DIFF 1000
enum
{
PROP_TLS_INTERACTION,
PROP_DO_RETRANSMISSION,
PROP_NTP_TIME_SOURCE,
- PROP_USER_AGENT
+ PROP_USER_AGENT,
+ PROP_MAX_RTCP_RTP_TIME_DIFF
};
#define GST_TYPE_RTSP_NAT_METHOD (gst_rtsp_nat_method_get_type())
"The User-Agent string to send to the server",
DEFAULT_USER_AGENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_MAX_RTCP_RTP_TIME_DIFF,
+ g_param_spec_int ("max-rtcp-rtp-time-diff", "Max RTCP RTP Time Diff",
+ "Maximum amount of time in ms that the RTP time in RTCP SRs "
+ "is allowed to be ahead (-1 disabled)", -1, G_MAXINT,
+ DEFAULT_MAX_RTCP_RTP_TIME_DIFF,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
/**
* GstRTSPSrc::handle-request:
* @rtspsrc: a #GstRTSPSrc
src->do_retransmission = DEFAULT_DO_RETRANSMISSION;
src->ntp_time_source = DEFAULT_NTP_TIME_SOURCE;
src->user_agent = g_strdup (DEFAULT_USER_AGENT);
+ src->max_rtcp_rtp_time_diff = DEFAULT_MAX_RTCP_RTP_TIME_DIFF;
/* get a list of all extensions */
src->extensions = gst_rtsp_ext_list_get ();
gst_rtspsrc_set_proxy (rtspsrc, g_value_get_string (value));
break;
case PROP_PROXY_ID:
- if (rtspsrc->prop_proxy_id)
- g_free (rtspsrc->prop_proxy_id);
+ g_free (rtspsrc->prop_proxy_id);
rtspsrc->prop_proxy_id = g_value_dup_string (value);
break;
case PROP_PROXY_PW:
- if (rtspsrc->prop_proxy_pw)
- g_free (rtspsrc->prop_proxy_pw);
+ g_free (rtspsrc->prop_proxy_pw);
rtspsrc->prop_proxy_pw = g_value_dup_string (value);
break;
case PROP_RTP_BLOCKSIZE:
rtspsrc->rtp_blocksize = g_value_get_uint (value);
break;
case PROP_USER_ID:
- if (rtspsrc->user_id)
- g_free (rtspsrc->user_id);
+ g_free (rtspsrc->user_id);
rtspsrc->user_id = g_value_dup_string (value);
break;
case PROP_USER_PW:
- if (rtspsrc->user_pw)
- g_free (rtspsrc->user_pw);
+ g_free (rtspsrc->user_pw);
rtspsrc->user_pw = g_value_dup_string (value);
break;
case PROP_BUFFER_MODE:
const gchar *str;
str = g_value_get_string (value);
- if (str) {
- sscanf (str, "%u-%u",
- &rtspsrc->client_port_range.min, &rtspsrc->client_port_range.max);
- } else {
+ if (sscanf (str, "%u-%u", &rtspsrc->client_port_range.min,
+ &rtspsrc->client_port_range.max) != 2) {
rtspsrc->client_port_range.min = 0;
rtspsrc->client_port_range.max = 0;
}
g_free (rtspsrc->user_agent);
rtspsrc->user_agent = g_value_dup_string (value);
break;
+ case PROP_MAX_RTCP_RTP_TIME_DIFF:
+ rtspsrc->max_rtcp_rtp_time_diff = g_value_get_int (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
case PROP_USER_AGENT:
g_value_set_string (value, rtspsrc->user_agent);
break;
+ case PROP_MAX_RTCP_RTP_TIME_DIFF:
+ g_value_set_int (value, rtspsrc->max_rtcp_rtp_time_diff);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
{
guint i, len;
const gchar *proto;
+ GstCaps *global_caps;
/* get proto */
proto = gst_sdp_media_get_proto (media);
else
goto unknown_proto;
+ /* Parse global SDP attributes once */
+ global_caps = gst_caps_new_empty_simple ("application/x-unknown");
+ GST_DEBUG ("mapping sdp session level attributes to caps");
+ gst_rtspsrc_sdp_attributes_to_caps (sdp->attributes, global_caps);
+ GST_DEBUG ("mapping sdp media level attributes to caps");
+ gst_rtspsrc_sdp_attributes_to_caps (media->attributes, global_caps);
+
len = gst_sdp_media_formats_len (media);
for (i = 0; i < len; i++) {
gint pt;
- GstCaps *caps;
+ GstCaps *caps, *outcaps;
GstStructure *s;
const gchar *enc;
PtMapItem item;
if (strcmp (enc, "X-ASF-PF") == 0)
stream->container = TRUE;
}
- GST_DEBUG ("mapping sdp session level attributes to caps");
- gst_rtspsrc_sdp_attributes_to_caps (sdp->attributes, caps);
- GST_DEBUG ("mapping sdp media level attributes to caps");
- gst_rtspsrc_sdp_attributes_to_caps (media->attributes, caps);
+
+ /* Merge in global caps */
+ /* Intersect will merge in missing fields to the current caps */
+ outcaps = gst_caps_intersect (caps, global_caps);
+ gst_caps_unref (caps);
/* the first pt will be the default */
if (stream->ptmap->len == 0)
stream->default_pt = pt;
item.pt = pt;
- item.caps = caps;
+ item.caps = outcaps;
+
g_array_append_val (stream->ptmap, item);
}
+
+ gst_caps_unref (global_caps);
return;
no_proto:
parse_keymgmt (const gchar * keymgmt, GstCaps * caps)
{
gboolean res = FALSE;
- gchar *p, *kmpid;
gsize size;
guchar *data;
GstMIKEYMessage *msg;
const gchar *srtp_cipher;
const gchar *srtp_auth;
- p = (gchar *) keymgmt;
+ {
+ gchar *orig_value;
+ gchar *p, *kmpid;
- SKIP_SPACES (p);
- if (*p == '\0')
- return FALSE;
+ p = orig_value = g_strdup (keymgmt);
- PARSE_STRING (p, " ", kmpid);
- if (!g_str_equal (kmpid, "mikey"))
- return FALSE;
+ SKIP_SPACES (p);
+ if (*p == '\0') {
+ g_free (orig_value);
+ return FALSE;
+ }
+
+ PARSE_STRING (p, " ", kmpid);
+ if (kmpid == NULL || !g_str_equal (kmpid, "mikey")) {
+ g_free (orig_value);
+ return FALSE;
+ }
+ data = g_base64_decode (p, &size);
+
+ g_free (orig_value); /* Don't need this any more */
+ }
- data = g_base64_decode (p, &size);
if (data == NULL)
return FALSE;
gst_buffer_new_wrapped (g_memdup (pkd->key_data, pkd->key_len),
pkd->key_len);
gst_caps_set_simple (caps, "srtp-key", GST_TYPE_BUFFER, buf, NULL);
+ gst_buffer_unref (buf);
}
gst_caps_set_simple (caps,
NULL);
}
+ if (g_object_class_find_property (klass, "max-rtcp-rtp-time-diff")) {
+ g_object_set (src->manager, "max-rtcp-rtp-time-diff",
+ src->max_rtcp_rtp_time_diff, NULL);
+ }
+
/* buffer mode pauses are handled by adding offsets to buffer times,
* but some depayloaders may have a hard time syncing output times
* with such input times, e.g. container ones, most notably ASF */
if ((res = gst_rtsp_connection_create (info->url, &info->connection)) < 0)
goto could_not_create;
- if (info->url_str)
- g_free (info->url_str);
+ g_free (info->url_str);
info->url_str = gst_rtsp_url_get_request_uri (info->url);
GST_DEBUG_OBJECT (src, "sanitized uri %s", info->url_str);
switch (int_code) {
case GST_RTSP_STS_UNAUTHORIZED:
+ case GST_RTSP_STS_NOT_FOUND:
if (gst_rtspsrc_setup_auth (src, response)) {
/* Try the request/response again after configuring the auth info
* and loop again */
GstBuffer *buf;
guint8 *key_data;
#define KEY_SIZE 30
+ guint data_size = GST_ROUND_UP_4 (KEY_SIZE);
/* create a random key */
- key_data = g_malloc (KEY_SIZE);
- for (i = 0; i < KEY_SIZE; i += 4)
+ key_data = g_malloc (data_size);
+ for (i = 0; i < data_size; i += 4)
GST_WRITE_UINT32_BE (key_data + i, g_random_int ());
buf = gst_buffer_new_wrapped (key_data, KEY_SIZE);
}
/* it could be that the DESCRIBE method was not implemented */
- if (!src->methods & GST_RTSP_DESCRIBE)
+ if (!(src->methods & GST_RTSP_DESCRIBE))
goto no_describe;
/* check if reply is SDP */