static void rtsp_cmd_setup(HTTPContext *c, const char *url, 

                           RTSPHeader *h)

{

    FFStream *stream;

    int stream_index, port;

    char buf[1024];

    char path1[1024];

    const char *path;

    HTTPContext *rtp_c;

    RTSPTransportField *th;

    struct sockaddr_in dest_addr;

    RTSPActionServerSetup setup;

    

    /* find which url is asked */

    url_split(NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);

    path = path1;

    if (*path == '/')

        path++;



    /* now check each stream */

    for(stream = first_stream; stream != NULL; stream = stream->next) {

        if (!stream->is_feed && stream->fmt == &rtp_mux) {

            /* accept aggregate filenames only if single stream */

            if (!strcmp(path, stream->filename)) {

                if (stream->nb_streams != 1) {

                    rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);

                    return;

                }

                stream_index = 0;

                goto found;

            }

                

            for(stream_index = 0; stream_index < stream->nb_streams;

                stream_index++) {

                snprintf(buf, sizeof(buf), "%s/streamid=%d", 

                         stream->filename, stream_index);

                if (!strcmp(path, buf))

                    goto found;

            }

        }

    }

    /* no stream found */

    rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */

    return;

 found:



    /* generate session id if needed */

    if (h->session_id[0] == '\0') {

        snprintf(h->session_id, sizeof(h->session_id), 

                 "%08x%08x", (int)random(), (int)random());

    }



    /* find rtp session, and create it if none found */

    rtp_c = find_rtp_session(h->session_id);

    if (!rtp_c) {

        /* always prefer UDP */

        th = find_transport(h, RTSP_PROTOCOL_RTP_UDP);

        if (!th) {

            th = find_transport(h, RTSP_PROTOCOL_RTP_TCP);

            if (!th) {

                rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

                return;

            }

        }



        rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,

                                   th->protocol);

        if (!rtp_c) {

            rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);

            return;

        }



        /* open input stream */

        if (open_input_stream(rtp_c, "") < 0) {

            rtsp_reply_error(c, RTSP_STATUS_INTERNAL);

            return;

        }

    }

    

    /* test if stream is OK (test needed because several SETUP needs

       to be done for a given file) */

    if (rtp_c->stream != stream) {

        rtsp_reply_error(c, RTSP_STATUS_SERVICE);

        return;

    }

    

    /* test if stream is already set up */

    if (rtp_c->rtp_ctx[stream_index]) {

        rtsp_reply_error(c, RTSP_STATUS_STATE);

        return;

    }



    /* check transport */

    th = find_transport(h, rtp_c->rtp_protocol);

    if (!th || (th->protocol == RTSP_PROTOCOL_RTP_UDP && 

                th->client_port_min <= 0)) {

        rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

        return;

    }



    /* setup default options */

    setup.transport_option[0] = '\0';

    dest_addr = rtp_c->from_addr;

    dest_addr.sin_port = htons(th->client_port_min);

    

    /* add transport option if needed */

    if (ff_rtsp_callback) {

        setup.ipaddr = ntohl(dest_addr.sin_addr.s_addr);

        if (ff_rtsp_callback(RTSP_ACTION_SERVER_SETUP, rtp_c->session_id, 

                             (char *)&setup, sizeof(setup),

                             stream->rtsp_option) < 0) {

            rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

            return;

        }

        dest_addr.sin_addr.s_addr = htonl(setup.ipaddr);

    }

    

    /* setup stream */

    if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {

        rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

        return;

    }



    /* now everything is OK, so we can send the connection parameters */

    rtsp_reply_header(c, RTSP_STATUS_OK);

    /* session ID */

    url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id);



    switch(rtp_c->rtp_protocol) {

    case RTSP_PROTOCOL_RTP_UDP:

        port = rtp_get_local_port(rtp_c->rtp_handles[stream_index]);

        url_fprintf(c->pb, "Transport: RTP/AVP/UDP;unicast;"

                    "client_port=%d-%d;server_port=%d-%d",

                    th->client_port_min, th->client_port_min + 1,

                    port, port + 1);

        break;

    case RTSP_PROTOCOL_RTP_TCP:

        url_fprintf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",

                    stream_index * 2, stream_index * 2 + 1);

        break;

    default:

        break;

    }

    if (setup.transport_option[0] != '\0') {

        url_fprintf(c->pb, ";%s", setup.transport_option);

    }

    url_fprintf(c->pb, "\r\n");

    



    url_fprintf(c->pb, "\r\n");

}

static void rtsp_cmd_setup(HTTPContext *c, const char *url, 

                           RTSPHeader *h)

