rtsp.c 73.7 KB
Newer Older
1
/*
2
 * RTSP/SDP client
3
 * Copyright (c) 2002 Fabrice Bellard
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13 14 15 16 17
 * 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
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

22
#include "libavutil/base64.h"
23
#include "libavutil/avstring.h"
24
#include "libavutil/intreadwrite.h"
J
Josh Allmann 已提交
25
#include "libavutil/random_seed.h"
26 27
#include "avformat.h"

28
#include <sys/time.h>
29
#if HAVE_SYS_SELECT_H
30
#include <sys/select.h>
31
#endif
32
#include <strings.h>
33
#include "internal.h"
34
#include "network.h"
35
#include "os_support.h"
J
Josh Allmann 已提交
36
#include "http.h"
37
#include "rtsp.h"
38

39
#include "rtpdec.h"
40
#include "rdt.h"
41
#include "rtpdec_formats.h"
R
Ryan Martell 已提交
42

43
//#define DEBUG
F
Fabrice Bellard 已提交
44
//#define DEBUG_RTP_TCP
45

R
Ronald S. Bultje 已提交
46
#if LIBAVFORMAT_VERSION_INT < (53 << 16)
47
int rtsp_default_protocols = (1 << RTSP_LOWER_TRANSPORT_UDP);
R
Ronald S. Bultje 已提交
48
#endif
F
Fabrice Bellard 已提交
49

R
Reimar Döffinger 已提交
50
/* Timeout values for socket select, in ms,
51 52 53 54
 * and read_packet(), in seconds  */
#define SELECT_TIMEOUT_MS 100
#define READ_PACKET_TIMEOUT_S 10
#define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / SELECT_TIMEOUT_MS
55
#define SDP_MAX_SIZE 16384
56
#define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
57

58 59
static void get_word_until_chars(char *buf, int buf_size,
                                 const char *sep, const char **pp)
60 61 62 63 64
{
    const char *p;
    char *q;

    p = *pp;
65
    p += strspn(p, SPACE_CHARS);
66 67 68 69 70 71 72 73 74 75 76
    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;
}

77 78
static void get_word_sep(char *buf, int buf_size, const char *sep,
                         const char **pp)
79
{
80 81 82
    if (**pp == '/') (*pp)++;
    get_word_until_chars(buf, buf_size, sep, pp);
}
83

84 85 86
static void get_word(char *buf, int buf_size, const char **pp)
{
    get_word_until_chars(buf, buf_size, SPACE_CHARS, pp);
87 88
}

89
/* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */
90 91
static int sdp_parse_rtpmap(AVFormatContext *s,
                            AVCodecContext *codec, RTSPStream *rtsp_st,
92
                            int payload_type, const char *p)
93 94
{
    char buf[256];
R
Romain Degez 已提交
95 96
    int i;
    AVCodec *c;
97
    const char *c_name;
98

R
Romain Degez 已提交
99
    /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and
100 101 102 103 104
     * 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);
R
Romain Degez 已提交
105
    if (payload_type >= RTP_PT_PRIVATE) {
106 107 108 109 110 111 112 113 114
        RTPDynamicProtocolHandler *handler;
        for (handler = RTPFirstDynamicPayloadHandler;
             handler; handler = handler->next) {
            if (!strcasecmp(buf, handler->enc_name) &&
                codec->codec_type == handler->codec_type) {
                codec->codec_id          = handler->codec_id;
                rtsp_st->dynamic_handler = handler;
                if (handler->open)
                    rtsp_st->dynamic_protocol_context = handler->open();
R
Romain Degez 已提交
115 116
                break;
            }
R
Ryan Martell 已提交
117
        }
118 119 120 121 122 123
        /* 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)
            codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
124
    } else {
125 126
        /* We are in a standard case
         * (from http://www.iana.org/assignments/rtp-parameters). */
R
Romain Degez 已提交
127
        /* search into AVRtpPayloadTypes[] */
128
        codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
R
Romain Degez 已提交
129 130 131 132
    }

    c = avcodec_find_decoder(codec->codec_id);
    if (c && c->name)
133
        c_name = c->name;
R
Romain Degez 已提交
134
    else
135
        c_name = "(null)";
R
Romain Degez 已提交
136

R
Ronald S. Bultje 已提交
137 138 139
    get_word_sep(buf, sizeof(buf), "/", &p);
    i = atoi(buf);
    switch (codec->codec_type) {
140
    case AVMEDIA_TYPE_AUDIO:
R
Ronald S. Bultje 已提交
141 142 143 144 145 146 147 148 149 150 151 152 153
        av_log(s, AV_LOG_DEBUG, "audio codec set to: %s\n", c_name);
        codec->sample_rate = RTSP_DEFAULT_AUDIO_SAMPLERATE;
        codec->channels = RTSP_DEFAULT_NB_AUDIO_CHANNELS;
        if (i > 0) {
            codec->sample_rate = i;
            get_word_sep(buf, sizeof(buf), "/", &p);
            i = atoi(buf);
            if (i > 0)
                codec->channels = i;
            // TODO: there is a bug here; if it is a mono stream, and
            // less than 22000Hz, faad upconverts to stereo and twice
            // the frequency.  No problem, but the sample rate is being
            // set here by the sdp line. Patch on its way. (rdm)
R
Romain Degez 已提交
154
        }
R
Ronald S. Bultje 已提交
155 156 157 158 159
        av_log(s, AV_LOG_DEBUG, "audio samplerate set to: %i\n",
               codec->sample_rate);
        av_log(s, AV_LOG_DEBUG, "audio channels set to: %i\n",
               codec->channels);
        break;
160
    case AVMEDIA_TYPE_VIDEO:
R
Ronald S. Bultje 已提交
161 162 163 164 165 166
        av_log(s, AV_LOG_DEBUG, "video codec set to: %s\n", c_name);
        break;
    default:
        break;
    }
    return 0;
167 168
}

R
Reimar Döffinger 已提交
169
/* parse the attribute line from the fmtp a line of an sdp response. This
170 171
 * is broken out as a function because it is used in rtp_h264.c, which is
 * forthcoming. */
172
int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size,
M
Martin Storsjö 已提交
173
                                char *value, int value_size)
174
{
175
    *p += strspn(*p, SPACE_CHARS);
176
    if (**p) {
177 178 179 180 181 182 183 184 185 186 187
        get_word_sep(attr, attr_size, "=", p);
        if (**p == '=')
            (*p)++;
        get_word_sep(value, value_size, ";", p);
        if (**p == ';')
            (*p)++;
        return 1;
    }
    return 0;
}

S
Stefano Sabatini 已提交
188
/** Parse a string p in the form of Range:npt=xx-xx, and determine the start
189 190 191 192 193 194 195
 *  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];

196
    p += strspn(p, SPACE_CHARS);
197
    if (!av_stristart(p, "npt=", &p))
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
        return;

    *start = AV_NOPTS_VALUE;
    *end = AV_NOPTS_VALUE;

    get_word_sep(buf, sizeof(buf), "-", &p);
    *start = parse_date(buf, 1);
    if (*p == '-') {
        p++;
        get_word_sep(buf, sizeof(buf), "-", &p);
        *end = parse_date(buf, 1);
    }
//    av_log(NULL, AV_LOG_DEBUG, "Range Start: %lld\n", *start);
//    av_log(NULL, AV_LOG_DEBUG, "Range End: %lld\n", *end);
}

M
Martin Storsjö 已提交
214 215 216 217 218 219 220 221 222 223 224 225
static int get_sockaddr(const char *buf, struct sockaddr_storage *sock)
{
    struct addrinfo hints, *ai = NULL;
    memset(&hints, 0, sizeof(hints));
    hints.ai_flags = AI_NUMERICHOST;
    if (getaddrinfo(buf, NULL, &hints, &ai))
        return -1;
    memcpy(sock, ai->ai_addr, FFMIN(sizeof(*sock), ai->ai_addrlen));
    freeaddrinfo(ai);
    return 0;
}

226 227
typedef struct SDPParseState {
    /* SDP only */
M
Martin Storsjö 已提交
228
    struct sockaddr_storage default_ip;
229 230
    int            default_ttl;
    int            skip_media;  ///< set if an unknown m= line occurs
231 232 233
} SDPParseState;

