rtsp.c 65.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"
25 26
#include "avformat.h"

27
#include <sys/time.h>
28
#if HAVE_SYS_SELECT_H
29
#include <sys/select.h>
30
#endif
31
#include <strings.h>
32
#include "network.h"
33
#include "os_support.h"
34
#include "rtsp.h"
35

36
#include "rtpdec.h"
37
#include "rdt.h"
38 39
#include "rtpdec_asf.h"
#include "rtpdec_vorbis.h"
R
Ryan Martell 已提交
40

41
//#define DEBUG
F
Fabrice Bellard 已提交
42
//#define DEBUG_RTP_TCP
43

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

48
#define SPACE_CHARS " \t\r\n"
49 50 51
/* we use memchr() instead of strchr() here because strchr() will return
 * the terminating '\0' of SPACE_CHARS instead of NULL if c is '\0'. */
#define redir_isspace(c) memchr(SPACE_CHARS, c, 4)
52 53 54 55 56 57 58 59 60
static void skip_spaces(const char **pp)
{
    const char *p;
    p = *pp;
    while (redir_isspace(*p))
        p++;
    *pp = p;
}

61 62
static void get_word_until_chars(char *buf, int buf_size,
                                 const char *sep, const char **pp)
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
{
    const char *p;
    char *q;

    p = *pp;
    skip_spaces(&p);
    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;
}

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

87 88 89
static void get_word(char *buf, int buf_size, const char **pp)
{
    get_word_until_chars(buf, buf_size, SPACE_CHARS, pp);
90 91
}

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

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

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

R
Ronald S. Bultje 已提交
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
    get_word_sep(buf, sizeof(buf), "/", &p);
    i = atoi(buf);
    switch (codec->codec_type) {
    case CODEC_TYPE_AUDIO:
        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 已提交
151
        }
R
Ronald S. Bultje 已提交
152 153 154 155 156 157 158 159 160 161 162 163
        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;
    case CODEC_TYPE_VIDEO:
        av_log(s, AV_LOG_DEBUG, "video codec set to: %s\n", c_name);
        break;
    default:
        break;
    }
    return 0;
164 165
}

166
/* return the length and optionally the data */
167 168 169 170 171 172
static int hex_to_data(uint8_t *data, const char *p)
{
    int c, len, v;

    len = 0;
    v = 1;
173
    for (;;) {
174
        skip_spaces(&p);
175
        if (*p == '\0')
176
            break;
177
        c = toupper((unsigned char) *p++);
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
        if (c >= '0' && c <= '9')
            c = c - '0';
        else if (c >= 'A' && c <= 'F')
            c = c - 'A' + 10;
        else
            break;
        v = (v << 4) | c;
        if (v & 0x100) {
            if (data)
                data[len] = v;
            len++;
            v = 1;
        }
    }
    return len;
}

195 196
static void sdp_parse_fmtp_config(AVCodecContext * codec, void *ctx,
                                  char *attr, char *value)
R
Romain Degez 已提交
197 198
{
    switch (codec->codec_id) {
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
    case CODEC_ID_MPEG4:
    case CODEC_ID_AAC:
        if (!strcmp(attr, "config")) {
            /* decode the hexa encoded parameter */
            int len = hex_to_data(NULL, value);
            if (codec->extradata)
                av_free(codec->extradata);
            codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!codec->extradata)
                return;
            codec->extradata_size = len;
            hex_to_data(codec->extradata, value);
        }
        break;
    case CODEC_ID_VORBIS:
        ff_vorbis_parse_fmtp_config(codec, ctx, attr, value);
        break;
    default:
        break;
R
Romain Degez 已提交
218 219 220 221
    }
    return;
}

L
Luca Barbato 已提交
222
typedef struct {
223
    const char *str;
224 225
    uint16_t    type;
    uint32_t    offset;
L
Luca Barbato 已提交
226
} AttrNameMap;
R
Romain Degez 已提交
227 228 229 230

/* All known fmtp parmeters and the corresping RTPAttrTypeEnum */
#define ATTR_NAME_TYPE_INT 0
#define ATTR_NAME_TYPE_STR 1
L
Luca Barbato 已提交
231
static const AttrNameMap attr_names[]=
R
Romain Degez 已提交
232
{
233 234 235 236 237 238 239 240 241 242 243 244 245
    { "SizeLength",       ATTR_NAME_TYPE_INT,
      offsetof(RTPPayloadData, sizelength) },
    { "IndexLength",      ATTR_NAME_TYPE_INT,
      offsetof(RTPPayloadData, indexlength) },
    { "IndexDeltaLength", ATTR_NAME_TYPE_INT,
      offsetof(RTPPayloadData, indexdeltalength) },
    { "profile-level-id", ATTR_NAME_TYPE_INT,
      offsetof(RTPPayloadData, profile_level_id) },
    { "StreamType",       ATTR_NAME_TYPE_INT,
      offsetof(RTPPayloadData, streamtype) },
    { "mode",             ATTR_NAME_TYPE_STR,
      offsetof(RTPPayloadData, mode) },
    { NULL, -1, -1 },
R
Romain Degez 已提交
246 247
};

248 249 250
/* parse the attribute line from the fmtp a line of an sdp resonse. This
 * is broken out as a function because it is used in rtp_h264.c, which is
 * forthcoming. */
251
int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size,
M
Martin Storsjö 已提交
252
                                char *value, int value_size)
253 254
{
    skip_spaces(p);
255
    if (**p) {
256 257 258 259 260 261 262 263 264 265 266
        get_word_sep(attr, attr_size, "=", p);
        if (**p == '=')
            (*p)++;
        get_word_sep(value, value_size, ";", p);
        if (**p == ';')
            (*p)++;
        return 1;
    }
    return 0;
}

R
Romain Degez 已提交
267 268
/* parse a SDP line and save stream attributes */
static void sdp_parse_fmtp(AVStream *st, const char *p)
269 270
{
    char attr[256];
271 272 273
    /* Vorbis setup headers can be up to 12KB and are sent base64
     * encoded, giving a 12KB * (4/3) = 16KB FMTP line. */
    char value[16384];
R
Romain Degez 已提交
274 275
    int i;
    RTSPStream *rtsp_st = st->priv_data;
276
    AVCodecContext *codec = st->codec;
277
    RTPPayloadData *rtp_payload_data = &rtsp_st->rtp_payload_data;
278 279

    /* loop on each attribute */
280
    while (ff_rtsp_next_attr_and_value(&p, attr, sizeof(attr),
M
Martin Storsjö 已提交
281
                                       value, sizeof(value))) {
282 283
        /* grab the codec extra_data from the config parameter of the fmtp
         * line */
284 285
        sdp_parse_fmtp_config(codec, rtsp_st->dynamic_protocol_context,
                              attr, value);
R
Romain Degez 已提交
286 287 288
        /* Looking for a known attribute */
        for (i = 0; attr_names[i].str; ++i) {
            if (!strcasecmp(attr, attr_names[i].str)) {
289 290 291 292 293 294
                if (attr_names[i].type == ATTR_NAME_TYPE_INT) {
                    *(int *)((char *)rtp_payload_data +
                        attr_names[i].offset) = atoi(value);
                } else if (attr_names[i].type == ATTR_NAME_TYPE_STR)
                    *(char **)((char *)rtp_payload_data +
                        attr_names[i].offset) = av_strdup(value);
295
            }
296 297 298 299
        }
    }
}

S
Stefano Sabatini 已提交
300
/** Parse a string p in the form of Range:npt=xx-xx, and determine the start
301 302 303 304 305 306 307 308
 *  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];

    skip_spaces(&p);
309
    if (!av_stristart(p, "npt=", &p))
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
        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);
}

326 327 328
typedef struct SDPParseState {
    /* SDP only */
    struct in_addr default_ip;
