From df8cf076c8627d9240e62187ac98cd88f757353c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 8 Aug 2012 21:37:47 +0300 Subject: rtsp: Support receiving plain data over UDP without any RTP encapsulation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EvoStream Media Server can serve data in this format, and VLC/live555 already supports it. Signed-off-by: Martin Storsjö --- libavformat/rtsp.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'libavformat/rtsp.c') diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index d25dafa..e03021b 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -370,7 +370,9 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, get_word(buf1, sizeof(buf1), &p); /* port */ rtsp_st->sdp_port = atoi(buf1); - get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */ + get_word(buf1, sizeof(buf1), &p); /* protocol */ + if (!strcmp(buf1, "udp")) + rt->transport = RTSP_TRANSPORT_RAW; /* XXX: handle list of formats */ get_word(buf1, sizeof(buf1), &p); /* format list */ @@ -563,7 +565,7 @@ void ff_rtsp_undo_setup(AVFormatContext *s) avformat_free_context(rtpctx); } else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC) ff_rdt_parse_close(rtsp_st->transport_priv); - else if (CONFIG_RTPDEC) + else if (rt->transport == RTSP_TRANSPORT_RAW && CONFIG_RTPDEC) ff_rtp_parse_close(rtsp_st->transport_priv); } rtsp_st->transport_priv = NULL; @@ -617,6 +619,8 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) rtsp_st->rtp_handle = NULL; if (ret < 0) return ret; + } else if (rt->transport == RTSP_TRANSPORT_RAW) { + return 0; // Don't need to open any parser here } else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC) rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index, rtsp_st->dynamic_protocol_context, @@ -629,7 +633,7 @@ int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) if (!rtsp_st->transport_priv) { return AVERROR(ENOMEM); - } else if (rt->transport != RTSP_TRANSPORT_RDT && CONFIG_RTPDEC) { + } else if (rt->transport == RTSP_TRANSPORT_RTP && CONFIG_RTPDEC) { if (rtsp_st->dynamic_handler) { ff_rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv, rtsp_st->dynamic_protocol_context, @@ -698,6 +702,15 @@ static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p) get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p); profile[0] = '\0'; th->transport = RTSP_TRANSPORT_RDT; + } else if (!av_strcasecmp(transport_protocol, "raw")) { + get_word_sep(profile, sizeof(profile), "/;,", &p); + lower_transport[0] = '\0'; + /* raw/raw/ */ + if (*p == '/') { + get_word_sep(lower_transport, sizeof(lower_transport), + ";,", &p); + } + th->transport = RTSP_TRANSPORT_RAW; } if (!av_strcasecmp(lower_transport, "TCP")) th->lower_transport = RTSP_LOWER_TRANSPORT_TCP; @@ -1187,6 +1200,8 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, if (rt->transport == RTSP_TRANSPORT_RDT) trans_pref = "x-pn-tng"; + else if (rt->transport == RTSP_TRANSPORT_RAW) + trans_pref = "RAW/RAW"; else trans_pref = "RTP/AVP"; @@ -1822,7 +1837,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR_EOF; if (rt->transport == RTSP_TRANSPORT_RDT) { ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len); - } else { + } else if (rt->transport == RTSP_TRANSPORT_RTP) { ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len); if (ret < 0) { /* Either bad packet, or a RTCP packet. Check if the @@ -1861,6 +1876,8 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR_EOF; } } + } else { + return AVERROR_INVALIDDATA; } end: if (ret < 0) -- cgit v1.1 From 1243c722510f6cf878039e5edfd912ab25fe66f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 8 Aug 2012 23:05:52 +0300 Subject: rtsp: Support mpegts in raw udp packets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is basically the same way as mpegts packets are parsed in rtpdec.c. Signed-off-by: Martin Storsjö --- libavformat/rtsp.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'libavformat/rtsp.c') diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index e03021b..7506d39 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -46,6 +46,7 @@ #include "rtpenc_chain.h" #include "url.h" #include "rtpenc.h" +#include "mpegts.h" //#define DEBUG @@ -380,6 +381,8 @@ static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) { /* no corresponding stream */ + if (rt->transport == RTSP_TRANSPORT_RAW && !rt->ts && CONFIG_RTPDEC) + rt->ts = ff_mpegts_parse_open(s); } else if (rt->server_type == RTSP_SERVER_WMS && codec_type == AVMEDIA_TYPE_DATA) { /* RTX stream, a stream that carries all the other actual @@ -596,6 +599,8 @@ void ff_rtsp_close_streams(AVFormatContext *s) if (rt->asf_ctx) { avformat_close_input(&rt->asf_ctx); } + if (rt->ts && CONFIG_RTPDEC) + ff_mpegts_parse_close(rt->ts); av_free(rt->p); av_free(rt->recvbuf); } @@ -1773,8 +1778,15 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) if (rt->cur_transport_priv) { if (rt->transport == RTSP_TRANSPORT_RDT) { ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0); - } else + } else if (rt->transport == RTSP_TRANSPORT_RTP) { ret = ff_rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0); + } else if (rt->ts && CONFIG_RTPDEC) { + ret = ff_mpegts_parse_packet(rt->ts, pkt, rt->recvbuf + rt->recvbuf_pos, rt->recvbuf_len - rt->recvbuf_pos); + if (ret >= 0) { + rt->recvbuf_pos += ret; + ret = rt->recvbuf_pos < rt->recvbuf_len; + } + } if (ret == 0) { rt->cur_transport_priv = NULL; return 0; @@ -1876,6 +1888,18 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR_EOF; } } + } else if (rt->ts && CONFIG_RTPDEC) { + ret = ff_mpegts_parse_packet(rt->ts, pkt, rt->recvbuf, len); + if (ret >= 0) { + if (ret < len) { + rt->recvbuf_len = len; + rt->recvbuf_pos = ret; + rt->cur_transport_priv = rt->ts; + return 1; + } else { + ret = 0; + } + } } else { return AVERROR_INVALIDDATA; } -- cgit v1.1