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, n; struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}}; for(;;) { if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; /* build fdset to listen to RTP and RTCP packets */ n = poll(p, 2, 100); if (n > 0) { /* first try RTCP */ if (p[1].revents & POLLIN) { from_len = sizeof(from); len = recvfrom (s->rtcp_fd, buf, size, 0, (struct sockaddr *)&from, &from_len); if (len < 0) { if (ff_neterrno() == AVERROR(EAGAIN) || ff_neterrno() == AVERROR(EINTR)) continue; return AVERROR(EIO); } if (rtp_check_source_lists(s, &from)) continue; break; } /* then RTP */ if (p[0].revents & POLLIN) { from_len = sizeof(from); len = recvfrom (s->rtp_fd, buf, size, 0, (struct sockaddr *)&from, &from_len); if (len < 0) { if (ff_neterrno() == AVERROR(EAGAIN) || ff_neterrno() == AVERROR(EINTR)) continue; return AVERROR(EIO); } if (rtp_check_source_lists(s, &from)) continue; break; } } else if (n < 0) { if (ff_neterrno() == AVERROR(EINTR)) continue; return AVERROR(EIO); } } return len; }
static int rtp_read(URLContext *h, uint8_t *buf, int size) { RTPContext *s = h->priv_data; int len, n, i; struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}}; int poll_delay = h->flags & AVIO_FLAG_NONBLOCK ? 0 : 100; struct sockaddr_storage *addrs[2] = { &s->last_rtp_source, &s->last_rtcp_source }; socklen_t *addr_lens[2] = { &s->last_rtp_source_len, &s->last_rtcp_source_len }; for(;;) { if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; n = poll(p, 2, poll_delay); if (n > 0) { /* first try RTCP, then RTP */ for (i = 1; i >= 0; i--) { if (!(p[i].revents & POLLIN)) continue; *addr_lens[i] = sizeof(*addrs[i]); len = recvfrom(p[i].fd, buf, size, 0, (struct sockaddr *)addrs[i], addr_lens[i]); if (len < 0) { if (ff_neterrno() == AVERROR(EAGAIN) || ff_neterrno() == AVERROR(EINTR)) continue; return AVERROR(EIO); } if (rtp_check_source_lists(s, addrs[i])) continue; return len; } } else if (n < 0) { if (ff_neterrno() == AVERROR(EINTR)) continue; return AVERROR(EIO); } if (h->flags & AVIO_FLAG_NONBLOCK) return AVERROR(EAGAIN); } return len; }