/*
 * RTSP/SDP client
 * Copyright (c) 2002 Fabrice Bellard
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "libavutil/avassert.h"
#include "libavutil/base64.h"
#include "libavutil/avstring.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
#include "libavutil/random_seed.h"
#include "libavutil/dict.h"
#include "libavutil/opt.h"
#include "libavutil/time.h"
#include "avformat.h"
#include "avio_internal.h"

#if HAVE_POLL_H
#include <poll.h>
#endif
#include "internal.h"
#include "network.h"
#include "os_support.h"
#include "http.h"
#include "rtsp.h"

#include "rtpdec.h"
#include "rtpproto.h"
#include "rdt.h"
#include "rtpdec_formats.h"
#include "rtpenc_chain.h"
#include "url.h"
#include "rtpenc.h"
#include "mpegts.h"

/* Timeout values for socket poll, in ms,
 * and read_packet(), in seconds  */
#define POLL_TIMEOUT_MS 100
#define READ_PACKET_TIMEOUT_S 10
#define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / POLL_TIMEOUT_MS
#define SDP_MAX_SIZE 16384
#define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
#define DEFAULT_REORDERING_DELAY 100000

#define OFFSET(x) offsetof(RTSPState, x)
#define DEC AV_OPT_FLAG_DECODING_PARAM
#define ENC AV_OPT_FLAG_ENCODING_PARAM

#define RTSP_FLAG_OPTS(name, longname) \
    { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \
    { "filter_src", "only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, "rtsp_flags" }

#define RTSP_MEDIATYPE_OPTS(name, longname) \
    { name, longname, OFFSET(media_type_mask), AV_OPT_TYPE_FLAGS, { .i64 = (1 << (AVMEDIA_TYPE_SUBTITLE+1)) - 1 }, INT_MIN, INT_MAX, DEC, "allowed_media_types" }, \
    { "video", "Video", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_VIDEO}, 0, 0, DEC, "allowed_media_types" }, \
    { "audio", "Audio", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_AUDIO}, 0, 0, DEC, "allowed_media_types" }, \
    { "data", "Data", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_DATA}, 0, 0, DEC, "allowed_media_types" }, \
    { "subtitle", "Subtitle", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_SUBTITLE}, 0, 0, DEC, "allowed_media_types" }

#define COMMON_OPTS() \
    { "reorder_queue_size", "set number of packets to buffer for handling of reordered packets", OFFSET(reordering_queue_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC }, \
    { "buffer_size",        "Underlying protocol send/receive buffer size",                  OFFSET(buffer_size),           AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC|ENC } \


const AVOption ff_rtsp_options[] = {
    { "initial_pause",  "do not start playing the stream immediately", OFFSET(initial_pause), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
    FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags),
    { "rtsp_transport", "set RTSP transport protocols", OFFSET(lower_transport_mask), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC|ENC, "rtsp_transport" }, \
    { "udp", "UDP", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_UDP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
    { "tcp", "TCP", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_TCP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
    { "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, "rtsp_transport" },
    { "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {.i64 = (1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, "rtsp_transport" },
    RTSP_FLAG_OPTS("rtsp_flags", "set RTSP flags"),
    { "listen", "wait for incoming connections", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_LISTEN}, 0, 0, DEC, "rtsp_flags" },
    { "prefer_tcp", "try RTP via TCP first, if available", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_PREFER_TCP}, 0, 0, DEC|ENC, "rtsp_flags" },
    RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"),
    { "min_port", "set minimum local UDP port", OFFSET(rtp_port_min), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MIN}, 0, 65535, DEC|ENC },
    { "max_port", "set maximum local UDP port", OFFSET(rtp_port_max), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MAX}, 0, 65535, DEC|ENC },
    { "listen_timeout", "set maximum timeout (in seconds) to wait for incoming connections (-1 is infinite, imply flag listen)", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC },
#if FF_API_OLD_RTSP_OPTIONS
    { "timeout", "set maximum timeout (in seconds) to wait for incoming connections (-1 is infinite, imply flag listen) (deprecated, use listen_timeout)", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC },
    { "stimeout", "set timeout (in microseconds) of socket TCP I/O operations", OFFSET(stimeout), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC },
#else
    { "timeout", "set timeout (in microseconds) of socket TCP I/O operations", OFFSET(stimeout), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC },
#endif
    COMMON_OPTS(),
    { "user_agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, DEC },
#if FF_API_OLD_RTSP_OPTIONS
    { "user-agent", "override User-Agent header (deprecated, use user_agent)", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, DEC },
#endif
    { NULL },
};

static const AVOption sdp_options[] = {
    RTSP_FLAG_OPTS("sdp_flags", "SDP flags"),
    { "custom_io", "use custom I/O", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_CUSTOM_IO}, 0, 0, DEC, "rtsp_flags" },
    { "rtcp_to_source", "send RTCP packets to the source address of received packets", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_RTCP_TO_SOURCE}, 0, 0, DEC, "rtsp_flags" },
    RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"),
    COMMON_OPTS(),
    { NULL },
};

static const AVOption rtp_options[] = {
    RTSP_FLAG_OPTS("rtp_flags", "set RTP flags"),
    COMMON_OPTS(),
    { NULL },
};


static AVDictionary *map_to_opts(RTSPState *rt)
{
    AVDictionary *opts = NULL;
    char buf[256];

    snprintf(buf, sizeof(buf), "%d", rt->buffer_size);
    av_dict_set(&opts, "buffer_size", buf, 0);

    return opts;
}

static void get_word_until_chars(char *buf, int buf_size,
                                 const char *sep, const char **pp)
{
    const char *p;
    char *q;

    p = *pp;
    p += strspn(p, SPACE_CHARS);
    q = buf;
    while (!strchr(sep, *p) && *p != '\0') {
        if ((q - buf) < buf_size - 1)
            *q++ = *p;
        p++;
    }
    if (buf_size > 0)
        *q = '\0';
    *pp = p;
}

static void get_word_sep(char *buf, int buf_size, const char *sep,
                         const char **pp)
{
    if (**pp == '/') (*pp)++;
    get_word_until_chars(buf, buf_size, sep, pp);
}

static void get_word(char *buf, int buf_size, const char **pp)
{
    get_word_until_chars(buf, buf_size, SPACE_CHARS, pp);
}

/** Parse a string p in the form of Range:npt=xx-xx, and determine the start
 *  and end time.
 *  Used for seeking in the rtp stream.
 */
static void rtsp_parse_range_npt(const char *p, int64_t *start, int64_t *end)
{
    char buf[256];

    p += strspn(p, SPACE_CHARS);
    if (!av_stristart(p, "npt=", &p))
        return;

    *start = AV_NOPTS_VALUE;
    *end = AV_NOPTS_VALUE;

    get_word_sep(buf, sizeof(buf), "-", &p);
    if (av_parse_time(start, buf, 1) < 0)
        return;
    if (*p == '-') {
        p++;
        get_word_sep(buf, sizeof(buf), "-", &p);
        if (av_parse_time(end, buf, 1) < 0)
            av_log(NULL, AV_LOG_DEBUG, "Failed to parse interval end specification '%s'\n", buf);
    }
}

static int get_sockaddr(AVFormatContext *s,
                        const char *buf, struct sockaddr_storage *sock)
{
    struct addrinfo hints = { 0 }, *ai = NULL;
    int ret;

    hints.ai_flags = AI_NUMERICHOST;
    if ((ret = getaddrinfo(buf, NULL, &hints, &ai))) {
        av_log(s, AV_LOG_ERROR, "getaddrinfo(%s): %s\n",
               buf,
               gai_strerror(ret));
        return -1;
    }
    memcpy(sock, ai->ai_addr, FFMIN(sizeof(*sock), ai->ai_addrlen));
    freeaddrinfo(ai);
    return 0;
}

#if CONFIG_RTPDEC
static void init_rtp_handler(const RTPDynamicProtocolHandler *handler,
                             RTSPStream *rtsp_st, AVStream *st)
{
    AVCodecParameters *par = st ? st->codecpar : NULL;
    if (!handler)
        return;
    if (par)
        par->codec_id          = handler->codec_id;
    rtsp_st->dynamic_handler = handler;
    if (st)
        st->need_parsing = handler->need_parsing;
    if (handler->priv_data_size) {
        rtsp_st->dynamic_protocol_context = av_mallocz(handler->priv_data_size);
        if (!rtsp_st->dynamic_protocol_context)
            rtsp_st->dynamic_handler = NULL;
    }
}

static void finalize_rtp_handler_init(AVFormatContext *s, RTSPStream *rtsp_st,
                                      AVStream *st)
{
    if (rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->init) {
        int ret = rtsp_st->dynamic_handler->init(s, st ? st->index : -1,
                                                 rtsp_st->dynamic_protocol_context);
        if (ret < 0) {
            if (rtsp_st->dynamic_protocol_context) {
                if (rtsp_st->dynamic_handler->close)
                    rtsp_st->dynamic_handler->close(
                        rtsp_st->dynamic_protocol_context);
                av_free(rtsp_st->dynamic_protocol_context);
            }
            rtsp_st->dynamic_protocol_context = NULL;
            rtsp_st->dynamic_handler = NULL;
        }
    }
}

/* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */
static int sdp_parse_rtpmap(AVFormatContext *s,
                            AVStream *st, RTSPStream *rtsp_st,
                            int payload_type, const char *p)
{
    AVCodecParameters *par = st->codecpar;
    char buf[256];
    int i;
    const AVCodecDescriptor *desc;
    const char *c_name;

    /* See if we can handle this kind of payload.
     * The space should normally not be there but some Real streams or
     * particular servers ("RealServer Version 6.1.3.970", see issue 1658)
     * have a trailing space. */
    get_word_sep(buf, sizeof(buf), "/ ", &p);
    if (payload_type < RTP_PT_PRIVATE) {
        /* We are in a standard case
         * (from http://www.iana.org/assignments/rtp-parameters). */
        par->codec_id = ff_rtp_codec_id(buf, par->codec_type);
    }

    if (par->codec_id == AV_CODEC_ID_NONE) {
        const RTPDynamicProtocolHandler *handler =
            ff_rtp_handler_find_by_name(buf, par->codec_type);
        init_rtp_handler(handler, rtsp_st, st);
        /* If no dynamic handler was found, check with the list of standard
         * allocated types, if such a stream for some reason happens to
         * use a private payload type. This isn't handled in rtpdec.c, since
         * the format name from the rtpmap line never is passed into rtpdec. */
        if (!rtsp_st->dynamic_handler)
            par->codec_id = ff_rtp_codec_id(buf, par->codec_type);
    }

    desc = avcodec_descriptor_get(par->codec_id);
    if (desc && desc->name)
        c_name = desc->name;
    else
        c_name = "(null)";

    get_word_sep(buf, sizeof(buf), "/", &p);
    i = atoi(buf);
    switch (par->codec_type) {
    case AVMEDIA_TYPE_AUDIO:
        av_log(s, AV_LOG_DEBUG, "audio codec set to: %s\n", c_name);
        par->sample_rate = RTSP_DEFAULT_AUDIO_SAMPLERATE;
        par->channels = RTSP_DEFAULT_NB_AUDIO_CHANNELS;
        if (i > 0) {
            par->sample_rate = i;
            avpriv_set_pts_info(st, 32, 1, par->sample_rate);
            get_word_sep(buf, sizeof(buf), "/", &p);
            i = atoi(buf);
            if (i > 0)
                par->channels = i;
        }
        av_log(s, AV_LOG_DEBUG, "audio samplerate set to: %i\n",
               par->sample_rate);
        av_log(s, AV_LOG_DEBUG, "audio channels set to: %i\n",
               par->channels);
        break;
    case AVMEDIA_TYPE_VIDEO:
        av_log(s, AV_LOG_DEBUG, "video codec set to: %s\n", c_name);
        if (i > 0)
            avpriv_set_pts_info(st, 32, 1, i);
        break;
    default:
        break;
    }
    finalize_rtp_handler_init(s, rtsp_st, st);
    return 0;
}

