diff options
Diffstat (limited to 'libavformat/rtsp.c')
-rw-r--r-- | libavformat/rtsp.c | 51 |
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) |