コード例 #1
0
ファイル: rtspdec.c プロジェクト: 63n/FFmpeg
static inline int check_sessionid(AVFormatContext *s,
                                  RTSPMessageHeader *request)
{
    RTSPState *rt = s->priv_data;
    unsigned char *session_id = rt->session_id;
    if (!session_id[0]) {
        av_log(s, AV_LOG_WARNING, "There is no session-id at the moment\n");
        return 0;
    }
    if (strcmp(session_id, request->session_id)) {
        av_log(s, AV_LOG_ERROR, "Unexpected session-id %s\n",
               request->session_id);
        rtsp_send_reply(s, RTSP_STATUS_SESSION, NULL, request->seq);
        return AVERROR_STREAM_NOT_FOUND;
    }
    return 0;
}
コード例 #2
0
ファイル: rtspdec.c プロジェクト: 26mansi/FFmpeg
static int rtsp_read_options(AVFormatContext *s)
{
    RTSPState *rt             = s->priv_data;
    RTSPMessageHeader request = { 0 };
    int ret                   = 0;

    /* Parsing headers */
    ret = rtsp_read_request(s, &request, "OPTIONS");
    if (ret)
        return ret;
    rt->seq++;
    /* Send Reply */
    rtsp_send_reply(s, RTSP_STATUS_OK,
                    "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, RECORD\r\n",
                    request.seq);
    return 0;
}
コード例 #3
0
ファイル: rtspdec.c プロジェクト: BradburyLab/ffmpeg-hds
static int rtsp_read_record(AVFormatContext *s)
{
    RTSPState *rt             = s->priv_data;
    RTSPMessageHeader request = { 0 };
    int ret                   = 0;
    char responseheaders[1024];

    ret = rtsp_read_request(s, &request, "RECORD");
    if (ret)
        return ret;
    ret = check_sessionid(s, &request);
    if (ret)
        return ret;
    rt->seq++;
    snprintf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
             rt->session_id);
    rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);

    rt->state = RTSP_STATE_STREAMING;
    return 0;
}
コード例 #4
0
ファイル: rtspdec.c プロジェクト: BradburyLab/ffmpeg-hds
static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl)
{
    RTSPState *rt             = s->priv_data;
    RTSPMessageHeader request = { 0 };
    int ret                   = 0;
    char url[1024];
    RTSPStream *rtsp_st;
    char responseheaders[1024];
    int localport    = -1;
    int transportidx = 0;
    int streamid     = 0;

    ret = rtsp_read_request(s, &request, "SETUP");
    if (ret)
        return ret;
    rt->seq++;
    if (!request.nb_transports) {
        av_log(s, AV_LOG_ERROR, "No transport defined in SETUP\n");
        return AVERROR_INVALIDDATA;
    }
    for (transportidx = 0; transportidx < request.nb_transports;
         transportidx++) {
        if (!request.transports[transportidx].mode_record ||
            (request.transports[transportidx].lower_transport !=
             RTSP_LOWER_TRANSPORT_UDP &&
             request.transports[transportidx].lower_transport !=
             RTSP_LOWER_TRANSPORT_TCP)) {
            av_log(s, AV_LOG_ERROR, "mode=record/receive not set or transport"
                   " protocol not supported (yet)\n");
            return AVERROR_INVALIDDATA;
        }
    }
    if (request.nb_transports > 1)
        av_log(s, AV_LOG_WARNING, "More than one transport not supported, "
               "using first of all\n");
    for (streamid = 0; streamid < rt->nb_rtsp_streams; streamid++) {
        if (!strcmp(rt->rtsp_streams[streamid]->control_url,
                    controlurl))
            break;
    }
    if (streamid == rt->nb_rtsp_streams) {
        av_log(s, AV_LOG_ERROR, "Unable to find requested track\n");
        return AVERROR_STREAM_NOT_FOUND;
    }
    rtsp_st   = rt->rtsp_streams[streamid];
    localport = rt->rtp_port_min;

    if (request.transports[0].lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
        rt->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
        if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
            rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
            return ret;
        }
        rtsp_st->interleaved_min = request.transports[0].interleaved_min;
        rtsp_st->interleaved_max = request.transports[0].interleaved_max;
        snprintf(responseheaders, sizeof(responseheaders), "Transport: "
                 "RTP/AVP/TCP;unicast;mode=receive;interleaved=%d-%d"
                 "\r\n", request.transports[0].interleaved_min,
                 request.transports[0].interleaved_max);
    } else {
        do {
            ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
            av_dlog(s, "Opening: %s", url);
            ret = ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
                             &s->interrupt_callback, NULL);
            if (ret)
                localport += 2;
        } while (ret || localport > rt->rtp_port_max);
        if (localport > rt->rtp_port_max) {
            rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
            return ret;
        }

        av_dlog(s, "Listening on: %d",
                ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle));
        if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
            rtsp_send_reply(s, RTSP_STATUS_TRANSPORT, NULL, request.seq);
            return ret;
        }

        localport = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
        snprintf(responseheaders, sizeof(responseheaders), "Transport: "
                 "RTP/AVP/UDP;unicast;mode=receive;source=%s;"
                 "client_port=%d-%d;server_port=%d-%d\r\n",
                 host, request.transports[0].client_port_min,
                 request.transports[0].client_port_max, localport,
                 localport + 1);
    }

    /* Establish sessionid if not previously set */
    /* Put this in a function? */
    /* RFC 2326: session id must be at least 8 digits */
    while (strlen(rt->session_id) < 8)
        av_strlcatf(rt->session_id, 512, "%u", av_get_random_seed());

    av_strlcatf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
                rt->session_id);
    /* Send Reply */
    rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);

    rt->state = RTSP_STATE_PAUSED;
    return 0;
}