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

        trans_pref = "RTP/AVP";



    /* default timeout: 1 minute */

    rt->timeout = 60;



    /* for each stream, make the setup request */

    /* XXX: we assume the same server is used for the control of each

     * RTSP stream */



    /* 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) {

                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;

                if (!ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE,

                               &s->interrupt_callback, NULL))

                    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]->codec->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=receive", 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 (i == 0 && rt->server_type == RTSP_SERVER_REAL && CONFIG_RTPDEC) {

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



            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]) {

                ff_url_join(url, sizeof(url), "rtp", NULL,

                            reply->transports[0].source,

                            reply->transports[0].server_port_min, "%s", options);

            } else {

                ff_url_join(url, sizeof(url), "rtp", NULL, host,

                            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;

            }

            /* Try to initialize the connection state in a

             * potential NAT router by sending dummy packets.

             * RTP/RTCP dummy packets are used for RDT, too.

             */

            if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat &&

                CONFIG_RTPDEC)

                ff_rtp_send_punch_packets(rtsp_st->rtp_handle);

            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(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,

                           &s->interrupt_callback, NULL) < 0) {

                err = AVERROR_INVALIDDATA;

                goto fail;

            }

            break;

        }

        }



        if ((err = rtsp_open_transport_ctx(s, rtsp_st)))

            goto fail;

    }



    if (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);

    return err;

}

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

        trans_pref = "RTP/AVP";



    

    rt->timeout = 60;



    

    





    





    port_off = av_get_random_seed() % ((rt->rtp_port_max - rt->rtp_port_min)/2);

    

    port_off -= port_off & 0x01;



    for (j = rt->rtp_port_min + port_off, i = 0; i < rt->nb_rtsp_streams; ++i) {

        char transport[2048];



        









        if (lower_transport == RTSP_LOWER_TRANSPORT_UDP &&

             rt->server_type == RTSP_SERVER_WMS) {

            if (i == 0) {

                

                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; 

                rtsp_st = rt->rtsp_streams[rtx];

            } else

                rtsp_st = rt->rtsp_streams[i > rtx ? i : i - 1];

        } else

            rtsp_st = rt->rtsp_streams[i];



        

        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;

            }



            

            while (j <= rt->rtp_port_max) {

                ff_url_join(buf, sizeof(buf), "rtp", NULL, host, -1,

                            "?localport=%d", j);

                

                j += 2;

                if (!ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE,

                               &s->interrupt_callback, NULL))

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

        }



        

        else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) {

            





            if (rt->server_type == RTSP_SERVER_WMS &&

                (rtsp_st->stream_index < 0 ||

                 s->streams[rtsp_st->stream_index]->codec->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=receive", 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 (i == 0 && rt->server_type == RTSP_SERVER_REAL && CONFIG_RTPDEC) {

            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  && i == 0) {

            err = 1;

            goto fail;

        } else if (reply->status_code != RTSP_STATUS_OK ||

                   reply->nb_transports != 1) {

            err = AVERROR_INVALIDDATA;

            goto fail;

        }



        

        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;

        }



        



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



            if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)

                av_strlcpy(options, "?connect=1", sizeof(options));

            

            if (reply->transports[0].source[0]) {

                ff_url_join(url, sizeof(url), "rtp", NULL,

                            reply->transports[0].source,

                            reply->transports[0].server_port_min, "%s", options);

            } else {

                ff_url_join(url, sizeof(url), "rtp", NULL, host,

                            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;

            }

            







            if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat &&

                CONFIG_RTPDEC)

                ff_rtp_send_punch_packets(rtsp_st->rtp_handle);

            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(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,

                           &s->interrupt_callback, NULL) < 0) {

                err = AVERROR_INVALIDDATA;

                goto fail;

            }

            break;

        }

        }



        if ((err = rtsp_open_transport_ctx(s, rtsp_st)))

            goto fail;

    }



    if (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);

    return err;

}

    if (reply->timeout > 0)