{

    FFStream *stream;

    int stream_index, port;

    char buf[1024];

    char path1[1024];

    const char *path;

    HTTPContext *rtp_c;

    RTSPTransportField *th;

    struct sockaddr_in dest_addr;

    RTSPActionServerSetup setup;

    

    

    url_split(NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);

    path = path1;

    if (*path == '/')

        path++;



    

    for(stream = first_stream; stream != NULL; stream = stream->next) {

        if (!stream->is_feed && stream->fmt == &rtp_mux) {

            

            if (!strcmp(path, stream->filename)) {

                if (stream->nb_streams != 1) {

                    rtsp_reply_error(c, RTSP_STATUS_AGGREGATE);

                    return;

                }

                stream_index = 0;

                goto found;

            }

                

            for(stream_index = 0; stream_index < stream->nb_streams;

                stream_index++) {

                snprintf(buf, sizeof(buf), "%s/streamid=%d", 

                         stream->filename, stream_index);

                if (!strcmp(path, buf))

                    goto found;

            }

        }

    }

    

    rtsp_reply_error(c, RTSP_STATUS_SERVICE); 

    return;

 found:



    

    if (h->session_id[0] == '\0') {

        snprintf(h->session_id, sizeof(h->session_id), 

                 "%08x%08x", (int)random(), (int)random());

    }



    

    rtp_c = find_rtp_session(h->session_id);

    if (!rtp_c) {

        

        th = find_transport(h, RTSP_PROTOCOL_RTP_UDP);

        if (!th) {

            th = find_transport(h, RTSP_PROTOCOL_RTP_TCP);

            if (!th) {

                rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

                return;

            }

        }



        rtp_c = rtp_new_connection(&c->from_addr, stream, h->session_id,

                                   th->protocol);

        if (!rtp_c) {

            rtsp_reply_error(c, RTSP_STATUS_BANDWIDTH);

            return;

        }



        

        if (open_input_stream(rtp_c, "") < 0) {

            rtsp_reply_error(c, RTSP_STATUS_INTERNAL);

            return;

        }

    }

    

    



    if (rtp_c->stream != stream) {

        rtsp_reply_error(c, RTSP_STATUS_SERVICE);

        return;

    }

    

    

    if (rtp_c->rtp_ctx[stream_index]) {

        rtsp_reply_error(c, RTSP_STATUS_STATE);

        return;

    }



    

    th = find_transport(h, rtp_c->rtp_protocol);

    if (!th || (th->protocol == RTSP_PROTOCOL_RTP_UDP && 

                th->client_port_min <= 0)) {

        rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

        return;

    }



    

    setup.transport_option[0] = '\0';

    dest_addr = rtp_c->from_addr;

    dest_addr.sin_port = htons(th->client_port_min);

    

    

    if (ff_rtsp_callback) {

        setup.ipaddr = ntohl(dest_addr.sin_addr.s_addr);

        if (ff_rtsp_callback(RTSP_ACTION_SERVER_SETUP, rtp_c->session_id, 

                             (char *)&setup, sizeof(setup),

                             stream->rtsp_option) < 0) {

            rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

            return;

        }

        dest_addr.sin_addr.s_addr = htonl(setup.ipaddr);

    }

    

    

    if (rtp_new_av_stream(rtp_c, stream_index, &dest_addr, c) < 0) {

        rtsp_reply_error(c, RTSP_STATUS_TRANSPORT);

        return;

    }



    

    rtsp_reply_header(c, RTSP_STATUS_OK);

    

    url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id);



    switch(rtp_c->rtp_protocol) {

    case RTSP_PROTOCOL_RTP_UDP:

        port = rtp_get_local_port(rtp_c->rtp_handles[stream_index]);

        url_fprintf(c->pb, "Transport: RTP/AVP/UDP;unicast;"

                    "client_port=%d-%d;server_port=%d-%d",

                    th->client_port_min, th->client_port_min + 1,

                    port, port + 1);

        break;

    case RTSP_PROTOCOL_RTP_TCP:

        url_fprintf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",

                    stream_index * 2, stream_index * 2 + 1);

        break;

    default:

        break;

    }

    if (setup.transport_option[0] != '\0') {

        url_fprintf(c->pb, ";%s", setup.transport_option);

    }

    url_fprintf(c->pb, "\r\n");

    



    url_fprintf(c->pb, "\r\n");

}

static void FUNC_0(HTTPContext *VAR_0, const char *VAR_1, 

                           RTSPHeader *VAR_2)

