rtsp.c 64.0 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 23 24
/* needed by inet_aton() */
#define _SVID_SOURCE

25
#include "libavutil/base64.h"
26
#include "libavutil/avstring.h"
27
#include "libavutil/intreadwrite.h"
28 29
#include "avformat.h"

30
#include <sys/time.h>
31
#if HAVE_SYS_SELECT_H
32
#include <sys/select.h>
33
#endif
34
#include <strings.h>
35
#include "network.h"
36
#include "rtsp.h"
37

38
#include "rtpdec.h"
39
#include "rdt.h"
40
#include "rtp_asf.h"
41
#include "rtp_vorbis.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

50
#define SPACE_CHARS " \t\r\n"
51 52 53
/* 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)
54 55 56 57 58 59 60 61 62
static void skip_spaces(const char **pp)
{
    const char *p;
    p = *pp;
    while (redir_isspace(*p))
        p++;
    *pp = p;
}

63 64
static void get_word_until_chars(char *buf, int buf_size,
                                 const char *sep, const char **pp)
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
{
    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;
}

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

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

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

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

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

R
Ronald S. Bultje 已提交
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
    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 已提交
153
        }
R
Ronald S. Bultje 已提交
154 155 156 157 158 159 160 161 162 163 164 165
        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;
166 167
}

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

    len = 0;
    v = 1;
175
    for (;;) {
176
        skip_spaces(&p);
177
        if (*p == '\0')
178
            break;
179
        c = toupper((unsigned char) *p++);
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
        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;
}

197 198
static void sdp_parse_fmtp_config(AVCodecContext * codec, void *ctx,
                                  char *attr, char *value)
R
Romain Degez 已提交
199 200
{
    switch (codec->codec_id) {
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
    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 已提交
220 221 222 223
    }
    return;
}

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

/* All known fmtp parmeters and the corresping RTPAttrTypeEnum */
#define ATTR_NAME_TYPE_INT 0
#define ATTR_NAME_TYPE_STR 1
L
Luca Barbato 已提交
233
static const AttrNameMap attr_names[]=
R
Romain Degez 已提交
234
{
235 236 237 238 239 240 241 242 243 244 245 246 247
    { "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 已提交
248 249
};

250 251 252 253 254
/* 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. */
int rtsp_next_attr_and_value(const char **p, char *attr, int attr_size,
                             char *value, int value_size)
255 256
{
    skip_spaces(p);
257
    if (**p) {
258 259 260 261 262 263 264 265 266 267 268
        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 已提交
269 270
/* parse a SDP line and save stream attributes */
static void sdp_parse_fmtp(AVStream *st, const char *p)
271 272
{
    char attr[256];
273 274 275
    /* 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 已提交
276 277
    int i;
    RTSPStream *rtsp_st = st->priv_data;
278
    AVCodecContext *codec = st->codec;
279
    RTPPayloadData *rtp_payload_data = &rtsp_st->rtp_payload_data;
280 281

    /* loop on each attribute */
282 283 284 285
    while (rtsp_next_attr_and_value(&p, attr, sizeof(attr),
                                    value, sizeof(value))) {
        /* grab the codec extra_data from the config parameter of the fmtp
         * line */
286 287
        sdp_parse_fmtp_config(codec, rtsp_st->dynamic_protocol_context,
                              attr, value);
R
Romain Degez 已提交
288 289 290
        /* Looking for a known attribute */
        for (i = 0; attr_names[i].str; ++i) {
            if (!strcasecmp(attr, attr_names[i].str)) {
291 292 293 294 295 296
                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);
297
            }
298 299 300 301
        }
    }
}

S
Stefano Sabatini 已提交
302
/** Parse a string p in the form of Range:npt=xx-xx, and determine the start
303 304 305 306 307 308 309 310
 *  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);
311
    if (!av_stristart(p, "npt=", &p))
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
        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);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

613 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
static void *rtsp_rtp_mux_open(AVFormatContext *s, AVStream *st, URLContext *handle) {
    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 (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 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 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 935
        /* 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 {
            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 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 rtsp_send_cmd_async(AVFormatContext *s, const char *cmd)
1004 1005 1006 1007
{
    rtsp_send_cmd_with_content_async(s, cmd, NULL, 0);
}

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

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

1017
void 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 1025 1026 1027 1028
{
    rtsp_send_cmd_with_content_async(s, cmd, send_content, send_content_length);

    rtsp_read_reply(s, reply, content_ptr, 0);
}

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 1093 1094 1095 1096 1097
                while (j <= RTSP_RTP_PORT_MAX) {
                    snprintf(buf, sizeof(buf), "rtp://%s?localport=%d",
                             host, j);
                    /* 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
        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 1204 1205 1206 1207 1208 1209
        case RTSP_LOWER_TRANSPORT_UDP: {
            char url[1024];

            /* XXX: also use address if specified */
            snprintf(url, sizeof(url), "rtp://%s:%d",
                     host, reply->transports[0].server_port_min);
            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 1233 1234 1235 1236 1237
        }
        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;
            }
            snprintf(url, sizeof(url), "rtp://%s:%d?ttl=%d",
                     inet_ntoa(in), port, ttl);
            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 1285 1286 1287 1288 1289
                     (double)rt->seek_timestamp / AV_TIME_BASE);
        }
        rtsp_send_cmd(s, cmd, reply, NULL);
        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 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332
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",
             s->filename);
    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));
    }
    rtsp_send_cmd(s, cmd, reply, &content);
    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 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380