static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
234 235
                           int letter, const char *buf)
{
236
    RTSPState *rt = s->priv_data;
237 238
    char buf1[64], st_type[64];
    const char *p;
239
    enum AVMediaType codec_type;
D
Diego Pettenò 已提交
240
    int payload_type, i;
241 242
    AVStream *st;
    RTSPStream *rtsp_st;
M
Martin Storsjö 已提交
243
    struct sockaddr_storage sdp_ip;
244 245
    int ttl;

246
    dprintf(s, "sdp: %c='%s'\n", letter, buf);
247 248

    p = buf;
249 250
    if (s1->skip_media && letter != 'm')
        return;
251
    switch (letter) {
252 253 254 255 256
    case 'c':
        get_word(buf1, sizeof(buf1), &p);
        if (strcmp(buf1, "IN") != 0)
            return;
        get_word(buf1, sizeof(buf1), &p);
M
Martin Storsjö 已提交
257
        if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6"))
258 259
            return;
        get_word_sep(buf1, sizeof(buf1), "/", &p);
M
Martin Storsjö 已提交
260
        if (get_sockaddr(buf1, &sdp_ip))
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
            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 {
            st = s->streams[s->nb_streams - 1];
            rtsp_st = st->priv_data;
            rtsp_st->sdp_ip = sdp_ip;
            rtsp_st->sdp_ttl = ttl;
        }
        break;
278
    case 's':
279
        av_metadata_set2(&s->metadata, "title", p, 0);
280 281 282
        break;
    case 'i':
        if (s->nb_streams == 0) {
283
            av_metadata_set2(&s->metadata, "comment", p, 0);
284 285 286 287 288
            break;
        }
        break;
    case 'm':
        /* new stream */
289
        s1->skip_media = 0;
290 291
        get_word(st_type, sizeof(st_type), &p);
        if (!strcmp(st_type, "audio")) {
292
            codec_type = AVMEDIA_TYPE_AUDIO;
293
        } else if (!strcmp(st_type, "video")) {
294
            codec_type = AVMEDIA_TYPE_VIDEO;
295
        } else if (!strcmp(st_type, "application")) {
296
            codec_type = AVMEDIA_TYPE_DATA;
297
        } else {
298
            s1->skip_media = 1;
299 300 301 302 303
            return;
        }
        rtsp_st = av_mallocz(sizeof(RTSPStream));
        if (!rtsp_st)
            return;
304 305
        rtsp_st->stream_index = -1;
        dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st);
306 307 308 309 310 311 312 313

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

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

        get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */
314

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

319
        if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
320 321 322 323 324 325 326
            /* no corresponding stream */
        } else {
            st = av_new_stream(s, 0);
            if (!st)
                return;
            st->priv_data = rtsp_st;
            rtsp_st->stream_index = st->index;
327
            st->codec->codec_type = codec_type;
R
Romain Degez 已提交
328
            if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
329
                /* if standard payload type, we can find the codec right now */
330
                ff_rtp_get_codec_info(st->codec, rtsp_st->sdp_payload_type);
331 332
            }
        }
333
        /* put a default control url */
334
        av_strlcpy(rtsp_st->control_url, rt->control_uri,
335
                   sizeof(rtsp_st->control_url));
336 337
        break;
    case 'a':
338 339 340 341 342 343
        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 {
344 345 346 347
            char proto[32];
            /* get the control url */
            st = s->streams[s->nb_streams - 1];
            rtsp_st = st->priv_data;
348

349
            /* XXX: may need to add full url resolution */
M
Måns Rullgård 已提交
350
            av_url_split(proto, sizeof(proto), NULL, 0, NULL, 0,
M
Martin Storsjö 已提交
351
                         NULL, NULL, 0, p);
352 353
            if (proto[0] == '\0') {
                /* relative control URL */
354
                if (rtsp_st->control_url[strlen(rtsp_st->control_url)-1]!='/')
355 356 357 358 359 360 361
                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));
362
            }
363
        } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) {
364
            /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
365
            get_word(buf1, sizeof(buf1), &p);
366
            payload_type = atoi(buf1);
367
            st = s->streams[s->nb_streams - 1];
R
Ronald S. Bultje 已提交
368
            rtsp_st = st->priv_data;
369
            sdp_parse_rtpmap(s, st->codec, rtsp_st, payload_type, p);
370 371
        } else if (av_strstart(p, "fmtp:", &p) ||
                   av_strstart(p, "framesize:", &p)) {
372
            /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */
373 374 375
            // let dynamic protocol handlers have a stab at the line.
            get_word(buf1, sizeof(buf1), &p);
            payload_type = atoi(buf1);
376 377
            for (i = 0; i < s->nb_streams; i++) {
                st      = s->streams[i];
378
                rtsp_st = st->priv_data;
379 380 381 382 383
                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, buf);
384
            }
385
        } else if (av_strstart(p, "range:", &p)) {
386 387 388 389
            int64_t start, end;

            // this is so that seeking on a streamed file can work.
            rtsp_parse_range_npt(p, &start, &end);
390 391 392 393
            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;
394 395 396
        } else if (av_strstart(p, "IsRealDataType:integer;",&p)) {
            if (atoi(p) == 1)
                rt->transport = RTSP_TRANSPORT_RDT;
397 398 399 400
        } else {
            if (rt->server_type == RTSP_SERVER_WMS)
                ff_wms_parse_sdp_a_line(s, p);
            if (s->nb_streams > 0) {
R
Ronald S. Bultje 已提交
401 402 403 404 405 406
                if (rt->server_type == RTSP_SERVER_REAL)
                    ff_real_parse_sdp_a_line(s, s->nb_streams - 1, p);

                rtsp_st = s->streams[s->nb_streams - 1]->priv_data;
                if (rtsp_st->dynamic_handler &&
                    rtsp_st->dynamic_handler->parse_sdp_a_line)
407 408
                    rtsp_st->dynamic_handler->parse_sdp_a_line(s,
                        s->nb_streams - 1,
R
Ronald S. Bultje 已提交
409
                        rtsp_st->dynamic_protocol_context, buf);
410
            }
411 412 413 414 415
        }
        break;
    }
}

416
static int sdp_parse(AVFormatContext *s, const char *content)
417 418 419
{
    const char *p;
    int letter;
420 421 422 423
    /* 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
424 425
     * buffer is large.
     *
426 427
     * The Vorbis FMTP line can be up to 16KB - see xiph_parse_sdp_line
     * in rtpdec_xiph.c. */
428
    char buf[16384], *q;
429
    SDPParseState sdp_parse_state, *s1 = &sdp_parse_state;
430

431
    memset(s1, 0, sizeof(SDPParseState));
432
    p = content;
433
    for (;;) {
434
        p += strspn(p, SPACE_CHARS);
435 436 437 438 439 440 441 442 443
        letter = *p;
        if (letter == '\0')
            break;
        p++;
        if (*p != '=')
            goto next_line;
        p++;
        /* get the content */
        q = buf;
F
Fabrice Bellard 已提交
444
        while (*p != '\n' && *p != '\r' && *p != '\0') {
445 446 447 448 449
            if ((q - buf) < sizeof(buf) - 1)
                *q++ = *p;
            p++;
        }
        *q = '\0';
450
        sdp_parse_line(s, s1, letter, buf);
451 452 453 454 455 456 457 458 459
    next_line:
        while (*p != '\n' && *p != '\0')
            p++;
        if (*p == '\n')
            p++;
    }
    return 0;
}

460
/* close and free RTSP streams */
461
void ff_rtsp_close_streams(AVFormatContext *s)
462
{
463
    RTSPState *rt = s->priv_data;
464 465 466
    int i;
    RTSPStream *rtsp_st;

467
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
468 469 470
        rtsp_st = rt->rtsp_streams[i];
        if (rtsp_st) {
            if (rtsp_st->transport_priv) {
471 472 473
                if (s->oformat) {
                    AVFormatContext *rtpctx = rtsp_st->transport_priv;
                    av_write_trailer(rtpctx);
474 475 476 477 478
                    if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
                        uint8_t *ptr;
                        url_close_dyn_buf(rtpctx->pb, &ptr);
                        av_free(ptr);
                    } else {
M
Martin Storsjö 已提交
479
                        url_fclose(rtpctx->pb);
480
                    }
481 482
                    av_metadata_free(&rtpctx->streams[0]->metadata);
                    av_metadata_free(&rtpctx->metadata);
483 484 485
                    av_free(rtpctx->streams[0]);
                    av_free(rtpctx);
                } else if (rt->transport == RTSP_TRANSPORT_RDT)
486 487 488 489 490 491 492
                    ff_rdt_parse_close(rtsp_st->transport_priv);
                else
                    rtp_parse_close(rtsp_st->transport_priv);
            }
            if (rtsp_st->rtp_handle)
                url_close(rtsp_st->rtp_handle);
            if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context)
493 494
                rtsp_st->dynamic_handler->close(
                    rtsp_st->dynamic_protocol_context);
495 496 497 498 499 500 501
        }
    }
    av_free(rt->rtsp_streams);
    if (rt->asf_ctx) {
        av_close_input_stream (rt->asf_ctx);
        rt->asf_ctx = NULL;
    }
502
    av_free(rt->recvbuf);
503 504
}

505 506
static AVFormatContext *rtsp_rtp_mux_open(AVFormatContext *s, AVStream *st,
                                          URLContext *handle, int packet_size)
507
{
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
    AVFormatContext *rtpctx;
    int ret;
    AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL);

    if (!rtp_format)
        return NULL;

    /* Allocate an AVFormatContext for each output stream */
    rtpctx = avformat_alloc_context();
    if (!rtpctx)
        return NULL;

    rtpctx->oformat = rtp_format;
    if (!av_new_stream(rtpctx, 0)) {
        av_free(rtpctx);
        return NULL;
    }
    /* Copy the max delay setting; the rtp muxer reads this. */
    rtpctx->max_delay = s->max_delay;
    /* Copy other stream parameters. */
    rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio;

530
    /* Set the synchronized start time. */
531
    rtpctx->start_time_realtime = s->start_time_realtime;
532

533 534 535 536 537 538
    /* Remove the local codec, link to the original codec
     * context instead, to give the rtp muxer access to
     * codec parameters. */
    av_free(rtpctx->streams[0]->codec);
    rtpctx->streams[0]->codec = st->codec;

539
    if (handle) {
M
Martin Storsjö 已提交
540
        url_fdopen(&rtpctx->pb, handle);
541
    } else
542
        url_open_dyn_packet_buf(&rtpctx->pb, packet_size);
