summaryrefslogtreecommitdiffstats
path: root/libavformat/rtsp.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-08-09 19:09:39 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-08-09 19:31:56 +0200
commit9f088a1ed4d34f0cf4244a4b80960af9e8f23dfc (patch)
tree049c8db5ee42c462bfe3d999146a224cff29bf03 /libavformat/rtsp.c
parente1a983e6010930ab742bede275de1ccf921485b7 (diff)
parentf69f4036f8cc3b673864dce01d2714fd5e49e8da (diff)
downloadffmpeg-streaming-9f088a1ed4d34f0cf4244a4b80960af9e8f23dfc.zip
ffmpeg-streaming-9f088a1ed4d34f0cf4244a4b80960af9e8f23dfc.tar.gz
Merge remote-tracking branch 'qatar/master'
* qatar/master: mpegvideo: reduce excessive inlining of mpeg_motion() mpegvideo: convert mpegvideo_common.h to a .c file build: factor out mpegvideo.o dependencies to CONFIG_MPEGVIDEO Move MASK_ABS macro to libavcodec/mathops.h x86: move MANGLE() and related macros to libavutil/x86/asm.h x86: rename libavutil/x86_cpu.h to libavutil/x86/asm.h aacdec: Don't fall back to the old output configuration when no old configuration is present. rtmp: Add message tracking rtsp: Support mpegts in raw udp packets rtsp: Support receiving plain data over UDP without any RTP encapsulation rtpdec: Remove an unused include rtpenc: Remove an av_abort() that depends on user-supplied data vsrc_movie: discourage its use with avconv. avconv: allow no input files. avconv: prevent invalid reads in transcode_init() avconv: rename OutputStream.is_past_recording_time to finished. Conflicts: configure doc/filters.texi ffmpeg.c ffmpeg.h libavcodec/Makefile libavcodec/aacdec.c libavcodec/mpegvideo.c libavformat/version.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/rtsp.c')
-rw-r--r--libavformat/rtsp.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index 633ec39..b5e6858 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
@@ -370,7 +371,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 */
@@ -378,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
@@ -563,7 +568,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;
@@ -594,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);
}
@@ -617,6 +624,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 +638,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 +707,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/<protocol> */
+ 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 +1205,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";
@@ -1753,8 +1773,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;
@@ -1817,7 +1844,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
@@ -1856,6 +1883,20 @@ 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;
}
end:
if (ret < 0)
OpenPOWER on IntegriCloud