/* parse the attribute line from the fmtp a line of an sdp response. This
 * is broken out as a function because it is used in rtp_h264.c, which is
 * forthcoming. */
int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size,
                                char *value, int value_size)
{
    *p += strspn(*p, SPACE_CHARS);
    if (**p) {
        get_word_sep(attr, attr_size, "=", p);
        if (**p == '=')
            (*p)++;
        get_word_sep(value, value_size, ";", p);
        if (**p == ';')
            (*p)++;
        return 1;
    }
    return 0;
}

typedef struct SDPParseState {
    /* SDP only */
    struct sockaddr_storage default_ip;
    int            default_ttl;
    int            skip_media;  ///< set if an unknown m= line occurs
    int nb_default_include_source_addrs; /**< Number of source-specific multicast include source IP address (from SDP content) */
    struct RTSPSource **default_include_source_addrs; /**< Source-specific multicast include source IP address (from SDP content) */
    int nb_default_exclude_source_addrs; /**< Number of source-specific multicast exclude source IP address (from SDP content) */
    struct RTSPSource **default_exclude_source_addrs; /**< Source-specific multicast exclude source IP address (from SDP content) */
    int seen_rtpmap;
    int seen_fmtp;
    char delayed_fmtp[2048];
} SDPParseState;

static void copy_default_source_addrs(struct RTSPSource **addrs, int count,
                                      struct RTSPSource ***dest, int *dest_count)
{
    RTSPSource *rtsp_src, *rtsp_src2;
    int i;
    for (i = 0; i < count; i++) {
        rtsp_src = addrs[i];
        rtsp_src2 = av_malloc(sizeof(*rtsp_src2));
        if (!rtsp_src2)
            continue;
        memcpy(rtsp_src2, rtsp_src, sizeof(*rtsp_src));
        dynarray_add(dest, dest_count, rtsp_src2);
    }
}

static void parse_fmtp(AVFormatContext *s, RTSPState *rt,
                       int payload_type, const char *line)
{
    int i;

    for (i = 0; i < rt->nb_rtsp_streams; i++) {
        RTSPStream *rtsp_st = rt->rtsp_streams[i];
        if (rtsp_st->sdp_payload_type == payload_type &&
            rtsp_st->dynamic_handler &&
            rtsp_st->dynamic_handler->parse_sdp_a_line) {
            rtsp_st->dynamic_handler->parse_sdp_a_line(s, i,
                rtsp_st->dynamic_protocol_context, line);
        }
    }
}

static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
                           int letter, const char *buf)
{
    RTSPState *rt = s->priv_data;
    char buf1[64], st_type[64];
    const char *p;
    enum AVMediaType codec_type;
    int payload_type;
    AVStream *st;
    RTSPStream *rtsp_st;
    RTSPSource *rtsp_src;
    struct sockaddr_storage sdp_ip;
    int ttl;

    av_log(s, AV_LOG_TRACE, "sdp: %c='%s'\n", letter, buf);

    p = buf;
    if (s1->skip_media && letter != 'm')
        return;
    switch (letter) {
    case 'c':
        get_word(buf1, sizeof(buf1), &p);
        if (strcmp(buf1, "IN") != 0)
            return;
        get_word(buf1, sizeof(buf1), &p);
        if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6"))
            return;
        get_word_sep(buf1, sizeof(buf1), "/", &p);
        if (get_sockaddr(s, buf1, &sdp_ip))
            return;
        ttl = 16;
        if (*p == '/') {
            p++;
            get_word_sep(buf1, sizeof(buf1), "/", &p);
            ttl = atoi(buf1);
        }
        if (s->nb_streams == 0) {
            s1->default_ip = sdp_ip;
            s1->default_ttl = ttl;
        } else {
            rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
            rtsp_st->sdp_ip = sdp_ip;
            rtsp_st->sdp_ttl = ttl;
        }
        break;
    case 's':
        av_dict_set(&s->metadata, "title", p, 0);
        break;
    case 'i':
        if (s->nb_streams == 0) {
            av_dict_set(&s->metadata, "comment", p, 0);
            break;
        }
        break;
    case 'm':
        /* new stream */
        s1->skip_media  = 0;
        s1->seen_fmtp   = 0;
        s1->seen_rtpmap = 0;
        codec_type = AVMEDIA_TYPE_UNKNOWN;
        get_word(st_type, sizeof(st_type), &p);
        if (!strcmp(st_type, "audio")) {
            codec_type = AVMEDIA_TYPE_AUDIO;
        } else if (!strcmp(st_type, "video")) {
            codec_type = AVMEDIA_TYPE_VIDEO;
        } else if (!strcmp(st_type, "application")) {
            codec_type = AVMEDIA_TYPE_DATA;
        } else if (!strcmp(st_type, "text")) {
            codec_type = AVMEDIA_TYPE_SUBTITLE;
        }
        if (codec_type == AVMEDIA_TYPE_UNKNOWN || !(rt->media_type_mask & (1 << codec_type))) {
            s1->skip_media = 1;
            return;
        }
        rtsp_st = av_mallocz(sizeof(RTSPStream));
        if (!rtsp_st)
            return;
        rtsp_st->stream_index = -1;
        dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st);

        rtsp_st->sdp_ip = s1->default_ip;
        rtsp_st->sdp_ttl = s1->default_ttl;

        copy_default_source_addrs(s1->default_include_source_addrs,
                                  s1->nb_default_include_source_addrs,
                                  &rtsp_st->include_source_addrs,
                                  &rtsp_st->nb_include_source_addrs);
        copy_default_source_addrs(s1->default_exclude_source_addrs,
                                  s1->nb_default_exclude_source_addrs,
                                  &rtsp_st->exclude_source_addrs,
                                  &rtsp_st->nb_exclude_source_addrs);

        get_word(buf1, sizeof(buf1), &p); /* port */
        rtsp_st->sdp_port = atoi(buf1);

        get_word(buf1, sizeof(buf1), &p); /* protocol */
        if (!strcmp(buf1, "udp"))
            rt->transport = RTSP_TRANSPORT_RAW;
        else if (strstr(buf1, "/AVPF") || strstr(buf1, "/SAVPF"))
            rtsp_st->feedback = 1;

        /* XXX: handle list of formats */
        get_word(buf1, sizeof(buf1), &p); /* format list */
        rtsp_st->sdp_payload_type = atoi(buf1);

        if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
            /* no corresponding stream */
            if (rt->transport == RTSP_TRANSPORT_RAW) {
                if (CONFIG_RTPDEC && !rt->ts)
                    rt->ts = avpriv_mpegts_parse_open(s);
            } else {
                const RTPDynamicProtocolHandler *handler;
                handler = ff_rtp_handler_find_by_id(
                              rtsp_st->sdp_payload_type, AVMEDIA_TYPE_DATA);
                init_rtp_handler(handler, rtsp_st, NULL);
                finalize_rtp_handler_init(s, rtsp_st, NULL);
            }
        } else if (rt->server_type == RTSP_SERVER_WMS &&
                   codec_type == AVMEDIA_TYPE_DATA) {
            /* RTX stream, a stream that carries all the other actual
             * audio/video streams. Don't expose this to the callers. */
        } else {
            st = avformat_new_stream(s, NULL);
            if (!st)
                return;
            st->id = rt->nb_rtsp_streams - 1;
            rtsp_st->stream_index = st->index;
            st->codecpar->codec_type = codec_type;
            if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
                const RTPDynamicProtocolHandler *handler;
                /* if standard payload type, we can find the codec right now */
                ff_rtp_get_codec_info(st->codecpar, rtsp_st->sdp_payload_type);
                if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
                    st->codecpar->sample_rate > 0)
                    avpriv_set_pts_info(st, 32, 1, st->codecpar->sample_rate);
                /* Even static payload types may need a custom depacketizer */
                handler = ff_rtp_handler_find_by_id(
                              rtsp_st->sdp_payload_type, st->codecpar->codec_type);
                init_rtp_handler(handler, rtsp_st, st);
                finalize_rtp_handler_init(s, rtsp_st, st);
            }
            if (rt->default_lang[0])
                av_dict_set(&st->metadata, "language", rt->default_lang, 0);
        }
        /* put a default control url */
        av_strlcpy(rtsp_st->control_url, rt->control_uri,
                   sizeof(rtsp_st->control_url));
        break;
    case 'a':
        if (av_strstart(p, "control:", &p)) {
            if (s->nb_streams == 0) {
                if (!strncmp(p, "rtsp://", 7))
                    av_strlcpy(rt->control_uri, p,
                               sizeof(rt->control_uri));
            } else {
                char proto[32];
                /* get the control url */
                rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];

                /* XXX: may need to add full url resolution */
                av_url_split(proto, sizeof(proto), NULL, 0, NULL, 0,
                             NULL, NULL, 0, p);
                if (proto[0] == '\0') {
                    /* relative control URL */
                    if (rtsp_st->control_url[strlen(rtsp_st->control_url)-1]!='/')
                    av_strlcat(rtsp_st->control_url, "/",
                               sizeof(rtsp_st->control_url));
                    av_strlcat(rtsp_st->control_url, p,
                               sizeof(rtsp_st->control_url));
                } else
                    av_strlcpy(rtsp_st->control_url, p,
                               sizeof(rtsp_st->control_url));
            }
        } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) {
            /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
            get_word(buf1, sizeof(buf1), &p);
            payload_type = atoi(buf1);
            rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
            if (rtsp_st->stream_index >= 0) {
                st = s->streams[rtsp_st->stream_index];
                sdp_parse_rtpmap(s, st, rtsp_st, payload_type, p);
            }
            s1->seen_rtpmap = 1;
            if (s1->seen_fmtp) {
                parse_fmtp(s, rt, payload_type, s1->delayed_fmtp);
            }
        } else if (av_strstart(p, "fmtp:", &p) ||
                   av_strstart(p, "framesize:", &p)) {
            // let dynamic protocol handlers have a stab at the line.
            get_word(buf1, sizeof(buf1), &p);
            payload_type = atoi(buf1);
            if (s1->seen_rtpmap) {
                parse_fmtp(s, rt, payload_type, buf);
            } else {
                s1->seen_fmtp = 1;
                av_strlcpy(s1->delayed_fmtp, buf, sizeof(s1->delayed_fmtp));
            }
        } else if (av_strstart(p, "ssrc:", &p) && s->nb_streams > 0) {
            rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
            get_word(buf1, sizeof(buf1), &p);
            rtsp_st->ssrc = strtoll(buf1, NULL, 10);
        } else if (av_strstart(p, "range:", &p)) {
            int64_t start, end;

            // this is so that seeking on a streamed file can work.
            rtsp_parse_range_npt(p, &start, &end);
            s->start_time = start;
            /* AV_NOPTS_VALUE means live broadcast (and can't seek) */
            s->duration   = (end == AV_NOPTS_VALUE) ?
                            AV_NOPTS_VALUE : end - start;
        } else if (av_strstart(p, "lang:", &p)) {
            if (s->nb_streams > 0) {
                get_word(buf1, sizeof(buf1), &p);
                rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
                if (rtsp_st->stream_index >= 0) {
                    st = s->streams[rtsp_st->stream_index];
                    av_dict_set(&st->metadata, "language", buf1, 0);
                }
            } else
                get_word(rt->default_lang, sizeof(rt->default_lang), &p);
        } else if (av_strstart(p, "IsRealDataType:integer;",&p)) {
            if (atoi(p) == 1)
                rt->transport = RTSP_TRANSPORT_RDT;
        } else if (av_strstart(p, "SampleRate:integer;", &p) &&
                   s->nb_streams > 0) {
            st = s->streams[s->nb_streams - 1];
            st->codecpar->sample_rate = atoi(p);
        } else if (av_strstart(p, "crypto:", &p) && s->nb_streams > 0) {
            // RFC 4568
            rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
            get_word(buf1, sizeof(buf1), &p); // ignore tag
            get_word(rtsp_st->crypto_suite, sizeof(rtsp_st->crypto_suite), &p);
            p += strspn(p, SPACE_CHARS);
            if (av_strstart(p, "inline:", &p))
                get_word(rtsp_st->crypto_params, sizeof(rtsp_st->crypto_params), &p);
        } else if (av_strstart(p, "source-filter:", &p)) {
            int exclude = 0;
            get_word(buf1, sizeof(buf1), &p);
            if (strcmp(buf1, "incl") && strcmp(buf1, "excl"))
                return;
            exclude = !strcmp(buf1, "excl");

            get_word(buf1, sizeof(buf1), &p);
            if (strcmp(buf1, "IN") != 0)
                return;
            get_word(buf1, sizeof(buf1), &p);
            if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6") && strcmp(buf1, "*"))
                return;
            // not checking that the destination address actually matches or is wildcard
            get_word(buf1, sizeof(buf1), &p);

            while (*p != '\0') {
                rtsp_src = av_mallocz(sizeof(*rtsp_src));
                if (!rtsp_src)
                    return;
                get_word(rtsp_src->addr, sizeof(rtsp_src->addr), &p);
                if (exclude) {
                    if (s->nb_streams == 0) {
                        dynarray_add(&s1->default_exclude_source_addrs, &s1->nb_default_exclude_source_addrs, rtsp_src);
                    } else {
                        rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
                        dynarray_add(&rtsp_st->exclude_source_addrs, &rtsp_st->nb_exclude_source_addrs, rtsp_src);
                    }
                } else {
                    if (s->nb_streams == 0) {
                        dynarray_add(&s1->default_include_source_addrs, &s1->nb_default_include_source_addrs, rtsp_src);
                    } else {
                        rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
                        dynarray_add(&rtsp_st->include_source_addrs, &rtsp_st->nb_include_source_addrs, rtsp_src);
                    }
                }
            }
        } else {
            if (rt->server_type == RTSP_SERVER_WMS)
                ff_wms_parse_sdp_a_line(s, p);
            if (s->nb_streams > 0) {
                rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];

                if (rt->server_type == RTSP_SERVER_REAL)
                    ff_real_parse_sdp_a_line(s, rtsp_st->stream_index, p);

                if (rtsp_st->dynamic_handler &&
                    rtsp_st->dynamic_handler->parse_sdp_a_line)
                    rtsp_st->dynamic_handler->parse_sdp_a_line(s,
                        rtsp_st->stream_index,
                        rtsp_st->dynamic_protocol_context, buf);
            }
        }
        break;
    }
}

