session-media: let the session-media make the RTPInfo
authorWim Taymans <wtaymans@redhat.com>
Thu, 26 Dec 2013 14:41:14 +0000 (15:41 +0100)
committerWim Taymans <wtaymans@redhat.com>
Thu, 26 Dec 2013 15:29:38 +0000 (16:29 +0100)
Add method to create the RTPInfo for a stream-transport.
Add method to create the RTPInfo for all stream-transports in a
session-media.
Use the session-media RTPInfo code in client. This allows us to refactor
another method to link the TCP callbacks.

gst/rtsp-server/rtsp-client.c
gst/rtsp-server/rtsp-session-media.c
gst/rtsp-server/rtsp-session-media.h
gst/rtsp-server/rtsp-stream-transport.c
gst/rtsp-server/rtsp-stream-transport.h

index e87a8de..1a1de6c 100644 (file)
@@ -658,6 +658,32 @@ link_transport (GstRTSPClient * client, GstRTSPSession * session,
 }
 
 static void
+link_session_transports (GstRTSPClient * client, GstRTSPSession * session,
+    GstRTSPSessionMedia * sessmedia)
+{
+  guint n_streams, i;
+
+  n_streams =
+      gst_rtsp_media_n_streams (gst_rtsp_session_media_get_media (sessmedia));
+  for (i = 0; i < n_streams; i++) {
+    GstRTSPStreamTransport *trans;
+    const GstRTSPTransport *tr;
+
+    /* get the transport, if there is no transport configured, skip this stream */
+    trans = gst_rtsp_session_media_get_transport (sessmedia, i);
+    if (trans == NULL)
+      continue;
+
+    tr = gst_rtsp_stream_transport_get_transport (trans);
+
+    if (tr->lower_transport == GST_RTSP_LOWER_TRANS_TCP) {
+      /* for TCP, link the stream to the TCP connection of the client */
+      link_transport (client, session, trans);
+    }
+  }
+}
+
+static void
 unlink_transport (GstRTSPClient * client, GstRTSPSession * session,
     GstRTSPStreamTransport * trans)
 {
@@ -1042,14 +1068,12 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
   GstRTSPMedia *media;
   GstRTSPStatusCode code;
   GstRTSPUrl *uri;
-  GString *rtpinfo;
-  guint n_streams, i, infocount;
   gchar *str;
   GstRTSPTimeRange *range;
   GstRTSPResult res;
   GstRTSPState rtspstate;
   GstRTSPRangeUnit unit = GST_RTSP_RANGE_NPT;
-  gchar *path;
+  gchar *path, *rtpinfo;
   gint matched;
 
   if (!(session = ctx->session))
@@ -1069,6 +1093,8 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
   if (path[matched] != '\0')
     goto no_aggregate;
 
+  g_free (path);
+
   ctx->sessmedia = sessmedia;
   ctx->media = media = gst_rtsp_session_media_get_media (sessmedia);
 
@@ -1092,49 +1118,11 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
     }
   }
 
-  /* grab RTPInfo from the payloaders now */
-  rtpinfo = g_string_new ("");
+  /* link the all TCP callbacks */
+  link_session_transports (client, session, sessmedia);
 
-  n_streams = gst_rtsp_media_n_streams (media);
-  for (i = 0, infocount = 0; i < n_streams; i++) {
-    GstRTSPStreamTransport *trans;
-    GstRTSPStream *stream;
-    const GstRTSPTransport *tr;
-    guint rtptime, seq;
-
-    /* get the transport, if there is no transport configured, skip this stream */
-    trans = gst_rtsp_session_media_get_transport (sessmedia, i);
-    if (trans == NULL) {
-      GST_INFO ("stream %d is not configured", i);
-      continue;
-    }
-    tr = gst_rtsp_stream_transport_get_transport (trans);
-
-    if (tr->lower_transport == GST_RTSP_LOWER_TRANS_TCP) {
-      /* for TCP, link the stream to the TCP connection of the client */
-      link_transport (client, session, trans);
-    }
-
-    stream = gst_rtsp_stream_transport_get_stream (trans);
-    if (gst_rtsp_stream_get_rtpinfo (stream, &rtptime, &seq)) {
-      const GstRTSPUrl *url;
-      gchar *url_str;
-
-      if (infocount > 0)
-        g_string_append (rtpinfo, ", ");
-
-      url = gst_rtsp_stream_transport_get_url (trans);
-      url_str = gst_rtsp_url_get_request_uri (url);
-      g_string_append_printf (rtpinfo, "url=%s;seq=%u;rtptime=%u",
-          url_str, seq, rtptime);
-      g_free (url_str);
-
-      infocount++;
-    } else {
-      GST_WARNING ("RTP-Info cannot be determined for stream %d", i);
-    }
-  }
-  g_free (path);
+  /* grab RTPInfo from the media now */
+  rtpinfo = gst_rtsp_session_media_get_rtpinfo (sessmedia);
 
   /* construct the response now */
   code = GST_RTSP_STS_OK;
@@ -1142,12 +1130,9 @@ handle_play_request (GstRTSPClient * client, GstRTSPContext * ctx)
       gst_rtsp_status_as_text (code), ctx->request);
 
   /* add the RTP-Info header */
-  if (infocount > 0) {
-    str = g_string_free (rtpinfo, FALSE);
-    gst_rtsp_message_take_header (ctx->response, GST_RTSP_HDR_RTP_INFO, str);
-  } else {
-    g_string_free (rtpinfo, TRUE);
-  }
+  if (rtpinfo)
+    gst_rtsp_message_take_header (ctx->response, GST_RTSP_HDR_RTP_INFO,
+        rtpinfo);
 
   /* add the range */
   str = gst_rtsp_media_get_range_string (media, TRUE, unit);
