Mercurial > libavformat.hg
changeset 4877:940946a4569b libavformat
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
Real wants OPTIONS) while the connection is idle, otherwise it will
be aborted after a short period (usually a minute). See the thread
"[PATCH] rtsp.c: keep-alive" on the mailinglist.
author | rbultje |
---|---|
date | Wed, 15 Apr 2009 13:04:34 +0000 |
parents | 3a1ffb822e81 |
children | 5f8639313523 |
files | rtsp.c rtsp.h |
diffstat | 2 files changed, 56 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/rtsp.c Wed Apr 15 06:41:08 2009 +0000 +++ b/rtsp.c Wed Apr 15 13:04:34 2009 +0000 @@ -682,7 +682,12 @@ /* NOTE: we do case independent match for broken servers */ p = buf; if (av_stristart(p, "Session:", &p)) { + int t; get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p); + if (av_stristart(p, ";timeout=", &p) && + (t = strtol(p, NULL, 10)) > 0) { + reply->timeout = t; + } } else if (av_stristart(p, "Content-Length:", &p)) { reply->content_length = strtol(p, NULL, 10); } else if (av_stristart(p, "Transport:", &p)) { @@ -837,7 +842,7 @@ return 0; } -static void rtsp_send_cmd(AVFormatContext *s, +static void rtsp_send_cmd_async (AVFormatContext *s, const char *cmd, RTSPMessageHeader *reply, unsigned char **content_ptr) { @@ -857,6 +862,14 @@ printf("Sending:\n%s--\n", buf); #endif url_write(rt->rtsp_hd, buf, strlen(buf)); + rt->last_cmd_time = av_gettime(); +} + +static void rtsp_send_cmd (AVFormatContext *s, + const char *cmd, RTSPMessageHeader *reply, + unsigned char **content_ptr) +{ + rtsp_send_cmd_async(s, cmd, reply, content_ptr); rtsp_read_reply(s, reply, content_ptr, 0); } @@ -943,6 +956,9 @@ else trans_pref = "RTP/AVP"; + /* default timeout: 1 minute */ + rt->timeout = 60; + /* for each stream, make the setup request */ /* XXX: we assume the same server is used for the control of each RTSP stream */ @@ -1123,6 +1139,9 @@ goto fail; } + if (reply->timeout > 0) + rt->timeout = reply->timeout; + if (rt->server_type == RTSP_SERVER_REAL) rt->need_subscription = 1; @@ -1403,12 +1422,12 @@ RTSPStream *rtsp_st; int ret, len; uint8_t buf[10 * RTP_MAX_PACKET_LENGTH]; + RTSPMessageHeader reply1, *reply = &reply1; + char cmd[1024]; if (rt->server_type == RTSP_SERVER_REAL) { int i; - RTSPMessageHeader reply1, *reply = &reply1; enum AVDiscard cache[MAX_STREAMS]; - char cmd[1024]; for (i = 0; i < s->nb_streams; i++) cache[i] = s->streams[i]->discard; @@ -1508,6 +1527,22 @@ /* more packets may follow, so we save the RTP context */ rt->cur_transport_priv = rtsp_st->transport_priv; } + + /* send dummy request to keep TCP connection alive */ + if ((rt->server_type == RTSP_SERVER_WMS || + rt->server_type == RTSP_SERVER_REAL) && + (av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) { + if (rt->server_type == RTSP_SERVER_WMS) { + snprintf(cmd, sizeof(cmd) - 1, + "GET_PARAMETER %s RTSP/1.0\r\n", + s->filename); + rtsp_send_cmd_async(s, cmd, reply, NULL); + } else { + rtsp_send_cmd_async(s, "OPTIONS * RTSP/1.0\r\n", + reply, NULL); + } + } + return 0; }
--- a/rtsp.h Wed Apr 15 06:41:08 2009 +0000 +++ b/rtsp.h Wed Apr 15 13:04:34 2009 +0000 @@ -132,6 +132,14 @@ * (RealServer compatible)" or "RealServer Version v.e.r.sion (platform)", * where platform is the output of $uname -msr | sed 's/ /-/g'. */ char server[64]; + + /** The "timeout" comes as part of the server response to the "SETUP" + * command, in the "Session: <xyz>[;timeout=<value>]" line. It is the + * time, in seconds, that the server will go without traffic over the + * RTSP/TCP connection before it closes the connection. To prevent + * this, sent dummy requests (e.g. OPTIONS) with intervals smaller + * than this value. */ + int timeout; } RTSPMessageHeader; /** @@ -192,6 +200,16 @@ * identifier that the client should re-transmit in each RTSP command */ char session_id[512]; + /** copy of RTSPMessageHeader->timeout, i.e. the time (in seconds) that + * the server will go without traffic on the RTSP/TCP line before it + * closes the connection. */ + int timeout; + + /** timestamp of the last RTSP command that we sent to the RTSP server. + * This is used to calculate when to send dummy commands to keep the + * connection alive, in conjunction with \p timeout. */ + int64_t last_cmd_time; + /** the negotiated data/packet transport protocol; e.g. RTP or RDT */ enum RTSPTransport transport;