Add a timeout to the select() call. Patch by Sam Gerstein <sgerstein bluefinlab
authorSam Gerstein <sgerstein@bluefinlab.com>
Mon, 29 Mar 2010 17:36:08 +0000 (17:36 +0000)
committerRonald S. Bultje <rsbultje@gmail.com>
Mon, 29 Mar 2010 17:36:08 +0000 (17:36 +0000)
com>.

Originally committed as revision 22718 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/rtsp.c

index 575ef44..255c18e 100644 (file)
 int rtsp_default_protocols = (1 << RTSP_LOWER_TRANSPORT_UDP);
 #endif
 
+/* Timout values for socket select, in ms,
+ * and read_packet(), in seconds  */
+#define SELECT_TIMEOUT_MS 100
+#define READ_PACKET_TIMEOUT_S 10
+#define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / SELECT_TIMEOUT_MS
+
 #define SPACE_CHARS " \t\r\n"
 /* we use memchr() instead of strchr() here because strchr() will return
  * the terminating '\0' of SPACE_CHARS instead of NULL if c is '\0'. */
@@ -1634,7 +1640,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
     RTSPState *rt = s->priv_data;
     RTSPStream *rtsp_st;
     fd_set rfds;
-    int fd, fd_max, n, i, ret, tcp_fd;
+    int fd, fd_max, n, i, ret, tcp_fd, timeout_cnt = 0;
     struct timeval tv;
 
     for (;;) {
@@ -1660,9 +1666,10 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
             }
         }
         tv.tv_sec = 0;
-        tv.tv_usec = 100 * 1000;
+        tv.tv_usec = SELECT_TIMEOUT_MS * 1000;
         n = select(fd_max + 1, &rfds, NULL, NULL, &tv);
         if (n > 0) {
+            timeout_cnt = 0;
             for (i = 0; i < rt->nb_rtsp_streams; i++) {
                 rtsp_st = rt->rtsp_streams[i];
                 if (rtsp_st->rtp_handle) {
@@ -1688,7 +1695,10 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
                     return 0;
             }
 #endif
-        }
+        } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) {
+            return AVERROR(ETIME);
+        } else if (n < 0 && errno != EINTR)
+            return AVERROR(errno);
     }
 }