From: Vincent Luo <vincent860...@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 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel