rtsp: Only do keepalive using GET_PARAMETER if the server supports it
authorMartin Storsjö <martin@martin.st>
Mon, 9 May 2011 17:11:16 +0000 (20:11 +0300)
committerMartin Storsjö <martin@martin.st>
Wed, 11 May 2011 07:42:34 +0000 (10:42 +0300)
This is more like what VLC does. If the server doesn't mention
supporting GET_PARAMETER in response to an OPTIONS request,
VLC doesn't send any keepalive requests at all. After this patch,
libavformat will still send OPTIONS keepalives if GET_PARAMETER
isn't explicitly said to be supported.

Some RTSP cameras don't support GET_PARAMETER, and will
close the connection if this is sent as keepalive request
(but support OPTIONS just fine, but probably don't need any
keepalive at all). Some other cameras don't support using
OPTIONS as keepalive, but require GET_PARAMETER instead.

Signed-off-by: Martin Storsjö <martin@martin.st>
libavformat/rtsp.c
libavformat/rtsp.h
libavformat/rtspdec.c

index 14111e69fd774bdce477abc160a2c1707abfd54d..2ebf7e0510a97d3bac52b5cedad00b9dbbb522fa 100644 (file)
@@ -808,6 +808,10 @@ void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
         p += strspn(p, SPACE_CHARS);
         if (method && !strcmp(method, "PLAY"))
             rtsp_parse_rtp_info(rt, p);
+    } else if (av_stristart(p, "Public:", &p) && rt) {
+        if (strstr(p, "GET_PARAMETER") &&
+            method && !strcmp(method, "OPTIONS"))
+            rt->get_parameter_supported = 1;
     }
 }
 
index e1f1df990e0eaf0037d034a654d20251d41667b2..ff665026264866d1523b0af75ea87db09ae5e834 100644 (file)
@@ -331,6 +331,11 @@ typedef struct RTSPState {
      * Polling array for udp
      */
     struct pollfd *p;
+
+    /**
+     * Whether the server supports the GET_PARAMETER method.
+     */
+    int get_parameter_supported;
 } RTSPState;
 
 /**
index 866f313d106bbcda738873e9c547df200b5dfe69..ccfc4d8e279034f8ba12b7316be4688d57aaf076 100644 (file)
@@ -341,7 +341,9 @@ retry:
 
     /* send dummy request to keep TCP connection alive */
     if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {
-        if (rt->server_type != RTSP_SERVER_REAL) {
+        if (rt->server_type == RTSP_SERVER_WMS ||
+           (rt->server_type != RTSP_SERVER_REAL &&
+            rt->get_parameter_supported)) {
             ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
         } else {
             ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);