{

    FFStream *stream;

    int VAR_3, VAR_4;

    char VAR_5[1024];

    char VAR_6[1024];

    const char *VAR_7;

    HTTPContext *rtp_c;

    RTSPTransportField *th;

    struct sockaddr_in VAR_8;

    RTSPActionServerSetup setup;

    

    

    url_split(NULL, 0, NULL, 0, NULL, VAR_6, sizeof(VAR_6), VAR_1);

    VAR_7 = VAR_6;

    if (*VAR_7 == '/')

        VAR_7++;



    

    for(stream = first_stream; stream != NULL; stream = stream->next) {

        if (!stream->is_feed && stream->fmt == &rtp_mux) {

            

            if (!strcmp(VAR_7, stream->filename)) {

                if (stream->nb_streams != 1) {

                    rtsp_reply_error(VAR_0, RTSP_STATUS_AGGREGATE);

                    return;

                }

                VAR_3 = 0;

                goto found;

            }

                

            for(VAR_3 = 0; VAR_3 < stream->nb_streams;

                VAR_3++) {

                snprintf(VAR_5, sizeof(VAR_5), "%s/streamid=%d", 

                         stream->filename, VAR_3);

                if (!strcmp(VAR_7, VAR_5))

                    goto found;

            }

        }

    }

    

    rtsp_reply_error(VAR_0, RTSP_STATUS_SERVICE); 

    return;

 found:



    

    if (VAR_2->session_id[0] == '\0') {

        snprintf(VAR_2->session_id, sizeof(VAR_2->session_id), 

                 "%08x%08x", (int)random(), (int)random());

    }



    

    rtp_c = find_rtp_session(VAR_2->session_id);

    if (!rtp_c) {

        

        th = find_transport(VAR_2, RTSP_PROTOCOL_RTP_UDP);

        if (!th) {

            th = find_transport(VAR_2, RTSP_PROTOCOL_RTP_TCP);

            if (!th) {

                rtsp_reply_error(VAR_0, RTSP_STATUS_TRANSPORT);

                return;

            }

        }



        rtp_c = rtp_new_connection(&VAR_0->from_addr, stream, VAR_2->session_id,

                                   th->protocol);

        if (!rtp_c) {

            rtsp_reply_error(VAR_0, RTSP_STATUS_BANDWIDTH);

            return;

        }



        

        if (open_input_stream(rtp_c, "") < 0) {

            rtsp_reply_error(VAR_0, RTSP_STATUS_INTERNAL);

            return;

        }

    }

    

    



    if (rtp_c->stream != stream) {

        rtsp_reply_error(VAR_0, RTSP_STATUS_SERVICE);

        return;

    }

    

    

    if (rtp_c->rtp_ctx[VAR_3]) {

        rtsp_reply_error(VAR_0, RTSP_STATUS_STATE);

        return;

    }



    

    th = find_transport(VAR_2, rtp_c->rtp_protocol);

    if (!th || (th->protocol == RTSP_PROTOCOL_RTP_UDP && 

                th->client_port_min <= 0)) {

        rtsp_reply_error(VAR_0, RTSP_STATUS_TRANSPORT);

        return;

    }



    

    setup.transport_option[0] = '\0';

    VAR_8 = rtp_c->from_addr;

    VAR_8.sin_port = htons(th->client_port_min);

    

    

    if (ff_rtsp_callback) {

        setup.ipaddr = ntohl(VAR_8.sin_addr.s_addr);

        if (ff_rtsp_callback(RTSP_ACTION_SERVER_SETUP, rtp_c->session_id, 

                             (char *)&setup, sizeof(setup),

                             stream->rtsp_option) < 0) {

            rtsp_reply_error(VAR_0, RTSP_STATUS_TRANSPORT);

            return;

        }

        VAR_8.sin_addr.s_addr = htonl(setup.ipaddr);

    }

    

    

    if (rtp_new_av_stream(rtp_c, VAR_3, &VAR_8, VAR_0) < 0) {

        rtsp_reply_error(VAR_0, RTSP_STATUS_TRANSPORT);

        return;

    }



    

    rtsp_reply_header(VAR_0, RTSP_STATUS_OK);

    

    url_fprintf(VAR_0->pb, "Session: %s\r\n", rtp_c->session_id);



    switch(rtp_c->rtp_protocol) {

    case RTSP_PROTOCOL_RTP_UDP:

        VAR_4 = rtp_get_local_port(rtp_c->rtp_handles[VAR_3]);

        url_fprintf(VAR_0->pb, "Transport: RTP/AVP/UDP;unicast;"

                    "client_port=%d-%d;server_port=%d-%d",

                    th->client_port_min, th->client_port_min + 1,

                    VAR_4, VAR_4 + 1);

        break;

    case RTSP_PROTOCOL_RTP_TCP:

        url_fprintf(VAR_0->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",

                    VAR_3 * 2, VAR_3 * 2 + 1);

        break;

    default:

        break;

    }

    if (setup.transport_option[0] != '\0') {

        url_fprintf(VAR_0->pb, ";%s", setup.transport_option);

    }

    url_fprintf(VAR_0->pb, "\r\n");

    



    url_fprintf(VAR_0->pb, "\r\n");

}