329 330
    int            default_ttl;
    int            skip_media;  ///< set if an unknown m= line occurs
331 332 333
} SDPParseState;

static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
334 335
                           int letter, const char *buf)
{
336
    RTSPState *rt = s->priv_data;
337 338
    char buf1[64], st_type[64];
    const char *p;
D
Diego Pettenò 已提交
339 340
    enum CodecType codec_type;
    int payload_type, i;
341 342
    AVStream *st;
    RTSPStream *rtsp_st;
343 344 345
    struct in_addr sdp_ip;
    int ttl;

346
    dprintf(s, "sdp: %c='%s'\n", letter, buf);
347 348

    p = buf;
349 350
    if (s1->skip_media && letter != 'm')
        return;
351
    switch (letter) {
352 353 354 355 356 357 358 359
    case 'c':
        get_word(buf1, sizeof(buf1), &p);
        if (strcmp(buf1, "IN") != 0)
            return;
        get_word(buf1, sizeof(buf1), &p);
        if (strcmp(buf1, "IP4") != 0)
            return;
        get_word_sep(buf1, sizeof(buf1), "/", &p);
360
        if (ff_inet_aton(buf1, &sdp_ip) == 0)
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
            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;
378
    case 's':
379
        av_metadata_set(&s->metadata, "title", p);
380 381 382
        break;
    case 'i':
        if (s->nb_streams == 0) {
383
            av_metadata_set(&s->metadata, "comment", p);
384 385 386 387 388
            break;
        }
        break;
    case 'm':
        /* new stream */
389
        s1->skip_media = 0;
390 391 392 393 394
        get_word(st_type, sizeof(st_type), &p);
        if (!strcmp(st_type, "audio")) {
            codec_type = CODEC_TYPE_AUDIO;
        } else if (!strcmp(st_type, "video")) {
            codec_type = CODEC_TYPE_VIDEO;
395 396
        } else if (!strcmp(st_type, "application")) {
            codec_type = CODEC_TYPE_DATA;
397
        } else {
398
            s1->skip_media = 1;
399 400 401 402 403
            return;
        }
        rtsp_st = av_mallocz(sizeof(RTSPStream));
        if (!rtsp_st)
            return;
404 405
        rtsp_st->stream_index = -1;
        dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st);
406 407 408 409 410 411 412 413

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

415 416 417 418
        /* XXX: handle list of formats */
        get_word(buf1, sizeof(buf1), &p); /* format list */
        rtsp_st->sdp_payload_type = atoi(buf1);

419
        if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
420 421 422 423 424 425 426
            /* no corresponding stream */
        } else {
            st = av_new_stream(s, 0);
            if (!st)
                return;
            st->priv_data = rtsp_st;
            rtsp_st->stream_index = st->index;
427
            st->codec->codec_type = codec_type;
R
Romain Degez 已提交
428
            if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
429
                /* if standard payload type, we can find the codec right now */
430
                ff_rtp_get_codec_info(st->codec, rtsp_st->sdp_payload_type);
431 432
            }
        }
433
        /* put a default control url */
434
        av_strlcpy(rtsp_st->control_url, rt->control_uri,
435
                   sizeof(rtsp_st->control_url));
436 437
        break;
    case 'a':
438 439 440 441 442 443
        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 {
444 445 446 447
            char proto[32];
            /* get the control url */
            st = s->streams[s->nb_streams - 1];
            rtsp_st = st->priv_data;
448

449
            /* XXX: may need to add full url resolution */
450
            ff_url_split(proto, sizeof(proto), NULL, 0, NULL, 0,
M
Martin Storsjö 已提交
451
                         NULL, NULL, 0, p);
452 453
            if (proto[0] == '\0') {
                /* relative control URL */
454
                if (rtsp_st->control_url[strlen(rtsp_st->control_url)-1]!='/')
455 456 457 458 459 460 461
                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));
462
            }
463
        } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) {
464
            /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
465
            get_word(buf1, sizeof(buf1), &p);
466
            payload_type = atoi(buf1);
467
            st = s->streams[s->nb_streams - 1];
R
Ronald S. Bultje 已提交
468
            rtsp_st = st->priv_data;
469
            sdp_parse_rtpmap(s, st->codec, rtsp_st, payload_type, p);
470
        } else if (av_strstart(p, "fmtp:", &p)) {
471
            /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */
472
            get_word(buf1, sizeof(buf1), &p);
473
            payload_type = atoi(buf1);
474 475
            for (i = 0; i < s->nb_streams; i++) {
                st      = s->streams[i];
476 477
                rtsp_st = st->priv_data;
                if (rtsp_st->sdp_payload_type == payload_type) {
478 479 480 481
                    if (!(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)))
482
                        sdp_parse_fmtp(st, p);
483 484
                }
            }
485
        } else if (av_strstart(p, "framesize:", &p)) {
486 487 488
            // let dynamic protocol handlers have a stab at the line.
            get_word(buf1, sizeof(buf1), &p);
            payload_type = atoi(buf1);
489 490
            for (i = 0; i < s->nb_streams; i++) {
                st      = s->streams[i];
491
                rtsp_st = st->priv_data;
492 493 494 495 496
                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);
497
            }
498
        } else if (av_strstart(p, "range:", &p)) {
499 500 501 502
            int64_t start, end;

            // this is so that seeking on a streamed file can work.
            rtsp_parse_range_npt(p, &start, &end);
503 504 505 506
            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;
507 508 509
        } else if (av_strstart(p, "IsRealDataType:integer;",&p)) {
            if (atoi(p) == 1)
                rt->transport = RTSP_TRANSPORT_RDT;
510 511 512 513
        } 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 已提交
514 515 516 517 518 519
                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)
520 521
                    rtsp_st->dynamic_handler->parse_sdp_a_line(s,
                        s->nb_streams - 1,
R
Ronald S. Bultje 已提交
522
                        rtsp_st->dynamic_protocol_context, buf);
523
            }
524 525 526 527 528
        }
        break;
    }
}

529
static int sdp_parse(AVFormatContext *s, const char *content)
530 531 532
{
    const char *p;
    int letter;
533 534 535 536
    /* 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
537 538 539 540
     * buffer is large.
     *
     * The Vorbis FMTP line can be up to 16KB - see sdp_parse_fmtp. */
    char buf[16384], *q;
541
    SDPParseState sdp_parse_state, *s1 = &sdp_parse_state;
542

543
    memset(s1, 0, sizeof(SDPParseState));
544
    p = content;
545
    for (;;) {
546 547 548 549 550 551 552 553 554 555
        skip_spaces(&p);
        letter = *p;
        if (letter == '\0')
            break;
        p++;
        if (*p != '=')
            goto next_line;
        p++;
        /* get the content */
        q = buf;
F
Fabrice Bellard 已提交
556
        while (*p != '\n' && *p != '\r' && *p != '\0') {
557 558 559 560 561
            if ((q - buf) < sizeof(buf) - 1)
                *q++ = *p;
            p++;
        }
        *q = '\0';
562
        sdp_parse_line(s, s1, letter, buf);
563 564 565 566 567 568 569 570 571
    next_line:
        while (*p != '\n' && *p != '\0')
            p++;
        if (*p == '\n')
            p++;
    }
    return 0;
}