static int rtsp_setup_output_streams(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    RTSPMessageHeader reply1, *reply = &reply1;
    char cmd[1024];
    int i;
    char *sdp;

    /* Announce the stream */
    snprintf(cmd, sizeof(cmd),
             "ANNOUNCE %s RTSP/1.0\r\n"
             "Content-Type: application/sdp\r\n",
             s->filename);
    sdp = av_mallocz(8192);
    if (sdp == NULL)
        return AVERROR(ENOMEM);
    if (avf_sdp_create(&s, 1, sdp, 8192)) {
        av_free(sdp);
        return AVERROR_INVALIDDATA;
    }
    av_log(s, AV_LOG_INFO, "SDP:\n%s\n", sdp);
    rtsp_send_cmd_with_content(s, cmd, reply, NULL, sdp, strlen(sdp));
    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;

        av_strlcpy(rtsp_st->control_url, s->filename, sizeof(rtsp_st->control_url));
        /* 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;
}

1381
int rtsp_connect(AVFormatContext *s)
1382 1383
{
    RTSPState *rt = s->priv_data;
1384 1385
    char host[1024], path[1024], tcpname[1024], cmd[2048], auth[128];
    char *option_list, *option, *filename;
1386
    URLContext *rtsp_hd;
1387
    int port, err;
1388
    RTSPMessageHeader reply1, *reply = &reply1;
1389
    int lower_transport_mask = 0;
1390
    char real_challenge[64];
1391
redirect:
1392
    /* extract hostname and port */
1393
    url_split(NULL, 0, auth, sizeof(auth),
1394
              host, sizeof(host), &port, path, sizeof(path), s->filename);
1395 1396 1397 1398 1399 1400 1401 1402 1403 1404
    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;
        }
    }
1405 1406 1407 1408 1409 1410
    if (port < 0)
        port = RTSP_DEFAULT_PORT;

    /* search for options */
    option_list = strchr(path, '?');
    if (option_list) {
1411
        filename = strchr(s->filename, '?');
1412
        while (option_list) {
1413
            /* move the option pointer */
1414
            option = ++option_list;
1415 1416
            option_list = strchr(option_list, '&');
            if (option_list)
1417 1418
                *option_list = 0;

1419
            /* handle the options */
1420
            if (!strcmp(option, "udp")) {
1421
                lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_UDP);
1422
            } else if (!strcmp(option, "multicast")) {
1423
                lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_UDP_MULTICAST);
1424
            } else if (!strcmp(option, "tcp")) {
1425
                lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_TCP);
