[FFmpeg-cvslog] r17777 - trunk/libavformat/rtsp.c
rbultje
subversion
Tue Mar 3 17:52:37 CET 2009
Author: rbultje
Date: Tue Mar 3 17:52:35 2009
New Revision: 17777
Log:
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
RTSP-MS UDP" thread on mailinglist.
Basically, UDP setup needs to be done in a particular order (first rtx
on two UDP ports (one for RTP, one for RTCP), then the other streams over
one, single port for all of them together). Not doing this correctly results
in a "461" error (invalid transport) during setup.
Modified:
trunk/libavformat/rtsp.c
Modified: trunk/libavformat/rtsp.c
==============================================================================
--- trunk/libavformat/rtsp.c Tue Mar 3 17:48:56 2009 (r17776)
+++ trunk/libavformat/rtsp.c Tue Mar 3 17:52:35 2009 (r17777)
@@ -888,7 +888,7 @@ make_setup_request (AVFormatContext *s,
int lower_transport, const char *real_challenge)
{
RTSPState *rt = s->priv_data;
- int j, i, err, interleave = 0;
+ int rtx, j, i, err, interleave = 0;
RTSPStream *rtsp_st;
RTSPMessageHeader reply1, *reply = &reply1;
char cmd[2048];
@@ -906,12 +906,38 @@ make_setup_request (AVFormatContext *s,
for(j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) {
char transport[2048];
+ /**
+ * WMS serves all UDP data over a single connection, the RTX, which
+ * isn't necessarily the first in the SDP but has to be the first
+ * to be set up, else the second/third SETUP will fail with a 461.
+ */
+ if (lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
+ rt->server_type == RTSP_SERVER_WMS) {
+ if (i == 0) {
+ /* rtx first */
+ for (rtx = 0; rtx < rt->nb_rtsp_streams; rtx++) {
+ int len = strlen(rt->rtsp_streams[rtx]->control_url);
+ if (len >= 4 &&
+ !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4, "/rtx"))
+ break;
+ }
+ if (rtx == rt->nb_rtsp_streams)
+ return -1; /* no RTX found */
+ rtsp_st = rt->rtsp_streams[rtx];
+ } else
+ rtsp_st = rt->rtsp_streams[i > rtx ? i : i - 1];
+ } else
rtsp_st = rt->rtsp_streams[i];
/* RTP/UDP */
if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
char buf[256];
+ if (rt->server_type == RTSP_SERVER_WMS && i > 1) {
+ port = reply->transports[0].client_port_min;
+ goto have_port;
+ }
+
/* first try in specified port range */
if (RTSP_RTP_PORT_MIN != 0) {
while(j <= RTSP_RTP_PORT_MAX) {
@@ -932,13 +958,15 @@ make_setup_request (AVFormatContext *s,
rtp_opened:
port = rtp_get_local_port(rtsp_st->rtp_handle);
+ have_port:
snprintf(transport, sizeof(transport) - 1,
"%s/UDP;", trans_pref);
if (rt->server_type != RTSP_SERVER_REAL)
av_strlcat(transport, "unicast;", sizeof(transport));
av_strlcatf(transport, sizeof(transport),
"client_port=%d", port);
- if (rt->transport == RTSP_TRANSPORT_RTP)
+ if (rt->transport == RTSP_TRANSPORT_RTP &&
+ !(rt->server_type == RTSP_SERVER_WMS && i > 0))
av_strlcatf(transport, sizeof(transport), "-%d", port + 1);
}
@@ -1022,7 +1050,8 @@ make_setup_request (AVFormatContext *s,
/* XXX: also use address if specified */
snprintf(url, sizeof(url), "rtp://%s:%d",
host, reply->transports[0].server_port_min);
- if (rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
+ if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
+ rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
err = AVERROR_INVALIDDATA;
goto fail;
}
@@ -1286,11 +1315,13 @@ static int udp_read_packet(AVFormatConte
fd_max = -1;
for(i = 0; i < rt->nb_rtsp_streams; i++) {
rtsp_st = rt->rtsp_streams[i];
+ if (rtsp_st->rtp_handle) {
/* currently, we cannot probe RTCP handle because of blocking restrictions */
rtp_get_file_handles(rtsp_st->rtp_handle, &fd1, &fd2);
if (fd1 > fd_max)
fd_max = fd1;
FD_SET(fd1, &rfds);
+ }
}
tv.tv_sec = 0;
tv.tv_usec = 100 * 1000;
@@ -1298,6 +1329,7 @@ static int udp_read_packet(AVFormatConte
if (n > 0) {
for(i = 0; i < rt->nb_rtsp_streams; i++) {
rtsp_st = rt->rtsp_streams[i];
+ if (rtsp_st->rtp_handle) {
rtp_get_file_handles(rtsp_st->rtp_handle, &fd1, &fd2);
if (FD_ISSET(fd1, &rfds)) {
ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
@@ -1306,6 +1338,7 @@ static int udp_read_packet(AVFormatConte
return ret;
}
}
+ }
}
}
}
More information about the ffmpeg-cvslog
mailing list