543 544 545
    ret = av_write_header(rtpctx);

    if (ret) {
546
        if (handle) {
M
Martin Storsjö 已提交
547
            url_fclose(rtpctx->pb);
548 549 550 551 552
        } else {
            uint8_t *ptr;
            url_close_dyn_buf(rtpctx->pb, &ptr);
            av_free(ptr);
        }
553 554 555 556 557 558 559 560 561 562
        av_free(rtpctx->streams[0]);
        av_free(rtpctx);
        return NULL;
    }

    /* Copy the RTP AVStream timebase back to the original AVStream */
    st->time_base = rtpctx->streams[0]->time_base;
    return rtpctx;
}

563
static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
564 565 566 567 568 569 570 571 572 573
{
    RTSPState *rt = s->priv_data;
    AVStream *st = NULL;

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

574
    if (s->oformat) {
575 576
        rtsp_st->transport_priv = rtsp_rtp_mux_open(s, st, rtsp_st->rtp_handle,
                                                    RTSP_TCP_MAX_PACKET_SIZE);
R
Reimar Döffinger 已提交
577
        /* Ownership of rtp_handle is passed to the rtp mux context */
578 579
        rtsp_st->rtp_handle = NULL;
    } else if (rt->transport == RTSP_TRANSPORT_RDT)
580 581 582 583 584
        rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
                                            rtsp_st->dynamic_protocol_context,
                                            rtsp_st->dynamic_handler);
    else
        rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle,
585 586 587
                                         rtsp_st->sdp_payload_type,
            (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP || !s->max_delay)
            ? 0 : RTP_REORDER_QUEUE_DEFAULT_SIZE);
588 589 590 591

    if (!rtsp_st->transport_priv) {
         return AVERROR(ENOMEM);
    } else if (rt->transport != RTSP_TRANSPORT_RDT) {
592
        if (rtsp_st->dynamic_handler) {
593 594 595 596 597 598 599 600 601
            rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
                                           rtsp_st->dynamic_protocol_context,
                                           rtsp_st->dynamic_handler);
        }
    }

    return 0;
}

M
Martin Storsjö 已提交
602
#if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER
603 604 605 606 607 608 609
static int rtsp_probe(AVProbeData *p)
{
    if (av_strstart(p->filename, "rtsp:", NULL))
        return AVPROBE_SCORE_MAX;
    return 0;
}

610 611 612 613 614 615
static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
{
    const char *p;
    int v;

    p = *pp;
616
    p += strspn(p, SPACE_CHARS);
617 618 619 620 621 622 623 624 625 626 627 628 629 630
    v = strtol(p, (char **)&p, 10);
    if (*p == '-') {
        p++;
        *min_ptr = v;
        v = strtol(p, (char **)&p, 10);
        *max_ptr = v;
    } else {
        *min_ptr = v;
        *max_ptr = v;
    }
    *pp = p;
}

/* XXX: only one transport specification is parsed */
631
static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p)
632 633 634 635 636 637 638
{
    char transport_protocol[16];
    char profile[16];
    char lower_transport[16];
    char parameter[16];
    RTSPTransportField *th;
    char buf[256];
639

640
    reply->nb_transports = 0;
641

642
    for (;;) {
643
        p += strspn(p, SPACE_CHARS);
644 645 646 647 648
        if (*p == '\0')
            break;

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

649
        get_word_sep(transport_protocol, sizeof(transport_protocol),
650
                     "/", &p);
651
        if (!strcasecmp (transport_protocol, "rtp")) {
652 653 654 655 656 657
            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);
658 659 660 661
            }
            th->transport = RTSP_TRANSPORT_RTP;
        } else if (!strcasecmp (transport_protocol, "x-pn-tng") ||
                   !strcasecmp (transport_protocol, "x-real-rdt")) {
662
            /* x-pn-tng/<protocol> */
663 664
            get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p);
            profile[0] = '\0';
665
            th->transport = RTSP_TRANSPORT_RDT;
666
        }
F
Fabrice Bellard 已提交
667
        if (!strcasecmp(lower_transport, "TCP"))
668
            th->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
669
        else
670
            th->lower_transport = RTSP_LOWER_TRANSPORT_UDP;
671

672 673 674 675 676 677 678 679 680 681 682 683 684
        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++;
685
                    rtsp_parse_range(&th->client_port_min,
686 687 688 689 690
                                     &th->client_port_max, &p);
                }
            } else if (!strcmp(parameter, "server_port")) {
                if (*p == '=') {
                    p++;
691
                    rtsp_parse_range(&th->server_port_min,
692 693 694 695 696
                                     &th->server_port_max, &p);
                }
            } else if (!strcmp(parameter, "interleaved")) {
                if (*p == '=') {
                    p++;
697
                    rtsp_parse_range(&th->interleaved_min,
698 699 700
                                     &th->interleaved_max, &p);
                }
            } else if (!strcmp(parameter, "multicast")) {
701 702
                if (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP)
                    th->lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST;
703 704 705 706 707 708 709 710 711
            } else if (!strcmp(parameter, "ttl")) {
                if (*p == '=') {
                    p++;
                    th->ttl = strtol(p, (char **)&p, 10);
                }
            } else if (!strcmp(parameter, "destination")) {
                if (*p == '=') {
                    p++;
                    get_word_sep(buf, sizeof(buf), ";,", &p);
M
Martin Storsjö 已提交
712
                    get_sockaddr(buf, &th->destination);
713
                }
714 715 716 717 718 719
            } else if (!strcmp(parameter, "source")) {
                if (*p == '=') {
                    p++;
                    get_word_sep(buf, sizeof(buf), ";,", &p);
                    av_strlcpy(th->source, buf, sizeof(th->source));
                }
720
            }
721

722 723 724 725 726 727 728 729 730 731 732 733
            while (*p != ';' && *p != '\0' && *p != ',')
                p++;
            if (*p == ';')
                p++;
        }
        if (*p == ',')
            p++;

        reply->nb_transports++;
    }
}

734 735
void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
                        HTTPAuthState *auth_state)
736 737 738 739 740
{
    const char *p;

    /* NOTE: we do case independent match for broken servers */
    p = buf;
741
    if (av_stristart(p, "Session:", &p)) {
742
        int t;
743
        get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p);
744 745 746 747
        if (av_stristart(p, ";timeout=", &p) &&
            (t = strtol(p, NULL, 10)) > 0) {
            reply->timeout = t;
        }
748
    } else if (av_stristart(p, "Content-Length:", &p)) {
749
        reply->content_length = strtol(p, NULL, 10);
750
    } else if (av_stristart(p, "Transport:", &p)) {
751
        rtsp_parse_transport(reply, p);
752
    } else if (av_stristart(p, "CSeq:", &p)) {
753
        reply->seq = strtol(p, NULL, 10);
754
    } else if (av_stristart(p, "Range:", &p)) {
755
        rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end);
756
    } else if (av_stristart(p, "RealChallenge1:", &p)) {
757
        p += strspn(p, SPACE_CHARS);
758
        av_strlcpy(reply->real_challenge, p, sizeof(reply->real_challenge));
759
    } else if (av_stristart(p, "Server:", &p)) {
760
        p += strspn(p, SPACE_CHARS);
761
        av_strlcpy(reply->server, p, sizeof(reply->server));
762 763 764
    } else if (av_stristart(p, "Notice:", &p) ||
               av_stristart(p, "X-Notice:", &p)) {
        reply->notice = strtol(p, NULL, 10);
L
Luca Barbato 已提交
765
    } else if (av_stristart(p, "Location:", &p)) {
766
        p += strspn(p, SPACE_CHARS);
L
Luca Barbato 已提交
767
        av_strlcpy(reply->location, p , sizeof(reply->location));
768
    } else if (av_stristart(p, "WWW-Authenticate:", &p) && auth_state) {
769
        p += strspn(p, SPACE_CHARS);
770 771
        ff_http_auth_handle_header(auth_state, "WWW-Authenticate", p);
    } else if (av_stristart(p, "Authentication-Info:", &p) && auth_state) {
772
        p += strspn(p, SPACE_CHARS);
773
        ff_http_auth_handle_header(auth_state, "Authentication-Info", p);
774 775 776
    }
}

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

784
    ret = url_read_complete(rt->rtsp_hd, buf, 3);
785 786
    if (ret != 3)
        return;
787
    len = AV_RB16(buf + 1);
788 789 790

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

791 792 793 794 795
    /* skip payload */
    while (len > 0) {
        len1 = len;
        if (len1 > sizeof(buf))
            len1 = sizeof(buf);
796
        ret = url_read_complete(rt->rtsp_hd, buf, len1);
797 798 799 800 801
        if (ret != len1)
            return;
        len -= len1;
    }
}
802

803
int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
M
Martin Storsjö 已提交
804 805
                       unsigned char **content_ptr,
                       int return_on_interleaved_data)
