aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2013-10-30 19:12:45 +0200
committerMartin Storsjö <martin@martin.st>2013-11-01 09:57:06 +0200
commit50aef03b24d949249b020226dffa3a78077f1056 (patch)
tree99f576b21f7c68ff57ef8d6c717b567306bdc86d /libavformat
parent9ceed7af377cea6a430d63a2f5d5cf1afe0d4f05 (diff)
downloadffmpeg-50aef03b24d949249b020226dffa3a78077f1056.tar.gz
rtspenc: Make sure BYE packets are sent before TEARDOWN
Also make sure the BYE packets are sent at all when using TCP interleaved transport. Signed-off-by: Martin Storsjö <martin@martin.st>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/rtsp.c8
-rw-r--r--libavformat/rtsp.h7
-rw-r--r--libavformat/rtspdec.c2
-rw-r--r--libavformat/rtspenc.c9
4 files changed, 19 insertions, 7 deletions
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 16b5d416f2..70f8e2104e 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -638,7 +638,7 @@ int ff_sdp_parse(AVFormatContext *s, const char *content)
}
#endif /* CONFIG_RTPDEC */
-void ff_rtsp_undo_setup(AVFormatContext *s)
+void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
{
RTSPState *rt = s->priv_data;
int i;
@@ -653,6 +653,8 @@ void ff_rtsp_undo_setup(AVFormatContext *s)
av_write_trailer(rtpctx);
if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
uint8_t *ptr;
+ if (CONFIG_RTSP_MUXER && rtpctx->pb && send_packets)
+ ff_rtsp_tcp_write_packet(s, rtsp_st);
avio_close_dyn_buf(rtpctx->pb, &ptr);
av_free(ptr);
} else {
@@ -678,7 +680,7 @@ void ff_rtsp_close_streams(AVFormatContext *s)
int i, j;
RTSPStream *rtsp_st;
- ff_rtsp_undo_setup(s);
+ ff_rtsp_undo_setup(s, 0);
for (i = 0; i < rt->nb_rtsp_streams; i++) {
rtsp_st = rt->rtsp_streams[i];
if (rtsp_st) {
@@ -1549,7 +1551,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
return 0;
fail:
- ff_rtsp_undo_setup(s);
+ ff_rtsp_undo_setup(s, 0);
return err;
}
diff --git a/libavformat/rtsp.h b/libavformat/rtsp.h
index c6f2ffae4b..7a910b06db 100644
--- a/libavformat/rtsp.h
+++ b/libavformat/rtsp.h
@@ -588,6 +588,11 @@ int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
uint8_t *buf, int buf_size);
/**
+ * Send buffered packets over TCP.
+ */
+int ff_rtsp_tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st);
+
+/**
* Receive one packet from the RTSPStreams set up in the AVFormatContext
* (which should contain a RTSPState struct as priv_data).
*/
@@ -605,7 +610,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
* Undo the effect of ff_rtsp_make_setup_request, close the
* transport_priv and rtp_handle fields.
*/
-void ff_rtsp_undo_setup(AVFormatContext *s);
+void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets);
/**
* Open RTSP transport context.
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 43dcb47ac1..160d49bb3d 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -769,7 +769,7 @@ static int resetup_tcp(AVFormatContext *s)
av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
s->filename);
- ff_rtsp_undo_setup(s);
+ ff_rtsp_undo_setup(s, 0);
return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP,
rt->real_challenge);
}
diff --git a/libavformat/rtspenc.c b/libavformat/rtspenc.c
index d8e5b0e212..8a334ec49b 100644
--- a/libavformat/rtspenc.c
+++ b/libavformat/rtspenc.c
@@ -136,7 +136,7 @@ static int rtsp_write_header(AVFormatContext *s)
return 0;
}
-static int tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
+int ff_rtsp_tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
{
RTSPState *rt = s->priv_data;
AVFormatContext *rtpctx = rtsp_st->transport_priv;
@@ -217,7 +217,7 @@ static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt)
* packets, so we need to send them out on the TCP connection separately.
*/
if (!ret && rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP)
- ret = tcp_write_packet(s, rtsp_st);
+ ret = ff_rtsp_tcp_write_packet(s, rtsp_st);
return ret;
}
@@ -225,6 +225,11 @@ static int rtsp_write_close(AVFormatContext *s)
{
RTSPState *rt = s->priv_data;
+ // If we want to send RTCP_BYE packets, these are sent by av_write_trailer.
+ // Thus call this on all streams before doing the teardown. This is
+ // done within ff_rtsp_undo_setup.
+ ff_rtsp_undo_setup(s, 1);
+
ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
ff_rtsp_close_streams(s);