diff --git a/libavformat/os_support.c b/libavformat/os_support.c index 83f0820662..70cca92c8d 100644 --- a/libavformat/os_support.c +++ b/libavformat/os_support.c @@ -236,7 +236,6 @@ int ff_socket_nonblock(int socket, int enable) } #endif /* CONFIG_NETWORK */ -#if CONFIG_FFSERVER #if !HAVE_POLL_H int poll(struct pollfd *fds, nfds_t numfds, int timeout) { @@ -305,5 +304,3 @@ int poll(struct pollfd *fds, nfds_t numfds, int timeout) return rc; } #endif /* HAVE_POLL_H */ -#endif /* CONFIG_FFSERVER */ - diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index 6ef67849f5..aa2cc37776 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -34,8 +34,8 @@ #include "network.h" #include "os_support.h" #include -#if HAVE_SYS_SELECT_H -#include +#if HAVE_POLL_H +#include #endif #include @@ -221,9 +221,9 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size) RTPContext *s = h->priv_data; struct sockaddr_storage from; socklen_t from_len; - int len, fd_max, n; - fd_set rfds; - struct timeval tv; + int len, n; + struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}}; + #if 0 for(;;) { from_len = sizeof(from); @@ -242,18 +242,10 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size) if (url_interrupt_cb()) return AVERROR(EINTR); /* build fdset to listen to RTP and RTCP packets */ - FD_ZERO(&rfds); - fd_max = s->rtp_fd; - FD_SET(s->rtp_fd, &rfds); - if (s->rtcp_fd > fd_max) - fd_max = s->rtcp_fd; - FD_SET(s->rtcp_fd, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - n = select(fd_max + 1, &rfds, NULL, NULL, &tv); + n = poll(p, 2, 100); if (n > 0) { /* first try RTCP */ - if (FD_ISSET(s->rtcp_fd, &rfds)) { + if (p[1].revents & POLLIN) { from_len = sizeof(from); len = recvfrom (s->rtcp_fd, buf, size, 0, (struct sockaddr *)&from, &from_len); @@ -266,7 +258,7 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size) break; } /* then RTP */ - if (FD_ISSET(s->rtp_fd, &rfds)) { + if (p[0].revents & POLLIN) { from_len = sizeof(from); len = recvfrom (s->rtp_fd, buf, size, 0, (struct sockaddr *)&from, &from_len); diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 752f429f49..a56ff99547 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -26,8 +26,8 @@ #include "avformat.h" #include -#if HAVE_SYS_SELECT_H -#include +#if HAVE_POLL_H +#include #endif #include #include "internal.h" @@ -44,11 +44,11 @@ //#define DEBUG //#define DEBUG_RTP_TCP -/* Timeout values for socket select, in ms, +/* Timeout values for socket poll, in ms, * and read_packet(), in seconds */ -#define SELECT_TIMEOUT_MS 100 +#define POLL_TIMEOUT_MS 100 #define READ_PACKET_TIMEOUT_S 10 -#define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / SELECT_TIMEOUT_MS +#define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / POLL_TIMEOUT_MS #define SDP_MAX_SIZE 16384 #define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH @@ -429,8 +429,14 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, } } +/** + * Parse the sdp description and allocate the rtp streams and the + * pollfd array used for udp ones. + */ + int ff_sdp_parse(AVFormatContext *s, const char *content) { + RTSPState *rt = s->priv_data; const char *p; int letter; /* Some SDP lines, particularly for Realmedia or ASF RTSP streams, @@ -470,6 +476,8 @@ int ff_sdp_parse(AVFormatContext *s, const char *content) if (*p == '\n') p++; } + rt->p = av_malloc(sizeof(struct pollfd)*2*(rt->nb_rtsp_streams+1)); + if (!rt->p) return AVERROR(ENOMEM); return 0; } #endif /* CONFIG_RTPDEC */ @@ -531,6 +539,7 @@ void ff_rtsp_close_streams(AVFormatContext *s) av_close_input_stream (rt->asf_ctx); rt->asf_ctx = NULL; } + av_free(rt->p); av_free(rt->recvbuf); } @@ -1554,55 +1563,51 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, { RTSPState *rt = s->priv_data; RTSPStream *rtsp_st; - fd_set rfds; - int fd, fd_rtcp, fd_max, n, i, ret, tcp_fd, timeout_cnt = 0; - struct timeval tv; + int n, i, ret, tcp_fd, timeout_cnt = 0; + int max_p = 0; + struct pollfd *p = rt->p; for (;;) { if (url_interrupt_cb()) return AVERROR(EINTR); if (wait_end && wait_end - av_gettime() < 0) return AVERROR(EAGAIN); - FD_ZERO(&rfds); + max_p = 0; if (rt->rtsp_hd) { - tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd); - FD_SET(tcp_fd, &rfds); + tcp_fd = url_get_file_handle(rt->rtsp_hd); + p[max_p].fd = tcp_fd; + p[max_p++].events = POLLIN; } else { - fd_max = 0; tcp_fd = -1; } for (i = 0; i < rt->nb_rtsp_streams; i++) { rtsp_st = rt->rtsp_streams[i]; if (rtsp_st->rtp_handle) { - fd = url_get_file_handle(rtsp_st->rtp_handle); - fd_rtcp = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle); - if (FFMAX(fd, fd_rtcp) > fd_max) - fd_max = FFMAX(fd, fd_rtcp); - FD_SET(fd, &rfds); - FD_SET(fd_rtcp, &rfds); + p[max_p].fd = url_get_file_handle(rtsp_st->rtp_handle); + p[max_p++].events = POLLIN; + p[max_p].fd = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle); + p[max_p++].events = POLLIN; } } - tv.tv_sec = 0; - tv.tv_usec = SELECT_TIMEOUT_MS * 1000; - n = select(fd_max + 1, &rfds, NULL, NULL, &tv); + n = poll(p, max_p, POLL_TIMEOUT_MS); if (n > 0) { + int j = 1 - (tcp_fd == -1); timeout_cnt = 0; for (i = 0; i < rt->nb_rtsp_streams; i++) { rtsp_st = rt->rtsp_streams[i]; if (rtsp_st->rtp_handle) { - fd = url_get_file_handle(rtsp_st->rtp_handle); - fd_rtcp = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle); - if (FD_ISSET(fd_rtcp, &rfds) || FD_ISSET(fd, &rfds)) { + if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) { ret = url_read(rtsp_st->rtp_handle, buf, buf_size); if (ret > 0) { *prtsp_st = rtsp_st; return ret; } } + j+=2; } } #if CONFIG_RTSP_DEMUXER - if (tcp_fd != -1 && FD_ISSET(tcp_fd, &rfds)) { + if (tcp_fd != -1 && p[0].revents & POLLIN) { RTSPMessageHeader reply; ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL); diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h index f0ead10da5..14d3f41eb5 100644 --- a/libavformat/rtsp.h +++ b/libavformat/rtsp.h @@ -326,6 +326,11 @@ typedef struct RTSPState { * The number of returned packets */ uint64_t packets; + + /** + * Polling array for udp + */ + struct pollfd *p; } RTSPState; /** diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c index dc8ecd80f2..88f093f5c1 100644 --- a/libavformat/rtspenc.c +++ b/libavformat/rtspenc.c @@ -22,8 +22,8 @@ #include "avformat.h" #include -#if HAVE_SYS_SELECT_H -#include +#if HAVE_POLL_H +#include #endif #include "network.h" #include "rtsp.h" @@ -172,23 +172,16 @@ static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt) { RTSPState *rt = s->priv_data; RTSPStream *rtsp_st; - fd_set rfds; - int n, tcp_fd; - struct timeval tv; + int n; + struct pollfd p = {url_get_file_handle(rt->rtsp_hd), POLLIN, 0}; AVFormatContext *rtpctx; int ret; - tcp_fd = url_get_file_handle(rt->rtsp_hd); - while (1) { - FD_ZERO(&rfds); - FD_SET(tcp_fd, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 0; - n = select(tcp_fd + 1, &rfds, NULL, NULL, &tv); + n = poll(&p, 1, 0); if (n <= 0) break; - if (FD_ISSET(tcp_fd, &rfds)) { + if (p.revents & POLLIN) { RTSPMessageHeader reply; /* Don't let ff_rtsp_read_reply handle interleaved packets, diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c index 208591cd0c..73525f5df8 100644 --- a/libavformat/sapdec.c +++ b/libavformat/sapdec.c @@ -25,8 +25,8 @@ #include "network.h" #include "os_support.h" #include "internal.h" -#if HAVE_SYS_SELECT_H -#include +#if HAVE_POLL_H +#include #endif #include @@ -183,19 +183,15 @@ static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt) struct SAPState *sap = s->priv_data; int fd = url_get_file_handle(sap->ann_fd); int n, ret; - fd_set rfds; - struct timeval tv; + struct pollfd p = {fd, POLLIN, 0}; uint8_t recvbuf[1500]; if (sap->eof) return AVERROR_EOF; while (1) { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - tv.tv_sec = tv.tv_usec = 0; - n = select(fd + 1, &rfds, NULL, NULL, &tv); - if (n <= 0 || !FD_ISSET(fd, &rfds)) + n = poll(&p, 1, 0); + if (n <= 0 || !(p.revents & POLLIN)) break; ret = url_read(sap->ann_fd, recvbuf, sizeof(recvbuf)); if (ret >= 8) { diff --git a/libavformat/tcp.c b/libavformat/tcp.c index 5cb4b8f9c7..ac4e4b09db 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -23,8 +23,8 @@ #include "internal.h" #include "network.h" #include "os_support.h" -#if HAVE_SYS_SELECT_H -#include +#if HAVE_POLL_H +#include #endif #include @@ -38,9 +38,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) struct addrinfo hints, *ai, *cur_ai; int port, fd = -1; TCPContext *s = NULL; - fd_set wfds, efds; - int fd_max, ret; - struct timeval tv; + int ret; socklen_t optlen; char hostname[1024],proto[1024],path[1024]; char portstr[10]; @@ -73,6 +71,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) redo: ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen); if (ret < 0) { + struct pollfd p = {fd, POLLOUT, 0}; if (ff_neterrno() == FF_NETERROR(EINTR)) { if (url_interrupt_cb()) goto fail1; @@ -88,15 +87,8 @@ static int tcp_open(URLContext *h, const char *uri, int flags) ret = AVERROR(EINTR); goto fail1; } - fd_max = fd; - FD_ZERO(&wfds); - FD_ZERO(&efds); - FD_SET(fd, &wfds); - FD_SET(fd, &efds); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - ret = select(fd_max + 1, NULL, &wfds, &efds, &tv); - if (ret > 0 && (FD_ISSET(fd, &wfds) || FD_ISSET(fd, &efds))) + ret = poll(&p, 1, 100); + if (ret > 0) break; } @@ -140,20 +132,14 @@ static int tcp_open(URLContext *h, const char *uri, int flags) static int tcp_read(URLContext *h, uint8_t *buf, int size) { TCPContext *s = h->priv_data; - int len, fd_max, ret; - fd_set rfds; - struct timeval tv; + struct pollfd p = {s->fd, POLLIN, 0}; + int len, ret; for (;;) { if (url_interrupt_cb()) return AVERROR(EINTR); - fd_max = s->fd; - FD_ZERO(&rfds); - FD_SET(s->fd, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - ret = select(fd_max + 1, &rfds, NULL, NULL, &tv); - if (ret > 0 && FD_ISSET(s->fd, &rfds)) { + ret = poll(&p, 1, 100); + if (ret == 1 && p.revents & POLLIN) { len = recv(s->fd, buf, size, 0); if (len < 0) { if (ff_neterrno() != FF_NETERROR(EINTR) && @@ -171,21 +157,15 @@ static int tcp_read(URLContext *h, uint8_t *buf, int size) static int tcp_write(URLContext *h, const uint8_t *buf, int size) { TCPContext *s = h->priv_data; - int ret, size1, fd_max, len; - fd_set wfds; - struct timeval tv; + int ret, size1, len; + struct pollfd p = {s->fd, POLLOUT, 0}; size1 = size; while (size > 0) { if (url_interrupt_cb()) return AVERROR(EINTR); - fd_max = s->fd; - FD_ZERO(&wfds); - FD_SET(s->fd, &wfds); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - ret = select(fd_max + 1, NULL, &wfds, NULL, &tv); - if (ret > 0 && FD_ISSET(s->fd, &wfds)) { + ret = poll(&p, 1, 100); + if (ret == 1 && p.revents & POLLOUT) { len = send(s->fd, buf, size, 0); if (len < 0) { if (ff_neterrno() != FF_NETERROR(EINTR) && diff --git a/libavformat/udp.c b/libavformat/udp.c index 8080c98045..aa17c979f3 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -31,8 +31,8 @@ #include "internal.h" #include "network.h" #include "os_support.h" -#if HAVE_SYS_SELECT_H -#include +#if HAVE_POLL_H +#include #endif #include @@ -432,25 +432,20 @@ static int udp_open(URLContext *h, const char *uri, int flags) static int udp_read(URLContext *h, uint8_t *buf, int size) { UDPContext *s = h->priv_data; + struct pollfd p = {s->udp_fd, POLLIN, 0}; int len; - fd_set rfds; int ret; - struct timeval tv; for(;;) { if (url_interrupt_cb()) return AVERROR(EINTR); - FD_ZERO(&rfds); - FD_SET(s->udp_fd, &rfds); - tv.tv_sec = 0; - tv.tv_usec = 100 * 1000; - ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv); + ret = poll(&p, 1, 100); if (ret < 0) { if (ff_neterrno() == FF_NETERROR(EINTR)) continue; return AVERROR(EIO); } - if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds))) + if (!(ret == 1 && p.revents & POLLIN)) continue; len = recv(s->udp_fd, buf, size, 0); if (len < 0) {