572
/* close and free RTSP streams */
573
void ff_rtsp_close_streams(AVFormatContext *s)
574
{
575
    RTSPState *rt = s->priv_data;
576 577 578
    int i;
    RTSPStream *rtsp_st;

579
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
580 581 582
        rtsp_st = rt->rtsp_streams[i];
        if (rtsp_st) {
            if (rtsp_st->transport_priv) {
583 584 585 586
                if (s->oformat) {
                    AVFormatContext *rtpctx = rtsp_st->transport_priv;
                    av_write_trailer(rtpctx);
                    url_fclose(rtpctx->pb);
587 588
                    av_metadata_free(&rtpctx->streams[0]->metadata);
                    av_metadata_free(&rtpctx->metadata);
589 590 591
                    av_free(rtpctx->streams[0]);
                    av_free(rtpctx);
                } else if (rt->transport == RTSP_TRANSPORT_RDT)
592 593 594 595 596 597 598
                    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)
599 600
                rtsp_st->dynamic_handler->close(
                    rtsp_st->dynamic_protocol_context);
601 602 603 604 605 606 607 608 609 610
        }
    }
    av_free(rt->rtsp_streams);
    if (rt->asf_ctx) {
        av_close_input_stream (rt->asf_ctx);
        rt->asf_ctx = NULL;
    }
    av_freep(&rt->auth_b64);
}

611 612 613
static void *rtsp_rtp_mux_open(AVFormatContext *s, AVStream *st,
                               URLContext *handle)
{
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656
    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;

    /* 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;

    url_fdopen(&rtpctx->pb, handle);
    ret = av_write_header(rtpctx);

    if (ret) {
        url_fclose(rtpctx->pb);
        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;
}

657
static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
658 659 660 661 662 663 664 665 666 667
{
    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;

668 669 670 671 672
    if (s->oformat) {
        rtsp_st->transport_priv = rtsp_rtp_mux_open(s, st, rtsp_st->rtp_handle);
        /* Ownage of rtp_handle is passed to the rtp mux context */
        rtsp_st->rtp_handle = NULL;
    } else if (rt->transport == RTSP_TRANSPORT_RDT)
673 674 675 676 677 678 679 680 681 682 683
        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,
                                         rtsp_st->sdp_payload_type,
                                         &rtsp_st->rtp_payload_data);

    if (!rtsp_st->transport_priv) {
         return AVERROR(ENOMEM);
    } else if (rt->transport != RTSP_TRANSPORT_RDT) {
684
        if (rtsp_st->dynamic_handler) {
685 686 687 688 689 690 691 692 693
            rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv,
                                           rtsp_st->dynamic_protocol_context,
                                           rtsp_st->dynamic_handler);
        }
    }

    return 0;
}

M
Martin Storsjö 已提交
694
#if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER
695 696 697 698 699 700 701
static int rtsp_probe(AVProbeData *p)
{
    if (av_strstart(p->filename, "rtsp:", NULL))
        return AVPROBE_SCORE_MAX;
    return 0;
}

702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722
static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
{
    const char *p;
    int v;

    p = *pp;
    skip_spaces(&p);
    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 */
723
static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p)
724 725 726 727 728 729 730
{
    char transport_protocol[16];
    char profile[16];
    char lower_transport[16];
    char parameter[16];
    RTSPTransportField *th;
    char buf[256];
731

732
    reply->nb_transports = 0;
733

734
    for (;;) {
735 736 737 738 739 740
        skip_spaces(&p);
        if (*p == '\0')
            break;

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

741
        get_word_sep(transport_protocol, sizeof(transport_protocol),
742
                     "/", &p);
743
        if (!strcasecmp (transport_protocol, "rtp")) {
744 745 746 747 748 749
            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);
750 751 752 753
            }
            th->transport = RTSP_TRANSPORT_RTP;
        } else if (!strcasecmp (transport_protocol, "x-pn-tng") ||
                   !strcasecmp (transport_protocol, "x-real-rdt")) {
754
            /* x-pn-tng/<protocol> */
755 756
            get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p);
            profile[0] = '\0';
757
            th->transport = RTSP_TRANSPORT_RDT;
758
        }
F
Fabrice Bellard 已提交
759
        if (!strcasecmp(lower_transport, "TCP"))
760
            th->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
761
        else
762
            th->lower_transport = RTSP_LOWER_TRANSPORT_UDP;
763

764 765 766 767 768 769 770 771 772 773 774 775 776
        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++;
777
                    rtsp_parse_range(&th->client_port_min,
778 779 780 781 782
                                     &th->client_port_max, &p);
                }
            } else if (!strcmp(parameter, "server_port")) {
                if (*p == '=') {
                    p++;
783
                    rtsp_parse_range(&th->server_port_min,
784 785 786 787 788
                                     &th->server_port_max, &p);
                }
            } else if (!strcmp(parameter, "interleaved")) {
                if (*p == '=') {
                    p++;
789
                    rtsp_parse_range(&th->interleaved_min,
790 791 792
                                     &th->interleaved_max, &p);
                }
            } else if (!strcmp(parameter, "multicast")) {
793 794
                if (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP)
                    th->lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST;
795 796 797 798 799 800 801 802 803 804 805
            } else if (!strcmp(parameter, "ttl")) {
                if (*p == '=') {
                    p++;
                    th->ttl = strtol(p, (char **)&p, 10);
                }
            } else if (!strcmp(parameter, "destination")) {
                struct in_addr ipaddr;

                if (*p == '=') {
                    p++;
                    get_word_sep(buf, sizeof(buf), ";,", &p);
806
                    if (ff_inet_aton(buf, &ipaddr))
807 808 809 810 811 812 813 814 815 816 817 818 819 820 821
                        th->destination = ntohl(ipaddr.s_addr);
                }
            }
            while (*p != ';' && *p != '\0' && *p != ',')
                p++;
            if (*p == ';')
                p++;
        }
        if (*p == ',')
            p++;

        reply->nb_transports++;
    }
}

822
void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf)
823 824 825 826 827
{
    const char *p;

    /* NOTE: we do case independent match for broken servers */
    p = buf;
828
    if (av_stristart(p, "Session:", &p)) {
829
        int t;
830
        get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p);
831 832 833 834
        if (av_stristart(p, ";timeout=", &p) &&
            (t = strtol(p, NULL, 10)) > 0) {
            reply->timeout = t;
        }
835
    } else if (av_stristart(p, "Content-Length:", &p)) {
836
        reply->content_length = strtol(p, NULL, 10);
837
    } else if (av_stristart(p, "Transport:", &p)) {
838
        rtsp_parse_transport(reply, p);
839
    } else if (av_stristart(p, "CSeq:", &p)) {
840
        reply->seq = strtol(p, NULL, 10);
841
    } else if (av_stristart(p, "Range:", &p)) {
842
        rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end);
843 844 845
    } else if (av_stristart(p, "RealChallenge1:", &p)) {
        skip_spaces(&p);
        av_strlcpy(reply->real_challenge, p, sizeof(reply->real_challenge));
846 847 848
    } else if (av_stristart(p, "Server:", &p)) {
        skip_spaces(&p);
        av_strlcpy(reply->server, p, sizeof(reply->server));
849 850 851
    } else if (av_stristart(p, "Notice:", &p) ||
               av_stristart(p, "X-Notice:", &p)) {
        reply->notice = strtol(p, NULL, 10);
L
Luca Barbato 已提交
852 853 854
    } else if (av_stristart(p, "Location:", &p)) {
        skip_spaces(&p);
        av_strlcpy(reply->location, p , sizeof(reply->location));
855 856 857
    }
}

858 859 860 861 862 863 864
/* skip a RTP/TCP interleaved packet */
static void rtsp_skip_packet(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    int ret, len, len1;
    uint8_t buf[1024];

865
    ret = url_read_complete(rt->rtsp_hd, buf, 3);
866 867
    if (ret != 3)
        return;
868
    len = AV_RB16(buf + 1);
869 870 871

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

872 873 874 875 876
    /* skip payload */
    while (len > 0) {
        len1 = len;
        if (len1 > sizeof(buf))
            len1 = sizeof(buf);
877
        ret = url_read_complete(rt->rtsp_hd, buf, len1);
878 879 880 881 882
        if (ret != len1)
            return;
        len -= len1;
    }
}
883

