rtsp: Return AVERROR_EOF when all streams have received an RTCP BYE packet
authorJosh Allmann <joshua.allmann@gmail.com>
Sun, 29 Aug 2010 10:25:16 +0000 (10:25 +0000)
committerMartin Storsjö <martin@martin.st>
Sun, 29 Aug 2010 10:25:16 +0000 (10:25 +0000)
Patch by Josh Allmann, joshua dot allmann at gmail

Originally committed as revision 24965 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/rtpdec.c
libavformat/rtsp.c
libavformat/rtsp.h

index 25fe5a7..debc14c 100644 (file)
@@ -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)
index 16997e3..c3f4d00 100644 (file)
@@ -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)
index 49dbfde..c6c3972 100644 (file)
@@ -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;
 
 /**