806 807 808 809 810
{
    RTSPState *rt = s->priv_data;
    char buf[4096], buf1[1024], *q;
    unsigned char ch;
    const char *p;
811
    int ret, content_length, line_count = 0;
812 813
    unsigned char *content = NULL;

814
    memset(reply, 0, sizeof(*reply));
815 816 817

    /* parse reply (XXX: use buffers) */
    rt->last_reply[0] = '\0';
818
    for (;;) {
819
        q = buf;
820
        for (;;) {
821
            ret = url_read_complete(rt->rtsp_hd, &ch, 1);
822
#ifdef DEBUG_RTP_TCP
823
            dprintf(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);
824 825
#endif
            if (ret != 1)
826
                return AVERROR_EOF;
827 828
            if (ch == '\n')
                break;
829 830
            if (ch == '$') {
                /* XXX: only parse it if first char on line ? */
831 832 833
                if (return_on_interleaved_data) {
                    return 1;
                } else
834
                    ff_rtsp_skip_packet(s);
835
            } else if (ch != '\r') {
836 837 838 839 840
                if ((q - buf) < sizeof(buf) - 1)
                    *q++ = ch;
            }
        }
        *q = '\0';
841 842 843

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

844 845 846 847 848 849 850 851 852
        /* test if last line */
        if (buf[0] == '\0')
            break;
        p = buf;
        if (line_count == 0) {
            /* get reply code */
            get_word(buf1, sizeof(buf1), &p);
            get_word(buf1, sizeof(buf1), &p);
            reply->status_code = atoi(buf1);
L
Luca Barbato 已提交
853
            av_strlcpy(reply->reason, p, sizeof(reply->reason));
854
        } else {
855
            ff_rtsp_parse_line(reply, p, &rt->auth_state);
M
Måns Rullgård 已提交
856 857
            av_strlcat(rt->last_reply, p,    sizeof(rt->last_reply));
            av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply));
858 859 860
        }
        line_count++;
    }
861

862
    if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0')
M
Måns Rullgård 已提交
863
        av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id));
864

865 866 867 868
    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);
869
        (void)url_read_complete(rt->rtsp_hd, content, content_length);
870 871 872 873
        content[content_length] = '\0';
    }
    if (content_ptr)
        *content_ptr = content;
874 875
    else
        av_free(content);
876

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

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

893
    return 0;
894 895
}

896
int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
M
Martin Storsjö 已提交
897 898 899 900
                                        const char *method, const char *url,
                                        const char *headers,
                                        const unsigned char *send_content,
                                        int send_content_length)
901 902
{
    RTSPState *rt = s->priv_data;
J
Josh Allmann 已提交
903 904
    char buf[4096], *out_buf;
    char base64buf[AV_BASE64_SIZE(sizeof(buf))];
905

J
Josh Allmann 已提交
906 907
    /* Add in RTSP headers */
    out_buf = buf;
908
    rt->seq++;
909 910 911
    snprintf(buf, sizeof(buf), "%s %s RTSP/1.0\r\n", method, url);
    if (headers)
        av_strlcat(buf, headers, sizeof(buf));
912
    av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", rt->seq);
913 914
    if (rt->session_id[0] != '\0' && (!headers ||
        !strstr(headers, "\nIf-Match:"))) {
915
        av_strlcatf(buf, sizeof(buf), "Session: %s\r\n", rt->session_id);
916
    }
917 918 919 920 921 922 923
    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);
    }
924 925
    if (send_content_length > 0 && send_content)
        av_strlcatf(buf, sizeof(buf), "Content-Length: %d\r\n", send_content_length);
926
    av_strlcat(buf, "\r\n", sizeof(buf));
927

J
Josh Allmann 已提交
928 929 930 931 932 933
    /* base64 encode rtsp if tunneling */
    if (rt->control_transport == RTSP_MODE_TUNNEL) {
        av_base64_encode(base64buf, sizeof(base64buf), buf, strlen(buf));
        out_buf = base64buf;
    }

934 935
    dprintf(s, "Sending:\n%s--\n", buf);

J
Josh Allmann 已提交
936 937 938 939 940 941 942
    url_write(rt->rtsp_hd_out, out_buf, strlen(out_buf));
    if (send_content_length > 0 && send_content) {
        if (rt->control_transport == RTSP_MODE_TUNNEL) {
            av_log(s, AV_LOG_ERROR, "tunneling of RTSP requests "
                                    "with content data not supported\n");
            return AVERROR_PATCHWELCOME;
        }
943
        url_write(rt->rtsp_hd_out, send_content, send_content_length);
J
Josh Allmann 已提交
944
    }
945
    rt->last_cmd_time = av_gettime();
946 947

    return 0;
948 949
}

950
int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method,
M
Martin Storsjö 已提交
951
                           const char *url, const char *headers)
952
{
953
    return ff_rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
954 955
}

956
int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url,
M
Martin Storsjö 已提交
957 958
                     const char *headers, RTSPMessageHeader *reply,
                     unsigned char **content_ptr)
959
{
960
    return ff_rtsp_send_cmd_with_content(s, method, url, headers, reply,
M
Martin Storsjö 已提交
961
                                         content_ptr, NULL, 0);
962 963
}

964
int ff_rtsp_send_cmd_with_content(AVFormatContext *s,
M
Martin Storsjö 已提交
965 966 967 968 969 970
                                  const char *method, const char *url,
                                  const char *header,
                                  RTSPMessageHeader *reply,
                                  unsigned char **content_ptr,
                                  const unsigned char *send_content,
                                  int send_content_length)
971
{
972 973
    RTSPState *rt = s->priv_data;
    HTTPAuthType cur_auth_type;
974
    int ret;
975 976 977

retry:
    cur_auth_type = rt->auth_state.auth_type;
978
    if ((ret = ff_rtsp_send_cmd_with_content_async(s, method, url, header,
M
Martin Storsjö 已提交
979 980
                                                   send_content,
                                                   send_content_length)))
981
        return ret;
982

983 984
    if ((ret = ff_rtsp_read_reply(s, reply, content_ptr, 0) ) < 0)
        return ret;
985 986 987 988

    if (reply->status_code == 401 && cur_auth_type == HTTP_AUTH_NONE &&
        rt->auth_state.auth_type != HTTP_AUTH_NONE)
        goto retry;
989

990
    if (reply->status_code > 400){
L
Luca Barbato 已提交
991
        av_log(s, AV_LOG_ERROR, "method %s failed: %d%s\n",
992
               method,
L
Luca Barbato 已提交
993 994
               reply->status_code,
               reply->reason);
995 996 997
        av_log(s, AV_LOG_DEBUG, "%s\n", rt->last_reply);
    }

998
    return 0;
999 1000
}

1001
/**
B
Benoit Fouet 已提交
1002
 * @return 0 on success, <0 on error, 1 if protocol is unavailable.
1003
 */
1004 1005
static int make_setup_request(AVFormatContext *s, const char *host, int port,
                              int lower_transport, const char *real_challenge)
