From: Sam Gerstein Date: Mon, 29 Mar 2010 17:36:08 +0000 (+0000) Subject: Add a timeout to the select() call. Patch by Sam Gerstein . Originally committed as revision 22718 to svn://svn.ffmpeg.org/ffmpeg/trunk --- diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 575ef44..255c18e 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -46,6 +46,12 @@ 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); } }