int ff_sdp_parse(AVFormatContext *s, const char *content)
{
    const char *p;
    int letter, i;
    /* Some SDP lines, particularly for Realmedia or ASF RTSP streams,
     * contain long SDP lines containing complete ASF Headers (several
     * kB) or arrays of MDPR (RM stream descriptor) headers plus
     * "rulebooks" describing their properties. Therefore, the SDP line
     * buffer is large.
     *
     * The Vorbis FMTP line can be up to 16KB - see xiph_parse_sdp_line
     * in rtpdec_xiph.c. */
    char buf[16384], *q;
    SDPParseState sdp_parse_state = { { 0 } }, *s1 = &sdp_parse_state;

    p = content;
    for (;;) {
        p += strspn(p, SPACE_CHARS);
        letter = *p;
        if (letter == '\0')
            break;
        p++;
        if (*p != '=')
            goto next_line;
        p++;
        /* get the content */
        q = buf;
        while (*p != '\n' && *p != '\r' && *p != '\0') {
            if ((q - buf) < sizeof(buf) - 1)
                *q++ = *p;
            p++;
        }
        *q = '\0';
        sdp_parse_line(s, s1, letter, buf);
    next_line:
        while (*p != '\n' && *p != '\0')
            p++;
        if (*p == '\n')
            p++;
    }

    for (i = 0; i < s1->nb_default_include_source_addrs; i++)
        av_freep(&s1->default_include_source_addrs[i]);
    av_freep(&s1->default_include_source_addrs);
    for (i = 0; i < s1->nb_default_exclude_source_addrs; i++)
        av_freep(&s1->default_exclude_source_addrs[i]);
    av_freep(&s1->default_exclude_source_addrs);

    return 0;
}
#endif /* CONFIG_RTPDEC */

void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
{
    RTSPState *rt = s->priv_data;
    int i;

    for (i = 0; i < rt->nb_rtsp_streams; i++) {
        RTSPStream *rtsp_st = rt->rtsp_streams[i];
        if (!rtsp_st)
            continue;
        if (rtsp_st->transport_priv) {
            if (s->oformat) {
                AVFormatContext *rtpctx = rtsp_st->transport_priv;
                av_write_trailer(rtpctx);
                if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
                    if (CONFIG_RTSP_MUXER && rtpctx->pb && send_packets)
                        ff_rtsp_tcp_write_packet(s, rtsp_st);
                    ffio_free_dyn_buf(&rtpctx->pb);
                } else {
                    avio_closep(&rtpctx->pb);
                }
                avformat_free_context(rtpctx);
            } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
                ff_rdt_parse_close(rtsp_st->transport_priv);
            else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP)
                ff_rtp_parse_close(rtsp_st->transport_priv);
        }
        rtsp_st->transport_priv = NULL;
        if (rtsp_st->rtp_handle)
            ffurl_close(rtsp_st->rtp_handle);
        rtsp_st->rtp_handle = NULL;
    }
}

/* close and free RTSP streams */
void ff_rtsp_close_streams(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    int i, j;
    RTSPStream *rtsp_st;

    ff_rtsp_undo_setup(s, 0);
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
        rtsp_st = rt->rtsp_streams[i];
        if (rtsp_st) {
            if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context) {
                if (rtsp_st->dynamic_handler->close)
                    rtsp_st->dynamic_handler->close(
                        rtsp_st->dynamic_protocol_context);
                av_free(rtsp_st->dynamic_protocol_context);
            }
            for (j = 0; j < rtsp_st->nb_include_source_addrs; j++)
                av_freep(&rtsp_st->include_source_addrs[j]);
            av_freep(&rtsp_st->include_source_addrs);
            for (j = 0; j < rtsp_st->nb_exclude_source_addrs; j++)
                av_freep(&rtsp_st->exclude_source_addrs[j]);
            av_freep(&rtsp_st->exclude_source_addrs);

            av_freep(&rtsp_st);
        }
    }
    av_freep(&rt->rtsp_streams);
    if (rt->asf_ctx) {
        avformat_close_input(&rt->asf_ctx);
    }
    if (CONFIG_RTPDEC && rt->ts)
        avpriv_mpegts_parse_close(rt->ts);
    av_freep(&rt->p);
    av_freep(&rt->recvbuf);
}

int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
{
    RTSPState *rt = s->priv_data;
    AVStream *st = NULL;
    int reordering_queue_size = rt->reordering_queue_size;
    if (reordering_queue_size < 0) {
        if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP || !s->max_delay)
            reordering_queue_size = 0;
        else
            reordering_queue_size = RTP_REORDER_QUEUE_DEFAULT_SIZE;
    }

    /* open the RTP context */
    if (rtsp_st->stream_index >= 0)
        st = s->streams[rtsp_st->stream_index];
    if (!st)
        s->ctx_flags |= AVFMTCTX_NOHEADER;

    if (CONFIG_RTSP_MUXER && s->oformat && st) {
        int ret = ff_rtp_chain_mux_open((AVFormatContext **)&rtsp_st->transport_priv,
                                        s, st, rtsp_st->rtp_handle,
                                        RTSP_TCP_MAX_PACKET_SIZE,
                                        rtsp_st->stream_index);
        /* Ownership of rtp_handle is passed to the rtp mux context */
        rtsp_st->rtp_handle = NULL;
        if (ret < 0)
            return ret;
        st->time_base = ((AVFormatContext*)rtsp_st->transport_priv)->streams[0]->time_base;
    } else if (rt->transport == RTSP_TRANSPORT_RAW) {
        return 0; // Don't need to open any parser here
    } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT && st)
        rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
                                            rtsp_st->dynamic_protocol_context,
                                            rtsp_st->dynamic_handler);
    else if (CONFIG_RTPDEC)
        rtsp_st->transport_priv = ff_rtp_parse_open(s, st,
                                         rtsp_st->sdp_payload_type,
                                         reordering_queue_size);

    if (!rtsp_st->transport_priv) {
         return AVERROR(ENOMEM);
    } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP &&
               s->iformat) {
        RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
        rtpctx->ssrc = rtsp_st->ssrc;
        if (rtsp_st->dynamic_handler) {
            ff_rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
                                              rtsp_st->dynamic_protocol_context,
                                              rtsp_st->dynamic_handler);
        }
        if (rtsp_st->crypto_suite[0])
            ff_rtp_parse_set_crypto(rtsp_st->transport_priv,
                                    rtsp_st->crypto_suite,
                                    rtsp_st->crypto_params);
    }

    return 0;
}