1006 1007
{
    RTSPState *rt = s->priv_data;
1008
    int rtx, j, i, err, interleave = 0;
1009
    RTSPStream *rtsp_st;
1010
    RTSPMessageHeader reply1, *reply = &reply1;
1011
    char cmd[2048];
1012 1013
    const char *trans_pref;

1014
    if (rt->transport == RTSP_TRANSPORT_RDT)
1015 1016 1017
        trans_pref = "x-pn-tng";
    else
        trans_pref = "RTP/AVP";
1018

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

1022 1023
    /* for each stream, make the setup request */
    /* XXX: we assume the same server is used for the control of each
1024
     * RTSP stream */
R
Romain Degez 已提交
1025

1026
    for (j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) {
1027 1028
        char transport[2048];

1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
        /**
         * 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 &&
1041 1042
                        !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4,
                                "/rtx"))
1043 1044 1045 1046 1047 1048 1049 1050
                        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
R
Ronald S. Bultje 已提交
1051
            rtsp_st = rt->rtsp_streams[i];
1052 1053

        /* RTP/UDP */
1054
        if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
F
Fabrice Bellard 已提交
1055 1056
            char buf[256];

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

F
Fabrice Bellard 已提交
1062
            /* first try in specified port range */
R
Romain Degez 已提交
1063
            if (RTSP_RTP_PORT_MIN != 0) {
1064
                while (j <= RTSP_RTP_PORT_MAX) {
1065 1066
                    ff_url_join(buf, sizeof(buf), "rtp", NULL, host, -1,
                                "?localport=%d", j);
1067 1068 1069
                    /* we will use two ports per rtp stream (rtp and rtcp) */
                    j += 2;
                    if (url_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0)
F
Fabrice Bellard 已提交
1070 1071
                        goto rtp_opened;
                }
1072
            }
F
Fabrice Bellard 已提交
1073

1074 1075 1076 1077 1078 1079 1080
#if 0
            /* then try on any port */
            if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) {
                err = AVERROR_INVALIDDATA;
                goto fail;
            }
#endif
F
Fabrice Bellard 已提交
1081 1082

        rtp_opened:
1083
            port = rtp_get_local_port(rtsp_st->rtp_handle);
1084
        have_port:
1085
            snprintf(transport, sizeof(transport) - 1,
1086 1087 1088 1089 1090
                     "%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);
1091 1092
            if (rt->transport == RTSP_TRANSPORT_RTP &&
                !(rt->server_type == RTSP_SERVER_WMS && i > 0))
1093
                av_strlcatf(transport, sizeof(transport), "-%d", port + 1);
1094 1095 1096
        }

        /* RTP/TCP */
1097
        else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
1098 1099 1100 1101
            /** 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 &&
1102
                s->streams[rtsp_st->stream_index]->codec->codec_type ==
1103
                    AVMEDIA_TYPE_DATA)
1104
                continue;
1105
            snprintf(transport, sizeof(transport) - 1,
1106 1107 1108 1109 1110 1111 1112
                     "%s/TCP;", trans_pref);
            if (rt->server_type == RTSP_SERVER_WMS)
                av_strlcat(transport, "unicast;", sizeof(transport));
            av_strlcatf(transport, sizeof(transport),
                        "interleaved=%d-%d",
                        interleave, interleave + 1);
            interleave += 2;
1113 1114
        }

1115
        else if (lower_transport == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) {
1116
            snprintf(transport, sizeof(transport) - 1,
1117
                     "%s/UDP;multicast", trans_pref);
1118
        }
1119 1120 1121
        if (s->oformat) {
            av_strlcat(transport, ";mode=receive", sizeof(transport));
        } else if (rt->server_type == RTSP_SERVER_REAL ||
1122
                   rt->server_type == RTSP_SERVER_WMS)
1123
            av_strlcat(transport, ";mode=play", sizeof(transport));
1124
        snprintf(cmd, sizeof(cmd),
F
Fabrice Bellard 已提交
1125
                 "Transport: %s\r\n",
1126
                 transport);
1127
        if (i == 0 && rt->server_type == RTSP_SERVER_REAL) {
1128 1129 1130 1131 1132 1133 1134 1135
            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);
        }
1136
        ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL);
1137 1138 1139
        if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) {
            err = 1;
            goto fail;
1140 1141
        } else if (reply->status_code != RTSP_STATUS_OK ||
                   reply->nb_transports != 1) {
1142 1143 1144 1145 1146 1147
            err = AVERROR_INVALIDDATA;
            goto fail;
        }

        /* XXX: same protocol for all streams is required */
        if (i > 0) {
1148 1149
            if (reply->transports[0].lower_transport != rt->lower_transport ||
                reply->transports[0].transport != rt->transport) {
1150 1151 1152 1153
                err = AVERROR_INVALIDDATA;
                goto fail;
            }
        } else {
1154
            rt->lower_transport = reply->transports[0].lower_transport;
1155
            rt->transport = reply->transports[0].transport;
1156 1157
        }

R
Reinhard Tartler 已提交
1158
        /* close RTP connection if not chosen */
1159 1160
        if (reply->transports[0].lower_transport != RTSP_LOWER_TRANSPORT_UDP &&
            (lower_transport == RTSP_LOWER_TRANSPORT_UDP)) {
1161 1162
            url_close(rtsp_st->rtp_handle);
            rtsp_st->rtp_handle = NULL;
1163 1164
        }

1165 1166
        switch(reply->transports[0].lower_transport) {
        case RTSP_LOWER_TRANSPORT_TCP:
1167 1168 1169
            rtsp_st->interleaved_min = reply->transports[0].interleaved_min;
            rtsp_st->interleaved_max = reply->transports[0].interleaved_max;
            break;
1170

1171 1172 1173
        case RTSP_LOWER_TRANSPORT_UDP: {
            char url[1024];

1174 1175 1176 1177 1178 1179
            /* 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, NULL);
            } else {
R
Ronald S. Bultje 已提交
1180 1181
                ff_url_join(url, sizeof(url), "rtp", NULL, host,
                            reply->transports[0].server_port_min, NULL);
1182
            }
1183 1184 1185 1186
            if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
                rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
                err = AVERROR_INVALIDDATA;
                goto fail;
1187
            }
1188 1189 1190 1191
            /* Try to initialize the connection state in a
             * potential NAT router by sending dummy packets.
             * RTP/RTCP dummy packets are used for RDT, too.
             */
1192
            if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat)
1193
                rtp_send_punch_packets(rtsp_st->rtp_handle);
1194
            break;
1195 1196
        }
        case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
M
Martin Storsjö 已提交
1197 1198
            char url[1024], namebuf[50];
            struct sockaddr_storage addr;
1199 1200
            int port, ttl;

M
Martin Storsjö 已提交
1201 1202
            if (reply->transports[0].destination.ss_family) {
                addr      = reply->transports[0].destination;
1203 1204 1205
                port      = reply->transports[0].port_min;
                ttl       = reply->transports[0].ttl;
            } else {
M
Martin Storsjö 已提交
1206
                addr      = rtsp_st->sdp_ip;
1207 1208 1209
                port      = rtsp_st->sdp_port;
                ttl       = rtsp_st->sdp_ttl;
            }
M
Martin Storsjö 已提交
1210 1211 1212
            getnameinfo((struct sockaddr*) &addr, sizeof(addr),
                        namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
            ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
1213
                        port, "?ttl=%d", ttl);
1214 1215 1216
            if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
                err = AVERROR_INVALIDDATA;
                goto fail;
1217 1218 1219
            }
            break;
        }
1220
        }
R
Romain Degez 已提交
1221

1222
        if ((err = rtsp_open_transport_ctx(s, rtsp_st)))
1223
            goto fail;
1224 1225
    }

1226 1227 1228
    if (reply->timeout > 0)
        rt->timeout = reply->timeout;

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

1232 1233 1234
    return 0;

fail:
1235
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
1236 1237 1238 1239 1240
        if (rt->rtsp_streams[i]->rtp_handle) {
            url_close(rt->rtsp_streams[i]->rtp_handle);
            rt->rtsp_streams[i]->rtp_handle = NULL;
        }
    }
1241 1242 1243
    return err;
}

1244 1245 1246 1247
static int rtsp_read_play(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    RTSPMessageHeader reply1, *reply = &reply1;
1248
    int i;
1249 1250 1251
    char cmd[1024];

    av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
1252
    rt->nb_byes = 0;
1253 1254 1255

    if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
        if (rt->state == RTSP_STATE_PAUSED) {
1256
            cmd[0] = 0;
1257 1258 1259 1260 1261
        } else {
            snprintf(cmd, sizeof(cmd),
                     "Range: npt=%0.3f-\r\n",
                     (double)rt->seek_timestamp / AV_TIME_BASE);
        }
1262
        ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
1263 1264 1265
        if (reply->status_code != RTSP_STATUS_OK) {
            return -1;
        }
M
Martin Storsjö 已提交
1266
        if (rt->transport == RTSP_TRANSPORT_RTP) {
1267 1268 1269 1270
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
                RTSPStream *rtsp_st = rt->rtsp_streams[i];
                RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
                AVStream *st = NULL;
1271 1272
                if (!rtpctx)
                    continue;
1273 1274
                if (rtsp_st->stream_index >= 0)
                    st = s->streams[rtsp_st->stream_index];
1275
                ff_rtp_reset_packet_queue(rtpctx);
1276
                if (reply->range_start != AV_NOPTS_VALUE) {
M
Martin Storsjö 已提交
1277 1278 1279 1280 1281 1282
                    rtpctx->last_rtcp_ntp_time  = AV_NOPTS_VALUE;
                    rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
                    if (st)
                        rtpctx->range_start_offset =
                            av_rescale_q(reply->range_start, AV_TIME_BASE_Q,
                                         st->time_base);
1283
                }
1284 1285
            }
        }
1286
    }
1287
    rt->state = RTSP_STATE_STREAMING;
1288 1289 1290
    return 0;
}

1291
static int rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply)
1292 1293 1294 1295 1296 1297 1298 1299
{
    RTSPState *rt = s->priv_data;
    char cmd[1024];
    unsigned char *content = NULL;
    int ret;

    /* describe the stream */
    snprintf(cmd, sizeof(cmd),
1300
             "Accept: application/sdp\r\n");
1301 1302 1303 1304 1305 1306 1307 1308 1309
    if (rt->server_type == RTSP_SERVER_REAL) {
        /**
         * The Require: attribute is needed for proper streaming from
         * Realmedia servers.
         */
        av_strlcat(cmd,
                   "Require: com.real.retain-entity-for-setup\r\n",
                   sizeof(cmd));
    }
1310
    ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
1311 1312 1313 1314 1315 1316 1317
    if (!content)
        return AVERROR_INVALIDDATA;
    if (reply->status_code != RTSP_STATUS_OK) {
        av_freep(&content);
        return AVERROR_INVALIDDATA;
    }

M
Martin Storsjö 已提交
1318
    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
1319 1320 1321 1322 1323 1324 1325 1326 1327
    /* now we got the SDP description, we parse it */
    ret = sdp_parse(s, (const char *)content);
    av_freep(&content);
    if (ret < 0)
        return AVERROR_INVALIDDATA;

    return 0;
}

1328
static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr)
1329 1330 1331 1332 1333
{
    RTSPState *rt = s->priv_data;
    RTSPMessageHeader reply1, *reply = &reply1;
    int i;
    char *sdp;
1334
    AVFormatContext sdp_ctx, *ctx_array[1];
1335

1336
    s->start_time_realtime = av_gettime();
1337 1338

    /* Announce the stream */
1339
    sdp = av_mallocz(SDP_MAX_SIZE);
1340 1341
    if (sdp == NULL)
        return AVERROR(ENOMEM);
1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357
    /* We create the SDP based on the RTSP AVFormatContext where we
     * aren't allowed to change the filename field. (We create the SDP
     * based on the RTSP context since the contexts for the RTP streams
     * don't exist yet.) In order to specify a custom URL with the actual
     * peer IP instead of the originally specified hostname, we create
     * a temporary copy of the AVFormatContext, where the custom URL is set.
     *
     * FIXME: Create the SDP without copying the AVFormatContext.
     * This either requires setting up the RTP stream AVFormatContexts
     * already here (complicating things immensely) or getting a more
     * flexible SDP creation interface.
     */
    sdp_ctx = *s;
    ff_url_join(sdp_ctx.filename, sizeof(sdp_ctx.filename),
                "rtsp", NULL, addr, -1, NULL);
    ctx_array[0] = &sdp_ctx;
1358
    if (avf_sdp_create(ctx_array, 1, sdp, SDP_MAX_SIZE)) {
1359 1360 1361
        av_free(sdp);
        return AVERROR_INVALIDDATA;
    }
1362
    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp);
