Also make sure the BYE packets are sent at all when using TCP interleaved transport. Signed-off-by: Martin Storsjö <martin@martin.st>tags/n2.2-rc1
| @@ -638,7 +638,7 @@ int ff_sdp_parse(AVFormatContext *s, const char *content) | |||||
| } | } | ||||
| #endif /* CONFIG_RTPDEC */ | #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; | RTSPState *rt = s->priv_data; | ||||
| int i; | int i; | ||||
| @@ -653,6 +653,8 @@ void ff_rtsp_undo_setup(AVFormatContext *s) | |||||
| av_write_trailer(rtpctx); | av_write_trailer(rtpctx); | ||||
| if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) { | if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) { | ||||
| uint8_t *ptr; | 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); | avio_close_dyn_buf(rtpctx->pb, &ptr); | ||||
| av_free(ptr); | av_free(ptr); | ||||
| } else { | } else { | ||||
| @@ -678,7 +680,7 @@ void ff_rtsp_close_streams(AVFormatContext *s) | |||||
| int i, j; | int i, j; | ||||
| RTSPStream *rtsp_st; | RTSPStream *rtsp_st; | ||||
| ff_rtsp_undo_setup(s); | |||||
| ff_rtsp_undo_setup(s, 0); | |||||
| for (i = 0; i < rt->nb_rtsp_streams; i++) { | for (i = 0; i < rt->nb_rtsp_streams; i++) { | ||||
| rtsp_st = rt->rtsp_streams[i]; | rtsp_st = rt->rtsp_streams[i]; | ||||
| if (rtsp_st) { | if (rtsp_st) { | ||||
| @@ -1549,7 +1551,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, | |||||
| return 0; | return 0; | ||||
| fail: | fail: | ||||
| ff_rtsp_undo_setup(s); | |||||
| ff_rtsp_undo_setup(s, 0); | |||||
| return err; | return err; | ||||
| } | } | ||||
| @@ -587,6 +587,11 @@ int ff_sdp_parse(AVFormatContext *s, const char *content); | |||||
| int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, | int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, | ||||
| uint8_t *buf, int buf_size); | 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 | * Receive one packet from the RTSPStreams set up in the AVFormatContext | ||||
| * (which should contain a RTSPState struct as priv_data). | * (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 | * Undo the effect of ff_rtsp_make_setup_request, close the | ||||
| * transport_priv and rtp_handle fields. | * 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. | * Open RTSP transport context. | ||||
| @@ -769,7 +769,7 @@ static int resetup_tcp(AVFormatContext *s) | |||||
| av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, | av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, | ||||
| s->filename); | 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, | return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP, | ||||
| rt->real_challenge); | rt->real_challenge); | ||||
| } | } | ||||
| @@ -136,7 +136,7 @@ static int rtsp_write_header(AVFormatContext *s) | |||||
| return 0; | 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; | RTSPState *rt = s->priv_data; | ||||
| AVFormatContext *rtpctx = rtsp_st->transport_priv; | 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. | * packets, so we need to send them out on the TCP connection separately. | ||||
| */ | */ | ||||
| if (!ret && rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) | 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; | return ret; | ||||
| } | } | ||||
| @@ -225,6 +225,11 @@ static int rtsp_write_close(AVFormatContext *s) | |||||
| { | { | ||||
| RTSPState *rt = s->priv_data; | 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_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL); | ||||
| ff_rtsp_close_streams(s); | ff_rtsp_close_streams(s); | ||||