static void FUNC_0(HTTPContext *VAR_0, const char *VAR_1,
RTSPHeader *VAR_2)
{ FFStream *stream; int VAR_3, VAR_4; char VAR_5[1024]; char VAR_6[1024]; const char *VAR_7; HTTPContext *rtp_c; RTSPTransportField *th; struct sockaddr_in VAR_8; RTSPActionServerSetup setup; url_split(NULL, 0, NULL, 0, NULL, VAR_6, sizeof(VAR_6), VAR_1); VAR_7 = VAR_6; if (*VAR_7 == '/')
VAR_7++; for(stream = first_stream; stream != NULL; stream = stream->next) { if (!stream->is_feed && stream->fmt == &rtp_mux) { if (!strcmp(VAR_7, stream->filename)) { if (stream->nb_streams != 1) { rtsp_reply_error(VAR_0, RTSP_STATUS_AGGREGATE); return; } VAR_3 = 0; goto found; } for(VAR_3 = 0; VAR_3 < stream->nb_streams; VAR_3++) { snprintf(VAR_5, sizeof(VAR_5), "%s/streamid=%d",
stream->filename, VAR_3); if (!strcmp(VAR_7, VAR_5))
goto found; } } } rtsp_reply_error(VAR_0, RTSP_STATUS_SERVICE); return; found:
if (VAR_2->session_id[0] == '\0') { snprintf(VAR_2->session_id, sizeof(VAR_2->session_id),
"%08x%08x", (int)random(), (int)random()); } rtp_c = find_rtp_session(VAR_2->session_id); if (!rtp_c) { th = find_transport(VAR_2, RTSP_PROTOCOL_RTP_UDP); if (!th) { th = find_transport(VAR_2, RTSP_PROTOCOL_RTP_TCP); if (!th) { rtsp_reply_error(VAR_0, RTSP_STATUS_TRANSPORT); return; } } rtp_c = rtp_new_connection(&VAR_0->from_addr, stream, VAR_2->session_id,
th->protocol); if (!rtp_c) { rtsp_reply_error(VAR_0, RTSP_STATUS_BANDWIDTH); return; } if (open_input_stream(rtp_c, "") < 0) { rtsp_reply_error(VAR_0, RTSP_STATUS_INTERNAL); return; } } if (rtp_c->stream != stream) { rtsp_reply_error(VAR_0, RTSP_STATUS_SERVICE); return; } if (rtp_c->rtp_ctx[VAR_3]) { rtsp_reply_error(VAR_0, RTSP_STATUS_STATE); return; } th = find_transport(VAR_2, rtp_c->rtp_protocol); if (!th || (th->protocol == RTSP_PROTOCOL_RTP_UDP &&
th->client_port_min <= 0)) { rtsp_reply_error(VAR_0, RTSP_STATUS_TRANSPORT); return; } setup.transport_option[0] = '\0'; VAR_8 = rtp_c->from_addr; VAR_8.sin_port = htons(th->client_port_min); if (ff_rtsp_callback) { setup.ipaddr = ntohl(VAR_8.sin_addr.s_addr); if (ff_rtsp_callback(RTSP_ACTION_SERVER_SETUP, rtp_c->session_id,
(char *)&setup, sizeof(setup),
stream->rtsp_option) < 0) { rtsp_reply_error(VAR_0, RTSP_STATUS_TRANSPORT); return; } VAR_8.sin_addr.s_addr = htonl(setup.ipaddr); } if (rtp_new_av_stream(rtp_c, VAR_3, &VAR_8, VAR_0) < 0) { rtsp_reply_error(VAR_0, RTSP_STATUS_TRANSPORT); return; } rtsp_reply_header(VAR_0, RTSP_STATUS_OK); url_fprintf(VAR_0->pb, "Session: %s\r\n", rtp_c->session_id); switch(rtp_c->rtp_protocol) { case RTSP_PROTOCOL_RTP_UDP:
VAR_4 = rtp_get_local_port(rtp_c->rtp_handles[VAR_3]); url_fprintf(VAR_0->pb, "Transport: RTP/AVP/UDP;unicast;" "client_port=%d-%d;server_port=%d-%d", th->client_port_min, th->client_port_min + 1,
VAR_4, VAR_4 + 1); break; case RTSP_PROTOCOL_RTP_TCP:
url_fprintf(VAR_0->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d", VAR_3 * 2, VAR_3 * 2 + 1); break; default:
break; } if (setup.transport_option[0] != '\0') { url_fprintf(VAR_0->pb, ";%s", setup.transport_option); } url_fprintf(VAR_0->pb, "\r\n"); url_fprintf(VAR_0->pb, "\r\n"); }