int FUNC_0(AVFormatContext *VAR_0, const char *VAR_1, int VAR_2,

                              int VAR_3, const char *VAR_4)

{

    RTSPState *rt = VAR_0->priv_data;

    int VAR_5 = 0, VAR_6, VAR_7, VAR_8, VAR_9 = 0, VAR_10;

    RTSPStream *rtsp_st;

    RTSPMessageHeader reply1, *reply = &reply1;

    char VAR_11[2048];

    const char *VAR_12;



    if (rt->transport == RTSP_TRANSPORT_RDT)

        VAR_12 = "x-pn-tng";

    else

        VAR_12 = "RTP/AVP";



    

    rt->timeout = 60;



    

    





    





    VAR_10 = av_get_random_seed() % ((rt->rtp_port_max - rt->rtp_port_min)/2);

    

    VAR_10 -= VAR_10 & 0x01;



    for (VAR_6 = rt->rtp_port_min + VAR_10, VAR_7 = 0; VAR_7 < rt->nb_rtsp_streams; ++VAR_7) {

        char transport[2048];



        









        if (VAR_3 == RTSP_LOWER_TRANSPORT_UDP &&

             rt->server_type == RTSP_SERVER_WMS) {

            if (VAR_7 == 0) {

                

                for (VAR_5 = 0; VAR_5 < rt->nb_rtsp_streams; VAR_5++) {

                    int len = strlen(rt->rtsp_streams[VAR_5]->control_url);

                    if (len >= 4 &&

                        !strcmp(rt->rtsp_streams[VAR_5]->control_url + len - 4,

                                "/VAR_5"))

                        break;

                }

                if (VAR_5 == rt->nb_rtsp_streams)

                    return -1; 

                rtsp_st = rt->rtsp_streams[VAR_5];

            } else

                rtsp_st = rt->rtsp_streams[VAR_7 > VAR_5 ? VAR_7 : VAR_7 - 1];

        } else

            rtsp_st = rt->rtsp_streams[VAR_7];



        

        if (VAR_3 == RTSP_LOWER_TRANSPORT_UDP) {

            char buf[256];



            if (rt->server_type == RTSP_SERVER_WMS && VAR_7 > 1) {

                VAR_2 = reply->transports[0].client_port_min;

                goto have_port;

            }



            

            while (VAR_6 <= rt->rtp_port_max) {

                ff_url_join(buf, sizeof(buf), "rtp", NULL, VAR_1, -1,

                            "?localport=%d", VAR_6);

                

                VAR_6 += 2;

                if (!ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE,

                               &VAR_0->interrupt_callback, NULL))

                    goto rtp_opened;

            }



            av_log(VAR_0, AV_LOG_ERROR, "Unable to open an input RTP VAR_2\n");

            VAR_8 = AVERROR(EIO);

            goto fail;



        rtp_opened:

            VAR_2 = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);

        have_port:

            snprintf(transport, sizeof(transport) - 1,

                     "%VAR_0/UDP;", VAR_12);

            if (rt->server_type != RTSP_SERVER_REAL)

                av_strlcat(transport, "unicast;", sizeof(transport));

            av_strlcatf(transport, sizeof(transport),

                     "client_port=%d", VAR_2);

            if (rt->transport == RTSP_TRANSPORT_RTP &&

                !(rt->server_type == RTSP_SERVER_WMS && VAR_7 > 0))

                av_strlcatf(transport, sizeof(transport), "-%d", VAR_2 + 1);

        }



        

        else if (VAR_3 == RTSP_LOWER_TRANSPORT_TCP) {

            





            if (rt->server_type == RTSP_SERVER_WMS &&

                (rtsp_st->stream_index < 0 ||

                 VAR_0->streams[rtsp_st->stream_index]->codec->codec_type ==

                    AVMEDIA_TYPE_DATA))

                continue;

            snprintf(transport, sizeof(transport) - 1,

                     "%VAR_0/TCP;", VAR_12);

            if (rt->transport != RTSP_TRANSPORT_RDT)

                av_strlcat(transport, "unicast;", sizeof(transport));

            av_strlcatf(transport, sizeof(transport),

                        "interleaved=%d-%d",

                        VAR_9, VAR_9 + 1);

            VAR_9 += 2;

        }



        else if (VAR_3 == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) {

            snprintf(transport, sizeof(transport) - 1,

                     "%VAR_0/UDP;multicast", VAR_12);

        }

        if (VAR_0->oformat) {

            av_strlcat(transport, ";mode=receive", sizeof(transport));

        } else if (rt->server_type == RTSP_SERVER_REAL ||

                   rt->server_type == RTSP_SERVER_WMS)

            av_strlcat(transport, ";mode=play", sizeof(transport));

        snprintf(VAR_11, sizeof(VAR_11),

                 "Transport: %VAR_0\r\n",

                 transport);

        if (rt->accept_dynamic_rate)

            av_strlcat(VAR_11, "x-Dynamic-Rate: 0\r\n", sizeof(VAR_11));

        if (VAR_7 == 0 && rt->server_type == RTSP_SERVER_REAL && CONFIG_RTPDEC) {

            char real_res[41], real_csum[9];

            ff_rdt_calc_response_and_checksum(real_res, real_csum,

                                              VAR_4);

            av_strlcatf(VAR_11, sizeof(VAR_11),

                        "If-Match: %VAR_0\r\n"

                        "RealChallenge2: %VAR_0, sd=%VAR_0\r\n",

                        rt->session_id, real_res, real_csum);

        }

        ff_rtsp_send_cmd(VAR_0, "SETUP", rtsp_st->control_url, VAR_11, reply, NULL);

        if (reply->status_code == 461  && VAR_7 == 0) {

            VAR_8 = 1;

            goto fail;

        } else if (reply->status_code != RTSP_STATUS_OK ||

                   reply->nb_transports != 1) {

            VAR_8 = AVERROR_INVALIDDATA;

            goto fail;

        }



        

        if (VAR_7 > 0) {

            if (reply->transports[0].VAR_3 != rt->VAR_3 ||

                reply->transports[0].transport != rt->transport) {

                VAR_8 = AVERROR_INVALIDDATA;

                goto fail;

            }

        } else {

            rt->VAR_3 = reply->transports[0].VAR_3;

            rt->transport = reply->transports[0].transport;

        }



        



        if (reply->transports[0].VAR_3 != VAR_3) {

            av_log(VAR_0, AV_LOG_ERROR, "Nonmatching transport in server reply\n");

            VAR_8 = AVERROR_INVALIDDATA;

            goto fail;

        }



        switch(reply->transports[0].VAR_3) {

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



            if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)

                av_strlcpy(options, "?connect=1", sizeof(options));

            

            if (reply->transports[0].source[0]) {

                ff_url_join(url, sizeof(url), "rtp", NULL,

                            reply->transports[0].source,

                            reply->transports[0].server_port_min, "%VAR_0", options);

            } else {

                ff_url_join(url, sizeof(url), "rtp", NULL, VAR_1,

                            reply->transports[0].server_port_min, "%VAR_0", options);

            }

            if (!(rt->server_type == RTSP_SERVER_WMS && VAR_7 > 1) &&

                ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {

                VAR_8 = AVERROR_INVALIDDATA;

                goto fail;

            }

            







            if (!(rt->server_type == RTSP_SERVER_WMS && VAR_7 > 1) && VAR_0->iformat &&

                CONFIG_RTPDEC)

                ff_rtp_send_punch_packets(rtsp_st->rtp_handle);

            break;

        }

        case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {

            char url[1024], namebuf[50], optbuf[20] = "";

            struct sockaddr_storage addr;

            int VAR_2, ttl;



            if (reply->transports[0].destination.ss_family) {

                addr      = reply->transports[0].destination;

                VAR_2      = reply->transports[0].port_min;

                ttl       = reply->transports[0].ttl;

            } else {

                addr      = rtsp_st->sdp_ip;

                VAR_2      = 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,

                        VAR_2, "%VAR_0", optbuf);

            if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,

                           &VAR_0->interrupt_callback, NULL) < 0) {

                VAR_8 = AVERROR_INVALIDDATA;

                goto fail;

            }

            break;

        }

        }



        if ((VAR_8 = rtsp_open_transport_ctx(VAR_0, rtsp_st)))

            goto fail;

    }



    if (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(VAR_0);

    return VAR_8;

}

