diff options
author | Martin Storsjö <martin@martin.st> | 2010-10-01 17:52:26 +0000 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2010-10-01 17:52:26 +0000 |
commit | 321259c1ab1fb348f9896f00f481ba3dfe227e30 (patch) | |
tree | af4a6b104060d91488d20827eb3db1595e0af7ea | |
parent | 58ee09911e0dab6432b18e9a2c5a876fdf8ef078 (diff) | |
download | ffmpeg-321259c1ab1fb348f9896f00f481ba3dfe227e30.tar.gz |
rtsp: Return a queued packet if it has been in the queue for longer than max_delay
Originally committed as revision 25295 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavformat/rtsp.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 1e4b9c1db7..5759788b71 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1674,7 +1674,7 @@ static int rtsp_read_header(AVFormatContext *s, } static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, - uint8_t *buf, int buf_size) + uint8_t *buf, int buf_size, int64_t wait_end) { RTSPState *rt = s->priv_data; RTSPStream *rtsp_st; @@ -1685,6 +1685,8 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, for (;;) { if (url_interrupt_cb()) return AVERROR(EINTR); + if (wait_end && wait_end - av_gettime() < 0) + return AVERROR(EAGAIN); FD_ZERO(&rfds); if (rt->rtsp_hd) { tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd); @@ -1800,7 +1802,8 @@ static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) { RTSPState *rt = s->priv_data; int ret, len; - RTSPStream *rtsp_st; + RTSPStream *rtsp_st, *first_queue_st = NULL; + int64_t wait_end = 0; if (rt->nb_byes == rt->nb_rtsp_streams) return AVERROR_EOF; @@ -1820,6 +1823,22 @@ static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) rt->cur_transport_priv = NULL; } + if (rt->transport == RTSP_TRANSPORT_RTP) { + int i; + int64_t first_queue_time = 0; + for (i = 0; i < rt->nb_rtsp_streams; i++) { + RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv; + int64_t queue_time = ff_rtp_queued_packet_time(rtpctx); + if (queue_time && (queue_time - first_queue_time < 0 || + !first_queue_time)) { + first_queue_time = queue_time; + first_queue_st = rt->rtsp_streams[i]; + } + } + if (first_queue_time) + wait_end = first_queue_time + s->max_delay; + } + /* read next RTP packet */ redo: if (!rt->recvbuf) { @@ -1837,11 +1856,17 @@ static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) #endif case RTSP_LOWER_TRANSPORT_UDP: case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: - len = udp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE); + len = udp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end); if (len >=0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP) rtp_check_and_send_back_rr(rtsp_st->transport_priv, len); break; } + if (len == AVERROR(EAGAIN) && first_queue_st && + rt->transport == RTSP_TRANSPORT_RTP) { + rtsp_st = first_queue_st; + ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0); + goto end; + } if (len < 0) return len; if (len == 0) @@ -1878,6 +1903,7 @@ static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) } } } +end: if (ret < 0) goto redo; if (ret == 1) |