diff --git a/ffplay.c b/ffplay.c
index 4a084b4..c47cc95 100644
|
a
|
b
|
static void stream_component_close(VideoState *is, int stream_index)
|
| 1192 | 1192 | |
| 1193 | 1193 | static void stream_close(VideoState *is) |
| 1194 | 1194 | { |
| | 1195 | avformat_preclose_input(&is->ic); |
| | 1196 | |
| 1195 | 1197 | /* XXX: use a special url_shutdown call to abort parse cleanly */ |
| 1196 | 1198 | is->abort_request = 1; |
| 1197 | 1199 | SDL_WaitThread(is->read_tid, NULL); |
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index f3ffcfb..76d9402 100644
|
a
|
b
|
typedef struct AVInputFormat {
|
| 693 | 693 | int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); |
| 694 | 694 | |
| 695 | 695 | /** |
| | 696 | * The stream is going to be closed. The AVFormatContext and AVStreams are not |
| | 697 | * freed by this function |
| | 698 | */ |
| | 699 | int (*read_preclose)(struct AVFormatContext *); |
| | 700 | |
| | 701 | /** |
| 696 | 702 | * Close the stream. The AVFormatContext and AVStreams are not |
| 697 | 703 | * freed by this function |
| 698 | 704 | */ |
| … |
… |
int av_read_play(AVFormatContext *s);
|
| 2231 | 2237 | int av_read_pause(AVFormatContext *s); |
| 2232 | 2238 | |
| 2233 | 2239 | /** |
| | 2240 | * Call before closing input AVFormatContext. |
| | 2241 | */ |
| | 2242 | void avformat_preclose_input(AVFormatContext **s); |
| | 2243 | /** |
| | 2244 | * @} |
| | 2245 | */ |
| | 2246 | |
| | 2247 | /** |
| 2234 | 2248 | * Close an opened input AVFormatContext. Free it and all its contents |
| 2235 | 2249 | * and set *s to NULL. |
| 2236 | 2250 | */ |
diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c
index 3c0010e..17afd47 100644
|
a
|
b
|
static const struct RTSPStatusMessage {
|
| 53 | 53 | { 0, "NULL" } |
| 54 | 54 | }; |
| 55 | 55 | |
| 56 | | static int rtsp_read_close(AVFormatContext *s) |
| | 56 | static int rtsp_read_preclose(AVFormatContext *s) |
| 57 | 57 | { |
| 58 | 58 | RTSPState *rt = s->priv_data; |
| 59 | 59 | |
| 60 | | if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) |
| 61 | | ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); |
| | 60 | if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) { |
| | 61 | ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); |
| | 62 | } |
| | 63 | return 0; |
| | 64 | } |
| 62 | 65 | |
| | 66 | static int rtsp_read_close(AVFormatContext *s) |
| | 67 | { |
| | 68 | RTSPState *rt = s->priv_data; |
| | 69 | |
| 63 | 70 | ff_rtsp_close_streams(s); |
| 64 | 71 | ff_rtsp_close_connections(s); |
| 65 | 72 | ff_network_close(); |
| … |
… |
static int rtsp_read_play(AVFormatContext *s)
|
| 551 | 558 | ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL); |
| 552 | 559 | if (reply->status_code != RTSP_STATUS_OK) { |
| 553 | 560 | return ff_rtsp_averror(reply->status_code, -1); |
| 554 | | } |
| | 561 | } |
| 555 | 562 | if (rt->transport == RTSP_TRANSPORT_RTP && |
| 556 | 563 | reply->range_start != AV_NOPTS_VALUE) { |
| 557 | 564 | for (i = 0; i < rt->nb_rtsp_streams; i++) { |
| … |
… |
int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply)
|
| 616 | 623 | } |
| 617 | 624 | if (!content) |
| 618 | 625 | return AVERROR_INVALIDDATA; |
| 619 | | |
| | 626 | |
| 620 | 627 | av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content); |
| 621 | 628 | /* now we got the SDP description, we parse it */ |
| 622 | 629 | ret = ff_sdp_parse(s, (const char *)content); |
| … |
… |
AVInputFormat ff_rtsp_demuxer = {
|
| 966 | 973 | .read_probe = rtsp_probe, |
| 967 | 974 | .read_header = rtsp_read_header, |
| 968 | 975 | .read_packet = rtsp_read_packet, |
| | 976 | .read_preclose = rtsp_read_preclose, |
| 969 | 977 | .read_close = rtsp_read_close, |
| 970 | 978 | .read_seek = rtsp_read_seek, |
| 971 | 979 | .flags = AVFMT_NOFILE, |
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 689473e..853fb59 100644
|
a
|
b
|
void avformat_free_context(AVFormatContext *s)
|
| 3707 | 3707 | av_free(s); |
| 3708 | 3708 | } |
| 3709 | 3709 | |
| | 3710 | void avformat_preclose_input(AVFormatContext **ps) |
| | 3711 | { |
| | 3712 | AVFormatContext *s; |
| | 3713 | |
| | 3714 | if (!ps || !*ps) |
| | 3715 | return; |
| | 3716 | |
| | 3717 | s = *ps; |
| | 3718 | |
| | 3719 | if (s->iformat) |
| | 3720 | if (s->iformat->read_preclose) |
| | 3721 | s->iformat->read_preclose(s); |
| | 3722 | } |
| | 3723 | |
| 3710 | 3724 | void avformat_close_input(AVFormatContext **ps) |
| 3711 | 3725 | { |
| 3712 | 3726 | AVFormatContext *s; |