static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
                           uint8_t *buf, int buf_size, int64_t wait_end)
{
    RTSPState *rt = s->priv_data;
    RTSPStream *rtsp_st;
    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);
        max_p = 0;
        if (rt->rtsp_hd) {
            tcp_fd = url_get_file_handle(rt->rtsp_hd);
            p[max_p].fd = tcp_fd;
            p[max_p++].events = POLLIN;
        } else {
            tcp_fd = -1;
        }
        for (i = 0; i < rt->nb_rtsp_streams; i++) {
            rtsp_st = rt->rtsp_streams[i];
            if (rtsp_st->rtp_handle) {
                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;
            }
        }
        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) {
                    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 && p[0].revents & POLLIN) {
                RTSPMessageHeader reply;

                ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL);
                if (ret < 0)
                    return ret;
                /* XXX: parse message */
                if (rt->state != RTSP_STATE_STREAMING)
                    return 0;
            }
#endif
        } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) {
            return FF_NETERROR(ETIMEDOUT);
        } else if (n < 0 && errno != EINTR)
            return AVERROR(errno);
    }
}