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; 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)) { len = recv(s->fd, buf, size, 0); if (len < 0) { if (ff_neterrno() != FF_NETERROR(EINTR) && ff_neterrno() != FF_NETERROR(EAGAIN)) return AVERROR(errno); } else return len; } else if (ret < 0) { return -1; } } }
static int sctp_wait_fd(int fd, int write) { int ev = write ? POLLOUT : POLLIN; struct pollfd p = { .fd = fd, .events = ev, .revents = 0 }; int ret; ret = poll(&p, 1, 100); return ret < 0 ? ff_neterrno() : p.revents & ev ? 0 : AVERROR(EAGAIN); } static int sctp_read(URLContext *h, uint8_t *buf, int size) { SCTPContext *s = h->priv_data; int ret; if (!(h->flags & AVIO_FLAG_NONBLOCK)) { ret = sctp_wait_fd(s->fd, 0); if (ret < 0) return ret; } if (s->max_streams) { /*StreamId is introduced as a 2byte code into the stream*/ struct sctp_sndrcvinfo info = { 0 }; ret = ff_sctp_recvmsg(s->fd, buf + 2, size - 2, NULL, 0, &info, 0); AV_WB16(buf, info.sinfo_stream); ret = ret < 0 ? ret : ret + 2; } else ret = recv(s->fd, buf, size, 0); return ret < 0 ? ff_neterrno() : ret; }
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; int ret; for(;;) { if (url_interrupt_cb()) return AVERROR(EINTR); ret = poll(&p, 1, 100); if (ret < 0) { if (ff_neterrno() == FF_NETERROR(EINTR)) continue; return AVERROR(EIO); } if (!(ret == 1 && p.revents & POLLIN)) continue; len = recv(s->udp_fd, buf, size, 0); if (len < 0) { if (ff_neterrno() != FF_NETERROR(EAGAIN) && ff_neterrno() != FF_NETERROR(EINTR)) return AVERROR(EIO); } else { break; } } return len; }
int ff_listen_bind(int fd, const struct sockaddr *addr, socklen_t addrlen, int timeout, URLContext *h) { int ret; int reuse = 1; struct pollfd lp = { fd, POLLIN, 0 }; if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) { av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_REUSEADDR) failed\n"); } ret = bind(fd, addr, addrlen); if (ret) return ff_neterrno(); ret = listen(fd, 1); if (ret) return ff_neterrno(); ret = ff_poll_interrupt(&lp, 1, timeout, &h->interrupt_callback); if (ret < 0) return ret; ret = accept(fd, NULL, NULL); if (ret < 0) return ff_neterrno(); closesocket(fd); ff_socket_nonblock(ret, 1); return ret; }
static int udp_read(URLContext *h, uint8_t *buf, int size) { UDPContext *s = h->priv_data; 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); if (ret < 0) return AVERROR(EIO); if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds))) continue; len = recv(s->udp_fd, buf, size, 0); if (len < 0) { if (ff_neterrno() != FF_NETERROR(EAGAIN) && ff_neterrno() != FF_NETERROR(EINTR)) return AVERROR(EIO); } else { break; } } return len; }
static int udp_read(URLContext *h, uint8_t *buf, int size) { UDPContext *s = h->priv_data; #ifndef CONFIG_IPV6 struct sockaddr_in from; #else struct sockaddr_storage from; #endif socklen_t from_len; int len; for(;;) { from_len = sizeof(from); len = recvfrom (s->udp_fd, buf, size, 0, (struct sockaddr *)&from, &from_len); if (len < 0) { if (ff_neterrno() != FF_NETERROR(EAGAIN) && ff_neterrno() != FF_NETERROR(EINTR)) return AVERROR(EIO); } else { break; } } return len; }
/* send data starting at c->buffer_ptr to the output connection(either UDP or TCP)*/ static int http_send_data(HTTPContext *c) { int len, ret; for(;;) { if (c->buffer_ptr >= c->buffer_end) { ret = c->hls_idx >= 0 ? hls_read(c) : sff_prepare_data(c); if (ret < 0) return -1; else if (ret != 0) /* state change requested */ break; } else { /* TCP data output */ len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0); if (len < 0) { if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) /* error : close connection */ return -1; else return 0; } else c->buffer_ptr += len; c->data_count += len; break; } } /* for(;;) */ return 0; }
static int tcp_write(URLContext *h, const uint8_t *buf, int size) { TCPContext *s = h->priv_data; int ret, size1, len; struct pollfd p = {s->fd, POLLOUT, 0}; size1 = size; while (size > 0) { if (url_interrupt_cb()) return AVERROR(EINTR); 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) && ff_neterrno() != FF_NETERROR(EAGAIN)) return ff_neterrno(); continue; } size -= len; buf += len; } else if (ret < 0) { if (ff_neterrno() == FF_NETERROR(EINTR)) continue; return -1; } } return size1 - size; }
static int tcp_write(URLContext *h, uint8_t *buf, int size) { TCPContext *s = h->priv_data; int ret, size1, fd_max, len; fd_set wfds; struct timeval tv; 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)) { len = send(s->fd, buf, size, 0); if (len < 0) { if (ff_neterrno() != FF_NETERROR(EINTR) && ff_neterrno() != FF_NETERROR(EAGAIN)) return AVERROR(errno); continue; } size -= len; buf += len; } else if (ret < 0) { return -1; } } return size1 - size; }
static void *circular_buffer_task( void *_URLContext) { URLContext *h = _URLContext; UDPContext *s = h->priv_data; fd_set rfds; struct timeval tv; for(;;) { int left; int ret; int len; if (url_interrupt_cb()) { s->circular_buffer_error = EINTR; return NULL; } FD_ZERO(&rfds); FD_SET(s->udp_fd, &rfds); tv.tv_sec = 1; tv.tv_usec = 0; ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv); if (ret < 0) { if (ff_neterrno() == AVERROR(EINTR)) continue; s->circular_buffer_error = EIO; return NULL; } if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds))) continue; /* How much do we have left to the end of the buffer */ /* Whats the minimum we can read so that we dont comletely fill the buffer */ left = av_fifo_space(s->fifo); left = FFMIN(left, s->fifo->end - s->fifo->wptr); /* No Space left, error, what do we do now */ if( !left) { av_log(h, AV_LOG_ERROR, "circular_buffer: OVERRUN\n"); s->circular_buffer_error = EIO; return NULL; } len = recv(s->udp_fd, s->fifo->wptr, left, 0); if (len < 0) { if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) { s->circular_buffer_error = EIO; return NULL; } } s->fifo->wptr += len; if (s->fifo->wptr >= s->fifo->end) s->fifo->wptr = s->fifo->buffer; s->fifo->wndx += len; } return NULL; }
static void *circular_buffer_task( void *_URLContext) { URLContext *h = _URLContext; UDPContext *s = h->priv_data; int old_cancelstate; pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate); pthread_mutex_lock(&s->mutex); if (ff_socket_nonblock(s->udp_fd, 0) < 0) { av_log(h, AV_LOG_ERROR, "Failed to set blocking mode"); s->circular_buffer_error = AVERROR(EIO); goto end; } while(1) { int len; pthread_mutex_unlock(&s->mutex); /* Blocking operations are always cancellation points; see "General Information" / "Thread Cancelation Overview" in Single Unix. */ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancelstate); len = recv(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate); pthread_mutex_lock(&s->mutex); if (len < 0) { if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) { s->circular_buffer_error = ff_neterrno(); goto end; } continue; } AV_WL32(s->tmp, len); if(av_fifo_space(s->fifo) < len + 4) { /* No Space left */ if (s->overrun_nonfatal) { av_log(h, AV_LOG_WARNING, "Circular buffer overrun. " "Surviving due to overrun_nonfatal option\n"); continue; } else { av_log(h, AV_LOG_ERROR, "Circular buffer overrun. " "To avoid, increase fifo_size URL option. " "To survive in such case, use overrun_nonfatal option\n"); s->circular_buffer_error = AVERROR(EIO); goto end; } } av_fifo_generic_write(s->fifo, s->tmp, len+4, NULL); pthread_cond_signal(&s->cond); } end: pthread_cond_signal(&s->cond); pthread_mutex_unlock(&s->mutex); return NULL; }
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 sctp_write(URLContext *h, const uint8_t *buf, int size) { SCTPContext *s = h->priv_data; int ret; if (!(h->flags & AVIO_FLAG_NONBLOCK)) { ret = sctp_wait_fd(s->fd, 1); if (ret < 0) return ret; } if (s->max_streams) { /*StreamId is introduced as a 2byte code into the stream*/ struct sctp_sndrcvinfo info = { 0 }; info.sinfo_stream = AV_RB16(buf); if (info.sinfo_stream > s->max_streams) { av_log(h, AV_LOG_ERROR, "bad input data\n"); return AVERROR(EINVAL); } ret = ff_sctp_send(s->fd, buf + 2, size - 2, &info, MSG_EOR); } else ret = send(s->fd, buf, size, 0); return ret < 0 ? ff_neterrno() : ret; }
int ff_network_wait_fd(int fd, int write) { int ev = write ? POLLOUT : POLLIN; struct pollfd p = { .fd = fd, .events = ev, .revents = 0 }; int ret; ret = poll(&p, 1, 100); return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN); } int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb) { int ret; int64_t wait_start = 0; while (1) { ret = ff_network_wait_fd(fd, write); if (ret != AVERROR(EAGAIN)) return ret; if (ff_check_interrupt(int_cb)) return AVERROR_EXIT; if (timeout) { if (!wait_start) wait_start = av_gettime(); else if (av_gettime() - wait_start > timeout) return AVERROR(ETIMEDOUT); } } }
int ff_network_wait_fd(int fd, int write) { int ev = write ? POLLOUT : POLLIN; struct pollfd p = { .fd = fd, .events = ev, .revents = 0 }; int ret; ret = poll(&p, 1, 100); return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN); } #endif void ff_network_close(void) { #if HAVE_WINSOCK2_H WSACleanup(); #endif } #if HAVE_WINSOCK2_H int ff_neterrno(void) { int err = WSAGetLastError(); switch (err) { case WSAEWOULDBLOCK: return AVERROR(EAGAIN); case WSAEINTR: return AVERROR(EINTR); } return -err; }
static int udp_read(URLContext *h, uint8_t *buf, int size) { UDPContext *s = h->priv_data; int ret; #if HAVE_PTHREAD_CANCEL int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK; if (s->fifo) { pthread_mutex_lock(&s->mutex); do { avail = av_fifo_size(s->fifo); if (avail) { // >=size) { uint8_t tmp[4]; av_fifo_generic_read(s->fifo, tmp, 4, NULL); avail= AV_RL32(tmp); if(avail > size) { av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n"); avail= size; } av_fifo_generic_read(s->fifo, buf, avail, NULL); av_fifo_drain(s->fifo, AV_RL32(tmp) - avail); pthread_mutex_unlock(&s->mutex); return avail; } else if(s->circular_buffer_error) { int err = s->circular_buffer_error; pthread_mutex_unlock(&s->mutex); return err; } else if(nonblock) { pthread_mutex_unlock(&s->mutex); return AVERROR(EAGAIN); } else { /* FIXME: using the monotonic clock would be better, but it does not exist on all supported platforms. */ int64_t t = av_gettime() + 100000; struct timespec tv = { .tv_sec = t / 1000000, .tv_nsec = (t % 1000000) * 1000 }; if (pthread_cond_timedwait(&s->cond, &s->mutex, &tv) < 0) { pthread_mutex_unlock(&s->mutex); return AVERROR(errno == ETIMEDOUT ? EAGAIN : errno); } nonblock = 1; } } while( 1); } #endif if (!(h->flags & AVIO_FLAG_NONBLOCK)) { ret = ff_network_wait_fd(s->udp_fd, 0); if (ret < 0) return ret; } ret = recv(s->udp_fd, buf, size, 0); return ret < 0 ? ff_neterrno() : ret; }
int ff_listen_connect(int fd, const struct sockaddr *addr, socklen_t addrlen, int timeout, URLContext *h, int will_try_next) { struct pollfd p = {fd, POLLOUT, 0}; int ret; socklen_t optlen; if (ff_socket_nonblock(fd, 1) < 0) av_log(NULL, AV_LOG_DEBUG, "ff_socket_nonblock failed\n"); while ((ret = connect(fd, addr, addrlen))) { ret = ff_neterrno(); switch (ret) { case AVERROR(EINTR): if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; continue; case AVERROR(EINPROGRESS): case AVERROR(EAGAIN): ret = ff_poll_interrupt(&p, 1, timeout, &h->interrupt_callback); if (ret < 0) return ret; optlen = sizeof(ret); if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen)) ret = AVUNERROR(ff_neterrno()); if (ret != 0) { char errbuf[100]; ret = AVERROR(ret); av_strerror(ret, errbuf, sizeof(errbuf)); if (will_try_next) av_log(h, AV_LOG_WARNING, "Connection to %s failed (%s), trying next address\n", h->filename, errbuf); else av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n", h->filename, errbuf); } default: return ret; } } return ret; }
static int udp_write(URLContext *h, uint8_t *buf, int size) { UDPContext *s = h->priv_data; int ret; for(;;) { ret = sendto (s->udp_fd, buf, size, 0, (struct sockaddr *) &s->dest_addr, s->dest_addr_len); if (ret < 0) { if (ff_neterrno() != FF_NETERROR(EINTR) && ff_neterrno() != FF_NETERROR(EAGAIN)) return AVERROR(EIO); } else { break; } } return size; }
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; }
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; int tout_cnt=100; //tout_cnt*time_out=10s 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 = 300 * 1000; ret = select(fd_max + 1, &rfds, NULL, NULL, &tv); if (ret > 0 && FD_ISSET(s->fd, &rfds)) { len = recv(s->fd, buf, size, 0); if (len < 0) { av_log(NULL,AV_LOG_INFO,"tcp_read recv failed: len= %d\n",len); if (ff_neterrno() != FF_NETERROR(EINTR) && ff_neterrno() != FF_NETERROR(EAGAIN)) return AVERROR(ff_neterrno()); } else return len; } else if (ret < 0) { av_log(NULL,AV_LOG_INFO,"tcp_read select failed: ret= %d\n",ret); return -1; } else if(ret == 0){ tout_cnt --; av_log(NULL,AV_LOG_INFO, "tcp_read(%d): read timeout,try again\n",tout_cnt); if(tout_cnt == 0) { return AVERROR(EAGAIN); } } } }
static int tcp_write(URLContext *h, const uint8_t *buf, int size) { TCPContext *s = h->priv_data; int ret; if (!(h->flags & AVIO_FLAG_NONBLOCK)) { ret = ff_network_wait_fd(s->fd, 1); if (ret < 0) return ret; } ret = send(s->fd, buf, size, 0); return ret < 0 ? ff_neterrno() : ret; }
static int tcp_read(URLContext *h, uint8_t *buf, int size) { TCPContext *s = h->priv_data; int ret; if (!(h->flags & AVIO_FLAG_NONBLOCK)) { ret = ff_network_wait_fd_timeout(s->fd, 0, h->rw_timeout, &h->interrupt_callback); if (ret) return ret; } ret = recv(s->fd, buf, size, 0); return ret < 0 ? ff_neterrno() : ret; }
static int tcp_write(URLContext *h, const uint8_t *buf, int size) { TCPContext *s = h->priv_data; int ret; if (!(h->flags & AVIO_FLAG_NONBLOCK)) { ret = ff_network_wait_fd_timeout(s->fd, 1, h->rw_timeout, &h->interrupt_callback); if (ret) return ret; } ret = send(s->fd, buf, size, MSG_NOSIGNAL); return ret < 0 ? ff_neterrno() : ret; }
static int unix_read(URLContext *h, uint8_t *buf, int size) { UnixContext *s = h->priv_data; int ret; if (!(h->flags & AVIO_FLAG_NONBLOCK)) { ret = ff_network_wait_fd(s->fd, 0); if (ret < 0) return ret; } ret = recv(s->fd, buf, size, 0); return ret < 0 ? ff_neterrno() : ret; }
static int tcp_wait_fd(int fd, int write) { int ev = write ? POLLOUT : POLLIN; struct pollfd p = { .fd = fd, .events = ev, .revents = 0 }; int ret; ret = poll(&p, 1, 100); return ret < 0 ? ff_neterrno() : p.revents & ev ? 0 : FF_NETERROR(EAGAIN); } static int tcp_read(URLContext *h, uint8_t *buf, int size) { TCPContext *s = h->priv_data; int ret; if (!(h->flags & URL_FLAG_NONBLOCK)) { ret = tcp_wait_fd(s->fd, 0); if (ret < 0) return ret; } ret = recv(s->fd, buf, size, 0); return ret < 0 ? ff_neterrno() : ret; }
static int tcp_accept(URLContext *s, URLContext **c) { TCPContext *sc = s->priv_data; TCPContext *cc; int ret; av_assert0(sc->listen); if ((ret = ffurl_alloc(c, s->filename, s->flags, &s->interrupt_callback)) < 0) return ret; cc = (*c)->priv_data; ret = ff_accept(sc->fd, sc->listen_timeout, s); if (ret < 0) return ff_neterrno(); cc->fd = ret; return 0; }
static int udp_read(URLContext *h, uint8_t *buf, int size) { UDPContext *s = h->priv_data; int ret; int avail; #if HAVE_PTHREADS if (s->fifo) { pthread_mutex_lock(&s->mutex); do { avail = av_fifo_size(s->fifo); if (avail) { // >=size) { uint8_t tmp[4]; pthread_mutex_unlock(&s->mutex); av_fifo_generic_read(s->fifo, tmp, 4, NULL); avail= AV_RL32(tmp); if(avail > size){ av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n"); avail= size; } av_fifo_generic_read(s->fifo, buf, avail, NULL); av_fifo_drain(s->fifo, AV_RL32(tmp) - avail); return avail; } else if(s->circular_buffer_error){ pthread_mutex_unlock(&s->mutex); return s->circular_buffer_error; } else if(h->flags & AVIO_FLAG_NONBLOCK) { pthread_mutex_unlock(&s->mutex); return AVERROR(EAGAIN); } else { pthread_cond_wait(&s->cond, &s->mutex); } } while( 1); } #endif if (!(h->flags & AVIO_FLAG_NONBLOCK)) { ret = ff_network_wait_fd(s->udp_fd, 0); if (ret < 0) return ret; } ret = recv(s->udp_fd, buf, size, 0); return ret < 0 ? ff_neterrno() : ret; }
static int tcp_get_window_size(URLContext *h) { TCPContext *s = h->priv_data; int avail; socklen_t avail_len = sizeof(avail); #if HAVE_WINSOCK2_H /* SO_RCVBUF with winsock only reports the actual TCP window size when auto-tuning has been disabled via setting SO_RCVBUF */ if (s->recv_buffer_size < 0) { return AVERROR(ENOSYS); } #endif if (getsockopt(s->fd, SOL_SOCKET, SO_RCVBUF, &avail, &avail_len)) { return ff_neterrno(); } return avail; }
static int tcp_read(URLContext *h, uint8_t *buf, int size) { TCPContext *s = h->priv_data; int ret; if (!(h->flags & AVIO_FLAG_NONBLOCK)) { ret = ff_network_wait_fd(s->fd, 0); if (ret < 0){ av_log(h, AV_LOG_INFO,"ff_network_wait_fd return error %d,errmsg:%s \n",ret,strerror(errno)!=NULL?strerror(errno):"unkown"); return ret; } } ret = recv(s->fd, buf, size, 0); if(ret<=0){ av_log(h, AV_LOG_INFO,"tcp_read return error %d,errno:%d,errmsg:%s \n",ret,errno,strerror(errno)!=NULL?strerror(errno):"unkown"); } return ret < 0 ? ff_neterrno() : ret; }
static int udp_write(URLContext *h, const uint8_t *buf, int size) { UDPContext *s = h->priv_data; int ret; if (!(h->flags & AVIO_FLAG_NONBLOCK)) { ret = ff_network_wait_fd(s->udp_fd, 1); if (ret < 0) return ret; } if (!s->is_connected) { ret = sendto (s->udp_fd, buf, size, 0, (struct sockaddr *) &s->dest_addr, s->dest_addr_len); } else ret = send(s->udp_fd, buf, size, 0); return ret < 0 ? ff_neterrno() : ret; }