1363 1364 1365
    ff_rtsp_send_cmd_with_content(s, "ANNOUNCE", rt->control_uri,
                                  "Content-Type: application/sdp\r\n",
                                  reply, NULL, sdp, strlen(sdp));
1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382
    av_free(sdp);
    if (reply->status_code != RTSP_STATUS_OK)
        return AVERROR_INVALIDDATA;

    /* Set up the RTSPStreams for each AVStream */
    for (i = 0; i < s->nb_streams; i++) {
        RTSPStream *rtsp_st;
        AVStream *st = s->streams[i];

        rtsp_st = av_mallocz(sizeof(RTSPStream));
        if (!rtsp_st)
            return AVERROR(ENOMEM);
        dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st);

        st->priv_data = rtsp_st;
        rtsp_st->stream_index = i;

1383
        av_strlcpy(rtsp_st->control_url, rt->control_uri, sizeof(rtsp_st->control_url));
1384 1385 1386 1387 1388 1389 1390 1391
        /* Note, this must match the relative uri set in the sdp content */
        av_strlcatf(rtsp_st->control_url, sizeof(rtsp_st->control_url),
                    "/streamid=%d", i);
    }

    return 0;
}

1392 1393 1394 1395 1396
void ff_rtsp_close_connections(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    if (rt->rtsp_hd_out != rt->rtsp_hd) url_close(rt->rtsp_hd_out);
    url_close(rt->rtsp_hd);
1397
    rt->rtsp_hd = rt->rtsp_hd_out = NULL;
1398 1399
}

1400
int ff_rtsp_connect(AVFormatContext *s)
1401 1402
{
    RTSPState *rt = s->priv_data;
1403 1404
    char host[1024], path[1024], tcpname[1024], cmd[2048], auth[128];
    char *option_list, *option, *filename;
1405
    int port, err, tcp_fd;
1406
    RTSPMessageHeader reply1 = {0}, *reply = &reply1;
1407
    int lower_transport_mask = 0;
1408
    char real_challenge[64];
1409 1410
    struct sockaddr_storage peer;
    socklen_t peer_len = sizeof(peer);
1411 1412 1413

    if (!ff_network_init())
        return AVERROR(EIO);
1414
redirect:
J
Josh Allmann 已提交
1415
    rt->control_transport = RTSP_MODE_PLAIN;
1416
    /* extract hostname and port */
M
Måns Rullgård 已提交
1417
    av_url_split(NULL, 0, auth, sizeof(auth),
M
Martin Storsjö 已提交
1418
                 host, sizeof(host), &port, path, sizeof(path), s->filename);
1419
    if (*auth) {
1420
        av_strlcpy(rt->auth, auth, sizeof(rt->auth));
1421
    }
1422 1423 1424 1425
    if (port < 0)
        port = RTSP_DEFAULT_PORT;

    /* search for options */
1426
    option_list = strrchr(path, '?');
1427
    if (option_list) {
1428 1429 1430
        /* Strip out the RTSP specific options, write out the rest of
         * the options back into the same string. */
        filename = option_list;
1431
        while (option_list) {
1432
            /* move the option pointer */
1433
            option = ++option_list;
1434 1435
            option_list = strchr(option_list, '&');
            if (option_list)
1436 1437
                *option_list = 0;

1438
            /* handle the options */
1439
            if (!strcmp(option, "udp")) {
1440
                lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_UDP);
1441
            } else if (!strcmp(option, "multicast")) {
1442
                lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_UDP_MULTICAST);
1443
            } else if (!strcmp(option, "tcp")) {
1444
                lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP);
J
Josh Allmann 已提交
1445 1446 1447
            } else if(!strcmp(option, "http")) {
                lower_transport_mask |= (1<< RTSP_LOWER_TRANSPORT_TCP);
                rt->control_transport = RTSP_MODE_TUNNEL;
1448
            } else {
1449 1450 1451 1452 1453
                /* Write options back into the buffer, using memmove instead
                 * of strcpy since the strings may overlap. */
                int len = strlen(option);
                memmove(++filename, option, len);
                filename += len;
1454 1455
                if (option_list) *filename = '&';
            }
1456
        }
1457
        *filename = 0;
1458 1459
    }

1460
    if (!lower_transport_mask)
1461
        lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
1462

1463
    if (s->oformat) {
1464 1465 1466
        /* Only UDP or TCP - UDP multicast isn't supported. */
        lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_UDP) |
                                (1 << RTSP_LOWER_TRANSPORT_TCP);
J
Josh Allmann 已提交
1467
        if (!lower_transport_mask || rt->control_transport == RTSP_MODE_TUNNEL) {
1468
            av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, "
1469
                                    "only UDP and TCP are supported for output.\n");
1470 1471 1472 1473 1474
            err = AVERROR(EINVAL);
            goto fail;
        }
    }

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

J
Josh Allmann 已提交
1481 1482 1483 1484 1485 1486
    if (rt->control_transport == RTSP_MODE_TUNNEL) {
        /* set up initial handshake for tunneling */
        char httpname[1024];
        char sessioncookie[17];
        char headers[1024];

1487
        ff_url_join(httpname, sizeof(httpname), "http", auth, host, port, "%s", path);
J
Josh Allmann 已提交
1488 1489 1490 1491
        snprintf(sessioncookie, sizeof(sessioncookie), "%08x%08x",
                 av_get_random_seed(), av_get_random_seed());

        /* GET requests */
1492
        if (url_alloc(&rt->rtsp_hd, httpname, URL_RDONLY) < 0) {
J
Josh Allmann 已提交
1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503
            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);
1504
        ff_http_set_headers(rt->rtsp_hd, headers);
J
Josh Allmann 已提交
1505 1506

        /* complete the connection */
1507
        if (url_connect(rt->rtsp_hd)) {
J
Josh Allmann 已提交
1508 1509 1510 1511 1512
            err = AVERROR(EIO);
            goto fail;
        }

        /* POST requests */
1513
        if (url_alloc(&rt->rtsp_hd_out, httpname, URL_WRONLY) < 0 ) {
J
Josh Allmann 已提交
1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526
            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);
1527 1528
        ff_http_set_headers(rt->rtsp_hd_out, headers);
        ff_http_set_chunked_transfer_encoding(rt->rtsp_hd_out, 0);
J
Josh Allmann 已提交
1529

1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547
        /* 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);

1548 1549 1550 1551 1552
        /* complete the connection */
        if (url_connect(rt->rtsp_hd_out)) {
            err = AVERROR(EIO);
            goto fail;
        }
J
Josh Allmann 已提交
1553
    } else {
1554
        /* open the tcp connection */
J
Josh Allmann 已提交
1555
        ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL);
1556
        if (url_open(&rt->rtsp_hd, tcpname, URL_RDWR) < 0) {
J
Josh Allmann 已提交
1557 1558 1559
            err = AVERROR(EIO);
            goto fail;
        }
1560
        rt->rtsp_hd_out = rt->rtsp_hd;
J
Josh Allmann 已提交
1561
    }
1562 1563
    rt->seq = 0;

1564
    tcp_fd = url_get_file_handle(rt->rtsp_hd);
1565 1566 1567 1568 1569
    if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) {
        getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host),
                    NULL, 0, NI_NUMERICHOST);
    }

1570 1571
    /* request options supported by the server; this also detects server
     * type */
1572
    for (rt->server_type = RTSP_SERVER_RTP;;) {
1573
        cmd[0] = 0;
1574
        if (rt->server_type == RTSP_SERVER_REAL)
1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589
            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.
                        * @param CompanyID is a 16-byte ID in base64
                        * @param ClientChallenge is a 16-byte ID in hex
                        */
                       "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));
1590
        ff_rtsp_send_cmd(s, "OPTIONS", rt->control_uri, cmd, reply, NULL);
1591 1592 1593 1594 1595 1596
        if (reply->status_code != RTSP_STATUS_OK) {
            err = AVERROR_INVALIDDATA;
            goto fail;
        }

        /* detect server type if not standard-compliant RTP */
1597 1598
        if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
            rt->server_type = RTSP_SERVER_REAL;
1599
            continue;
1600 1601
        } else if (!strncasecmp(reply->server, "WMServer/", 9)) {
            rt->server_type = RTSP_SERVER_WMS;
1602
        } else if (rt->server_type == RTSP_SERVER_REAL)
1603 1604 1605 1606
            strcpy(real_challenge, reply->real_challenge);
        break;
    }

1607
    if (s->iformat)
1608
        err = rtsp_setup_input_streams(s, reply);
1609
    else
1610
        err = rtsp_setup_output_streams(s, host);
1611
    if (err)
1612 1613
        goto fail;

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

1618
        err = make_setup_request(s, host, port, lower_transport,
1619
                                 rt->server_type == RTSP_SERVER_REAL ?
1620
                                     real_challenge : NULL);
1621
        if (err < 0)
1622
            goto fail;
1623 1624
        lower_transport_mask &= ~(1 << lower_transport);
        if (lower_transport_mask == 0 && err == 1) {
1625
            err = FF_NETERROR(EPROTONOSUPPORT);
1626 1627 1628
            goto fail;
        }
    } while (err);
1629

1630
    rt->state = RTSP_STATE_IDLE;
1631
    rt->seek_timestamp = 0; /* default is to start stream at position zero */