#if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER
static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
{
    const char *q;
    char *p;
    int v;

    q = *pp;
    q += strspn(q, SPACE_CHARS);
    v = strtol(q, &p, 10);
    if (*p == '-') {
        p++;
        *min_ptr = v;
        v = strtol(p, &p, 10);
        *max_ptr = v;
    } else {
        *min_ptr = v;
        *max_ptr = v;
    }
    *pp = p;
}

/* XXX: only one transport specification is parsed */
static void rtsp_parse_transport(AVFormatContext *s,
                                 RTSPMessageHeader *reply, const char *p)
{
    char transport_protocol[16];
    char profile[16];
    char lower_transport[16];
    char parameter[16];
    RTSPTransportField *th;
    char buf[256];

    reply->nb_transports = 0;

    for (;;) {
        p += strspn(p, SPACE_CHARS);
        if (*p == '\0')
            break;

        th = &reply->transports[reply->nb_transports];

        get_word_sep(transport_protocol, sizeof(transport_protocol),
                     "/", &p);
        if (!av_strcasecmp (transport_protocol, "rtp")) {
            get_word_sep(profile, sizeof(profile), "/;,", &p);
            lower_transport[0] = '\0';
            /* rtp/avp/<protocol> */
            if (*p == '/') {
                get_word_sep(lower_transport, sizeof(lower_transport),
                             ";,", &p);
            }
            th->transport = RTSP_TRANSPORT_RTP;
        } else if (!av_strcasecmp (transport_protocol, "x-pn-tng") ||
                   !av_strcasecmp (transport_protocol, "x-real-rdt")) {
            /* x-pn-tng/<protocol> */
            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;
        else
            th->lower_transport = RTSP_LOWER_TRANSPORT_UDP;

        if (*p == ';')
            p++;
        /* get each parameter */
        while (*p != '\0' && *p != ',') {
            get_word_sep(parameter, sizeof(parameter), "=;,", &p);
            if (!strcmp(parameter, "port")) {
                if (*p == '=') {
                    p++;
                    rtsp_parse_range(&th->port_min, &th->port_max, &p);
                }
            } else if (!strcmp(parameter, "client_port")) {
                if (*p == '=') {
                    p++;
                    rtsp_parse_range(&th->client_port_min,
                                     &th->client_port_max, &p);
                }
            } else if (!strcmp(parameter, "server_port")) {
                if (*p == '=') {
                    p++;
                    rtsp_parse_range(&th->server_port_min,
                                     &th->server_port_max, &p);
                }
            } else if (!strcmp(parameter, "interleaved")) {
                if (*p == '=') {
                    p++;
                    rtsp_parse_range(&th->interleaved_min,
                                     &th->interleaved_max, &p);
                }
            } else if (!strcmp(parameter, "multicast")) {
                if (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP)
                    th->lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST;
            } else if (!strcmp(parameter, "ttl")) {
                if (*p == '=') {
                    char *end;
                    p++;
                    th->ttl = strtol(p, &end, 10);
                    p = end;
                }
            } else if (!strcmp(parameter, "destination")) {
                if (*p == '=') {
                    p++;
                    get_word_sep(buf, sizeof(buf), ";,", &p);
                    get_sockaddr(s, buf, &th->destination);
                }
            } else if (!strcmp(parameter, "source")) {
                if (*p == '=') {
                    p++;
                    get_word_sep(buf, sizeof(buf), ";,", &p);
                    av_strlcpy(th->source, buf, sizeof(th->source));
                }
            } else if (!strcmp(parameter, "mode")) {
                if (*p == '=') {
                    p++;
                    get_word_sep(buf, sizeof(buf), ";, ", &p);
                    if (!strcmp(buf, "record") ||
                        !strcmp(buf, "receive"))
                        th->mode_record = 1;
                }
            }

            while (*p != ';' && *p != '\0' && *p != ',')
                p++;
            if (*p == ';')
                p++;
        }
        if (*p == ',')
            p++;

        reply->nb_transports++;
        if (reply->nb_transports >= RTSP_MAX_TRANSPORTS)
            break;
    }
}

static void handle_rtp_info(RTSPState *rt, const char *url,
                            uint32_t seq, uint32_t rtptime)
{
    int i;
    if (!rtptime || !url[0])
        return;
    if (rt->transport != RTSP_TRANSPORT_RTP)
        return;
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
        RTSPStream *rtsp_st = rt->rtsp_streams[i];
        RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
        if (!rtpctx)
            continue;
        if (!strcmp(rtsp_st->control_url, url)) {
            rtpctx->base_timestamp = rtptime;
            break;
        }
    }
}

static void rtsp_parse_rtp_info(RTSPState *rt, const char *p)
{
    int read = 0;
    char key[20], value[1024], url[1024] = "";
    uint32_t seq = 0, rtptime = 0;

    for (;;) {
        p += strspn(p, SPACE_CHARS);
        if (!*p)
            break;
        get_word_sep(key, sizeof(key), "=", &p);
        if (*p != '=')
            break;
        p++;
        get_word_sep(value, sizeof(value), ";, ", &p);
        read++;
        if (!strcmp(key, "url"))
            av_strlcpy(url, value, sizeof(url));
        else if (!strcmp(key, "seq"))
            seq = strtoul(value, NULL, 10);
        else if (!strcmp(key, "rtptime"))
            rtptime = strtoul(value, NULL, 10);
        if (*p == ',') {
            handle_rtp_info(rt, url, seq, rtptime);
            url[0] = '\0';
            seq = rtptime = 0;
            read = 0;
        }
        if (*p)
            p++;
    }
    if (read > 0)
        handle_rtp_info(rt, url, seq, rtptime);
}

void ff_rtsp_parse_line(AVFormatContext *s,
                        RTSPMessageHeader *reply, const char *buf,
                        RTSPState *rt, const char *method)
{
    const char *p;

    /* NOTE: we do case independent match for broken servers */
    p = buf;
    if (av_stristart(p, "Session:", &p)) {
        int t;
        get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p);
        if (av_stristart(p, ";timeout=", &p) &&
            (t = strtol(p, NULL, 10)) > 0) {
            reply->timeout = t;
        }
    } else if (av_stristart(p, "Content-Length:", &p)) {
        reply->content_length = strtol(p, NULL, 10);
    } else if (av_stristart(p, "Transport:", &p)) {
        rtsp_parse_transport(s, reply, p);
    } else if (av_stristart(p, "CSeq:", &p)) {
        reply->seq = strtol(p, NULL, 10);
    } else if (av_stristart(p, "Range:", &p)) {
        rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end);
    } else if (av_stristart(p, "RealChallenge1:", &p)) {
        p += strspn(p, SPACE_CHARS);
        av_strlcpy(reply->real_challenge, p, sizeof(reply->real_challenge));
    } else if (av_stristart(p, "Server:", &p)) {
        p += strspn(p, SPACE_CHARS);
        av_strlcpy(reply->server, p, sizeof(reply->server));
    } else if (av_stristart(p, "Notice:", &p) ||
               av_stristart(p, "X-Notice:", &p)) {
        reply->notice = strtol(p, NULL, 10);
    } else if (av_stristart(p, "Location:", &p)) {
        p += strspn(p, SPACE_CHARS);
        av_strlcpy(reply->location, p , sizeof(reply->location));
    } else if (av_stristart(p, "WWW-Authenticate:", &p) && rt) {
        p += strspn(p, SPACE_CHARS);
        ff_http_auth_handle_header(&rt->auth_state, "WWW-Authenticate", p);
    } else if (av_stristart(p, "Authentication-Info:", &p) && rt) {
        p += strspn(p, SPACE_CHARS);
        ff_http_auth_handle_header(&rt->auth_state, "Authentication-Info", p);
    } else if (av_stristart(p, "Content-Base:", &p) && rt) {
        p += strspn(p, SPACE_CHARS);
        if (method && !strcmp(method, "DESCRIBE"))
            av_strlcpy(rt->control_uri, p , sizeof(rt->control_uri));
    } else if (av_stristart(p, "RTP-Info:", &p) && rt) {
        p += strspn(p, SPACE_CHARS);
        if (method && !strcmp(method, "PLAY"))
            rtsp_parse_rtp_info(rt, p);
    } else if (av_stristart(p, "Public:", &p) && rt) {
        if (strstr(p, "GET_PARAMETER") &&
            method && !strcmp(method, "OPTIONS"))
            rt->get_parameter_supported = 1;
    } else if (av_stristart(p, "x-Accept-Dynamic-Rate:", &p) && rt) {
        p += strspn(p, SPACE_CHARS);
        rt->accept_dynamic_rate = atoi(p);
    } else if (av_stristart(p, "Content-Type:", &p)) {
        p += strspn(p, SPACE_CHARS);
        av_strlcpy(reply->content_type, p, sizeof(reply->content_type));
    }
}

/* skip a RTP/TCP interleaved packet */
void ff_rtsp_skip_packet(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    int ret, len, len1;
    uint8_t buf[1024];

    ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
    if (ret != 3)
        return;
    len = AV_RB16(buf + 1);

    av_log(s, AV_LOG_TRACE, "skipping RTP packet len=%d\n", len);

    /* skip payload */
    while (len > 0) {
        len1 = len;
        if (len1 > sizeof(buf))
            len1 = sizeof(buf);
        ret = ffurl_read_complete(rt->rtsp_hd, buf, len1);
        if (ret != len1)
            return;
        len -= len1;
    }
}

