mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 15:08:53 +00:00
gst/rtsp/gstrtspsrc.c: Improve udp port setup. Fixes #545710.
Original commit message from CVS: Patch by: Aurelien Grimaud <gstelzz at yahoo dot fr> * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_alloc_udp_ports): Improve udp port setup. Fixes #545710.
This commit is contained in:
parent
8f0079c7e2
commit
1e64691186
2 changed files with 58 additions and 39 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
2008-08-05 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
|
Patch by: Aurelien Grimaud <gstelzz at yahoo dot fr>
|
||||||
|
|
||||||
|
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_alloc_udp_ports):
|
||||||
|
Improve udp port setup. Fixes #545710.
|
||||||
|
|
||||||
2008-08-05 Wim Taymans <wim.taymans@collabora.co.uk>
|
2008-08-05 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
* gst/rtp/Makefile.am:
|
* gst/rtp/Makefile.am:
|
||||||
|
|
|
@ -1007,27 +1007,45 @@ gst_rtspsrc_alloc_udp_ports (GstRTSPStream * stream,
|
||||||
{
|
{
|
||||||
GstRTSPSrc *src;
|
GstRTSPSrc *src;
|
||||||
GstStateChangeReturn ret;
|
GstStateChangeReturn ret;
|
||||||
GstElement *tmp, *udpsrc0, *udpsrc1;
|
GstElement *udpsrc0, *udpsrc1;
|
||||||
gint tmp_rtp, tmp_rtcp;
|
gint tmp_rtp, tmp_rtcp;
|
||||||
guint count;
|
guint count;
|
||||||
|
|
||||||
src = stream->parent;
|
src = stream->parent;
|
||||||
|
|
||||||
tmp = NULL;
|
|
||||||
udpsrc0 = NULL;
|
udpsrc0 = NULL;
|
||||||
udpsrc1 = NULL;
|
udpsrc1 = NULL;
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
|
/* Start with random port */
|
||||||
|
tmp_rtp = 0;
|
||||||
|
|
||||||
/* try to allocate 2 UDP ports, the RTP port should be an even
|
/* try to allocate 2 UDP ports, the RTP port should be an even
|
||||||
* number and the RTCP port should be the next (uneven) port */
|
* number and the RTCP port should be the next (uneven) port */
|
||||||
again:
|
again:
|
||||||
udpsrc0 = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0:0", NULL);
|
udpsrc0 = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0", NULL);
|
||||||
if (udpsrc0 == NULL)
|
if (udpsrc0 == NULL)
|
||||||
goto no_udp_protocol;
|
goto no_udp_protocol;
|
||||||
|
g_object_set (G_OBJECT (udpsrc0), "port", tmp_rtp, NULL);
|
||||||
|
|
||||||
ret = gst_element_set_state (udpsrc0, GST_STATE_PAUSED);
|
ret = gst_element_set_state (udpsrc0, GST_STATE_PAUSED);
|
||||||
if (ret == GST_STATE_CHANGE_FAILURE)
|
if (ret == GST_STATE_CHANGE_FAILURE) {
|
||||||
goto start_udp_failure;
|
if (tmp_rtp != 0) {
|
||||||
|
GST_DEBUG_OBJECT (src, "Unable to make udpsrc from RTP port %d", tmp_rtp);
|
||||||
|
|
||||||
|
tmp_rtp += 2;
|
||||||
|
if (++count > src->retry)
|
||||||
|
goto no_ports;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (src, "free RTP udpsrc");
|
||||||
|
gst_element_set_state (udpsrc0, GST_STATE_NULL);
|
||||||
|
gst_object_unref (udpsrc0);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (src, "retry %d", count);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
goto no_udp_protocol;
|
||||||
|
}
|
||||||
|
|
||||||
g_object_get (G_OBJECT (udpsrc0), "port", &tmp_rtp, NULL);
|
g_object_get (G_OBJECT (udpsrc0), "port", &tmp_rtp, NULL);
|
||||||
GST_DEBUG_OBJECT (src, "got RTP port %d", tmp_rtp);
|
GST_DEBUG_OBJECT (src, "got RTP port %d", tmp_rtp);
|
||||||
|
@ -1035,27 +1053,19 @@ again:
|
||||||
/* check if port is even */
|
/* check if port is even */
|
||||||
if ((tmp_rtp & 0x01) != 0) {
|
if ((tmp_rtp & 0x01) != 0) {
|
||||||
/* port not even, close and allocate another */
|
/* port not even, close and allocate another */
|
||||||
count++;
|
if (++count > src->retry)
|
||||||
if (count > src->retry)
|
|
||||||
goto no_ports;
|
goto no_ports;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "RTP port not even, retry %d", count);
|
GST_DEBUG_OBJECT (src, "RTP port not even");
|
||||||
/* have to keep port allocated so we can get a new one */
|
|
||||||
if (tmp != NULL) {
|
GST_DEBUG_OBJECT (src, "free RTP udpsrc");
|
||||||
GST_DEBUG_OBJECT (src, "free temp");
|
gst_element_set_state (udpsrc0, GST_STATE_NULL);
|
||||||
gst_element_set_state (tmp, GST_STATE_NULL);
|
gst_object_unref (udpsrc0);
|
||||||
gst_object_unref (tmp);
|
|
||||||
}
|
|
||||||
tmp = udpsrc0;
|
|
||||||
GST_DEBUG_OBJECT (src, "retry %d", count);
|
GST_DEBUG_OBJECT (src, "retry %d", count);
|
||||||
|
tmp_rtp++;
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
/* free leftover temp element/port */
|
|
||||||
if (tmp) {
|
|
||||||
gst_element_set_state (tmp, GST_STATE_NULL);
|
|
||||||
gst_object_unref (tmp);
|
|
||||||
tmp = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate port+1 for RTCP now */
|
/* allocate port+1 for RTCP now */
|
||||||
udpsrc1 = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0", NULL);
|
udpsrc1 = gst_element_make_from_uri (GST_URI_SRC, "udp://0.0.0.0", NULL);
|
||||||
|
@ -1068,10 +1078,26 @@ again:
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (src, "starting RTCP on port %d", tmp_rtcp);
|
GST_DEBUG_OBJECT (src, "starting RTCP on port %d", tmp_rtcp);
|
||||||
ret = gst_element_set_state (udpsrc1, GST_STATE_PAUSED);
|
ret = gst_element_set_state (udpsrc1, GST_STATE_PAUSED);
|
||||||
/* FIXME, this could fail if the next port is not free, we
|
/* tmp_rtcp port is busy already : retry to make rtp/rtcp pair */
|
||||||
* should retry with another port then */
|
if (ret == GST_STATE_CHANGE_FAILURE) {
|
||||||
if (ret == GST_STATE_CHANGE_FAILURE)
|
|
||||||
goto start_rtcp_failure;
|
GST_DEBUG_OBJECT (src, "Unable to make udpsrc from RTCP port %d", tmp_rtcp);
|
||||||
|
|
||||||
|
if (++count > src->retry)
|
||||||
|
goto no_ports;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (src, "free RTP udpsrc");
|
||||||
|
gst_element_set_state (udpsrc0, GST_STATE_NULL);
|
||||||
|
gst_object_unref (udpsrc0);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (src, "free RTCP udpsrc");
|
||||||
|
gst_element_set_state (udpsrc1, GST_STATE_NULL);
|
||||||
|
gst_object_unref (udpsrc1);
|
||||||
|
|
||||||
|
tmp_rtp += 2;
|
||||||
|
GST_DEBUG_OBJECT (src, "retry %d", count);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
|
||||||
/* all fine, do port check */
|
/* all fine, do port check */
|
||||||
g_object_get (G_OBJECT (udpsrc0), "port", rtpport, NULL);
|
g_object_get (G_OBJECT (udpsrc0), "port", rtpport, NULL);
|
||||||
|
@ -1098,11 +1124,6 @@ no_udp_protocol:
|
||||||
GST_DEBUG_OBJECT (src, "could not get UDP source");
|
GST_DEBUG_OBJECT (src, "could not get UDP source");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
start_udp_failure:
|
|
||||||
{
|
|
||||||
GST_DEBUG_OBJECT (src, "could not start UDP source");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
no_ports:
|
no_ports:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (src, "could not allocate UDP port pair after %d retries",
|
GST_DEBUG_OBJECT (src, "could not allocate UDP port pair after %d retries",
|
||||||
|
@ -1114,11 +1135,6 @@ no_udp_rtcp_protocol:
|
||||||
GST_DEBUG_OBJECT (src, "could not get UDP source for RTCP");
|
GST_DEBUG_OBJECT (src, "could not get UDP source for RTCP");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
start_rtcp_failure:
|
|
||||||
{
|
|
||||||
GST_DEBUG_OBJECT (src, "could not start UDP source for RTCP");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
port_error:
|
port_error:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (src, "ports don't match rtp: %d<->%d, rtcp: %d<->%d",
|
GST_DEBUG_OBJECT (src, "ports don't match rtp: %d<->%d, rtcp: %d<->%d",
|
||||||
|
@ -1127,10 +1143,6 @@ port_error:
|
||||||
}
|
}
|
||||||
cleanup:
|
cleanup:
|
||||||
{
|
{
|
||||||
if (tmp) {
|
|
||||||
gst_element_set_state (tmp, GST_STATE_NULL);
|
|
||||||
gst_object_unref (tmp);
|
|
||||||
}
|
|
||||||
if (udpsrc0) {
|
if (udpsrc0) {
|
||||||
gst_element_set_state (udpsrc0, GST_STATE_NULL);
|
gst_element_set_state (udpsrc0, GST_STATE_NULL);
|
||||||
gst_object_unref (udpsrc0);
|
gst_object_unref (udpsrc0);
|
||||||
|
|
Loading…
Reference in a new issue