1426
            } else {
1427 1428 1429 1430
                strcpy(++filename, option);
                filename += strlen(option);
                if (option_list) *filename = '&';
            }
1431
        }
1432
        *filename = 0;
1433 1434
    }

1435
    if (!lower_transport_mask)
1436
        lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
1437

1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448
    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;
        }
    }

1449 1450
    /* open the tcp connexion */
    snprintf(tcpname, sizeof(tcpname), "tcp://%s:%d", host, port);
1451 1452 1453 1454
    if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0) {
        err = AVERROR(EIO);
        goto fail;
    }
1455 1456 1457
    rt->rtsp_hd = rtsp_hd;
    rt->seq = 0;

1458 1459
    /* request options supported by the server; this also detects server
     * type */
1460 1461
    av_strlcpy(rt->control_uri, s->filename,
               sizeof(rt->control_uri));
1462 1463 1464
    for (rt->server_type = RTSP_SERVER_RTP;;) {
        snprintf(cmd, sizeof(cmd),
                 "OPTIONS %s RTSP/1.0\r\n", s->filename);
1465
        if (rt->server_type == RTSP_SERVER_REAL)
1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487
            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));
        rtsp_send_cmd(s, cmd, reply, NULL);
        if (reply->status_code != RTSP_STATUS_OK) {
            err = AVERROR_INVALIDDATA;
            goto fail;
        }

        /* detect server type if not standard-compliant RTP */
1488 1489
        if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
            rt->server_type = RTSP_SERVER_REAL;
1490
            continue;
1491 1492
        } else if (!strncasecmp(reply->server, "WMServer/", 9)) {
            rt->server_type = RTSP_SERVER_WMS;
1493
        } else if (rt->server_type == RTSP_SERVER_REAL)
1494 1495 1496 1497
            strcpy(real_challenge, reply->real_challenge);
        break;
    }

1498
    if (s->iformat)
1499
        err = rtsp_setup_input_streams(s);
1500 1501
    else
        err = rtsp_setup_output_streams(s);
1502
    if (err)
1503 1504
        goto fail;

1505
    do {
1506 1507
        int lower_transport = ff_log2_tab[lower_transport_mask &
                                  ~(lower_transport_mask - 1)];
1508

1509
        err = make_setup_request(s, host, port, lower_transport,
1510
                                 rt->server_type == RTSP_SERVER_REAL ?
1511
                                     real_challenge : NULL);
1512
        if (err < 0)
1513
            goto fail;
1514 1515
        lower_transport_mask &= ~(1 << lower_transport);
        if (lower_transport_mask == 0 && err == 1) {
1516
            err = AVERROR(FF_NETERROR(EPROTONOSUPPORT));
1517 1518 1519
            goto fail;
        }
    } while (err);
1520

1521
    rt->state = RTSP_STATE_IDLE;
1522
    rt->seek_timestamp = 0; /* default is to start stream at position zero */
1523 1524
    return 0;
 fail:
1525
    rtsp_close_streams(s);
1526
    url_close(rt->rtsp_hd);
1527
    if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) {
L
Luca Barbato 已提交
1528 1529 1530 1531 1532 1533
        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;
    }
1534 1535
    return err;
}
M
Martin Storsjö 已提交
1536
#endif
1537

M
Martin Storsjö 已提交
1538
#if CONFIG_RTSP_DEMUXER
1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561
static int rtsp_read_header(AVFormatContext *s,
                            AVFormatParameters *ap)
{
    RTSPState *rt = s->priv_data;
    int ret;

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

    if (ap->initial_pause) {
         /* do not start immediately */
    } else {
         if (rtsp_read_play(s) < 0) {
            rtsp_close_streams(s);
            url_close(rt->rtsp_hd);
            return AVERROR_INVALIDDATA;
        }
    }

    return 0;
}

R
Ronald S. Bultje 已提交
1562 1563 1564 1565 1566 1567 1568 1569 1570
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;

