gboolean is_joined;
gchar *control;
+ GstRTSPProfile profiles;
GstRTSPLowerTrans protocols;
/* pads on the rtpbin */
};
#define DEFAULT_CONTROL NULL
+#define DEFAULT_PROFILES GST_RTSP_PROFILE_AVP
#define DEFAULT_PROTOCOLS GST_RTSP_LOWER_TRANS_UDP | GST_RTSP_LOWER_TRANS_UDP_MCAST | \
GST_RTSP_LOWER_TRANS_TCP
{
PROP_0,
PROP_CONTROL,
+ PROP_PROFILES,
PROP_PROTOCOLS,
PROP_LAST
};
"The control string for this stream", DEFAULT_CONTROL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (gobject_class, PROP_PROFILES,
+ g_param_spec_flags ("profiles", "Profiles",
+ "Allowed transfer profiles", GST_TYPE_RTSP_PROFILE,
+ DEFAULT_PROFILES, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
g_object_class_install_property (gobject_class, PROP_PROTOCOLS,
g_param_spec_flags ("protocols", "Protocols",
"Allowed lower transport protocols", GST_TYPE_RTSP_LOWER_TRANS,
priv->dscp_qos = -1;
priv->control = g_strdup (DEFAULT_CONTROL);
+ priv->profiles = DEFAULT_PROFILES;
priv->protocols = DEFAULT_PROTOCOLS;
g_mutex_init (&priv->lock);
case PROP_CONTROL:
g_value_take_string (value, gst_rtsp_stream_get_control (stream));
break;
+ case PROP_PROFILES:
+ g_value_set_flags (value, gst_rtsp_stream_get_profiles (stream));
+ break;
case PROP_PROTOCOLS:
g_value_set_flags (value, gst_rtsp_stream_get_protocols (stream));
break;
case PROP_CONTROL:
gst_rtsp_stream_set_control (stream, g_value_get_string (value));
break;
+ case PROP_PROFILES:
+ gst_rtsp_stream_set_profiles (stream, g_value_get_flags (value));
+ break;
case PROP_PROTOCOLS:
gst_rtsp_stream_set_protocols (stream, g_value_get_flags (value));
break;
}
/**
+ * gst_rtsp_stream_is_transport_supported:
+ * @stream: a #GstRTSPStream
+ * @transport: a #GstRTSPTransport
+ *
+ * Check if @transport can be handled by stream
+ *
+ * Returns: %TRUE if @transport can be handled by @stream.
+ */
+gboolean
+gst_rtsp_stream_is_transport_supported (GstRTSPStream * stream,
+ GstRTSPTransport * transport)
+{
+ GstRTSPStreamPrivate *priv;
+
+ g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
+
+ priv = stream->priv;
+
+ g_mutex_lock (&priv->lock);
+ if (transport->trans != GST_RTSP_TRANS_RTP)
+ goto unsupported_transmode;
+
+ if (!(transport->profile & priv->profiles))
+ goto unsupported_profile;
+
+ if (!(transport->lower_transport & priv->protocols))
+ goto unsupported_ltrans;
+
+ g_mutex_unlock (&priv->lock);
+
+ return TRUE;
+
+ /* ERRORS */
+unsupported_transmode:
+ {
+ GST_DEBUG ("unsupported transport mode %d", transport->trans);
+ g_mutex_unlock (&priv->lock);
+ return FALSE;
+ }
+unsupported_profile:
+ {
+ GST_DEBUG ("unsupported profile %d", transport->profile);
+ g_mutex_unlock (&priv->lock);
+ return FALSE;
+ }
+unsupported_ltrans:
+ {
+ GST_DEBUG ("unsupported lower transport %d", transport->lower_transport);
+ g_mutex_unlock (&priv->lock);
+ return FALSE;
+ }
+}
+
+/**
+ * gst_rtsp_stream_set_profiles:
+ * @stream: a #GstRTSPStream
+ * @profiles: the new profiles
+ *
+ * Configure the allowed profiles for @stream.
+ */
+void
+gst_rtsp_stream_set_profiles (GstRTSPStream * stream, GstRTSPProfile profiles)
+{
+ GstRTSPStreamPrivate *priv;
+
+ g_return_if_fail (GST_IS_RTSP_STREAM (stream));
+
+ priv = stream->priv;
+
+ g_mutex_lock (&priv->lock);
+ priv->profiles = profiles;
+ g_mutex_unlock (&priv->lock);
+}
+
+/**
+ * gst_rtsp_stream_get_profiles:
+ * @stream: a #GstRTSPStream
+ *
+ * Get the allowed profiles of @stream.
+ *
+ * Returns: a #GstRTSPProfile
+ */
+GstRTSPProfile
+gst_rtsp_stream_get_profiles (GstRTSPStream * stream)
+{
+ GstRTSPStreamPrivate *priv;
+ GstRTSPProfile res;
+
+ g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), GST_RTSP_PROFILE_UNKNOWN);
+
+ priv = stream->priv;
+
+ g_mutex_lock (&priv->lock);
+ res = priv->profiles;
+ g_mutex_unlock (&priv->lock);
+
+ return res;
+}
+
+/**
* gst_rtsp_stream_set_protocols:
* @stream: a #GstRTSPStream
* @protocols: the new flags
was_not_joined:
{
+ g_mutex_unlock (&priv->lock);
return TRUE;
}
}
* @stream: a #GstRTSPStream
* @rtptime: (allow-none): result RTP timestamp
* @seq: (allow-none): result RTP seqnum
+ * @clock_rate: the clock rate
* @running_time: (allow-none): result running-time
*
* Retrieve the current rtptime, seq and running-time. This is used to
*/
gboolean
gst_rtsp_stream_get_rtpinfo (GstRTSPStream * stream,
- guint * rtptime, guint * seq, GstClockTime * running_time)
+ guint * rtptime, guint * seq, guint * clock_rate,
+ GstClockTime * running_time)
{
GstRTSPStreamPrivate *priv;
+ GstStructure *stats;
GObjectClass *payobjclass;
g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), FALSE);
payobjclass = G_OBJECT_GET_CLASS (priv->payloader);
- if (seq && g_object_class_find_property (payobjclass, "seqnum"))
- g_object_get (priv->payloader, "seqnum", seq, NULL);
+ g_mutex_lock (&priv->lock);
- if (rtptime && g_object_class_find_property (payobjclass, "timestamp"))
- g_object_get (priv->payloader, "timestamp", rtptime, NULL);
+ if (g_object_class_find_property (payobjclass, "stats")) {
+ g_object_get (priv->payloader, "stats", &stats, NULL);
+ if (stats == NULL)
+ goto no_stats;
- if (running_time
- && g_object_class_find_property (payobjclass, "running-time"))
- g_object_get (priv->payloader, "running-time", running_time, NULL);
+ if (seq)
+ gst_structure_get_uint (stats, "seqnum", seq);
+
+ if (rtptime)
+ gst_structure_get_uint (stats, "timestamp", rtptime);
+
+ if (running_time)
+ gst_structure_get_clock_time (stats, "running-time", running_time);
+
+ if (clock_rate) {
+ gst_structure_get_uint (stats, "clock-rate", clock_rate);
+ if (*clock_rate == 0 && running_time)
+ *running_time = GST_CLOCK_TIME_NONE;
+ }
+ gst_structure_free (stats);
+ } else {
+ if (!g_object_class_find_property (payobjclass, "seqnum") ||
+ !g_object_class_find_property (payobjclass, "timestamp"))
+ goto no_stats;
+
+ if (seq)
+ g_object_get (priv->payloader, "seqnum", seq, NULL);
+
+ if (rtptime)
+ g_object_get (priv->payloader, "timestamp", rtptime, NULL);
+
+ if (running_time)
+ *running_time = GST_CLOCK_TIME_NONE;
+ }
+ g_mutex_unlock (&priv->lock);
return TRUE;
+
+ /* ERRORS */
+no_stats:
+ {
+ GST_WARNING ("Could not get payloader stats");
+ g_mutex_unlock (&priv->lock);
+ return FALSE;
+ }
}
/**
}
if (add) {
- GST_INFO ("adding %s:%d-%d", dest, min, max);
- g_signal_emit_by_name (priv->udpsink[0], "add", dest, min, NULL);
- g_signal_emit_by_name (priv->udpsink[1], "add", dest, max, NULL);
if (ttl > 0) {
GST_INFO ("setting ttl-mc %d", ttl);
g_object_set (G_OBJECT (priv->udpsink[0]), "ttl-mc", ttl, NULL);
g_object_set (G_OBJECT (priv->udpsink[1]), "ttl-mc", ttl, NULL);
}
+ GST_INFO ("adding %s:%d-%d", dest, min, max);
+ g_signal_emit_by_name (priv->udpsink[0], "add", dest, min, NULL);
+ g_signal_emit_by_name (priv->udpsink[1], "add", dest, max, NULL);
priv->transports = g_list_prepend (priv->transports, trans);
} else {
GST_INFO ("removing %s:%d-%d", dest, min, max);
*
* @stream must be joined to a bin.
*
- * Returns: the RTP socket or %NULL if no socket could be allocated for @family.
- * Unref after usage
+ * Returns: (transfer full): the RTP socket or %NULL if no socket could be
+ * allocated for @family. Unref after usage
*/
GSocket *
gst_rtsp_stream_get_rtp_socket (GstRTSPStream * stream, GSocketFamily family)
{
GstRTSPStreamPrivate *priv = GST_RTSP_STREAM_GET_PRIVATE (stream);
GSocket *socket;
- gchar *name;
+ const gchar *name;
g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
g_return_val_if_fail (family == G_SOCKET_FAMILY_IPV4 ||
*
* @stream must be joined to a bin.
*
- * Returns: the RTCP socket or %NULL if no socket could be allocated for
- * @family. Unref after usage
+ * Returns: (transfer full): the RTCP socket or %NULL if no socket could be
+ * allocated for @family. Unref after usage
*/
GSocket *
gst_rtsp_stream_get_rtcp_socket (GstRTSPStream * stream, GSocketFamily family)
{
GstRTSPStreamPrivate *priv = GST_RTSP_STREAM_GET_PRIVATE (stream);
GSocket *socket;
- gchar *name;
+ const gchar *name;
g_return_val_if_fail (GST_IS_RTSP_STREAM (stream), NULL);
g_return_val_if_fail (family == G_SOCKET_FAMILY_IPV4 ||