int FUNC_0(AVFormatContext *VAR_0, const char *VAR_1, int VAR_2,
int VAR_3, const char *VAR_4)
{ RTSPState *rt = VAR_0->priv_data; int VAR_5 = 0, VAR_6, VAR_7, VAR_8, VAR_9 = 0, VAR_10; RTSPStream *rtsp_st; RTSPMessageHeader reply1, *reply = &reply1; char VAR_11[2048]; const char *VAR_12; if (rt->transport == RTSP_TRANSPORT_RDT)
VAR_12 = "x-pn-tng"; else
VAR_12 = "RTP/AVP"; rt->timeout = 60; VAR_10 = av_get_random_seed() % ((rt->rtp_port_max - rt->rtp_port_min)/2); VAR_10 -= VAR_10 & 0x01; for (VAR_6 = rt->rtp_port_min + VAR_10, VAR_7 = 0; VAR_7 < rt->nb_rtsp_streams; ++VAR_7) { char transport[2048]; if (VAR_3 == RTSP_LOWER_TRANSPORT_UDP &&
rt->server_type == RTSP_SERVER_WMS) { if (VAR_7 == 0) { for (VAR_5 = 0; VAR_5 < rt->nb_rtsp_streams; VAR_5++) { int len = strlen(rt->rtsp_streams[VAR_5]->control_url); if (len >= 4 &&
!strcmp(rt->rtsp_streams[VAR_5]->control_url + len - 4,
"/VAR_5"))
break; } if (VAR_5 == rt->nb_rtsp_streams)
return -1; rtsp_st = rt->rtsp_streams[VAR_5]; } else rtsp_st = rt->rtsp_streams[VAR_7 > VAR_5 ? VAR_7 : VAR_7 - 1]; } else rtsp_st = rt->rtsp_streams[VAR_7]; if (VAR_3 == RTSP_LOWER_TRANSPORT_UDP) { char buf[256]; if (rt->server_type == RTSP_SERVER_WMS && VAR_7 > 1) { VAR_2 = reply->transports[0].client_port_min; goto have_port; } while (VAR_6 <= rt->rtp_port_max) { ff_url_join(buf, sizeof(buf), "rtp", NULL, VAR_1, -1,
"?localport=%d", VAR_6); VAR_6 += 2; if (!ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE,
&VAR_0->interrupt_callback, NULL))
goto rtp_opened; } av_log(VAR_0, AV_LOG_ERROR, "Unable to open an input RTP VAR_2\n"); VAR_8 = AVERROR(EIO); goto fail; rtp_opened:
VAR_2 = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle); have_port:
snprintf(transport, sizeof(transport) - 1,
"%VAR_0/UDP;", VAR_12); if (rt->server_type != RTSP_SERVER_REAL)
av_strlcat(transport, "unicast;", sizeof(transport)); av_strlcatf(transport, sizeof(transport),
"client_port=%d", VAR_2); if (rt->transport == RTSP_TRANSPORT_RTP &&
!(rt->server_type == RTSP_SERVER_WMS && VAR_7 > 0))
av_strlcatf(transport, sizeof(transport), "-%d", VAR_2 + 1); } else if (VAR_3 == RTSP_LOWER_TRANSPORT_TCP) { if (rt->server_type == RTSP_SERVER_WMS &&
(rtsp_st->stream_index < 0 ||
VAR_0->streams[rtsp_st->stream_index]->codec->codec_type ==
AVMEDIA_TYPE_DATA))
continue; snprintf(transport, sizeof(transport) - 1,
"%VAR_0/TCP;", VAR_12); if (rt->transport != RTSP_TRANSPORT_RDT)
av_strlcat(transport, "unicast;", sizeof(transport)); av_strlcatf(transport, sizeof(transport),
"interleaved=%d-%d",
VAR_9, VAR_9 + 1); VAR_9 += 2; } else if (VAR_3 == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) { snprintf(transport, sizeof(transport) - 1,
"%VAR_0/UDP;multicast", VAR_12); } if (VAR_0->oformat) { av_strlcat(transport, ";mode=receive", sizeof(transport)); } else if (rt->server_type == RTSP_SERVER_REAL || rt->server_type == RTSP_SERVER_WMS)
av_strlcat(transport, ";mode=play", sizeof(transport)); snprintf(VAR_11, sizeof(VAR_11),
"Transport: %VAR_0\r\n",
transport); if (rt->accept_dynamic_rate)
av_strlcat(VAR_11, "x-Dynamic-Rate: 0\r\n", sizeof(VAR_11)); if (VAR_7 == 0 && rt->server_type == RTSP_SERVER_REAL && CONFIG_RTPDEC) { char real_res[41], real_csum[9]; ff_rdt_calc_response_and_checksum(real_res, real_csum,
VAR_4); av_strlcatf(VAR_11, sizeof(VAR_11),
"If-Match: %VAR_0\r\n"
"RealChallenge2: %VAR_0, sd=%VAR_0\r\n",
rt->session_id, real_res, real_csum); } ff_rtsp_send_cmd(VAR_0, "SETUP", rtsp_st->control_url, VAR_11, reply, NULL); if (reply->status_code == 461  && VAR_7 == 0) { VAR_8 = 1; goto fail; } else if (reply->status_code != RTSP_STATUS_OK || reply->nb_transports != 1) { VAR_8 = AVERROR_INVALIDDATA; goto fail; } if (VAR_7 > 0) { if (reply->transports[0].VAR_3 != rt->VAR_3 ||
reply->transports[0].transport != rt->transport) { VAR_8 = AVERROR_INVALIDDATA; goto fail; } } else { rt->VAR_3 = reply->transports[0].VAR_3; rt->transport = reply->transports[0].transport; } if (reply->transports[0].VAR_3 != VAR_3) { av_log(VAR_0, AV_LOG_ERROR, "Nonmatching transport in server reply\n"); VAR_8 = AVERROR_INVALIDDATA; goto fail; } switch(reply->transports[0].VAR_3) { 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] = ""; if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
av_strlcpy(options, "?connect=1", sizeof(options)); if (reply->transports[0].source[0]) { ff_url_join(url, sizeof(url), "rtp", NULL,
reply->transports[0].source,
reply->transports[0].server_port_min, "%VAR_0", options); } else { ff_url_join(url, sizeof(url), "rtp", NULL, VAR_1,
reply->transports[0].server_port_min, "%VAR_0", options); } if (!(rt->server_type == RTSP_SERVER_WMS && VAR_7 > 1) &&
ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) { VAR_8 = AVERROR_INVALIDDATA; goto fail; } if (!(rt->server_type == RTSP_SERVER_WMS && VAR_7 > 1) && VAR_0->iformat &&
CONFIG_RTPDEC)
ff_rtp_send_punch_packets(rtsp_st->rtp_handle); break; } case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: { char url[1024], namebuf[50], optbuf[20] = ""; struct sockaddr_storage addr; int VAR_2, ttl; if (reply->transports[0].destination.ss_family) { addr      = reply->transports[0].destination; VAR_2      = reply->transports[0].port_min; ttl       = reply->transports[0].ttl; } else { addr      = rtsp_st->sdp_ip; VAR_2      = 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,
VAR_2, "%VAR_0", optbuf); if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
&VAR_0->interrupt_callback, NULL) < 0) { VAR_8 = AVERROR_INVALIDDATA; goto fail; } break; } } if ((VAR_8 = rtsp_open_transport_ctx(VAR_0, rtsp_st)))
goto fail; } if (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(VAR_0); return VAR_8; }