1571
    for (;;) {
R
Ronald S. Bultje 已提交
1572 1573 1574 1575 1576 1577 1578 1579 1580 1581
        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;
        }
1582
        for (i = 0; i < rt->nb_rtsp_streams; i++) {
R
Ronald S. Bultje 已提交
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596
            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) {
1597
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
R
Ronald S. Bultje 已提交
1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610
                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
1611
            if (tcp_fd != -1 && FD_ISSET(tcp_fd, &rfds)) {
R
Ronald S. Bultje 已提交
1612 1613 1614 1615
                RTSPMessageHeader reply;

                rtsp_read_reply(s, &reply, NULL, 0);
                /* XXX: parse message */
1616
                if (rt->state != RTSP_STATE_STREAMING)
R
Ronald S. Bultje 已提交
1617 1618 1619 1620 1621 1622 1623
                    return 0;
            }
#endif
        }
    }
}

1624 1625
static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
                           uint8_t *buf, int buf_size)
1626 1627
{
    RTSPState *rt = s->priv_data;
F
Fabrice Bellard 已提交
1628
    int id, len, i, ret;
1629 1630
    RTSPStream *rtsp_st;

F
Fabrice Bellard 已提交
1631
#ifdef DEBUG_RTP_TCP
1632
    dprintf(s, "tcp_read_packet:\n");
F
Fabrice Bellard 已提交
1633
#endif
1634 1635
redo:
    for (;;) {
1636 1637 1638 1639
        RTSPMessageHeader reply;

        ret = rtsp_read_reply(s, &reply, NULL, 1);
        if (ret == -1)
1640
            return -1;
1641
        if (ret == 1) /* received '$' */
1642
            break;
1643
        /* XXX: parse message */
1644
        if (rt->state != RTSP_STATE_STREAMING)
1645
            return 0;
1646
    }
1647
    ret = url_read_complete(rt->rtsp_hd, buf, 3);
F
Fabrice Bellard 已提交
1648
    if (ret != 3)
1649
        return -1;
1650
    id  = buf[0];
1651
    len = AV_RB16(buf + 1);
F
Fabrice Bellard 已提交
1652
#ifdef DEBUG_RTP_TCP
1653
    dprintf(s, "id=%d len=%d\n", id, len);
F
Fabrice Bellard 已提交
1654
#endif
1655
    if (len > buf_size || len < 12)
1656 1657
        goto redo;
    /* get the data */
1658
    ret = url_read_complete(rt->rtsp_hd, buf, len);
F
Fabrice Bellard 已提交
1659
    if (ret != len)
1660
        return -1;
1661
    if (rt->transport == RTSP_TRANSPORT_RDT &&
1662
        ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0)
1663
        return -1;
1664

1665
    /* find the matching stream */
1666
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
1667
        rtsp_st = rt->rtsp_streams[i];
1668 1669
        if (id >= rtsp_st->interleaved_min &&
            id <= rtsp_st->interleaved_max)
1670 1671 1672
            goto found;
    }
    goto redo;
1673
found:
1674 1675
    *prtsp_st = rtsp_st;
    return len;
1676 1677
}

R
Ronald S. Bultje 已提交
1678 1679 1680 1681 1682 1683 1684 1685 1686
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) {
1687
        if (rt->transport == RTSP_TRANSPORT_RDT) {
R
Ronald S. Bultje 已提交
1688
            ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
1689
        } else
R
Ronald S. Bultje 已提交
1690 1691 1692 1693 1694 1695
            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;
1696
        } else
R
Ronald S. Bultje 已提交
1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719
            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;
1720
    if (rt->transport == RTSP_TRANSPORT_RDT) {
R
Ronald S. Bultje 已提交
1721
        ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, buf, len);
1722
    } else
R
Ronald S. Bultje 已提交
1723 1724 1725
        ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, buf, len);
    if (ret < 0)
        goto redo;
1726
    if (ret == 1)
R
Ronald S. Bultje 已提交
1727 1728 1729 1730 1731 1732
        /* more packets may follow, so we save the RTP context */
        rt->cur_transport_priv = rtsp_st->transport_priv;

    return ret;
}

