rtspclientsink: Fix client ports for the RTCP backchannel

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
This commit is contained in:
Mathieu Duponchelle 2018-03-29 02:51:02 +02:00
parent 3a129300f0
commit 7f9b8c2107
2 changed files with 45 additions and 3 deletions

View 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)

View 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) {