884
int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply,
M
Martin Storsjö 已提交
885 886
                       unsigned char **content_ptr,
                       int return_on_interleaved_data)
887 888 889 890 891
{
    RTSPState *rt = s->priv_data;
    char buf[4096], buf1[1024], *q;
    unsigned char ch;
    const char *p;
892
    int ret, content_length, line_count = 0;
893 894
    unsigned char *content = NULL;

895
    memset(reply, 0, sizeof(*reply));
896 897 898

    /* parse reply (XXX: use buffers) */
    rt->last_reply[0] = '\0';
899
    for (;;) {
900
        q = buf;
901
        for (;;) {
902
            ret = url_read_complete(rt->rtsp_hd, &ch, 1);
903
#ifdef DEBUG_RTP_TCP
904
            dprintf(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);
905 906 907
#endif
            if (ret != 1)
                return -1;
908 909
            if (ch == '\n')
                break;
910 911
            if (ch == '$') {
                /* XXX: only parse it if first char on line ? */
912 913 914
                if (return_on_interleaved_data) {
                    return 1;
                } else
915 916
                rtsp_skip_packet(s);
            } else if (ch != '\r') {
917 918 919 920 921
                if ((q - buf) < sizeof(buf) - 1)
                    *q++ = ch;
            }
        }
        *q = '\0';
922 923 924

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

925 926 927 928 929 930 931 932 933 934
        /* 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);
        } else {
935
            ff_rtsp_parse_line(reply, p);
M
Måns Rullgård 已提交
936 937
            av_strlcat(rt->last_reply, p,    sizeof(rt->last_reply));
            av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply));
938 939 940
        }
        line_count++;
    }
941

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

945 946 947 948
    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);
949
        (void)url_read_complete(rt->rtsp_hd, content, content_length);
950 951 952 953
        content[content_length] = '\0';
    }
    if (content_ptr)
        *content_ptr = content;
954 955
    else
        av_free(content);
956

957 958 959
    /* EOS */
    if (reply->notice == 2101 /* End-of-Stream Reached */      ||
        reply->notice == 2104 /* Start-of-Stream Reached */    ||
960
        reply->notice == 2306 /* Continuous Feed Terminated */) {
961
        rt->state = RTSP_STATE_IDLE;
962
    } else if (reply->notice >= 4400 && reply->notice < 5500) {
963
        return AVERROR(EIO); /* data or server error */
964
    } else if (reply->notice == 2401 /* Ticket Expired */ ||
965 966 967
             (reply->notice >= 5500 && reply->notice < 5600) /* end of term */ )
        return AVERROR(EPERM);

968
    return 0;
969 970
}

971
void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
M
Martin Storsjö 已提交
972 973 974
                                         const char *cmd,
                                         const unsigned char *send_content,
                                         int send_content_length)
975 976 977 978 979 980 981 982 983 984 985 986
{
    RTSPState *rt = s->priv_data;
    char buf[4096], buf1[1024];

    rt->seq++;
    av_strlcpy(buf, cmd, sizeof(buf));
    snprintf(buf1, sizeof(buf1), "CSeq: %d\r\n", rt->seq);
    av_strlcat(buf, buf1, sizeof(buf));
    if (rt->session_id[0] != '\0' && !strstr(cmd, "\nIf-Match:")) {
        snprintf(buf1, sizeof(buf1), "Session: %s\r\n", rt->session_id);
        av_strlcat(buf, buf1, sizeof(buf));
    }
987 988
    if (rt->auth_b64)
        av_strlcatf(buf, sizeof(buf),
989 990
                    "Authorization: Basic %s\r\n",
                    rt->auth_b64);
991 992
    if (send_content_length > 0 && send_content)
        av_strlcatf(buf, sizeof(buf), "Content-Length: %d\r\n", send_content_length);
993
    av_strlcat(buf, "\r\n", sizeof(buf));
994 995 996

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

997
    url_write(rt->rtsp_hd, buf, strlen(buf));
998 999
    if (send_content_length > 0 && send_content)
        url_write(rt->rtsp_hd, send_content, send_content_length);
1000 1001 1002
    rt->last_cmd_time = av_gettime();
}

1003
void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *cmd)
1004
{
1005
    ff_rtsp_send_cmd_with_content_async(s, cmd, NULL, 0);
1006 1007
}

1008
void ff_rtsp_send_cmd(AVFormatContext *s,
M
Martin Storsjö 已提交
1009 1010
                      const char *cmd, RTSPMessageHeader *reply,
                      unsigned char **content_ptr)
1011
{
1012
    ff_rtsp_send_cmd_async(s, cmd);
1013

1014
    ff_rtsp_read_reply(s, reply, content_ptr, 0);
1015 1016
}

1017
void ff_rtsp_send_cmd_with_content(AVFormatContext *s,
M
Martin Storsjö 已提交
1018 1019 1020 1021 1022
                                const char *cmd,
                                RTSPMessageHeader *reply,
                                unsigned char **content_ptr,
                                const unsigned char *send_content,
                                int send_content_length)
1023
{
1024
    ff_rtsp_send_cmd_with_content_async(s, cmd, send_content, send_content_length);
1025

1026
    ff_rtsp_read_reply(s, reply, content_ptr, 0);
1027 1028
}

1029 1030 1031
/**
 * @returns 0 on success, <0 on error, 1 if protocol is unavailable.
 */
1032 1033
static int make_setup_request(AVFormatContext *s, const char *host, int port,
                              int lower_transport, const char *real_challenge)