1733
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
1734 1735
{
    RTSPState *rt = s->priv_data;
1736
    int ret;
1737 1738
    RTSPMessageHeader reply1, *reply = &reply1;
    char cmd[1024];
1739

1740
    if (rt->server_type == RTSP_SERVER_REAL) {
1741
        int i;
1742
        enum AVDiscard cache[MAX_STREAMS];
1743

1744 1745 1746 1747 1748 1749
        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)) {
1750
                snprintf(cmd, sizeof(cmd),
R
Ronald S. Bultje 已提交
1751 1752
                         "SET_PARAMETER %s RTSP/1.0\r\n"
                         "Unsubscribe: %s\r\n",
1753
                         rt->control_uri, rt->last_subscription);
1754 1755 1756 1757 1758
                rtsp_send_cmd(s, cmd, reply, NULL);
                if (reply->status_code != RTSP_STATUS_OK)
                    return AVERROR_INVALIDDATA;
                rt->need_subscription = 1;
            }
1759 1760
        }

1761 1762 1763 1764 1765 1766 1767 1768 1769 1770
        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: ",
1771
                     rt->control_uri);
1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794
            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);
            rtsp_send_cmd(s, cmd, reply, NULL);
            if (reply->status_code != RTSP_STATUS_OK)
                return AVERROR_INVALIDDATA;
            rt->need_subscription = 0;

1795
            if (rt->state == RTSP_STATE_STREAMING)
1796 1797
                rtsp_read_play (s);
        }
1798 1799
    }

L
Luca Barbato 已提交
1800
    ret = rtsp_fetch_packet(s, pkt);
1801
    if (ret < 0)
1802
        return ret;
1803 1804 1805 1806 1807 1808 1809 1810

    /* 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",
1811
                     rt->control_uri);
1812
            rtsp_send_cmd_async(s, cmd);
1813
        } else {
1814
            rtsp_send_cmd_async(s, "OPTIONS * RTSP/1.0\r\n");
1815 1816 1817
        }
    }

1818
    return 0;
1819 1820
}

1821 1822
/* pause the stream */
static int rtsp_read_pause(AVFormatContext *s)
1823
{
1824
    RTSPState *rt = s->priv_data;
1825
    RTSPMessageHeader reply1, *reply = &reply1;
1826 1827 1828
    char cmd[1024];

    rt = s->priv_data;
1829

1830
    if (rt->state != RTSP_STATE_STREAMING)
1831
        return 0;
1832
    else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
1833 1834
        snprintf(cmd, sizeof(cmd),
                 "PAUSE %s RTSP/1.0\r\n",
1835
                 rt->control_uri);
1836 1837 1838 1839
        rtsp_send_cmd(s, cmd, reply, NULL);
        if (reply->status_code != RTSP_STATUS_OK) {
            return -1;
        }
1840
    }
1841 1842
    rt->state = RTSP_STATE_PAUSED;
    return 0;
1843 1844
}

1845
static int rtsp_read_seek(AVFormatContext *s, int stream_index,
1846
                          int64_t timestamp, int flags)
1847 1848
{
    RTSPState *rt = s->priv_data;
1849

1850 1851 1852
    rt->seek_timestamp = av_rescale_q(timestamp,
                                      s->streams[stream_index]->time_base,
                                      AV_TIME_BASE_Q);
1853 1854 1855 1856
    switch(rt->state) {
    default:
    case RTSP_STATE_IDLE:
        break;
1857
    case RTSP_STATE_STREAMING:
1858 1859 1860
        if (rtsp_read_pause(s) != 0)
            return -1;
        rt->state = RTSP_STATE_SEEKING;
1861 1862 1863 1864 1865 1866 1867 1868 1869 1870
        if (rtsp_read_play(s) != 0)
            return -1;
        break;
    case RTSP_STATE_PAUSED:
        rt->state = RTSP_STATE_IDLE;
        break;
    }
    return 0;
}