int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
                       unsigned char **content_ptr,
                       int return_on_interleaved_data, const char *method)
{
    RTSPState *rt = s->priv_data;
    char buf[4096], buf1[1024], *q;
    unsigned char ch;
    const char *p;
    int ret, content_length, line_count = 0, request = 0;
    unsigned char *content = NULL;

start:
    line_count = 0;
    request = 0;
    content = NULL;
    memset(reply, 0, sizeof(*reply));

    /* parse reply (XXX: use buffers) */
    rt->last_reply[0] = '\0';
    for (;;) {
        q = buf;
        for (;;) {
            ret = ffurl_read_complete(rt->rtsp_hd, &ch, 1);
            av_log(s, AV_LOG_TRACE, "ret=%d c=%02x [%c]\n", ret, ch, ch);
            if (ret != 1)
                return AVERROR_EOF;
            if (ch == '\n')
                break;
            if (ch == '$' && q == buf) {
                if (return_on_interleaved_data) {
                    return 1;
                } else
                    ff_rtsp_skip_packet(s);
            } else if (ch != '\r') {
                if ((q - buf) < sizeof(buf) - 1)
                    *q++ = ch;
            }
        }
        *q = '\0';

        av_log(s, AV_LOG_TRACE, "line='%s'\n", buf);

        /* test if last line */
        if (buf[0] == '\0')
            break;
        p = buf;
        if (line_count == 0) {
            /* get reply code */
            get_word(buf1, sizeof(buf1), &p);
            if (!strncmp(buf1, "RTSP/", 5)) {
                get_word(buf1, sizeof(buf1), &p);
                reply->status_code = atoi(buf1);
                av_strlcpy(reply->reason, p, sizeof(reply->reason));
            } else {
                av_strlcpy(reply->reason, buf1, sizeof(reply->reason)); // method
                get_word(buf1, sizeof(buf1), &p); // object
                request = 1;
            }
        } else {
            ff_rtsp_parse_line(s, reply, p, rt, method);
            av_strlcat(rt->last_reply, p,    sizeof(rt->last_reply));
            av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply));
        }
        line_count++;
    }

    if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0' && !request)
        av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id));

    content_length = reply->content_length;
    if (content_length > 0) {
        /* leave some room for a trailing '\0' (useful for simple parsing) */
        content = av_malloc(content_length + 1);
        if (!content)
            return AVERROR(ENOMEM);
        ffurl_read_complete(rt->rtsp_hd, content, content_length);
        content[content_length] = '\0';
    }
    if (content_ptr)
        *content_ptr = content;
    else
        av_freep(&content);

    if (request) {
        char buf[1024];
        char base64buf[AV_BASE64_SIZE(sizeof(buf))];
        const char* ptr = buf;

        if (!strcmp(reply->reason, "OPTIONS")) {
            snprintf(buf, sizeof(buf), "RTSP/1.0 200 OK\r\n");
            if (reply->seq)
                av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", reply->seq);
            if (reply->session_id[0])
                av_strlcatf(buf, sizeof(buf), "Session: %s\r\n",
                                              reply->session_id);
        } else {
            snprintf(buf, sizeof(buf), "RTSP/1.0 501 Not Implemented\r\n");
        }
        av_strlcat(buf, "\r\n", sizeof(buf));

        if (rt->control_transport == RTSP_MODE_TUNNEL) {
            av_base64_encode(base64buf, sizeof(base64buf), buf, strlen(buf));
            ptr = base64buf;
        }
        ffurl_write(rt->rtsp_hd_out, ptr, strlen(ptr));

        rt->last_cmd_time = av_gettime_relative();
        /* Even if the request from the server had data, it is not the data
         * that the caller wants or expects. The memory could also be leaked
         * if the actual following reply has content data. */
        if (content_ptr)
            av_freep(content_ptr);
        /* If method is set, this is called from ff_rtsp_send_cmd,
         * where a reply to exactly this request is awaited. For
         * callers from within packet receiving, we just want to
         * return to the caller and go back to receiving packets. */
        if (method)
            goto start;
        return 0;
    }

    if (rt->seq != reply->seq) {
        av_log(s, AV_LOG_WARNING, "CSeq %d expected, %d received.\n",
            rt->seq, reply->seq);
    }

    /* EOS */
    if (reply->notice == 2101 /* End-of-Stream Reached */      ||
        reply->notice == 2104 /* Start-of-Stream Reached */    ||
        reply->notice == 2306 /* Continuous Feed Terminated */) {
        rt->state = RTSP_STATE_IDLE;
    } else if (reply->notice >= 4400 && reply->notice < 5500) {
        return AVERROR(EIO); /* data or server error */
    } else if (reply->notice == 2401 /* Ticket Expired */ ||
             (reply->notice >= 5500 && reply->notice < 5600) /* end of term */ )
        return AVERROR(EPERM);

    return 0;
}

/**
 * Send a command to the RTSP server without waiting for the reply.
 *
 * @param s RTSP (de)muxer context
 * @param method the method for the request
 * @param url the target url for the request
 * @param headers extra header lines to include in the request
 * @param send_content if non-null, the data to send as request body content
 * @param send_content_length the length of the send_content data, or 0 if
 *                            send_content is null
 *
 * @return zero if success, nonzero otherwise
 */
static int rtsp_send_cmd_with_content_async(AVFormatContext *s,
                                            const char *method, const char *url,
                                            const char *headers,
                                            const unsigned char *send_content,
                                            int send_content_length)
{
    RTSPState *rt = s->priv_data;
    char buf[4096], *out_buf;
    char base64buf[AV_BASE64_SIZE(sizeof(buf))];

    /* Add in RTSP headers */
    out_buf = buf;
    rt->seq++;
    snprintf(buf, sizeof(buf), "%s %s RTSP/1.0\r\n", method, url);
    if (headers)
        av_strlcat(buf, headers, sizeof(buf));
    av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", rt->seq);
    av_strlcatf(buf, sizeof(buf), "User-Agent: %s\r\n",  rt->user_agent);
    if (rt->session_id[0] != '\0' && (!headers ||
        !strstr(headers, "\nIf-Match:"))) {
        av_strlcatf(buf, sizeof(buf), "Session: %s\r\n", rt->session_id);
    }
    if (rt->auth[0]) {
        char *str = ff_http_auth_create_response(&rt->auth_state,
                                                 rt->auth, url, method);
        if (str)
            av_strlcat(buf, str, sizeof(buf));
        av_free(str);
    }
    if (send_content_length > 0 && send_content)
        av_strlcatf(buf, sizeof(buf), "Content-Length: %d\r\n", send_content_length);
    av_strlcat(buf, "\r\n", sizeof(buf));

    /* base64 encode rtsp if tunneling */
    if (rt->control_transport == RTSP_MODE_TUNNEL) {
        av_base64_encode(base64buf, sizeof(base64buf), buf, strlen(buf));
        out_buf = base64buf;
    }

    av_log(s, AV_LOG_TRACE, "Sending:\n%s--\n", buf);

    ffurl_write(rt->rtsp_hd_out, out_buf, strlen(out_buf));
    if (send_content_length > 0 && send_content) {
        if (rt->control_transport == RTSP_MODE_TUNNEL) {
            avpriv_report_missing_feature(s, "Tunneling of RTSP requests with content data");
            return AVERROR_PATCHWELCOME;
        }
        ffurl_write(rt->rtsp_hd_out, send_content, send_content_length);
    }
    rt->last_cmd_time = av_gettime_relative();

    return 0;
}

int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method,
                           const char *url, const char *headers)
{
    return rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
}

int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url,
                     const char *headers, RTSPMessageHeader *reply,
                     unsigned char **content_ptr)
{
    return ff_rtsp_send_cmd_with_content(s, method, url, headers, reply,
                                         content_ptr, NULL, 0);
}

int ff_rtsp_send_cmd_with_content(AVFormatContext *s,
                                  const char *method, const char *url,
                                  const char *header,
                                  RTSPMessageHeader *reply,
                                  unsigned char **content_ptr,
                                  const unsigned char *send_content,
                                  int send_content_length)
{
    RTSPState *rt = s->priv_data;
    HTTPAuthType cur_auth_type;
    int ret, attempts = 0;

retry:
    cur_auth_type = rt->auth_state.auth_type;
    if ((ret = rtsp_send_cmd_with_content_async(s, method, url, header,
                                                send_content,
                                                send_content_length)))
        return ret;

    if ((ret = ff_rtsp_read_reply(s, reply, content_ptr, 0, method) ) < 0)
        return ret;
    attempts++;

    if (reply->status_code == 401 &&
        (cur_auth_type == HTTP_AUTH_NONE || rt->auth_state.stale) &&
        rt->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2)
        goto retry;

    if (reply->status_code > 400){
        av_log(s, AV_LOG_ERROR, "method %s failed: %d%s\n",
               method,
               reply->status_code,
               reply->reason);
        av_log(s, AV_LOG_DEBUG, "%s\n", rt->last_reply);
    }

    return 0;
}