1632 1633
    return 0;
 fail:
1634
    ff_rtsp_close_streams(s);
1635
    ff_rtsp_close_connections(s);
1636
    if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) {
L
Luca Barbato 已提交
1637 1638 1639 1640 1641 1642
        av_strlcpy(s->filename, reply->location, sizeof(s->filename));
        av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n",
               reply->status_code,
               s->filename);
        goto redirect;
    }
1643
    ff_network_close();
1644 1645
    return err;
}
1646
#endif /* CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER */
1647

R
Ronald S. Bultje 已提交
1648
static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
1649
                           uint8_t *buf, int buf_size, int64_t wait_end)
R
Ronald S. Bultje 已提交
1650 1651 1652 1653
{
    RTSPState *rt = s->priv_data;
    RTSPStream *rtsp_st;
    fd_set rfds;
1654
    int fd, fd_rtcp, fd_max, n, i, ret, tcp_fd, timeout_cnt = 0;
R
Ronald S. Bultje 已提交
1655 1656
    struct timeval tv;

1657
    for (;;) {
R
Ronald S. Bultje 已提交
1658 1659
        if (url_interrupt_cb())
            return AVERROR(EINTR);
1660 1661
        if (wait_end && wait_end - av_gettime() < 0)
            return AVERROR(EAGAIN);
R
Ronald S. Bultje 已提交
1662 1663 1664 1665 1666 1667 1668 1669
        FD_ZERO(&rfds);
        if (rt->rtsp_hd) {
            tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd);
            FD_SET(tcp_fd, &rfds);
        } else {
            fd_max = 0;
            tcp_fd = -1;
        }
1670
        for (i = 0; i < rt->nb_rtsp_streams; i++) {
R
Ronald S. Bultje 已提交
1671 1672 1673
            rtsp_st = rt->rtsp_streams[i];
            if (rtsp_st->rtp_handle) {
                fd = url_get_file_handle(rtsp_st->rtp_handle);
1674 1675 1676
                fd_rtcp = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
                if (FFMAX(fd, fd_rtcp) > fd_max)
                    fd_max = FFMAX(fd, fd_rtcp);
R
Ronald S. Bultje 已提交
1677
                FD_SET(fd, &rfds);
1678
                FD_SET(fd_rtcp, &rfds);
R
Ronald S. Bultje 已提交
1679 1680 1681
            }
        }
        tv.tv_sec = 0;
1682
        tv.tv_usec = SELECT_TIMEOUT_MS * 1000;
R
Ronald S. Bultje 已提交
1683 1684
        n = select(fd_max + 1, &rfds, NULL, NULL, &tv);
        if (n > 0) {
1685
            timeout_cnt = 0;
1686
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
R
Ronald S. Bultje 已提交
1687 1688 1689
                rtsp_st = rt->rtsp_streams[i];
                if (rtsp_st->rtp_handle) {
                    fd = url_get_file_handle(rtsp_st->rtp_handle);
1690 1691
                    fd_rtcp = rtp_get_rtcp_file_handle(rtsp_st->rtp_handle);
                    if (FD_ISSET(fd_rtcp, &rfds) || FD_ISSET(fd, &rfds)) {
R
Ronald S. Bultje 已提交
1692 1693 1694 1695 1696 1697 1698 1699
                        ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
                        if (ret > 0) {
                            *prtsp_st = rtsp_st;
                            return ret;
                        }
                    }
                }
            }
1700
#if CONFIG_RTSP_DEMUXER
1701
            if (tcp_fd != -1 && FD_ISSET(tcp_fd, &rfds)) {
R
Ronald S. Bultje 已提交
1702 1703
                RTSPMessageHeader reply;

1704 1705 1706
                ret = ff_rtsp_read_reply(s, &reply, NULL, 0);
                if (ret < 0)
                    return ret;
R
Ronald S. Bultje 已提交
1707
                /* XXX: parse message */
1708
                if (rt->state != RTSP_STATE_STREAMING)
R
Ronald S. Bultje 已提交
1709 1710
                    return 0;
            }
1711
#endif
1712
        } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) {
1713
            return FF_NETERROR(ETIMEDOUT);
1714 1715
        } else if (n < 0 && errno != EINTR)
            return AVERROR(errno);
R
Ronald S. Bultje 已提交
1716 1717 1718
    }
}

1719
static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
1720
                           uint8_t *buf, int buf_size);
1721

R
Ronald S. Bultje 已提交
1722 1723 1724 1725
static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
{
    RTSPState *rt = s->priv_data;
    int ret, len;
1726 1727
    RTSPStream *rtsp_st, *first_queue_st = NULL;
    int64_t wait_end = 0;
R
Ronald S. Bultje 已提交
1728

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

R
Ronald S. Bultje 已提交
1732 1733
    /* get next frames from the same RTP packet */
    if (rt->cur_transport_priv) {
1734
        if (rt->transport == RTSP_TRANSPORT_RDT) {
R
Ronald S. Bultje 已提交
1735
            ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
1736
        } else
R
Ronald S. Bultje 已提交
1737 1738 1739 1740 1741 1742
            ret = rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
        if (ret == 0) {
            rt->cur_transport_priv = NULL;
            return 0;
        } else if (ret == 1) {
            return 0;
1743
        } else
R
Ronald S. Bultje 已提交
1744 1745 1746
            rt->cur_transport_priv = NULL;
    }

1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762
    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 = 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;
    }

R
Ronald S. Bultje 已提交
1763 1764
    /* read next RTP packet */
 redo:
1765 1766 1767 1768 1769 1770
    if (!rt->recvbuf) {
        rt->recvbuf = av_malloc(RECVBUF_SIZE);
        if (!rt->recvbuf)
            return AVERROR(ENOMEM);
    }

R
Ronald S. Bultje 已提交
1771 1772
    switch(rt->lower_transport) {
    default:
1773
#if CONFIG_RTSP_DEMUXER
R
Ronald S. Bultje 已提交
1774
    case RTSP_LOWER_TRANSPORT_TCP:
1775
        len = tcp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE);
R
Ronald S. Bultje 已提交
1776
        break;
1777
#endif
R
Ronald S. Bultje 已提交
1778 1779
    case RTSP_LOWER_TRANSPORT_UDP:
    case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
1780
        len = udp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
R
Ronald S. Bultje 已提交
1781 1782 1783 1784
        if (len >=0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
            rtp_check_and_send_back_rr(rtsp_st->transport_priv, len);
        break;
    }
1785 1786 1787 1788 1789 1790
    if (len == AVERROR(EAGAIN) && first_queue_st &&
        rt->transport == RTSP_TRANSPORT_RTP) {
        rtsp_st = first_queue_st;
        ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
        goto end;
    }
R
Ronald S. Bultje 已提交
1791 1792 1793 1794
    if (len < 0)
        return len;
    if (len == 0)
        return AVERROR_EOF;
1795
    if (rt->transport == RTSP_TRANSPORT_RDT) {
1796
        ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
1797
    } else {
1798
        ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809
        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;
                for (i = 0; i < rt->nb_rtsp_streams; i++) {
1810
                    RTPDemuxContext *rtpctx2 = rt->rtsp_streams[i]->transport_priv;
1811 1812 1813 1814 1815
                    if (rtpctx2 &&
                        rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE)
                        rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_time;
                }
            }
1816 1817 1818 1819 1820 1821 1822 1823 1824
            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;
            }
1825 1826
        }
    }
1827
end:
R
Ronald S. Bultje 已提交
1828 1829
    if (ret < 0)
        goto redo;
1830
    if (ret == 1)
R
Ronald S. Bultje 已提交
1831 1832 1833 1834 1835 1836
        /* more packets may follow, so we save the RTP context */
        rt->cur_transport_priv = rtsp_st->transport_priv;

    return ret;
}

1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918
#if CONFIG_RTSP_DEMUXER
static int rtsp_read_header(AVFormatContext *s,
                            AVFormatParameters *ap)
{
    RTSPState *rt = s->priv_data;
    int ret;

    ret = ff_rtsp_connect(s);
    if (ret)
        return ret;

    rt->real_setup_cache = av_mallocz(2 * s->nb_streams * sizeof(*rt->real_setup_cache));
    if (!rt->real_setup_cache)
        return AVERROR(ENOMEM);
    rt->real_setup = rt->real_setup_cache + s->nb_streams * sizeof(*rt->real_setup);

    if (ap->initial_pause) {
         /* do not start immediately */
    } else {
         if (rtsp_read_play(s) < 0) {
            ff_rtsp_close_streams(s);
            ff_rtsp_close_connections(s);
            return AVERROR_INVALIDDATA;
        }
    }

    return 0;
}

static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
                           uint8_t *buf, int buf_size)
{
    RTSPState *rt = s->priv_data;
    int id, len, i, ret;
    RTSPStream *rtsp_st;

#ifdef DEBUG_RTP_TCP
    dprintf(s, "tcp_read_packet:\n");
#endif
redo:
    for (;;) {
        RTSPMessageHeader reply;

        ret = ff_rtsp_read_reply(s, &reply, NULL, 1);
        if (ret < 0)
            return ret;
        if (ret == 1) /* received '$' */
            break;
        /* XXX: parse message */
        if (rt->state != RTSP_STATE_STREAMING)
            return 0;
    }
    ret = url_read_complete(rt->rtsp_hd, buf, 3);
    if (ret != 3)
        return -1;
    id  = buf[0];
    len = AV_RB16(buf + 1);
#ifdef DEBUG_RTP_TCP
    dprintf(s, "id=%d len=%d\n", id, len);
#endif
    if (len > buf_size || len < 12)
        goto redo;
    /* get the data */
    ret = url_read_complete(rt->rtsp_hd, buf, len);
    if (ret != len)
        return -1;
    if (rt->transport == RTSP_TRANSPORT_RDT &&
        ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0)
        return -1;

    /* find the matching stream */
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
        rtsp_st = rt->rtsp_streams[i];
        if (id >= rtsp_st->interleaved_min &&
            id <= rtsp_st->interleaved_max)
            goto found;
    }
    goto redo;