1871 1872 1873 1874 1875
static int rtsp_read_close(AVFormatContext *s)
{
    RTSPState *rt = s->priv_data;
    char cmd[1024];

F
Fabrice Bellard 已提交
1876
#if 0
1877
    /* NOTE: it is valid to flush the buffer here */
1878
    if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
1879 1880
        url_fclose(&rt->rtsp_gb);
    }
F
Fabrice Bellard 已提交
1881
#endif
1882
    snprintf(cmd, sizeof(cmd),
F
Fabrice Bellard 已提交
1883
             "TEARDOWN %s RTSP/1.0\r\n",
1884
             s->filename);
1885
    rtsp_send_cmd_async(s, cmd);
1886

1887
    rtsp_close_streams(s);
1888 1889 1890 1891
    url_close(rt->rtsp_hd);
    return 0;
}

1892
AVInputFormat rtsp_demuxer = {
1893
    "rtsp",
1894
    NULL_IF_CONFIG_SMALL("RTSP input format"),
1895 1896 1897 1898 1899
    sizeof(RTSPState),
    rtsp_probe,
    rtsp_read_header,
    rtsp_read_packet,
    rtsp_read_close,
1900
    rtsp_read_seek,
1901
    .flags = AVFMT_NOFILE,
1902 1903
    .read_play = rtsp_read_play,
    .read_pause = rtsp_read_pause,
1904
};
1905
#endif
1906

1907
static int sdp_probe(AVProbeData *p1)
1908
{
1909
    const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
1910 1911

    /* we look for a line beginning "c=IN IP4" */
1912
    while (p < p_end && *p != '\0') {
1913 1914
        if (p + sizeof("c=IN IP4") - 1 < p_end &&
            av_strstart(p, "c=IN IP4", NULL))
1915
            return AVPROBE_SCORE_MAX / 2;
1916

1917
        while (p < p_end - 1 && *p != '\n') p++;
1918
        if (++p >= p_end)
1919 1920 1921 1922
            break;
        if (*p == '\r')
            p++;
    }
1923 1924 1925 1926 1927
    return 0;
}

#define SDP_MAX_SIZE 8192

1928
static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap)
1929
{
1930
    RTSPState *rt = s->priv_data;
1931 1932 1933 1934 1935 1936 1937 1938
    RTSPStream *rtsp_st;
    int size, i, err;
    char *content;
    char url[1024];

    /* read the whole sdp file */
    /* XXX: better loading */
    content = av_malloc(SDP_MAX_SIZE);
1939
    size = get_buffer(s->pb, content, SDP_MAX_SIZE - 1);
1940 1941 1942 1943 1944 1945 1946 1947 1948 1949
    if (size <= 0) {
        av_free(content);
        return AVERROR_INVALIDDATA;
    }
    content[size] ='\0';

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

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

1953
        snprintf(url, sizeof(url), "rtp://%s:%d?localport=%d&ttl=%d",
1954
                 inet_ntoa(rtsp_st->sdp_ip),
1955
                 rtsp_st->sdp_port,
1956
                 rtsp_st->sdp_port,
1957
                 rtsp_st->sdp_ttl);
1958
        if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
1959 1960 1961
            err = AVERROR_INVALIDDATA;
            goto fail;
        }
1962
        if ((err = rtsp_open_transport_ctx(s, rtsp_st)))
1963
            goto fail;
1964 1965
    }
    return 0;
1966
fail:
1967
    rtsp_close_streams(s);
1968 1969 1970 1971 1972
    return err;
}

static int sdp_read_close(AVFormatContext *s)
{
1973
    rtsp_close_streams(s);
1974 1975 1976
    return 0;
}

1977
AVInputFormat sdp_demuxer = {
1978
    "sdp",
1979
    NULL_IF_CONFIG_SMALL("SDP"),
1980 1981 1982
    sizeof(RTSPState),
    sdp_probe,
    sdp_read_header,
L
Luca Barbato 已提交
1983
    rtsp_fetch_packet,
1984 1985
    sdp_read_close,
};