@@ -1197,14 +1182,12 @@ invalid_state:
     GST_ERROR ("client %p: not PLAYING or READY", client);
     send_generic_response (client, GST_RTSP_STS_METHOD_NOT_VALID_IN_THIS_STATE,
         ctx);
-    g_free (path);
     return FALSE;
   }
 unsuspend_failed:
   {
     GST_ERROR ("client %p: unsuspend failed", client);
     send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, ctx);
-    g_free (path);
     return FALSE;
   }
 }
index d042ea0..e49e426 100644 (file)
@@ -233,6 +233,74 @@ gst_rtsp_session_media_get_base_time (GstRTSPSessionMedia * media)
 }
 
 /**
+ * gst_rtsp_session_media_get_rtpinfo:
+ * @media: a #GstRTSPSessionMedia
+ *
+ * Retrieve the RTP-Info header string for all streams in @media
+ * with configured transports.
+ *
+ * Returns: (transfer full): The RTP-Info as a string, g_free()
+ *   after usage.
+ */
+gchar *
+gst_rtsp_session_media_get_rtpinfo (GstRTSPSessionMedia * media)
+{
+  GstRTSPSessionMediaPrivate *priv;
+  GString *rtpinfo = NULL;
+  GstRTSPStreamTransport *transport;
+  guint i, n_streams;
+
+  g_return_val_if_fail (GST_IS_RTSP_SESSION_MEDIA (media), NULL);
+
+  priv = media->priv;
+  g_mutex_lock (&priv->lock);
+
+  n_streams = priv->transports->len;
+
+  GST_LOG_OBJECT (media, "collecting RTP info for %d transports", n_streams);
+
+  for (i = 0; i < n_streams; i++) {
+    gchar *stream_rtpinfo;
+
+    transport = g_ptr_array_index (priv->transports, i);
+    if (transport == NULL) {
+      GST_DEBUG_OBJECT (media, "ignoring unconfigured transport %d", i);
+      continue;
+    }
+
+    stream_rtpinfo = gst_rtsp_stream_transport_get_rtpinfo (transport);
+    if (stream_rtpinfo == NULL)
+      goto stream_rtpinfo_missing;
+
+    if (rtpinfo == NULL)
+      rtpinfo = g_string_new ("");
+    else
+      g_string_append (rtpinfo, ", ");
+
+    g_string_append (rtpinfo, stream_rtpinfo);
+    g_free (stream_rtpinfo);
+  }
+
+  if (rtpinfo == NULL) {
+    GST_INFO_OBJECT (media, "no transports configured, RTP info is empty");
+    rtpinfo = g_string_new ("");
+  }
+
+  g_mutex_unlock (&priv->lock);
+
+  return g_string_free (rtpinfo, FALSE);
+
+  /* ERRORS */
+stream_rtpinfo_missing:
+  {
+    g_mutex_unlock (&priv->lock);
+    g_string_free (rtpinfo, TRUE);
+    GST_ERROR_OBJECT (media, "could not get stream %d rtpinfo", i);
+    return NULL;
+  }
+}
+
+/**
  * gst_rtsp_session_media_set_transport:
  * @media: a #GstRTSPSessionMedia
  * @stream: a #GstRTSPStream
index 0b7c8c8..e2af5ad 100644 (file)
@@ -90,6 +90,8 @@ GstRTSPStreamTransport * gst_rtsp_session_media_get_transport  (GstRTSPSessionMe
 gboolean                 gst_rtsp_session_media_alloc_channels (GstRTSPSessionMedia *media,
                                                                 GstRTSPRange *range);
 
+gchar *                  gst_rtsp_session_media_get_rtpinfo    (GstRTSPSessionMedia * media);
+
 G_END_DECLS
 
 #endif /* __GST_RTSP_SESSION_MEDIA_H__ */
index 90e6310..cf8eb64 100644 (file)
@@ -310,6 +310,40 @@ gst_rtsp_stream_transport_get_url (GstRTSPStreamTransport * trans)
   return trans->priv->url;
 }
 
+ /**
+ * gst_rtsp_stream_transport_get_rtpinfo:
+ * @trans: a #GstRTSPStreamTransport
+ *
+ * Get the RTPInfo string for @trans.
+ *
+ * Returns: the RTPInfo string for @trans. g_free() after
+ * usage.
+ */
+gchar *
+gst_rtsp_stream_transport_get_rtpinfo (GstRTSPStreamTransport * trans)
+{
+  GstRTSPStreamTransportPrivate *priv;
+  gchar *url_str;
+  GString *rtpinfo;
+  guint rtptime, seq;
+
+  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))
+    return NULL;
+
+  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
index bc02df8..3a5e579 100644 (file)
@@ -99,6 +99,9 @@ void                     gst_rtsp_stream_transport_set_url       (GstRTSPStreamT
                                                                   const GstRTSPUrl * url);
 const GstRTSPUrl *       gst_rtsp_stream_transport_get_url       (GstRTSPStreamTransport *trans);
 
+
+gchar *                  gst_rtsp_stream_transport_get_rtpinfo   (GstRTSPStreamTransport *trans);
+
 void                     gst_rtsp_stream_transport_set_callbacks (GstRTSPStreamTransport *trans,
                                                                   GstRTSPSendFunc send_rtp,
                                                                   GstRTSPSendFunc send_rtcp,