1034 1035
{
    RTSPState *rt = s->priv_data;
1036
    int rtx, j, i, err, interleave = 0;
1037
    RTSPStream *rtsp_st;
1038
    RTSPMessageHeader reply1, *reply = &reply1;
1039
    char cmd[2048];
1040 1041
    const char *trans_pref;

1042
    if (rt->transport == RTSP_TRANSPORT_RDT)
1043 1044 1045
        trans_pref = "x-pn-tng";
    else
        trans_pref = "RTP/AVP";
1046

1047 1048 1049
    /* default timeout: 1 minute */
    rt->timeout = 60;

1050 1051
    /* for each stream, make the setup request */
    /* XXX: we assume the same server is used for the control of each
1052
     * RTSP stream */
R
Romain Degez 已提交
1053

1054
    for (j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) {
1055 1056
        char transport[2048];

1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068
        /**
         * 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 &&
1069 1070
                        !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4,
                                "/rtx"))
1071 1072 1073 1074 1075 1076 1077 1078
                        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 已提交
1079
            rtsp_st = rt->rtsp_streams[i];
1080 1081

        /* RTP/UDP */
1082
        if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
F
Fabrice Bellard 已提交
1083 1084
            char buf[256];

1085 1086 1087 1088 1089
            if (rt->server_type == RTSP_SERVER_WMS && i > 1) {
                port = reply->transports[0].client_port_min;
                goto have_port;
            }

F
Fabrice Bellard 已提交
1090
            /* first try in specified port range */
R
Romain Degez 已提交
1091
            if (RTSP_RTP_PORT_MIN != 0) {
1092
                while (j <= RTSP_RTP_PORT_MAX) {
1093 1094
                    ff_url_join(buf, sizeof(buf), "rtp", NULL, host, -1,
                                "?localport=%d", j);
1095 1096 1097
                    /* 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 已提交
1098 1099
                        goto rtp_opened;
                }
1100
            }
F
Fabrice Bellard 已提交
1101

1102 1103 1104 1105 1106 1107 1108
#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 已提交
1109 1110

        rtp_opened:
1111
            port = rtp_get_local_port(rtsp_st->rtp_handle);
1112
        have_port:
1113
            snprintf(transport, sizeof(transport) - 1,
1114 1115 1116 1117 1118
                     "%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);
1119 1120
            if (rt->transport == RTSP_TRANSPORT_RTP &&
                !(rt->server_type == RTSP_SERVER_WMS && i > 0))
1121
                av_strlcatf(transport, sizeof(transport), "-%d", port + 1);
1122 1123 1124
        }

        /* RTP/TCP */
1125
        else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
1126 1127 1128 1129
            /** 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 &&
1130 1131
                s->streams[rtsp_st->stream_index]->codec->codec_type ==
                    CODEC_TYPE_DATA)
1132
                continue;
1133
            snprintf(transport, sizeof(transport) - 1,
1134 1135 1136 1137 1138 1139 1140
                     "%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;
1141 1142
        }

1143
        else if (lower_transport == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) {
1144
            snprintf(transport, sizeof(transport) - 1,
1145
                     "%s/UDP;multicast", trans_pref);
1146
        }
1147 1148 1149
        if (s->oformat) {
            av_strlcat(transport, ";mode=receive", sizeof(transport));
        } else if (rt->server_type == RTSP_SERVER_REAL ||
1150
                   rt->server_type == RTSP_SERVER_WMS)
1151
            av_strlcat(transport, ";mode=play", sizeof(transport));
1152
        snprintf(cmd, sizeof(cmd),
F
Fabrice Bellard 已提交
1153 1154
                 "SETUP %s RTSP/1.0\r\n"
                 "Transport: %s\r\n",
1155
                 rtsp_st->control_url, transport);
1156
        if (i == 0 && rt->server_type == RTSP_SERVER_REAL) {
1157 1158 1159 1160 1161 1162 1163 1164
            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);
        }
1165
        ff_rtsp_send_cmd(s, cmd, reply, NULL);
1166 1167 1168
        if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) {
            err = 1;
            goto fail;
1169 1170
        } else if (reply->status_code != RTSP_STATUS_OK ||
                   reply->nb_transports != 1) {
1171 1172 1173 1174 1175 1176
            err = AVERROR_INVALIDDATA;
            goto fail;
        }

        /* XXX: same protocol for all streams is required */
        if (i > 0) {
1177 1178
            if (reply->transports[0].lower_transport != rt->lower_transport ||
                reply->transports[0].transport != rt->transport) {
1179 1180 1181 1182
                err = AVERROR_INVALIDDATA;
                goto fail;
            }
        } else {
1183
            rt->lower_transport = reply->transports[0].lower_transport;
1184
            rt->transport = reply->transports[0].transport;
1185 1186 1187
        }

        /* close RTP connection if not choosen */
1188 1189
        if (reply->transports[0].lower_transport != RTSP_LOWER_TRANSPORT_UDP &&
            (lower_transport == RTSP_LOWER_TRANSPORT_UDP)) {
1190 1191
            url_close(rtsp_st->rtp_handle);
            rtsp_st->rtp_handle = NULL;
1192 1193
        }

1194 1195
        switch(reply->transports[0].lower_transport) {
        case RTSP_LOWER_TRANSPORT_TCP:
1196 1197 1198
            rtsp_st->interleaved_min = reply->transports[0].interleaved_min;
            rtsp_st->interleaved_max = reply->transports[0].interleaved_max;
            break;
1199

1200 1201 1202 1203
        case RTSP_LOWER_TRANSPORT_UDP: {
            char url[1024];

            /* XXX: also use address if specified */
1204 1205
            ff_url_join(url, sizeof(url), "rtp", NULL, host,
                        reply->transports[0].server_port_min, NULL);
1206 1207 1208 1209
            if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
                rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
                err = AVERROR_INVALIDDATA;
                goto fail;
1210
            }
1211 1212 1213 1214
            /* Try to initialize the connection state in a
             * potential NAT router by sending dummy packets.
             * RTP/RTCP dummy packets are used for RDT, too.
             */
1215
            if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat)
1216
                rtp_send_punch_packets(rtsp_st->rtp_handle);
1217
            break;
1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232
        }
        case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: {
            char url[1024];
            struct in_addr in;
            int port, ttl;

            if (reply->transports[0].destination) {
                in.s_addr = htonl(reply->transports[0].destination);
                port      = reply->transports[0].port_min;
                ttl       = reply->transports[0].ttl;
            } else {
                in        = rtsp_st->sdp_ip;
                port      = rtsp_st->sdp_port;
                ttl       = rtsp_st->sdp_ttl;
            }
1233 1234
            ff_url_join(url, sizeof(url), "rtp", NULL, inet_ntoa(in),
                        port, "?ttl=%d", ttl);
1235 1236 1237
            if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
                err = AVERROR_INVALIDDATA;
                goto fail;
1238 1239 1240
            }
            break;
        }
1241
        }
R
Romain Degez 已提交
1242

1243
        if ((err = rtsp_open_transport_ctx(s, rtsp_st)))
1244
            goto fail;
1245 1246
    }

1247 1248 1249
    if (reply->timeout > 0)
        rt->timeout = reply->timeout;

1250
    if (rt->server_type == RTSP_SERVER_REAL)
1251 1252
        rt->need_subscription = 1;

1253 1254 1255
    return 0;

fail:
1256
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
1257 1258 1259 1260 1261
        if (rt->rtsp_streams[i]->rtp_handle) {
            url_close(rt->rtsp_streams[i]->rtp_handle);
            rt->rtsp_streams[i]->rtp_handle = NULL;
        }
    }
1262 1263 1264
    return err;
}

1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276
static int rtsp_read_play(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    RTSPMessageHeader reply1, *reply = &reply1;
    char cmd[1024];

    av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);

    if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
        if (rt->state == RTSP_STATE_PAUSED) {
            snprintf(cmd, sizeof(cmd),
                     "PLAY %s RTSP/1.0\r\n",
1277
                     rt->control_uri);
1278 1279 1280 1281
        } else {
            snprintf(cmd, sizeof(cmd),
                     "PLAY %s RTSP/1.0\r\n"
                     "Range: npt=%0.3f-\r\n",
1282
                     rt->control_uri,
1283 1284
                     (double)rt->seek_timestamp / AV_TIME_BASE);
        }
1285
        ff_rtsp_send_cmd(s, cmd, reply, NULL);
1286 1287 1288 1289
        if (reply->status_code != RTSP_STATUS_OK) {
            return -1;
        }
    }
1290
    rt->state = RTSP_STATE_STREAMING;
1291 1292 1293
    return 0;
}

1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305
static int rtsp_setup_input_streams(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    RTSPMessageHeader reply1, *reply = &reply1;
    char cmd[1024];
    unsigned char *content = NULL;
    int ret;

    /* describe the stream */
    snprintf(cmd, sizeof(cmd),
             "DESCRIBE %s RTSP/1.0\r\n"
             "Accept: application/sdp\r\n",
1306
             rt->control_uri);
1307 1308 1309 1310 1311 1312 1313 1314 1315
    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));
    }
1316
    ff_rtsp_send_cmd(s, cmd, reply, &content);
