Patch by Josh Allmann, joshua dot allmann at gmail Originally committed as revision 24965 to svn://svn.ffmpeg.org/ffmpeg/trunktags/n0.8
@@ -92,11 +92,13 @@ static int rtcp_parse_packet(RTPDemuxContext *s, const unsigned char *buf, int l | |||||
buf += payload_len; | buf += payload_len; | ||||
len -= payload_len; | len -= payload_len; | ||||
break; | break; | ||||
case RTCP_BYE: | |||||
return -RTCP_BYE; | |||||
default: | default: | ||||
return -1; | return -1; | ||||
} | } | ||||
} | } | ||||
return 0; | |||||
return -1; | |||||
} | } | ||||
#define RTP_SEQ_MOD (1<<16) | #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)) | if ((buf[0] & 0xc0) != (RTP_VERSION << 6)) | ||||
return -1; | return -1; | ||||
if (buf[1] >= RTCP_SR && buf[1] <= RTCP_APP) { | 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; | payload_type = buf[1] & 0x7f; | ||||
if (buf[1] & 0x80) | if (buf[1] & 0x80) | ||||
@@ -1226,6 +1226,7 @@ static int rtsp_read_play(AVFormatContext *s) | |||||
char cmd[1024]; | char cmd[1024]; | ||||
av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state); | 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->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { | ||||
if (rt->state == RTSP_STATE_PAUSED) { | 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]; | uint8_t buf[10 * RTP_MAX_PACKET_LENGTH]; | ||||
RTSPStream *rtsp_st; | RTSPStream *rtsp_st; | ||||
if (rt->nb_byes == rt->nb_rtsp_streams) | |||||
return AVERROR_EOF; | |||||
/* get next frames from the same RTP packet */ | /* get next frames from the same RTP packet */ | ||||
if (rt->cur_transport_priv) { | if (rt->cur_transport_priv) { | ||||
if (rt->transport == RTSP_TRANSPORT_RDT) { | 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; | 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) | if (ret < 0) | ||||
@@ -303,6 +303,11 @@ typedef struct RTSPState { | |||||
/** RTSP transport mode, such as plain or tunneled. */ | /** RTSP transport mode, such as plain or tunneled. */ | ||||
enum RTSPControlTransport control_transport; | 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; | } RTSPState; | ||||
/** | /** | ||||