url_split(NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
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");}