found:
    *prtsp_st = rtsp_st;
    return len;
}
1919
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
1920 1921
{
    RTSPState *rt = s->priv_data;
1922
    int ret;
1923 1924
    RTSPMessageHeader reply1, *reply = &reply1;
    char cmd[1024];
1925

1926
    if (rt->server_type == RTSP_SERVER_REAL) {
1927 1928
        int i;

1929
        for (i = 0; i < s->nb_streams; i++)
1930
            rt->real_setup[i] = s->streams[i]->discard;
1931 1932

        if (!rt->need_subscription) {
1933
            if (memcmp (rt->real_setup, rt->real_setup_cache,
1934
                        sizeof(enum AVDiscard) * s->nb_streams)) {
1935
                snprintf(cmd, sizeof(cmd),
R
Ronald S. Bultje 已提交
1936
                         "Unsubscribe: %s\r\n",
1937 1938 1939
                         rt->last_subscription);
                ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
                                 cmd, reply, NULL);
1940 1941 1942 1943
                if (reply->status_code != RTSP_STATUS_OK)
                    return AVERROR_INVALIDDATA;
                rt->need_subscription = 1;
            }
1944 1945
        }

1946 1947 1948
        if (rt->need_subscription) {
            int r, rule_nr, first = 1;

1949
            memcpy(rt->real_setup_cache, rt->real_setup,
1950 1951 1952 1953
                   sizeof(enum AVDiscard) * s->nb_streams);
            rt->last_subscription[0] = 0;

            snprintf(cmd, sizeof(cmd),
1954
                     "Subscribe: ");
1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
                rule_nr = 0;
                for (r = 0; r < s->nb_streams; r++) {
                    if (s->streams[r]->priv_data == rt->rtsp_streams[i]) {
                        if (s->streams[r]->discard != AVDISCARD_ALL) {
                            if (!first)
                                av_strlcat(rt->last_subscription, ",",
                                           sizeof(rt->last_subscription));
                            ff_rdt_subscribe_rule(
                                rt->last_subscription,
                                sizeof(rt->last_subscription), i, rule_nr);
                            first = 0;
                        }
                        rule_nr++;
                    }
                }
            }
            av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
1973 1974
            ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
                             cmd, reply, NULL);
1975 1976 1977 1978
            if (reply->status_code != RTSP_STATUS_OK)
                return AVERROR_INVALIDDATA;
            rt->need_subscription = 0;

1979
            if (rt->state == RTSP_STATE_STREAMING)
1980 1981
                rtsp_read_play (s);
        }
1982 1983
    }

L
Luca Barbato 已提交
1984
    ret = rtsp_fetch_packet(s, pkt);
1985
    if (ret < 0)
1986
        return ret;
1987 1988

    /* send dummy request to keep TCP connection alive */
1989
    if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {
1990
        if (rt->server_type == RTSP_SERVER_WMS) {
1991
            ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
1992
        } else {
1993
            ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);
1994 1995 1996
        }
    }

1997
    return 0;
1998 1999
}

2000 2001
/* pause the stream */
static int rtsp_read_pause(AVFormatContext *s)
2002
{
2003
    RTSPState *rt = s->priv_data;
2004
    RTSPMessageHeader reply1, *reply = &reply1;
2005

2006
    if (rt->state != RTSP_STATE_STREAMING)
2007
        return 0;
2008
    else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
2009
        ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
2010 2011 2012
        if (reply->status_code != RTSP_STATUS_OK) {
            return -1;
        }
2013
    }
2014 2015
    rt->state = RTSP_STATE_PAUSED;
    return 0;
2016 2017
}

2018
static int rtsp_read_seek(AVFormatContext *s, int stream_index,
2019
                          int64_t timestamp, int flags)
2020 2021
{
    RTSPState *rt = s->priv_data;
2022

2023 2024 2025
    rt->seek_timestamp = av_rescale_q(timestamp,
                                      s->streams[stream_index]->time_base,
                                      AV_TIME_BASE_Q);
2026 2027 2028 2029
    switch(rt->state) {
    default:
    case RTSP_STATE_IDLE:
        break;
2030
    case RTSP_STATE_STREAMING:
2031 2032 2033
        if (rtsp_read_pause(s) != 0)
            return -1;
        rt->state = RTSP_STATE_SEEKING;
2034 2035 2036 2037 2038 2039 2040 2041 2042 2043
        if (rtsp_read_play(s) != 0)
            return -1;
        break;
    case RTSP_STATE_PAUSED:
        rt->state = RTSP_STATE_IDLE;
        break;
    }
    return 0;
}

2044 2045 2046 2047
static int rtsp_read_close(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;

F
Fabrice Bellard 已提交
2048
#if 0
2049
    /* NOTE: it is valid to flush the buffer here */
2050
    if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
2051 2052
        url_fclose(&rt->rtsp_gb);
    }
F
Fabrice Bellard 已提交
2053
#endif
2054
    ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
2055

2056
    ff_rtsp_close_streams(s);
2057
    ff_rtsp_close_connections(s);
2058
    ff_network_close();
2059 2060
    rt->real_setup = NULL;
    av_freep(&rt->real_setup_cache);
2061 2062 2063
    return 0;
}

2064
AVInputFormat rtsp_demuxer = {
2065
    "rtsp",
2066
    NULL_IF_CONFIG_SMALL("RTSP input format"),
2067 2068 2069 2070 2071
    sizeof(RTSPState),
    rtsp_probe,
    rtsp_read_header,
    rtsp_read_packet,
    rtsp_read_close,
2072
    rtsp_read_seek,
2073
    .flags = AVFMT_NOFILE,
2074 2075
    .read_play = rtsp_read_play,
    .read_pause = rtsp_read_pause,
2076
};
2077
#endif /* CONFIG_RTSP_DEMUXER */
2078

2079
static int sdp_probe(AVProbeData *p1)
2080
{
2081
    const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
2082

M
Martin Storsjö 已提交
2083
    /* we look for a line beginning "c=IN IP" */
2084
    while (p < p_end && *p != '\0') {
M
Martin Storsjö 已提交
2085 2086
        if (p + sizeof("c=IN IP") - 1 < p_end &&
            av_strstart(p, "c=IN IP", NULL))
2087
            return AVPROBE_SCORE_MAX / 2;
2088

2089
        while (p < p_end - 1 && *p != '\n') p++;
2090
        if (++p >= p_end)
2091 2092 2093 2094
            break;
        if (*p == '\r')
            p++;
    }
2095 2096 2097
    return 0;
}

2098
static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap)
2099
{
2100
    RTSPState *rt = s->priv_data;
2101 2102 2103 2104 2105
    RTSPStream *rtsp_st;
    int size, i, err;
    char *content;
    char url[1024];

2106 2107 2108
    if (!ff_network_init())
        return AVERROR(EIO);

2109 2110 2111
    /* read the whole sdp file */
    /* XXX: better loading */
    content = av_malloc(SDP_MAX_SIZE);
2112
    size = get_buffer(s->pb, content, SDP_MAX_SIZE - 1);
2113 2114 2115 2116 2117 2118 2119 2120 2121 2122
    if (size <= 0) {
        av_free(content);
        return AVERROR_INVALIDDATA;
    }
    content[size] ='\0';

    sdp_parse(s, content);
    av_free(content);

    /* open each RTP stream */
2123
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
M
Martin Storsjö 已提交
2124
        char namebuf[50];
2125
        rtsp_st = rt->rtsp_streams[i];
2126

M
Martin Storsjö 已提交
2127 2128
        getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip, sizeof(rtsp_st->sdp_ip),
                    namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
2129
        ff_url_join(url, sizeof(url), "rtp", NULL,
M
Martin Storsjö 已提交
2130
                    namebuf, rtsp_st->sdp_port,
2131 2132
                    "?localport=%d&ttl=%d", rtsp_st->sdp_port,
                    rtsp_st->sdp_ttl);
2133
        if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
2134 2135 2136
            err = AVERROR_INVALIDDATA;
            goto fail;
        }
2137
        if ((err = rtsp_open_transport_ctx(s, rtsp_st)))
2138
            goto fail;
2139 2140
    }
    return 0;
2141
fail:
2142
    ff_rtsp_close_streams(s);
2143
    ff_network_close();
2144 2145 2146 2147 2148
    return err;
}

static int sdp_read_close(AVFormatContext *s)
{
2149
    ff_rtsp_close_streams(s);
2150
    ff_network_close();
2151 2152 2153
    return 0;
}

2154
AVInputFormat sdp_demuxer = {
2155
    "sdp",
2156
    NULL_IF_CONFIG_SMALL("SDP"),
2157 2158 2159
    sizeof(RTSPState),
    sdp_probe,
    sdp_read_header,
L
Luca Barbato 已提交
2160
    rtsp_fetch_packet,
2161 2162
    sdp_read_close,
};