Mercurial > libavformat.hg
comparison rtsp.c @ 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 | 13a2a1a475d5 |
children | 609322be76a6 |
comparison
equal
deleted
inserted
replaced
4876:3a1ffb822e81 | 4877:940946a4569b |
---|---|
680 const char *p; | 680 const char *p; |
681 | 681 |
682 /* NOTE: we do case independent match for broken servers */ | 682 /* NOTE: we do case independent match for broken servers */ |
683 p = buf; | 683 p = buf; |
684 if (av_stristart(p, "Session:", &p)) { | 684 if (av_stristart(p, "Session:", &p)) { |
685 int t; | |
685 get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p); | 686 get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p); |
687 if (av_stristart(p, ";timeout=", &p) && | |
688 (t = strtol(p, NULL, 10)) > 0) { | |
689 reply->timeout = t; | |
690 } | |
686 } else if (av_stristart(p, "Content-Length:", &p)) { | 691 } else if (av_stristart(p, "Content-Length:", &p)) { |
687 reply->content_length = strtol(p, NULL, 10); | 692 reply->content_length = strtol(p, NULL, 10); |
688 } else if (av_stristart(p, "Transport:", &p)) { | 693 } else if (av_stristart(p, "Transport:", &p)) { |
689 rtsp_parse_transport(reply, p); | 694 rtsp_parse_transport(reply, p); |
690 } else if (av_stristart(p, "CSeq:", &p)) { | 695 } else if (av_stristart(p, "CSeq:", &p)) { |
835 av_free(content); | 840 av_free(content); |
836 | 841 |
837 return 0; | 842 return 0; |
838 } | 843 } |
839 | 844 |
840 static void rtsp_send_cmd(AVFormatContext *s, | 845 static void rtsp_send_cmd_async (AVFormatContext *s, |
841 const char *cmd, RTSPMessageHeader *reply, | 846 const char *cmd, RTSPMessageHeader *reply, |
842 unsigned char **content_ptr) | 847 unsigned char **content_ptr) |
843 { | 848 { |
844 RTSPState *rt = s->priv_data; | 849 RTSPState *rt = s->priv_data; |
845 char buf[4096], buf1[1024]; | 850 char buf[4096], buf1[1024]; |
855 av_strlcat(buf, "\r\n", sizeof(buf)); | 860 av_strlcat(buf, "\r\n", sizeof(buf)); |
856 #ifdef DEBUG | 861 #ifdef DEBUG |
857 printf("Sending:\n%s--\n", buf); | 862 printf("Sending:\n%s--\n", buf); |
858 #endif | 863 #endif |
859 url_write(rt->rtsp_hd, buf, strlen(buf)); | 864 url_write(rt->rtsp_hd, buf, strlen(buf)); |
865 rt->last_cmd_time = av_gettime(); | |
866 } | |
867 | |
868 static void rtsp_send_cmd (AVFormatContext *s, | |
869 const char *cmd, RTSPMessageHeader *reply, | |
870 unsigned char **content_ptr) | |
871 { | |
872 rtsp_send_cmd_async(s, cmd, reply, content_ptr); | |
860 | 873 |
861 rtsp_read_reply(s, reply, content_ptr, 0); | 874 rtsp_read_reply(s, reply, content_ptr, 0); |
862 } | 875 } |
863 | 876 |
864 | 877 |
940 | 953 |
941 if (rt->transport == RTSP_TRANSPORT_RDT) | 954 if (rt->transport == RTSP_TRANSPORT_RDT) |
942 trans_pref = "x-pn-tng"; | 955 trans_pref = "x-pn-tng"; |
943 else | 956 else |
944 trans_pref = "RTP/AVP"; | 957 trans_pref = "RTP/AVP"; |
958 | |
959 /* default timeout: 1 minute */ | |
960 rt->timeout = 60; | |
945 | 961 |
946 /* for each stream, make the setup request */ | 962 /* for each stream, make the setup request */ |
947 /* XXX: we assume the same server is used for the control of each | 963 /* XXX: we assume the same server is used for the control of each |
948 RTSP stream */ | 964 RTSP stream */ |
949 | 965 |
1120 } | 1136 } |
1121 | 1137 |
1122 if ((err = rtsp_open_transport_ctx(s, rtsp_st))) | 1138 if ((err = rtsp_open_transport_ctx(s, rtsp_st))) |
1123 goto fail; | 1139 goto fail; |
1124 } | 1140 } |
1141 | |
1142 if (reply->timeout > 0) | |
1143 rt->timeout = reply->timeout; | |
1125 | 1144 |
1126 if (rt->server_type == RTSP_SERVER_REAL) | 1145 if (rt->server_type == RTSP_SERVER_REAL) |
1127 rt->need_subscription = 1; | 1146 rt->need_subscription = 1; |
1128 | 1147 |
1129 return 0; | 1148 return 0; |
1401 { | 1420 { |
1402 RTSPState *rt = s->priv_data; | 1421 RTSPState *rt = s->priv_data; |
1403 RTSPStream *rtsp_st; | 1422 RTSPStream *rtsp_st; |
1404 int ret, len; | 1423 int ret, len; |
1405 uint8_t buf[10 * RTP_MAX_PACKET_LENGTH]; | 1424 uint8_t buf[10 * RTP_MAX_PACKET_LENGTH]; |
1425 RTSPMessageHeader reply1, *reply = &reply1; | |
1426 char cmd[1024]; | |
1406 | 1427 |
1407 if (rt->server_type == RTSP_SERVER_REAL) { | 1428 if (rt->server_type == RTSP_SERVER_REAL) { |
1408 int i; | 1429 int i; |
1409 RTSPMessageHeader reply1, *reply = &reply1; | |
1410 enum AVDiscard cache[MAX_STREAMS]; | 1430 enum AVDiscard cache[MAX_STREAMS]; |
1411 char cmd[1024]; | |
1412 | 1431 |
1413 for (i = 0; i < s->nb_streams; i++) | 1432 for (i = 0; i < s->nb_streams; i++) |
1414 cache[i] = s->streams[i]->discard; | 1433 cache[i] = s->streams[i]->discard; |
1415 | 1434 |
1416 if (!rt->need_subscription) { | 1435 if (!rt->need_subscription) { |
1506 goto redo; | 1525 goto redo; |
1507 if (ret == 1) { | 1526 if (ret == 1) { |
1508 /* more packets may follow, so we save the RTP context */ | 1527 /* more packets may follow, so we save the RTP context */ |
1509 rt->cur_transport_priv = rtsp_st->transport_priv; | 1528 rt->cur_transport_priv = rtsp_st->transport_priv; |
1510 } | 1529 } |
1530 | |
1531 /* send dummy request to keep TCP connection alive */ | |
1532 if ((rt->server_type == RTSP_SERVER_WMS || | |
1533 rt->server_type == RTSP_SERVER_REAL) && | |
1534 (av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) { | |
1535 if (rt->server_type == RTSP_SERVER_WMS) { | |
1536 snprintf(cmd, sizeof(cmd) - 1, | |
1537 "GET_PARAMETER %s RTSP/1.0\r\n", | |
1538 s->filename); | |
1539 rtsp_send_cmd_async(s, cmd, reply, NULL); | |
1540 } else { | |
1541 rtsp_send_cmd_async(s, "OPTIONS * RTSP/1.0\r\n", | |
1542 reply, NULL); | |
1543 } | |
1544 } | |
1545 | |
1511 return 0; | 1546 return 0; |
1512 } | 1547 } |
1513 | 1548 |
1514 static int rtsp_read_play(AVFormatContext *s) | 1549 static int rtsp_read_play(AVFormatContext *s) |
1515 { | 1550 { |