/**
* SECTION:rtsp-stream-transport
* @short_description: A media stream transport configuration
- * @see_also: #GstRTSPStream
+ * @see_also: #GstRTSPStream, #GstRTSPSessionMedia
*
- * Last reviewed on 2013-07-11 (1.0.0)
+ * The #GstRTSPStreamTransport configures the transport used by a
+ * #GstRTSPStream. It is usually manages by a #GstRTSPSessionMedia object.
+ *
+ * With gst_rtsp_stream_transport_set_callbacks(), callbacks can be configured
+ * to handle the RTP and RTCP packets from the stream, for example when they
+ * need to be sent over TCP.
+ *
+ * With gst_rtsp_stream_transport_set_active() the transports are added and
+ * removed from the stream.
+ *
+ * A #GstRTSPStream will call gst_rtsp_stream_transport_keep_alive() when RTCP
+ * is received from the client. It will also call
+ * gst_rtsp_stream_transport_set_timed_out() when a receiver has timed out.
+ *
+ * Last reviewed on 2013-07-16 (1.0.0)
*/
#include <string.h>
gboolean timed_out;
GstRTSPTransport *transport;
+ GstRTSPUrl *url;
GObject *rtpsource;
};
gst_rtsp_stream_transport_set_callbacks (trans, NULL, NULL, NULL, NULL);
gst_rtsp_stream_transport_set_keepalive (trans, NULL, NULL, NULL);
+ if (priv->stream)
+ g_object_unref (priv->stream);
+
if (priv->transport)
gst_rtsp_transport_free (priv->transport);
+ if (priv->url)
+ gst_rtsp_url_free (priv->url);
+
G_OBJECT_CLASS (gst_rtsp_stream_transport_parent_class)->finalize (obj);
}
* Create a new #GstRTSPStreamTransport that can be used to manage
* @stream with transport @tr.
*
- * Returns: a new #GstRTSPStreamTransport
+ * Returns: (transfer full): a new #GstRTSPStreamTransport
*/
GstRTSPStreamTransport *
gst_rtsp_stream_transport_new (GstRTSPStream * stream, GstRTSPTransport * tr)
trans = g_object_new (GST_TYPE_RTSP_STREAM_TRANSPORT, NULL);
priv = trans->priv;
priv->stream = stream;
+ priv->stream = g_object_ref (priv->stream);
priv->transport = tr;
return trans;
* @trans: a #GstRTSPStreamTransport
* @send_rtp: (scope notified): a callback called when RTP should be sent
* @send_rtcp: (scope notified): a callback called when RTCP should be sent
- * @user_data: user data passed to callbacks
- * @notify: called with the user_data when no longer needed.
+ * @user_data: (closure): user data passed to callbacks
+ * @notify: (allow-none): called with the user_data when no longer needed.
*
* Install callbacks that will be called when data for a stream should be sent
* to a client. This is usually used when sending RTP/RTCP over TCP.
/**
* gst_rtsp_stream_transport_set_keepalive:
* @trans: a #GstRTSPStreamTransport
- * @keep_alive: a callback called when the receiver is active
- * @user_data: user data passed to callback
- * @notify: called with the user_data when no longer needed.
+ * @keep_alive: (scope notified): a callback called when the receiver is active
+ * @user_data: (closure): user data passed to callback
+ * @notify: (allow-none): called with the user_data when no longer needed.
*
* Install callbacks that will be called when RTCP packets are received from the
* receiver of @trans.
* Get the transport configured in @trans.
*
* Returns: (transfer none): the transport configured in @trans. It remains
- * valid for as long as @trans is valid.
+ * valid for as long as @trans is valid.
*/
const GstRTSPTransport *
gst_rtsp_stream_transport_get_transport (GstRTSPStreamTransport * trans)
}
/**
+ * gst_rtsp_stream_transport_set_url:
+ * @trans: a #GstRTSPStreamTransport
+ * @url: (transfer none): a client #GstRTSPUrl
+ *
+ * Set @url as the client url.
+ */
+void
+gst_rtsp_stream_transport_set_url (GstRTSPStreamTransport * trans,
+ const GstRTSPUrl * url)
+{
+ GstRTSPStreamTransportPrivate *priv;
+
+ g_return_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans));
+
+ priv = trans->priv;
+
+ /* keep track of the transports in the stream. */
+ if (priv->url)
+ gst_rtsp_url_free (priv->url);
+ priv->url = (url ? gst_rtsp_url_copy (url) : NULL);
+}
+
+/**
+ * gst_rtsp_stream_transport_get_url:
+ * @trans: a #GstRTSPStreamTransport
+ *
+ * Get the url configured in @trans.
+ *
+ * Returns: (transfer none): the url configured in @trans. It remains
+ * valid for as long as @trans is valid.
+ */
+const GstRTSPUrl *
+gst_rtsp_stream_transport_get_url (GstRTSPStreamTransport * trans)
+{
+ g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
+
+ return trans->priv->url;
+}
+
+ /**
+ * gst_rtsp_stream_transport_get_rtpinfo:
+ * @trans: a #GstRTSPStreamTransport
+ * @start_time: a star time
+ *
+ * Get the RTP-Info string for @trans and @start_time.
+ *
+ * Returns: (transfer full) (nullable): the RTPInfo string for @trans
+ * and @start_time or %NULL when the RTP-Info could not be
+ * determined. g_free() after usage.
+ */
+gchar *
+gst_rtsp_stream_transport_get_rtpinfo (GstRTSPStreamTransport * trans,
+ GstClockTime start_time)
+{
+ GstRTSPStreamTransportPrivate *priv;
+ gchar *url_str;
+ GString *rtpinfo;
+ guint rtptime, seq, clock_rate;
+ GstClockTime running_time = GST_CLOCK_TIME_NONE;
+
+ g_return_val_if_fail (GST_IS_RTSP_STREAM_TRANSPORT (trans), NULL);
+
+ priv = trans->priv;
+
+ if (!gst_rtsp_stream_get_rtpinfo (priv->stream, &rtptime, &seq, &clock_rate,
+ &running_time))
+ return NULL;
+
+ GST_DEBUG ("RTP time %u, seq %u, rate %u, running-time %" GST_TIME_FORMAT,
+ rtptime, seq, clock_rate, GST_TIME_ARGS (running_time));
+
+ if (GST_CLOCK_TIME_IS_VALID (running_time)
+ && GST_CLOCK_TIME_IS_VALID (start_time)) {
+ if (running_time > start_time) {
+ rtptime -=
+ gst_util_uint64_scale_int (running_time - start_time, clock_rate,
+ GST_SECOND);
+ } else {
+ rtptime +=
+ gst_util_uint64_scale_int (start_time - running_time, clock_rate,
+ GST_SECOND);
+ }
+ }
+ GST_DEBUG ("RTP time %u, for start-time %" GST_TIME_FORMAT,
+ rtptime, GST_TIME_ARGS (start_time));
+
+ rtpinfo = g_string_new ("");
+
+ url_str = gst_rtsp_url_get_request_uri (trans->priv->url);
+ g_string_append_printf (rtpinfo, "url=%s;seq=%u;rtptime=%u",
+ url_str, seq, rtptime);
+ g_free (url_str);
+
+ return g_string_free (rtpinfo, FALSE);
+}
+
+/**
* gst_rtsp_stream_transport_set_active:
* @trans: a #GstRTSPStreamTransport
* @active: new state of @trans
/**
* gst_rtsp_stream_transport_send_rtp:
* @trans: a #GstRTSPStreamTransport
- * @buffer: a #GstBuffer
+ * @buffer: (transfer none): a #GstBuffer
*
* Send @buffer to the installed RTP callback for @trans.
*
priv->send_rtp (buffer, priv->transport->interleaved.min,
priv->user_data);
+ if (res)
+ gst_rtsp_stream_transport_keep_alive (trans);
+
return res;
}
/**
* gst_rtsp_stream_transport_send_rtcp:
* @trans: a #GstRTSPStreamTransport
- * @buffer: a #GstBuffer
+ * @buffer: (transfer none): a #GstBuffer
*
* Send @buffer to the installed RTCP callback for @trans.
*
priv->send_rtcp (buffer, priv->transport->interleaved.max,
priv->user_data);
+ if (res)
+ gst_rtsp_stream_transport_keep_alive (trans);
+
return res;
}
if (priv->keep_alive)
priv->keep_alive (priv->ka_user_data);
}
+
+/**
+ * gst_rtsp_stream_transport_recv_data:
+ * @trans: a #GstRTSPStreamTransport
+ * @channel: a channel
+ * @buffer: (transfer full): a #GstBuffer
+ *
+ * Receive @buffer on @channel @trans.
+ *
+ * Returns: a #GstFlowReturn. Returns GST_FLOW_NOT_LINKED when @channel is not
+ * configured in the transport of @trans.
+ */
+GstFlowReturn
+gst_rtsp_stream_transport_recv_data (GstRTSPStreamTransport * trans,
+ guint channel, GstBuffer * buffer)
+{
+ GstRTSPStreamTransportPrivate *priv;
+ const GstRTSPTransport *tr;
+ GstFlowReturn res;
+
+ priv = trans->priv;
+ tr = priv->transport;
+
+ if (tr->interleaved.min == channel) {
+ res = gst_rtsp_stream_recv_rtp (priv->stream, buffer);
+ } else if (tr->interleaved.max == channel) {
+ res = gst_rtsp_stream_recv_rtcp (priv->stream, buffer);
+ } else {
+ res = GST_FLOW_NOT_LINKED;
+ }
+ return res;
+}