summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Allmann <joshua.allmann@gmail.com>2010-08-29 10:25:16 +0000
committerMartin Storsjö <martin@martin.st>2010-08-29 10:25:16 +0000
commitb20359f51a1c3be5603be9908061b27f883f9467 (patch)
treeda33f81dcf80d66304bda521c18494945ee12b0b
parent682d28a965c859a8826c1b52c3437a6a0c4ab59f (diff)
rtsp: Return AVERROR_EOF when all streams have received an RTCP BYE packet
Patch by Josh Allmann, joshua dot allmann at gmail Originally committed as revision 24965 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavformat/rtpdec.c7
-rw-r--r--libavformat/rtsp.c13
-rw-r--r--libavformat/rtsp.h5
3 files changed, 22 insertions, 3 deletions
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 25fe5a73f8..debc14c90b 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -92,11 +92,13 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int l
buf += payload_len;
len -= payload_len;
break;
+ case RTCP_BYE:
+ return -RTCP_BYE;
default:
return -1;
}
}
- return 0;
+ return -1;
}
#define RTP_SEQ_MOD (1<<16)
@@ -451,8 +453,7 @@ int rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt,
if ((buf[0] & 0xc0) != (RTP_VERSION << 6))
return -1;
if (buf[1] >= RTCP_SR && buf[1] <= RTCP_APP) {
- rtcp_parse_packet(s, buf, len);
- return -1;
+ return rtcp_parse_packet(s, buf, len);
}
payload_type = buf[1] & 0x7f;
if (buf[1] & 0x80)
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 16997e3245..c3f4d00858 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -1226,6 +1226,7 @@ static int rtsp_read_play(AVFormatContext *s)
char cmd[1024];
av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
+ rt->nb_byes = 0;
if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
if (rt->state == RTSP_STATE_PAUSED) {
@@ -1777,6 +1778,9 @@ static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
uint8_t buf[10 * RTP_MAX_PACKET_LENGTH];
RTSPStream *rtsp_st;
+ if (rt->nb_byes == rt->nb_rtsp_streams)
+ return AVERROR_EOF;
+
/* get next frames from the same RTP packet */
if (rt->cur_transport_priv) {
if (rt->transport == RTSP_TRANSPORT_RDT) {
@@ -1833,6 +1837,15 @@ static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_time;
}
}
+ if (ret == -RTCP_BYE) {
+ rt->nb_byes++;
+
+ av_log(s, AV_LOG_DEBUG, "Received BYE for stream %d (%d/%d)\n",
+ rtsp_st->stream_index, rt->nb_byes, rt->nb_rtsp_streams);
+
+ if (rt->nb_byes == rt->nb_rtsp_streams)
+ return AVERROR_EOF;
+ }
}
}
if (ret < 0)
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index 49dbfdef28..c6c3972576 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -303,6 +303,11 @@ typedef struct RTSPState {
/** RTSP transport mode, such as plain or tunneled. */
enum RTSPControlTransport control_transport;
+
+ /* Number of RTCP BYE packets the RTSP session has received.
+ * An EOF is propagated back if nb_byes == nb_streams.
+ * This is reset after a seek. */
+ int nb_byes;
} RTSPState;
/**