int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
                              int lower_transport, const char *real_challenge)
{
    RTSPState *rt = s->priv_data;
    int rtx = 0, j, i, err, interleave = 0, port_off;
    RTSPStream *rtsp_st;
    RTSPMessageHeader reply1, *reply = &reply1;
    char cmd[2048];
    const char *trans_pref;

    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";

    /* default timeout: 1 minute */
    rt->timeout = 60;

    /* Choose a random starting offset within the first half of the
     * port range, to allow for a number of ports to try even if the offset
     * happens to be at the end of the random range. */
    port_off = av_get_random_seed() % ((rt->rtp_port_max - rt->rtp_port_min)/2);
    /* even random offset */
    port_off -= port_off & 0x01;

    for (j = rt->rtp_port_min + port_off, i = 0; i < rt->nb_rtsp_streams; ++i) {
        char transport[2048];

        /*
         * WMS serves all UDP data over a single connection, the RTX, which
         * isn't necessarily the first in the SDP but has to be the first
         * to be set up, else the second/third SETUP will fail with a 461.
         */
        if (lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
             rt->server_type == RTSP_SERVER_WMS) {
            if (i == 0) {
                /* rtx first */
                for (rtx = 0; rtx < rt->nb_rtsp_streams; rtx++) {
                    int len = strlen(rt->rtsp_streams[rtx]->control_url);
                    if (len >= 4 &&
                        !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4,
                                "/rtx"))
                        break;
                }
                if (rtx == rt->nb_rtsp_streams)
                    return -1; /* no RTX found */
                rtsp_st = rt->rtsp_streams[rtx];
            } else
                rtsp_st = rt->rtsp_streams[i > rtx ? i : i - 1];
        } else
            rtsp_st = rt->rtsp_streams[i];

        /* RTP/UDP */
        if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
            char buf[256];

            if (rt->server_type == RTSP_SERVER_WMS && i > 1) {
                port = reply->transports[0].client_port_min;
                goto have_port;
            }

            /* first try in specified port range */
            while (j <= rt->rtp_port_max) {
                AVDictionary *opts = map_to_opts(rt);

                ff_url_join(buf, sizeof(buf), "rtp", NULL, host, -1,
                            "?localport=%d", j);
                /* we will use two ports per rtp stream (rtp and rtcp) */
                j += 2;
                err = ffurl_open_whitelist(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE,
                                 &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);

                av_dict_free(&opts);

                if (!err)
                    goto rtp_opened;
            }
            av_log(s, AV_LOG_ERROR, "Unable to open an input RTP port\n");
            err = AVERROR(EIO);
            goto fail;

        rtp_opened:
            port = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
        have_port:
            snprintf(transport, sizeof(transport) - 1,
                     "%s/UDP;", trans_pref);
            if (rt->server_type != RTSP_SERVER_REAL)
                av_strlcat(transport, "unicast;", sizeof(transport));
            av_strlcatf(transport, sizeof(transport),
                     "client_port=%d", port);
            if (rt->transport == RTSP_TRANSPORT_RTP &&
                !(rt->server_type == RTSP_SERVER_WMS && i > 0))
                av_strlcatf(transport, sizeof(transport), "-%d", port + 1);
        }

        /* RTP/TCP */
        else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
            /* For WMS streams, the application streams are only used for
             * UDP. When trying to set it up for TCP streams, the server
             * will return an error. Therefore, we skip those streams. */
            if (rt->server_type == RTSP_SERVER_WMS &&
                (rtsp_st->stream_index < 0 ||
                 s->streams[rtsp_st->stream_index]->codecpar->codec_type ==
                    AVMEDIA_TYPE_DATA))
                continue;
            snprintf(transport, sizeof(transport) - 1,
                     "%s/TCP;", trans_pref);
            if (rt->transport != RTSP_TRANSPORT_RDT)
                av_strlcat(transport, "unicast;", sizeof(transport));
            av_strlcatf(transport, sizeof(transport),
                        "interleaved=%d-%d",
                        interleave, interleave + 1);
            interleave += 2;
        }

        else if (lower_transport == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) {
            snprintf(transport, sizeof(transport) - 1,
                     "%s/UDP;multicast", trans_pref);
        }
        if (s->oformat) {
            av_strlcat(transport, ";mode=record", sizeof(transport));
        } else if (rt->server_type == RTSP_SERVER_REAL ||
                   rt->server_type == RTSP_SERVER_WMS)
            av_strlcat(transport, ";mode=play", sizeof(transport));
        snprintf(cmd, sizeof(cmd),
                 "Transport: %s\r\n",
                 transport);
        if (rt->accept_dynamic_rate)
            av_strlcat(cmd, "x-Dynamic-Rate: 0\r\n", sizeof(cmd));
        if (CONFIG_RTPDEC && i == 0 && rt->server_type == RTSP_SERVER_REAL) {
            char real_res[41], real_csum[9];
            ff_rdt_calc_response_and_checksum(real_res, real_csum,
                                              real_challenge);
            av_strlcatf(cmd, sizeof(cmd),
                        "If-Match: %s\r\n"
                        "RealChallenge2: %s, sd=%s\r\n",
                        rt->session_id, real_res, real_csum);
        }
        ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL);
        if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) {
            err = 1;
            goto fail;
        } else if (reply->status_code != RTSP_STATUS_OK ||
                   reply->nb_transports != 1) {
            err = ff_rtsp_averror(reply->status_code, AVERROR_INVALIDDATA);
            goto fail;
        }

        /* XXX: same protocol for all streams is required */
        if (i > 0) {
            if (reply->transports[0].lower_transport != rt->lower_transport ||
                reply->transports[0].transport != rt->transport) {
                err = AVERROR_INVALIDDATA;
                goto fail;
            }
        } else {
            rt->lower_transport = reply->transports[0].lower_transport;
            rt->transport = reply->transports[0].transport;
        }

        /* Fail if the server responded with another lower transport mode
         * than what we requested. */
        if (reply->transports[0].lower_transport != lower_transport) {
            av_log(s, AV_LOG_ERROR, "Nonmatching transport in server reply\n");
            err = AVERROR_INVALIDDATA;
            goto fail;
        }

        switch(reply->transports[0].lower_transport) {
        case RTSP_LOWER_TRANSPORT_TCP:
            rtsp_st->interleaved_min = reply->transports[0].interleaved_min;
            rtsp_st->interleaved_max = reply->transports[0].interleaved_max;
            break;

        case RTSP_LOWER_TRANSPORT_UDP: {
            char url[1024], options[30] = "";
            const char *peer = host;

            if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
                av_strlcpy(options, "?connect=1", sizeof(options));
            /* Use source address if specified */
            if (reply->transports[0].source[0])
                peer = reply->transports[0].source;
            ff_url_join(url, sizeof(url), "rtp", NULL, peer,
                        reply->transports[0].server_port_min, "%s", options);
            if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
                ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
                err = AVERROR_INVALIDDATA;
                goto fail;
            }
            break;
        }
        case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
            char url[1024], namebuf[50], optbuf[20] = "";
            struct sockaddr_storage addr;
            int port, ttl;

            if (reply->transports[0].destination.ss_family) {
                addr      = reply->transports[0].destination;
                port      = reply->transports[0].port_min;
                ttl       = reply->transports[0].ttl;
            } else {
                addr      = rtsp_st->sdp_ip;
                port      = rtsp_st->sdp_port;
                ttl       = rtsp_st->sdp_ttl;
            }
            if (ttl > 0)
                snprintf(optbuf, sizeof(optbuf), "?ttl=%d", ttl);
            getnameinfo((struct sockaddr*) &addr, sizeof(addr),
                        namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
            ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
                        port, "%s", optbuf);
            if (ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
                           &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist, NULL) < 0) {
                err = AVERROR_INVALIDDATA;
                goto fail;
            }
            break;
        }
        }

        if ((err = ff_rtsp_open_transport_ctx(s, rtsp_st)))
            goto fail;
    }

    if (rt->nb_rtsp_streams && reply->timeout > 0)
        rt->timeout = reply->timeout;

    if (rt->server_type == RTSP_SERVER_REAL)
        rt->need_subscription = 1;

    return 0;

fail:
    ff_rtsp_undo_setup(s, 0);
    return err;
}

void ff_rtsp_close_connections(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    if (rt->rtsp_hd_out != rt->rtsp_hd) ffurl_close(rt->rtsp_hd_out);
    ffurl_close(rt->rtsp_hd);
    rt->rtsp_hd = rt->rtsp_hd_out = NULL;
}

int ff_rtsp_connect(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    char proto[128], host[1024], path[1024];
    char tcpname[1024], cmd[2048], auth[128];
    const char *lower_rtsp_proto = "tcp";
    int port, err, tcp_fd;
    RTSPMessageHeader reply1 = {0}, *reply = &reply1;
    int lower_transport_mask = 0;
    int default_port = RTSP_DEFAULT_PORT;
    char real_challenge[64] = "";
    struct sockaddr_storage peer;
    socklen_t peer_len = sizeof(peer);

    if (rt->rtp_port_max < rt->rtp_port_min) {
        av_log(s, AV_LOG_ERROR, "Invalid UDP port range, max port %d less "
                                "than min port %d\n", rt->rtp_port_max,
                                                      rt->rtp_port_min);
        return AVERROR(EINVAL);
    }

    if (!ff_network_init())
        return AVERROR(EIO);

    if (s->max_delay < 0) /* Not set by the caller */
        s->max_delay = s->iformat ? DEFAULT_REORDERING_DELAY : 0;

    rt->control_transport = RTSP_MODE_PLAIN;
    if (rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_HTTP)) {
        rt->lower_transport_mask = 1 << RTSP_LOWER_TRANSPORT_TCP;
        rt->control_transport = RTSP_MODE_TUNNEL;
    }
    /* Only pass through valid flags from here */
    rt->lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_NB) - 1;

redirect:
    /* extract hostname and port */
    av_url_split(proto, sizeof(proto), auth, sizeof(auth),
                 host, sizeof(host), &port, path, sizeof(path), s->url);

    if (!strcmp(proto, "rtsps")) {
        lower_rtsp_proto         = "tls";
        default_port             = RTSPS_DEFAULT_PORT;
        rt->lower_transport_mask = 1 << RTSP_LOWER_TRANSPORT_TCP;
    }

    if (*auth) {
        av_strlcpy(rt->auth, auth, sizeof(rt->auth));
    }
    if (port < 0)
        port = default_port;

    lower_transport_mask = rt->lower_transport_mask;

    if (!lower_transport_mask)
        lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;

    if (s->oformat) {
        /* 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 || rt->control_transport == RTSP_MODE_TUNNEL) {
            av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, "
                                    "only UDP and TCP are supported for output.\n");
            err = AVERROR(EINVAL);
            goto fail;
        }
    }

    /* Construct the URI used in request; this is similar to s->url,
     * but with authentication credentials removed and RTSP specific options
     * stripped out. */
    ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL,
                host, port, "%s", path);

    if (rt->control_transport == RTSP_MODE_TUNNEL) {
        /* set up initial handshake for tunneling */
        char httpname[1024];
        char sessioncookie[17];
        char headers[1024];

        ff_url_join(httpname, sizeof(httpname), "http", auth, host, port, "%s", path);
        snprintf(sessioncookie, sizeof(sessioncookie), "%08x%08x",
                 av_get_random_seed(), av_get_random_seed());

        /* GET requests */
        if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_FLAG_READ,
                        &s->interrupt_callback) < 0) {
            err = AVERROR(EIO);
            goto fail;
        }

        /* generate GET headers */
        snprintf(headers, sizeof(headers),
                 "x-sessioncookie: %s\r\n"
                 "Accept: application/x-rtsp-tunnelled\r\n"
                 "Pragma: no-cache\r\n"
                 "Cache-Control: no-cache\r\n",
                 sessioncookie);
        av_opt_set(rt->rtsp_hd->priv_data, "headers", headers, 0);

        if (!rt->rtsp_hd->protocol_whitelist && s->protocol_whitelist) {
            rt->rtsp_hd->protocol_whitelist = av_strdup(s->protocol_whitelist);
            if (!rt->rtsp_hd->protocol_whitelist) {
                err = AVERROR(ENOMEM);
                goto fail;
            }
        }

        /* complete the connection */
        if (ffurl_connect(rt->rtsp_hd, NULL)) {
            err = AVERROR(EIO);
            goto fail;
        }

        /* POST requests */
        if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_FLAG_WRITE,
                        &s->interrupt_callback) < 0 ) {
            err = AVERROR(EIO);
            goto fail;
        }

        /* generate POST headers */
        snprintf(headers, sizeof(headers),
                 "x-sessioncookie: %s\r\n"
                 "Content-Type: application/x-rtsp-tunnelled\r\n"
                 "Pragma: no-cache\r\n"
                 "Cache-Control: no-cache\r\n"
                 "Content-Length: 32767\r\n"
                 "Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n",
                 sessioncookie);
        av_opt_set(rt->rtsp_hd_out->priv_data, "headers", headers, 0);
        av_opt_set(rt->rtsp_hd_out->priv_data, "chunked_post", "0", 0);

        /* Initialize the authentication state for the POST session. The HTTP
         * protocol implementation doesn't properly handle multi-pass
         * authentication for POST requests, since it would require one of
         * the following:
         * - implementing Expect: 100-continue, which many HTTP servers
         *   don't support anyway, even less the RTSP servers that do HTTP
         *   tunneling
         * - sending the whole POST data until getting a 401 reply specifying
         *   what authentication method to use, then resending all that data
         * - waiting for potential 401 replies directly after sending the
         *   POST header (waiting for some unspecified time)
         * Therefore, we copy the full auth state, which works for both basic
         * and digest. (For digest, we would have to synchronize the nonce
         * count variable between the two sessions, if we'd do more requests
         * with the original session, though.)
         */
        ff_http_init_auth_state(rt->rtsp_hd_out, rt->rtsp_hd);

        /* complete the connection */
        if (ffurl_connect(rt->rtsp_hd_out, NULL)) {
            err = AVERROR(EIO);
            goto fail;
        }
    } else {
        int ret;
        /* open the tcp connection */
        ff_url_join(tcpname, sizeof(tcpname), lower_rtsp_proto, NULL,
                    host, port,
                    "?timeout=%d", rt->stimeout);
        if ((ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
                       &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist, NULL)) < 0) {
            err = ret;
            goto fail;
        }
        rt->rtsp_hd_out = rt->rtsp_hd;
    }
    rt->seq = 0;

    tcp_fd = ffurl_get_file_handle(rt->rtsp_hd);
    if (tcp_fd < 0) {
        err = tcp_fd;
        goto fail;
    }
    if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) {
        getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host),
                    NULL, 0, NI_NUMERICHOST);
    }

    /* request options supported by the server; this also detects server
     * type */
    for (rt->server_type = RTSP_SERVER_RTP;;) {
        cmd[0] = 0;
        if (rt->server_type == RTSP_SERVER_REAL)
            av_strlcat(cmd,
                       /*
                        * The following entries are required for proper
                        * streaming from a Realmedia server. They are
                        * interdependent in some way although we currently
                        * don't quite understand how. Values were copied
                        * from mplayer SVN r23589.
                        *   ClientChallenge is a 16-byte ID in hex
                        *   CompanyID is a 16-byte ID in base64
                        */
                       "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
                       "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
                       "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
                       "GUID: 00000000-0000-0000-0000-000000000000\r\n",
                       sizeof(cmd));
        ff_rtsp_send_cmd(s, "OPTIONS", rt->control_uri, cmd, reply, NULL);
        if (reply->status_code != RTSP_STATUS_OK) {
            err = ff_rtsp_averror(reply->status_code, AVERROR_INVALIDDATA);
            goto fail;
        }

        /* detect server type if not standard-compliant RTP */
        if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
            rt->server_type = RTSP_SERVER_REAL;
            continue;
        } else if (!av_strncasecmp(reply->server, "WMServer/", 9)) {
            rt->server_type = RTSP_SERVER_WMS;
        } else if (rt->server_type == RTSP_SERVER_REAL)
            strcpy(real_challenge, reply->real_challenge);
        break;
    }

    if (CONFIG_RTSP_DEMUXER && s->iformat)
        err = ff_rtsp_setup_input_streams(s, reply);
    else if (CONFIG_RTSP_MUXER)
        err = ff_rtsp_setup_output_streams(s, host);
    else
        av_assert0(0);
    if (err)
        goto fail;

    do {
        int lower_transport = ff_log2_tab[lower_transport_mask &
                                  ~(lower_transport_mask - 1)];

        if ((lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP))
                && (rt->rtsp_flags & RTSP_FLAG_PREFER_TCP))
            lower_transport = RTSP_LOWER_TRANSPORT_TCP;

        err = ff_rtsp_make_setup_request(s, host, port, lower_transport,
                                 rt->server_type == RTSP_SERVER_REAL ?
                                     real_challenge : NULL);
        if (err < 0)
            goto fail;
        lower_transport_mask &= ~(1 << lower_transport);
        if (lower_transport_mask == 0 && err == 1) {
            err = AVERROR(EPROTONOSUPPORT);
            goto fail;
        }
    } while (err);

    rt->lower_transport_mask = lower_transport_mask;
    av_strlcpy(rt->real_challenge, real_challenge, sizeof(rt->real_challenge));
    rt->state = RTSP_STATE_IDLE;
    rt->seek_timestamp = 0; /* default is to start stream at position zero */
    return 0;
 fail:
    ff_rtsp_close_streams(s);
    ff_rtsp_close_connections(s);
    if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) {
        char *new_url = av_strdup(reply->location);
        if (!new_url) {
            err = AVERROR(ENOMEM);
            goto fail2;
        }
        ff_format_set_url(s, new_url);
        rt->session_id[0] = '\0';
        av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n",
               reply->status_code,
               s->url);
        goto redirect;
    }
 fail2:
    ff_network_close();
    return err;
}
#endif /* CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER */

