Skip to content
Snippets Groups Projects
Commit b7dc88fc authored by Martin Storsjö's avatar Martin Storsjö
Browse files

Add support for TCP as lower transport in the RTSP muxer

Originally committed as revision 22634 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 5d7bc46c
No related branches found
No related tags found
No related merge requests found
......@@ -584,7 +584,13 @@ void ff_rtsp_close_streams(AVFormatContext *s)
if (s->oformat) {
AVFormatContext *rtpctx = rtsp_st->transport_priv;
av_write_trailer(rtpctx);
if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
uint8_t *ptr;
url_close_dyn_buf(rtpctx->pb, &ptr);
av_free(ptr);
} else {
url_fclose(rtpctx->pb);
}
av_metadata_free(&rtpctx->streams[0]->metadata);
av_metadata_free(&rtpctx->metadata);
av_free(rtpctx->streams[0]);
......@@ -644,11 +650,20 @@ static void *rtsp_rtp_mux_open(AVFormatContext *s, AVStream *st,
av_free(rtpctx->streams[0]->codec);
rtpctx->streams[0]->codec = st->codec;
if (handle) {
url_fdopen(&rtpctx->pb, handle);
} else
url_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE);
ret = av_write_header(rtpctx);
if (ret) {
if (handle) {
url_fclose(rtpctx->pb);
} else {
uint8_t *ptr;
url_close_dyn_buf(rtpctx->pb, &ptr);
av_free(ptr);
}
av_free(rtpctx->streams[0]);
av_free(rtpctx);
return NULL;
......@@ -1464,11 +1479,12 @@ redirect:
lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
if (s->oformat) {
/* Only UDP output is supported at the moment. */
lower_transport_mask &= 1 << RTSP_LOWER_TRANSPORT_UDP;
/* Only UDP or TCP - UDP multicast isn't supported. */
lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_UDP) |
(1 << RTSP_LOWER_TRANSPORT_TCP);
if (!lower_transport_mask) {
av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, "
"only UDP is supported for output.\n");
"only UDP and TCP are supported for output.\n");
err = AVERROR(EINVAL);
goto fail;
}
......
......@@ -27,6 +27,7 @@
#endif
#include "network.h"
#include "rtsp.h"
#include <libavutil/intreadwrite.h>
static int rtsp_write_record(AVFormatContext *s)
{
......@@ -63,6 +64,40 @@ static int rtsp_write_header(AVFormatContext *s)
return 0;
}
static int tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
{
RTSPState *rt = s->priv_data;
AVFormatContext *rtpctx = rtsp_st->transport_priv;
uint8_t *buf, *ptr;
int size;
uint8_t interleave_header[4];
size = url_close_dyn_buf(rtpctx->pb, &buf);
ptr = buf;
while (size > 4) {
uint32_t packet_len = AV_RB32(ptr);
int id;
ptr += 4;
size -= 4;
if (packet_len > size || packet_len < 2)
break;
if (ptr[1] >= 200 && ptr[1] <= 204)
id = rtsp_st->interleaved_max; /* RTCP */
else
id = rtsp_st->interleaved_min; /* RTP */
interleave_header[0] = '$';
interleave_header[1] = id;
AV_WB16(interleave_header + 2, packet_len);
url_write(rt->rtsp_hd, interleave_header, 4);
url_write(rt->rtsp_hd, ptr, packet_len);
ptr += packet_len;
size -= packet_len;
}
av_free(buf);
url_open_dyn_packet_buf(&rtpctx->pb, RTSP_TCP_MAX_PACKET_SIZE);
return 0;
}
static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt)
{
RTSPState *rt = s->priv_data;
......@@ -111,7 +146,14 @@ static int rtsp_write_packet(AVFormatContext *s, AVPacket *pkt)
* the internal stream_index = 0 becomes visible to the muxer user. */
local_pkt = *pkt;
local_pkt.stream_index = 0;
return av_write_frame(rtpctx, &local_pkt);
ret = av_write_frame(rtpctx, &local_pkt);
/* av_write_frame does all the RTP packetization. If using TCP as
* transport, rtpctx->pb is only a dyn_packet_buf that queues up the
* 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);
return ret;
}
static int rtsp_write_close(AVFormatContext *s)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment