rtspclientsink: Fix client ports for the RTCP backchannel
authorMathieu Duponchelle <mathieu@centricular.com>
Thu, 29 Mar 2018 00:51:02 +0000 (02:51 +0200)
committerMathieu Duponchelle <mathieu@centricular.com>
Fri, 30 Mar 2018 15:55:32 +0000 (17:55 +0200)
This was broken since the work for delayed transport creation
was merged: the creation of the transports string depends on
calling stream_get_server_port, which only starts returning
something meaningful after a call to stream_allocate_udp_sockets
has been made, this function expects a transport that we parse
from the transport string ...

Significant refactoring is in order, but does not look entirely
trivial, for now we put a band aid on and create a second transport
string after the stream has been completed, to pass it in
the request headers instead of the previous, incomplete one.

https://bugzilla.gnome.org/show_bug.cgi?id=794789

gst/rtsp-sink/gstrtspclientsink.c
tests/check/gst/rtspclientsink.c

index 358b4e6..29ac59f 100644 (file)
@@ -3909,9 +3909,6 @@ gst_rtsp_client_sink_setup_streams (GstRTSPClientSink * sink, gboolean async)
       goto create_request_failed;
     }
 
-    /* select transport */
-    gst_rtsp_message_take_header (&request, GST_RTSP_HDR_TRANSPORT, transports);
-
     /* set up keys */
     if (cur_profile == GST_RTSP_PROFILE_SAVP ||
         cur_profile == GST_RTSP_PROFILE_SAVPF) {
@@ -3952,6 +3949,25 @@ gst_rtsp_client_sink_setup_streams (GstRTSPClientSink * sink, gboolean async)
       gst_rtsp_stream_set_blocked (stream, FALSE);
     }
 
+    /* FIXME:
+     * the creation of the transports string depends on
+     * calling stream_get_server_port, which only starts returning
+     * something meaningful after a call to stream_allocate_udp_sockets
+     * has been made, this function expects a transport that we parse
+     * from the transport string ...
+     *
+     * Significant refactoring is in order, but does not look entirely
+     * trivial, for now we put a band aid on and create a second transport
+     * string after the stream has been completed, to pass it in
+     * the request headers instead of the previous, incomplete one.
+     */
+    g_free (transports);
+    res = gst_rtsp_client_sink_create_transports_string (sink, context, family,
+        protocols & protocol_masks[mask], cur_profile, &transports);
+
+    /* select transport */
+    gst_rtsp_message_take_header (&request, GST_RTSP_HDR_TRANSPORT, transports);
+
     /* handle the code ourselves */
     res = gst_rtsp_client_sink_send (sink, info, &request, &response, &code);
     if (res < 0)
index ddafdba..f053307 100644 (file)
@@ -38,6 +38,7 @@ static GstRTSPServer *server = NULL;
 
 /* tcp port that the test server listens for rtsp requests on */
 static gint test_port = 0;
+static gint server_send_rtcp_port;
 
 /* id of the server's source within the GMainContext */
 static guint source_id;
@@ -132,6 +133,26 @@ get_server_uri (gint port, const gchar * mount_point)
   return uri_string;
 }
 
+static GstRTSPFilterResult
+check_transport (GstRTSPStream *stream, GstRTSPStreamTransport *strans, gpointer user_data)
+{
+  const GstRTSPTransport *trans = gst_rtsp_stream_transport_get_transport (strans);
+
+  server_send_rtcp_port = trans->client_port.max;
+
+  return GST_RTSP_FILTER_KEEP;
+}
+
+static void
+new_state_cb (GstRTSPMedia * media, gint state, gpointer user_data)
+{
+  if (state == GST_STATE_PLAYING) {
+    GstRTSPStream *stream = gst_rtsp_media_get_stream (media, 0);
+
+    gst_rtsp_stream_transport_filter (stream, (GstRTSPStreamTransportFilterFunc) check_transport, user_data);
+  }
+}
+
 static void
 media_constructed_cb (GstRTSPMediaFactory * mfactory, GstRTSPMedia * media,
     gpointer user_data)
@@ -139,6 +160,9 @@ media_constructed_cb (GstRTSPMediaFactory * mfactory, GstRTSPMedia * media,
   GstElement **p_sink = user_data;
   GstElement *bin;
 
+  g_signal_connect (media, "new-state",
+      G_CALLBACK (new_state_cb), user_data);
+
   bin = gst_rtsp_media_get_element (media);
   *p_sink = gst_bin_get_by_name (GST_BIN (bin), "sink");
   GST_INFO ("media constructed!: %" GST_PTR_FORMAT, *p_sink);
@@ -193,6 +217,8 @@ GST_START_TEST (test_record)
 
   iterate ();
 
+  fail_unless (server_send_rtcp_port != 0);
+
   /* check received data (we assume every buffer created by audiotestsrc and
    * subsequently encoded by mulawenc results in exactly one RTP packet) */
   for (i = 0; i < RECORD_N_BUFS; ++i) {