#if CONFIG_RTPDEC
static int parse_rtsp_message(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    int ret;

    if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
        if (rt->state == RTSP_STATE_STREAMING) {
            if (!ff_rtsp_parse_streaming_commands(s))
                return AVERROR_EOF;
            else
                av_log(s, AV_LOG_WARNING,
                       "Unable to answer to TEARDOWN\n");
        } else
            return 0;
    } else {
        RTSPMessageHeader reply;
        ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL);
        if (ret < 0)
            return ret;
        /* XXX: parse message */
        if (rt->state != RTSP_STATE_STREAMING)
            return 0;
    }

    return 0;
}

static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
                           uint8_t *buf, int buf_size, int64_t wait_end)
{
    RTSPState *rt = s->priv_data;
    RTSPStream *rtsp_st;
    int n, i, ret, timeout_cnt = 0;
    struct pollfd *p = rt->p;
    int *fds = NULL, fdsnum, fdsidx;

    if (!p) {
        p = rt->p = av_malloc_array(2 * (rt->nb_rtsp_streams + 1), sizeof(struct pollfd));
        if (!p)
            return AVERROR(ENOMEM);

        if (rt->rtsp_hd) {
            p[rt->max_p].fd = ffurl_get_file_handle(rt->rtsp_hd);
            p[rt->max_p++].events = POLLIN;
        }
        for (i = 0; i < rt->nb_rtsp_streams; i++) {
            rtsp_st = rt->rtsp_streams[i];
            if (rtsp_st->rtp_handle) {
                if (ret = ffurl_get_multi_file_handle(rtsp_st->rtp_handle,
                                                      &fds, &fdsnum)) {
                    av_log(s, AV_LOG_ERROR, "Unable to recover rtp ports\n");
                    return ret;
                }
                if (fdsnum != 2) {
                    av_log(s, AV_LOG_ERROR,
                           "Number of fds %d not supported\n", fdsnum);
                    return AVERROR_INVALIDDATA;
                }
                for (fdsidx = 0; fdsidx < fdsnum; fdsidx++) {
                    p[rt->max_p].fd       = fds[fdsidx];
                    p[rt->max_p++].events = POLLIN;
                }
                av_freep(&fds);
            }
        }
    }

    for (;;) {
        if (ff_check_interrupt(&s->interrupt_callback))
            return AVERROR_EXIT;
        if (wait_end && wait_end - av_gettime_relative() < 0)
            return AVERROR(EAGAIN);
        n = poll(p, rt->max_p, POLL_TIMEOUT_MS);
        if (n > 0) {
            int j = rt->rtsp_hd ? 1 : 0;
            timeout_cnt = 0;
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
                rtsp_st = rt->rtsp_streams[i];
                if (rtsp_st->rtp_handle) {
                    if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) {
                        ret = ffurl_read(rtsp_st->rtp_handle, buf, buf_size);
                        if (ret > 0) {
                            *prtsp_st = rtsp_st;
                            return ret;
                        }
                    }
                    j+=2;
                }
            }
#if CONFIG_RTSP_DEMUXER
            if (rt->rtsp_hd && p[0].revents & POLLIN) {
                if ((ret = parse_rtsp_message(s)) < 0) {
                    return ret;
                }
            }
#endif
        } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) {
            return AVERROR(ETIMEDOUT);
        } else if (n < 0 && errno != EINTR)
            return AVERROR(errno);
    }
}

static int pick_stream(AVFormatContext *s, RTSPStream **rtsp_st,
                       const uint8_t *buf, int len)
{
    RTSPState *rt = s->priv_data;
    int i;
    if (len < 0)
        return len;
    if (rt->nb_rtsp_streams == 1) {
        *rtsp_st = rt->rtsp_streams[0];
        return len;
    }
    if (len >= 8 && rt->transport == RTSP_TRANSPORT_RTP) {
        if (RTP_PT_IS_RTCP(rt->recvbuf[1])) {
            int no_ssrc = 0;
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
                RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
                if (!rtpctx)
                    continue;
                if (rtpctx->ssrc == AV_RB32(&buf[4])) {
                    *rtsp_st = rt->rtsp_streams[i];
                    return len;
                }
                if (!rtpctx->ssrc)
                    no_ssrc = 1;
            }
            if (no_ssrc) {
                av_log(s, AV_LOG_WARNING,
                       "Unable to pick stream for packet - SSRC not known for "
                       "all streams\n");
                return AVERROR(EAGAIN);
            }
        } else {
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
                if ((buf[1] & 0x7f) == rt->rtsp_streams[i]->sdp_payload_type) {
                    *rtsp_st = rt->rtsp_streams[i];
                    return len;
                }
            }
        }
    }
    av_log(s, AV_LOG_WARNING, "Unable to pick stream for packet\n");
    return AVERROR(EAGAIN);
}

static int read_packet(AVFormatContext *s,
                       RTSPStream **rtsp_st, RTSPStream *first_queue_st,
                       int64_t wait_end)
{
    RTSPState *rt = s->priv_data;
    int len;

    switch(rt->lower_transport) {
    default:
#if CONFIG_RTSP_DEMUXER
    case RTSP_LOWER_TRANSPORT_TCP:
        len = ff_rtsp_tcp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE);
        break;
#endif
    case RTSP_LOWER_TRANSPORT_UDP:
    case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
        len = udp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
        if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
            ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, (*rtsp_st)->rtp_handle, NULL, len);
        break;
    case RTSP_LOWER_TRANSPORT_CUSTOM:
        if (first_queue_st && rt->transport == RTSP_TRANSPORT_RTP &&
            wait_end && wait_end < av_gettime_relative())
            len = AVERROR(EAGAIN);
        else
            len = avio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE);
        len = pick_stream(s, rtsp_st, rt->recvbuf, len);
        if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
            ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, NULL, s->pb, len);
        break;
    }

    if (len == 0)
        return AVERROR_EOF;

    return len;
}

int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
{
    RTSPState *rt = s->priv_data;
    int ret, len;
    RTSPStream *rtsp_st, *first_queue_st = NULL;
    int64_t wait_end = 0;

    if (rt->nb_byes == rt->nb_rtsp_streams)
        return AVERROR_EOF;

    /* get next frames from the same RTP packet */
    if (rt->cur_transport_priv) {
        if (rt->transport == RTSP_TRANSPORT_RDT) {
            ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
        } else if (rt->transport == RTSP_TRANSPORT_RTP) {
            ret = ff_rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
        } else if (CONFIG_RTPDEC && rt->ts) {
            ret = avpriv_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;
            }
        } else
            ret = -1;
        if (ret == 0) {
            rt->cur_transport_priv = NULL;
            return 0;
        } else if (ret == 1) {
            return 0;
        } else
            rt->cur_transport_priv = NULL;
    }