1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332
    if (!content)
        return AVERROR_INVALIDDATA;
    if (reply->status_code != RTSP_STATUS_OK) {
        av_freep(&content);
        return AVERROR_INVALIDDATA;
    }

    /* 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;
}

1333
static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr)
1334 1335 1336 1337 1338 1339
{
    RTSPState *rt = s->priv_data;
    RTSPMessageHeader reply1, *reply = &reply1;
    char cmd[1024];
    int i;
    char *sdp;
1340
    AVFormatContext sdp_ctx, *ctx_array[1];
1341 1342 1343 1344 1345

    /* Announce the stream */
    snprintf(cmd, sizeof(cmd),
             "ANNOUNCE %s RTSP/1.0\r\n"
             "Content-Type: application/sdp\r\n",
1346
             rt->control_uri);
1347 1348 1349
    sdp = av_mallocz(8192);
    if (sdp == NULL)
        return AVERROR(ENOMEM);
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366
    /* 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;
    if (avf_sdp_create(ctx_array, 1, sdp, 8192)) {
1367 1368 1369 1370
        av_free(sdp);
        return AVERROR_INVALIDDATA;
    }
    av_log(s, AV_LOG_INFO, "SDP:\n%s\n", sdp);
1371
    ff_rtsp_send_cmd_with_content(s, cmd, reply, NULL, sdp, strlen(sdp));
1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388
    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;

1389
        av_strlcpy(rtsp_st->control_url, rt->control_uri, sizeof(rtsp_st->control_url));
1390 1391 1392 1393 1394 1395 1396 1397
        /* 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;
}

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

    if (!ff_network_init())
        return AVERROR(EIO);
1413
redirect:
1414
    /* extract hostname and port */
1415
    ff_url_split(NULL, 0, auth, sizeof(auth),
M
Martin Storsjö 已提交
1416
                 host, sizeof(host), &port, path, sizeof(path), s->filename);
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426
    if (*auth) {
        int auth_len = strlen(auth), b64_len = ((auth_len + 2) / 3) * 4 + 1;

        if (!(rt->auth_b64 = av_malloc(b64_len)))
            return AVERROR(ENOMEM);
        if (!av_base64_encode(rt->auth_b64, b64_len, auth, auth_len)) {
            err = AVERROR(EINVAL);
            goto fail;
        }
    }
1427 1428 1429 1430 1431 1432
    if (port < 0)
        port = RTSP_DEFAULT_PORT;

    /* search for options */
    option_list = strchr(path, '?');
    if (option_list) {
1433
        filename = strchr(s->filename, '?');
1434
        while (option_list) {
1435
            /* move the option pointer */
1436
            option = ++option_list;
1437 1438
            option_list = strchr(option_list, '&');
            if (option_list)
1439 1440
                *option_list = 0;

1441
            /* handle the options */
1442
            if (!strcmp(option, "udp")) {
1443
                lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_UDP);
1444
            } else if (!strcmp(option, "multicast")) {
1445
                lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_UDP_MULTICAST);
1446
            } else if (!strcmp(option, "tcp")) {
1447
                lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_TCP);
1448
            } else {
1449 1450 1451 1452
                strcpy(++filename, option);
                filename += strlen(option);
                if (option_list) *filename = '&';
            }
1453
        }
1454
        *filename = 0;
1455 1456
    }

1457
    if (!lower_transport_mask)
1458
        lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
1459

1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470
    if (s->oformat) {
        /* Only UDP output is supported at the moment. */
        lower_transport_mask &= 1 << RTSP_LOWER_TRANSPORT_UDP;
        if (!lower_transport_mask) {
            av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, "
                                    "only UDP is supported for output.\n");
            err = AVERROR(EINVAL);
            goto fail;
        }
    }

1471
    /* open the tcp connexion */
1472
    ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL);
1473 1474 1475 1476
    if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0) {
        err = AVERROR(EIO);
        goto fail;
    }
1477 1478 1479
    rt->rtsp_hd = rtsp_hd;
    rt->seq = 0;

1480 1481 1482 1483 1484 1485
    tcp_fd = url_get_file_handle(rtsp_hd);
    if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) {
        getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host),
                    NULL, 0, NI_NUMERICHOST);
    }

1486 1487
    /* request options supported by the server; this also detects server
     * type */
1488 1489
    av_strlcpy(rt->control_uri, s->filename,
               sizeof(rt->control_uri));
1490 1491
    for (rt->server_type = RTSP_SERVER_RTP;;) {
        snprintf(cmd, sizeof(cmd),
1492
                 "OPTIONS %s RTSP/1.0\r\n", rt->control_uri);
1493
        if (rt->server_type == RTSP_SERVER_REAL)
1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508
            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));
1509
        ff_rtsp_send_cmd(s, cmd, reply, NULL);
1510 1511 1512 1513 1514 1515
        if (reply->status_code != RTSP_STATUS_OK) {
            err = AVERROR_INVALIDDATA;
            goto fail;
        }

        /* detect server type if not standard-compliant RTP */
1516 1517
        if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
            rt->server_type = RTSP_SERVER_REAL;
1518
            continue;
1519 1520
        } else if (!strncasecmp(reply->server, "WMServer/", 9)) {
            rt->server_type = RTSP_SERVER_WMS;
1521
        } else if (rt->server_type == RTSP_SERVER_REAL)
1522 1523 1524 1525
            strcpy(real_challenge, reply->real_challenge);
        break;
    }

1526
    if (s->iformat)
1527
        err = rtsp_setup_input_streams(s);
1528
    else
1529
        err = rtsp_setup_output_streams(s, host);
1530
    if (err)
1531 1532
        goto fail;

1533
    do {
1534 1535
        int lower_transport = ff_log2_tab[lower_transport_mask &
                                  ~(lower_transport_mask - 1)];
1536

1537
        err = make_setup_request(s, host, port, lower_transport,
1538
                                 rt->server_type == RTSP_SERVER_REAL ?
1539
                                     real_challenge : NULL);
1540
        if (err < 0)
1541
            goto fail;
1542 1543
        lower_transport_mask &= ~(1 << lower_transport);
        if (lower_transport_mask == 0 && err == 1) {
1544
            err = AVERROR(FF_NETERROR(EPROTONOSUPPORT));
1545 1546 1547
            goto fail;
        }
    } while (err);
1548

1549
    rt->state = RTSP_STATE_IDLE;
1550
    rt->seek_timestamp = 0; /* default is to start stream at position zero */
1551 1552
    return 0;
 fail:
1553
    ff_rtsp_close_streams(s);
1554
    url_close(rt->rtsp_hd);
1555
    if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) {
L
Luca Barbato 已提交
1556 1557 1558 1559 1560 1561
        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;
    }
1562
    ff_network_close();
1563 1564
    return err;
}
M
Martin Storsjö 已提交
1565
#endif
1566

M
Martin Storsjö 已提交
1567
#if CONFIG_RTSP_DEMUXER
1568 1569 1570 1571 1572 1573
static int rtsp_read_header(AVFormatContext *s,
                            AVFormatParameters *ap)
{
    RTSPState *rt = s->priv_data;
    int ret;

1574
    ret = ff_rtsp_connect(s);
1575 1576 1577 1578 1579 1580 1581
    if (ret)
        return ret;

    if (ap->initial_pause) {
         /* do not start immediately */
    } else {
         if (rtsp_read_play(s) < 0) {
1582
            ff_rtsp_close_streams(s);
1583 1584 1585 1586 1587 1588 1589 1590
            url_close(rt->rtsp_hd);
            return AVERROR_INVALIDDATA;
        }
    }

    return 0;
}

