[FFmpeg-devel] [PATCH] update to add preclose function, help to fix rtsp didn't send teardown after ffplay close stream

Vincent Luo vincent860602 at gmail.com
Thu Mar 2 03:42:12 EET 2017


From: Vincent Luo <vincent860602 at gmail.com>

---
 ffplay.c               |  1 +
 libavformat/avformat.h | 11 ++++++++++-
 libavformat/rtspdec.c  |  9 +++++++++
 libavformat/utils.c    | 12 ++++++++++++
 4 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/ffplay.c b/ffplay.c
index 79dc768..42e538b 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -1178,6 +1178,7 @@ static void stream_component_close(VideoState *is, int stream_index)
 
 static void stream_close(VideoState *is)
 {
+    avformat_preclose_input(&is->ic); //added by vincent 20170228 for send teardown before close(Fix a rtsp issue)
     /* XXX: use a special url_shutdown call to abort parse cleanly */
     is->abort_request = 1;
     SDL_WaitThread(is->read_tid, NULL);
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index f9f4d72..c9f7a39 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -730,13 +730,18 @@ typedef struct AVInputFormat {
      */
     int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
 
+/**
+* The stream is going to be closed. The AVFormatContext and AVStreams are not
+* freed by this function
+*/
+int (*read_preclose)(struct AVFormatContext *);
     /**
      * Close the stream. The AVFormatContext and AVStreams are not
      * freed by this function
      */
     int (*read_close)(struct AVFormatContext *);
 
-    /**
+/**
      * Seek to a given timestamp relative to the frames in
      * stream component stream_index.
      * @param stream_index Must not be -1.
@@ -2365,6 +2370,10 @@ int av_read_play(AVFormatContext *s);
 int av_read_pause(AVFormatContext *s);
 
 /**
+* Call before closing input AVFormatContext.
+*/
+void avformat_preclose_input(AVFormatContext **s);
+/**
  * Close an opened input AVFormatContext. Free it and all its contents
  * and set *s to NULL.
  */
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index a722b98..cdcd578 100644
--- a/libavformat/rtspdec.c
+++ b/libavformat/rtspdec.c
@@ -53,6 +53,14 @@ static const struct RTSPStatusMessage {
     { 0,                          "NULL"                             }
 };
 
+static int rtsp_read_preclose(AVFormatContext *s)
+{
+    RTSPState *rt = s->priv_data;
+
+    if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN))
+       ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
+    return 0;
+}
 static int rtsp_read_close(AVFormatContext *s)
 {
     RTSPState *rt = s->priv_data;
@@ -968,6 +976,7 @@ AVInputFormat ff_rtsp_demuxer = {
     .read_probe     = rtsp_probe,
     .read_header    = rtsp_read_header,
     .read_packet    = rtsp_read_packet,
+    .read_preclose  = rtsp_read_preclose,
     .read_close     = rtsp_read_close,
     .read_seek      = rtsp_read_seek,
     .flags          = AVFMT_NOFILE,
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 5664646..45656c2 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -4175,7 +4175,19 @@ void avformat_free_context(AVFormatContext *s)
     flush_packet_queue(s);
     av_free(s);
 }
+void avformat_preclose_input(AVFormatContext **ps)
+{
+	AVFormatContext *s;
+
+	if (!ps || !*ps)
+        return;
 
+	s  = *ps;
+
+	if (s->iformat)
+	if (s->iformat->read_preclose)
+		s->iformat->read_preclose(s);
+}
 void avformat_close_input(AVFormatContext **ps)
 {
     AVFormatContext *s;
-- 
2.7.4



More information about the ffmpeg-devel mailing list