redo:
    if (rt->transport == RTSP_TRANSPORT_RTP) {
        int i;
        int64_t first_queue_time = 0;
        for (i = 0; i < rt->nb_rtsp_streams; i++) {
            RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
            int64_t queue_time;
            if (!rtpctx)
                continue;
            queue_time = ff_rtp_queued_packet_time(rtpctx);
            if (queue_time && (queue_time - first_queue_time < 0 ||
                               !first_queue_time)) {
                first_queue_time = queue_time;
                first_queue_st   = rt->rtsp_streams[i];
            }
        }
        if (first_queue_time) {
            wait_end = first_queue_time + s->max_delay;
        } else {
            wait_end = 0;
            first_queue_st = NULL;
        }
    }

    /* read next RTP packet */
    if (!rt->recvbuf) {
        rt->recvbuf = av_malloc(RECVBUF_SIZE);
        if (!rt->recvbuf)
            return AVERROR(ENOMEM);
    }

    len = read_packet(s, &rtsp_st, first_queue_st, wait_end);
    if (len == AVERROR(EAGAIN) && first_queue_st &&
        rt->transport == RTSP_TRANSPORT_RTP) {
        av_log(s, AV_LOG_WARNING,
                "max delay reached. need to consume packet\n");
        rtsp_st = first_queue_st;
        ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
        goto end;
    }
    if (len < 0)
        return len;

    if (rt->transport == RTSP_TRANSPORT_RDT) {
        ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
    } else if (rt->transport == RTSP_TRANSPORT_RTP) {
        ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
        if (rtsp_st->feedback) {
            AVIOContext *pb = NULL;
            if (rt->lower_transport == RTSP_LOWER_TRANSPORT_CUSTOM)
                pb = s->pb;
            ff_rtp_send_rtcp_feedback(rtsp_st->transport_priv, rtsp_st->rtp_handle, pb);
        }
        if (ret < 0) {
            /* Either bad packet, or a RTCP packet. Check if the
             * first_rtcp_ntp_time field was initialized. */
            RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
            if (rtpctx->first_rtcp_ntp_time != AV_NOPTS_VALUE) {
                /* first_rtcp_ntp_time has been initialized for this stream,
                 * copy the same value to all other uninitialized streams,
                 * in order to map their timestamp origin to the same ntp time
                 * as this one. */
                int i;
                AVStream *st = NULL;
                if (rtsp_st->stream_index >= 0)
                    st = s->streams[rtsp_st->stream_index];
                for (i = 0; i < rt->nb_rtsp_streams; i++) {
                    RTPDemuxContext *rtpctx2 = rt->rtsp_streams[i]->transport_priv;
                    AVStream *st2 = NULL;
                    if (rt->rtsp_streams[i]->stream_index >= 0)
                        st2 = s->streams[rt->rtsp_streams[i]->stream_index];
                    if (rtpctx2 && st && st2 &&
                        rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
                        rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_time;
                        rtpctx2->rtcp_ts_offset = av_rescale_q(
                            rtpctx->rtcp_ts_offset, st->time_base,
                            st2->time_base);
                    }
                }
                // Make real NTP start time available in AVFormatContext
                if (s->start_time_realtime == AV_NOPTS_VALUE) {
                    s->start_time_realtime = av_rescale (rtpctx->first_rtcp_ntp_time - (NTP_OFFSET << 32), 1000000, 1LL << 32);
                    if (rtpctx->st) {
                        s->start_time_realtime -=
                            av_rescale (rtpctx->rtcp_ts_offset,
                                        (uint64_t) rtpctx->st->time_base.num * 1000000,
                                                   rtpctx->st->time_base.den);
                    }
                }
            }
            if (ret == -RTCP_BYE) {
                rt->nb_byes++;

                av_log(s, AV_LOG_DEBUG, "Received BYE for stream %d (%d/%d)\n",
                       rtsp_st->stream_index, rt->nb_byes, rt->nb_rtsp_streams);

                if (rt->nb_byes == rt->nb_rtsp_streams)
                    return AVERROR_EOF;
            }
        }
    } else if (CONFIG_RTPDEC && rt->ts) {
        ret = avpriv_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)
        goto redo;
    if (ret == 1)
        /* more packets may follow, so we save the RTP context */
        rt->cur_transport_priv = rtsp_st->transport_priv;

    return ret;
}
#endif /* CONFIG_RTPDEC */

#if CONFIG_SDP_DEMUXER
static int sdp_probe(AVProbeData *p1)
{
    const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;

    /* we look for a line beginning "c=IN IP" */
    while (p < p_end && *p != '\0') {
        if (sizeof("c=IN IP") - 1 < p_end - p &&
            av_strstart(p, "c=IN IP", NULL))
            return AVPROBE_SCORE_EXTENSION;

        while (p < p_end - 1 && *p != '\n') p++;
        if (++p >= p_end)
            break;
        if (*p == '\r')
            p++;
    }
    return 0;
}

static void append_source_addrs(char *buf, int size, const char *name,
                                int count, struct RTSPSource **addrs)
{
    int i;
    if (!count)
        return;
    av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->addr);
    for (i = 1; i < count; i++)
        av_strlcatf(buf, size, ",%s", addrs[i]->addr);
}

static int sdp_read_header(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    RTSPStream *rtsp_st;
    int size, i, err;
    char *content;
    char url[1024];

    if (!ff_network_init())
        return AVERROR(EIO);

    if (s->max_delay < 0) /* Not set by the caller */
        s->max_delay = DEFAULT_REORDERING_DELAY;
    if (rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)
        rt->lower_transport = RTSP_LOWER_TRANSPORT_CUSTOM;

    /* read the whole sdp file */
    /* XXX: better loading */
    content = av_malloc(SDP_MAX_SIZE);
    if (!content)
        return AVERROR(ENOMEM);
    size = avio_read(s->pb, content, SDP_MAX_SIZE - 1);
    if (size <= 0) {
        av_free(content);
        return AVERROR_INVALIDDATA;
    }
    content[size] ='\0';

    err = ff_sdp_parse(s, content);
    av_freep(&content);
    if (err) goto fail;

    /* open each RTP stream */
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
        char namebuf[50];
        rtsp_st = rt->rtsp_streams[i];

        if (!(rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)) {
            AVDictionary *opts = map_to_opts(rt);

            err = getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip,
                              sizeof(rtsp_st->sdp_ip),
                              namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
            if (err) {
                av_log(s, AV_LOG_ERROR, "getnameinfo: %s\n", gai_strerror(err));
                err = AVERROR(EIO);
                av_dict_free(&opts);
                goto fail;
            }
            ff_url_join(url, sizeof(url), "rtp", NULL,
                        namebuf, rtsp_st->sdp_port,
                        "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
                        rtsp_st->sdp_port, rtsp_st->sdp_ttl,
                        rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
                        rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);

            append_source_addrs(url, sizeof(url), "sources",
                                rtsp_st->nb_include_source_addrs,
                                rtsp_st->include_source_addrs);
            append_source_addrs(url, sizeof(url), "block",
                                rtsp_st->nb_exclude_source_addrs,
                                rtsp_st->exclude_source_addrs);
            err = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ,
                           &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);

            av_dict_free(&opts);

            if (err < 0) {
                err = AVERROR_INVALIDDATA;
                goto fail;
            }
        }
        if ((err = ff_rtsp_open_transport_ctx(s, rtsp_st)))
            goto fail;
    }
    return 0;
fail:
    ff_rtsp_close_streams(s);
    ff_network_close();
    return err;
}

static int sdp_read_close(AVFormatContext *s)
{
    ff_rtsp_close_streams(s);
    ff_network_close();
    return 0;
}

static const AVClass sdp_demuxer_class = {
    .class_name     = "SDP demuxer",
    .item_name      = av_default_item_name,
    .option         = sdp_options,
    .version        = LIBAVUTIL_VERSION_INT,
};

AVInputFormat ff_sdp_demuxer = {
    .name           = "sdp",
    .long_name      = NULL_IF_CONFIG_SMALL("SDP"),
    .priv_data_size = sizeof(RTSPState),
    .read_probe     = sdp_probe,
    .read_header    = sdp_read_header,
    .read_packet    = ff_rtsp_fetch_packet,
    .read_close     = sdp_read_close,
    .priv_class     = &sdp_demuxer_class,
};
#endif /* CONFIG_SDP_DEMUXER */

#if CONFIG_RTP_DEMUXER
static int rtp_probe(AVProbeData *p)
{
    if (av_strstart(p->filename, "rtp:", NULL))
        return AVPROBE_SCORE_MAX;
    return 0;
}

static int rtp_read_header(AVFormatContext *s)
{
    uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
    char host[500], sdp[500];
    int ret, port;
    URLContext* in = NULL;
    int payload_type;
    AVCodecParameters *par = NULL;
    struct sockaddr_storage addr;
    AVIOContext pb;
    socklen_t addrlen = sizeof(addr);
    RTSPState *rt = s->priv_data;

    if (!ff_network_init())
        return AVERROR(EIO);

    ret = ffurl_open_whitelist(&in, s->url, AVIO_FLAG_READ,
                     &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist, NULL);
    if (ret)
        goto fail;

    while (1) {
        ret = ffurl_read(in, recvbuf, sizeof(recvbuf));
        if (ret == AVERROR(EAGAIN))
            continue;
        if (ret < 0)
            goto fail;
        if (ret < 12) {
            av_log(s, AV_LOG_WARNING, "Received too short packet\n");
            continue;
        }

        if ((recvbuf[0] & 0xc0) != 0x80) {
            av_log(s, AV_LOG_WARNING, "Unsupported RTP version packet "
                                      "received\n");
            continue;
        }

        if (RTP_PT_IS_RTCP(recvbuf[1]))
            continue;

        payload_type = recvbuf[1] & 0x7f;
        break;
    }
    getsockname(ffurl_get_file_handle(in), (struct sockaddr*) &addr, &addrlen);
    ffurl_close(in);
    in = NULL;

    par = avcodec_parameters_alloc();
    if (!par) {
        ret = AVERROR(ENOMEM);
        goto fail;
    }

    if (ff_rtp_get_codec_info(par, payload_type)) {
        av_log(s, AV_LOG_ERROR, "Unable to receive RTP payload type %d "
                                "without an SDP file describing it\n",
                                 payload_type);
        goto fail;
    }
    if (par->codec_type != AVMEDIA_TYPE_DATA) {
        av_log(s, AV_LOG_WARNING, "Guessing on RTP content - if not received "
                                  "properly you need an SDP file "
                                  "describing it\n");
    }

    av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
                 NULL, 0, s->url);

    snprintf(sdp, sizeof(sdp),
             "v=0\r\nc=IN IP%d %s\r\nm=%s %d RTP/AVP %d\r\n",
             addr.ss_family == AF_INET ? 4 : 6, host,
             par->codec_type == AVMEDIA_TYPE_DATA  ? "application" :
             par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
             port, payload_type);
    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp);
    avcodec_parameters_free(&par);

    ffio_init_context(&pb, sdp, strlen(sdp), 0, NULL, NULL, NULL, NULL);
    s->pb = &pb;

    /* sdp_read_header initializes this again */
    ff_network_close();

    rt->media_type_mask = (1 << (AVMEDIA_TYPE_SUBTITLE+1)) - 1;

    ret = sdp_read_header(s);
    s->pb = NULL;
    return ret;

fail:
    avcodec_parameters_free(&par);
    if (in)
        ffurl_close(in);
    ff_network_close();
    return ret;
}

static const AVClass rtp_demuxer_class = {
    .class_name     = "RTP demuxer",
    .item_name      = av_default_item_name,
    .option         = rtp_options,
    .version        = LIBAVUTIL_VERSION_INT,
};

AVInputFormat ff_rtp_demuxer = {
    .name           = "rtp",
    .long_name      = NULL_IF_CONFIG_SMALL("RTP input"),
    .priv_data_size = sizeof(RTSPState),
    .read_probe     = rtp_probe,
    .read_header    = rtp_read_header,
    .read_packet    = ff_rtsp_fetch_packet,
    .read_close     = sdp_read_close,
    .flags          = AVFMT_NOFILE,
    .priv_class     = &rtp_demuxer_class,
};
#endif /* CONFIG_RTP_DEMUXER */