R
Ronald S. Bultje 已提交
1591 1592 1593 1594 1595 1596 1597 1598 1599
static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
                           uint8_t *buf, int buf_size)
{
    RTSPState *rt = s->priv_data;
    RTSPStream *rtsp_st;
    fd_set rfds;
    int fd, fd_max, n, i, ret, tcp_fd;
    struct timeval tv;

1600
    for (;;) {
R
Ronald S. Bultje 已提交
1601 1602 1603 1604 1605 1606 1607 1608 1609 1610
        if (url_interrupt_cb())
            return AVERROR(EINTR);
        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;
        }
1611
        for (i = 0; i < rt->nb_rtsp_streams; i++) {
R
Ronald S. Bultje 已提交
1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625
            rtsp_st = rt->rtsp_streams[i];
            if (rtsp_st->rtp_handle) {
                /* currently, we cannot probe RTCP handle because of
                 * blocking restrictions */
                fd = url_get_file_handle(rtsp_st->rtp_handle);
                if (fd > fd_max)
                    fd_max = fd;
                FD_SET(fd, &rfds);
            }
        }
        tv.tv_sec = 0;
        tv.tv_usec = 100 * 1000;
        n = select(fd_max + 1, &rfds, NULL, NULL, &tv);
        if (n > 0) {
1626
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
R
Ronald S. Bultje 已提交
1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639
                rtsp_st = rt->rtsp_streams[i];
                if (rtsp_st->rtp_handle) {
                    fd = url_get_file_handle(rtsp_st->rtp_handle);
                    if (FD_ISSET(fd, &rfds)) {
                        ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
                        if (ret > 0) {
                            *prtsp_st = rtsp_st;
                            return ret;
                        }
                    }
                }
            }
#if CONFIG_RTSP_DEMUXER
1640
            if (tcp_fd != -1 && FD_ISSET(tcp_fd, &rfds)) {
R
Ronald S. Bultje 已提交
1641 1642
                RTSPMessageHeader reply;

1643
                ff_rtsp_read_reply(s, &reply, NULL, 0);
R
Ronald S. Bultje 已提交
1644
                /* XXX: parse message */
1645
                if (rt->state != RTSP_STATE_STREAMING)
R
Ronald S. Bultje 已提交
1646 1647 1648 1649 1650 1651 1652
                    return 0;
            }
#endif
        }
    }
}

1653 1654
static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
                           uint8_t *buf, int buf_size)
1655 1656
{
    RTSPState *rt = s->priv_data;
F
Fabrice Bellard 已提交
1657
    int id, len, i, ret;
1658 1659
    RTSPStream *rtsp_st;

F
Fabrice Bellard 已提交
1660
#ifdef DEBUG_RTP_TCP
1661
    dprintf(s, "tcp_read_packet:\n");
F
Fabrice Bellard 已提交
1662
#endif
1663 1664
redo:
    for (;;) {
1665 1666
        RTSPMessageHeader reply;

1667
        ret = ff_rtsp_read_reply(s, &reply, NULL, 1);
1668
        if (ret == -1)
1669
            return -1;
1670
        if (ret == 1) /* received '$' */
1671
            break;
1672
        /* XXX: parse message */
1673
        if (rt->state != RTSP_STATE_STREAMING)
1674
            return 0;
1675
    }
1676
    ret = url_read_complete(rt->rtsp_hd, buf, 3);
F
Fabrice Bellard 已提交
1677
    if (ret != 3)
1678
        return -1;
1679
    id  = buf[0];
1680
    len = AV_RB16(buf + 1);
F
Fabrice Bellard 已提交
1681
#ifdef DEBUG_RTP_TCP
1682
    dprintf(s, "id=%d len=%d\n", id, len);
F
Fabrice Bellard 已提交
1683
#endif
1684
    if (len > buf_size || len < 12)
1685 1686
        goto redo;
    /* get the data */
1687
    ret = url_read_complete(rt->rtsp_hd, buf, len);
F
Fabrice Bellard 已提交
1688
    if (ret != len)
1689
        return -1;
1690
    if (rt->transport == RTSP_TRANSPORT_RDT &&
1691
        ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0)
1692
        return -1;
1693

1694
    /* find the matching stream */
1695
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
1696
        rtsp_st = rt->rtsp_streams[i];
1697 1698
        if (id >= rtsp_st->interleaved_min &&
            id <= rtsp_st->interleaved_max)
1699 1700 1701
            goto found;
    }
    goto redo;
1702
found:
1703 1704
    *prtsp_st = rtsp_st;
    return len;
1705 1706
}

R
Ronald S. Bultje 已提交
1707 1708 1709 1710 1711 1712 1713 1714 1715
static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
{
    RTSPState *rt = s->priv_data;
    int ret, len;
    uint8_t buf[10 * RTP_MAX_PACKET_LENGTH];
    RTSPStream *rtsp_st;

    /* get next frames from the same RTP packet */
    if (rt->cur_transport_priv) {
1716
        if (rt->transport == RTSP_TRANSPORT_RDT) {
R
Ronald S. Bultje 已提交
1717
            ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
1718
        } else
R
Ronald S. Bultje 已提交
1719 1720 1721 1722 1723 1724
            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;
1725
        } else
R
Ronald S. Bultje 已提交
1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748
            rt->cur_transport_priv = NULL;
    }

    /* read next RTP packet */
 redo:
    switch(rt->lower_transport) {
    default:
#if CONFIG_RTSP_DEMUXER
    case RTSP_LOWER_TRANSPORT_TCP:
        len = tcp_read_packet(s, &rtsp_st, buf, sizeof(buf));
        break;
#endif
    case RTSP_LOWER_TRANSPORT_UDP:
    case RTSP_LOWER_TRANSPORT_UDP_MULTICAST:
        len = udp_read_packet(s, &rtsp_st, buf, sizeof(buf));
        if (len >=0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
            rtp_check_and_send_back_rr(rtsp_st->transport_priv, len);
        break;
    }
    if (len < 0)
        return len;
    if (len == 0)
        return AVERROR_EOF;
1749
    if (rt->transport == RTSP_TRANSPORT_RDT) {
R
Ronald S. Bultje 已提交
1750
        ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, buf, len);
1751
    } else
R
Ronald S. Bultje 已提交
1752 1753 1754
        ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, buf, len);
    if (ret < 0)
        goto redo;
1755
    if (ret == 1)
R
Ronald S. Bultje 已提交
1756 1757 1758 1759 1760 1761
        /* more packets may follow, so we save the RTP context */
        rt->cur_transport_priv = rtsp_st->transport_priv;

    return ret;
}

1762
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
1763 1764
{
    RTSPState *rt = s->priv_data;
1765
    int ret;
1766 1767
    RTSPMessageHeader reply1, *reply = &reply1;
    char cmd[1024];
1768

1769
    if (rt->server_type == RTSP_SERVER_REAL) {
1770
        int i;
1771
        enum AVDiscard cache[MAX_STREAMS];
1772

1773 1774 1775 1776 1777 1778
        for (i = 0; i < s->nb_streams; i++)
            cache[i] = s->streams[i]->discard;

        if (!rt->need_subscription) {
            if (memcmp (cache, rt->real_setup_cache,
                        sizeof(enum AVDiscard) * s->nb_streams)) {
1779
                snprintf(cmd, sizeof(cmd),
R
Ronald S. Bultje 已提交
1780 1781
                         "SET_PARAMETER %s RTSP/1.0\r\n"
                         "Unsubscribe: %s\r\n",
1782
                         rt->control_uri, rt->last_subscription);
1783
                ff_rtsp_send_cmd(s, cmd, reply, NULL);
1784 1785 1786 1787
                if (reply->status_code != RTSP_STATUS_OK)
                    return AVERROR_INVALIDDATA;
                rt->need_subscription = 1;
            }
1788 1789
        }

1790 1791 1792 1793 1794 1795 1796 1797 1798 1799
        if (rt->need_subscription) {
            int r, rule_nr, first = 1;

            memcpy(rt->real_setup_cache, cache,
                   sizeof(enum AVDiscard) * s->nb_streams);
            rt->last_subscription[0] = 0;

            snprintf(cmd, sizeof(cmd),
                     "SET_PARAMETER %s RTSP/1.0\r\n"
                     "Subscribe: ",
1800
                     rt->control_uri);
1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818
            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);
1819
            ff_rtsp_send_cmd(s, cmd, reply, NULL);
1820 1821 1822 1823
            if (reply->status_code != RTSP_STATUS_OK)
                return AVERROR_INVALIDDATA;
            rt->need_subscription = 0;

1824
            if (rt->state == RTSP_STATE_STREAMING)
1825 1826
                rtsp_read_play (s);
        }
1827 1828
    }

L
Luca Barbato 已提交
1829
    ret = rtsp_fetch_packet(s, pkt);
1830
    if (ret < 0)
1831
        return ret;
1832 1833 1834 1835 1836 1837 1838 1839

    /* send dummy request to keep TCP connection alive */
    if ((rt->server_type == RTSP_SERVER_WMS ||
         rt->server_type == RTSP_SERVER_REAL) &&
        (av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {
        if (rt->server_type == RTSP_SERVER_WMS) {
            snprintf(cmd, sizeof(cmd) - 1,
                     "GET_PARAMETER %s RTSP/1.0\r\n",
1840
                     rt->control_uri);
1841
            ff_rtsp_send_cmd_async(s, cmd);
1842
        } else {
1843
            ff_rtsp_send_cmd_async(s, "OPTIONS * RTSP/1.0\r\n");
1844 1845 1846
        }
    }

1847
    return 0;
1848 1849
}

1850 1851
/* pause the stream */
static int rtsp_read_pause(AVFormatContext *s)
1852
{
1853
    RTSPState *rt = s->priv_data;
1854
    RTSPMessageHeader reply1, *reply = &reply1;
1855 1856 1857
    char cmd[1024];

    rt = s->priv_data;
1858

1859
    if (rt->state != RTSP_STATE_STREAMING)
1860
        return 0;
1861
    else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
1862 1863
        snprintf(cmd, sizeof(cmd),
                 "PAUSE %s RTSP/1.0\r\n",
1864
                 rt->control_uri);
1865
        ff_rtsp_send_cmd(s, cmd, reply, NULL);
1866 1867 1868
        if (reply->status_code != RTSP_STATUS_OK) {
            return -1;
        }
1869
    }
1870 1871
    rt->state = RTSP_STATE_PAUSED;
    return 0;
1872 1873
}

1874
static int rtsp_read_seek(AVFormatContext *s, int stream_index,
1875
                          int64_t timestamp, int flags)
1876 1877
{
    RTSPState *rt = s->priv_data;
1878

1879 1880 1881
    rt->seek_timestamp = av_rescale_q(timestamp,
                                      s->streams[stream_index]->time_base,
                                      AV_TIME_BASE_Q);
1882 1883 1884 1885
    switch(rt->state) {
    default:
    case RTSP_STATE_IDLE:
        break;
1886
    case RTSP_STATE_STREAMING:
1887 1888 1889
        if (rtsp_read_pause(s) != 0)
            return -1;
        rt->state = RTSP_STATE_SEEKING;
1890 1891 1892 1893 1894 1895 1896 1897 1898 1899
        if (rtsp_read_play(s) != 0)
            return -1;
        break;
    case RTSP_STATE_PAUSED:
        rt->state = RTSP_STATE_IDLE;
        break;
    }
    return 0;
}

1900 1901 1902 1903 1904
static int rtsp_read_close(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    char cmd[1024];

F
Fabrice Bellard 已提交
1905
#if 0
1906
    /* NOTE: it is valid to flush the buffer here */
1907
    if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
1908 1909
        url_fclose(&rt->rtsp_gb);
    }
F
Fabrice Bellard 已提交
1910
#endif
1911
    snprintf(cmd, sizeof(cmd),
F
Fabrice Bellard 已提交
1912
             "TEARDOWN %s RTSP/1.0\r\n",
1913
             rt->control_uri);
1914
    ff_rtsp_send_cmd_async(s, cmd);
1915

1916
    ff_rtsp_close_streams(s);
1917
    url_close(rt->rtsp_hd);
1918
    ff_network_close();
1919 1920 1921
    return 0;
}

1922
AVInputFormat rtsp_demuxer = {
1923
    "rtsp",
1924
    NULL_IF_CONFIG_SMALL("RTSP input format"),
1925 1926 1927 1928 1929
    sizeof(RTSPState),
    rtsp_probe,
    rtsp_read_header,
    rtsp_read_packet,
    rtsp_read_close,
1930
    rtsp_read_seek,
1931
    .flags = AVFMT_NOFILE,
1932 1933
    .read_play = rtsp_read_play,
    .read_pause = rtsp_read_pause,
1934
};
1935
#endif
1936

1937
static int sdp_probe(AVProbeData *p1)
1938
{
1939
    const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
1940 1941

    /* we look for a line beginning "c=IN IP4" */
1942
    while (p < p_end && *p != '\0') {
1943 1944
        if (p + sizeof("c=IN IP4") - 1 < p_end &&
            av_strstart(p, "c=IN IP4", NULL))
1945
            return AVPROBE_SCORE_MAX / 2;
1946

1947
        while (p < p_end - 1 && *p != '\n') p++;
1948
        if (++p >= p_end)
1949 1950 1951 1952
            break;
        if (*p == '\r')
            p++;
    }
1953 1954 1955 1956 1957
    return 0;
}

#define SDP_MAX_SIZE 8192

1958
static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap)
1959
{
1960
    RTSPState *rt = s->priv_data;
1961 1962 1963 1964 1965
    RTSPStream *rtsp_st;
    int size, i, err;
    char *content;
    char url[1024];

1966 1967 1968
    if (!ff_network_init())
        return AVERROR(EIO);

1969 1970 1971
    /* read the whole sdp file */
    /* XXX: better loading */
    content = av_malloc(SDP_MAX_SIZE);
1972
    size = get_buffer(s->pb, content, SDP_MAX_SIZE - 1);
1973 1974 1975 1976 1977 1978 1979 1980 1981 1982
    if (size <= 0) {
        av_free(content);
        return AVERROR_INVALIDDATA;
    }
    content[size] ='\0';

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

    /* open each RTP stream */
1983
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
1984
        rtsp_st = rt->rtsp_streams[i];
1985

1986 1987 1988 1989
        ff_url_join(url, sizeof(url), "rtp", NULL,
                    inet_ntoa(rtsp_st->sdp_ip), rtsp_st->sdp_port,
                    "?localport=%d&ttl=%d", rtsp_st->sdp_port,
                    rtsp_st->sdp_ttl);
1990
        if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
1991 1992 1993
            err = AVERROR_INVALIDDATA;
            goto fail;
        }
1994
        if ((err = rtsp_open_transport_ctx(s, rtsp_st)))
1995
            goto fail;
1996 1997
    }
    return 0;
1998
fail:
1999
    ff_rtsp_close_streams(s);
2000
    ff_network_close();
2001 2002 2003 2004 2005
    return err;
}

static int sdp_read_close(AVFormatContext *s)
{
2006
    ff_rtsp_close_streams(s);
2007
    ff_network_close();
2008 2009 2010
    return 0;
}

2011
AVInputFormat sdp_demuxer = {
2012
    "sdp",
2013
    NULL_IF_CONFIG_SMALL("SDP"),
2014 2015 2016
    sizeof(RTSPState),
    sdp_probe,
    sdp_read_header,
L
Luca Barbato 已提交
2017
    rtsp_fetch_packet,
2018 2019
    sdp_read_close,
};