~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavformat/rtsp.c

  • Committer: Bazaar Package Importer
  • Author(s): John Dong
  • Date: 2008-02-25 15:47:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080225154712-qvr11ekcea4c9ry8
Tags: 1.1.6-0.1ubuntu1
* Merge from debian-multimedia (LP: #120003), Ubuntu Changes:
 - For ffmpeg-related build-deps, remove cvs from package names.
 - Standards-Version 3.7.3
 - Maintainer Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * RTSP/SDP client
3
3
 * Copyright (c) 2002 Fabrice Bellard.
4
4
 *
5
 
 * This library is free software; you can redistribute it and/or
 
5
 * This file is part of FFmpeg.
 
6
 *
 
7
 * FFmpeg is free software; you can redistribute it and/or
6
8
 * modify it under the terms of the GNU Lesser General Public
7
9
 * License as published by the Free Software Foundation; either
8
 
 * version 2 of the License, or (at your option) any later version.
 
10
 * version 2.1 of the License, or (at your option) any later version.
9
11
 *
10
 
 * This library is distributed in the hope that it will be useful,
 
12
 * FFmpeg is distributed in the hope that it will be useful,
11
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
15
 * Lesser General Public License for more details.
14
16
 *
15
17
 * You should have received a copy of the GNU Lesser General Public
16
 
 * License along with this library; if not, write to the Free Software
17
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
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
18
20
 */
19
21
#include "avformat.h"
20
22
 
 
23
#include <sys/time.h>
21
24
#include <unistd.h> /* for select() prototype */
22
 
#include <sys/time.h>
23
 
#include <netinet/in.h>
24
 
#include <sys/socket.h>
25
 
#ifndef __BEOS__
26
 
# include <arpa/inet.h>
27
 
#else
28
 
# include "barpainet.h"
29
 
#endif
 
25
#include "network.h"
 
26
 
 
27
#include "rtp_internal.h"
30
28
 
31
29
//#define DEBUG
32
30
//#define DEBUG_RTP_TCP
33
31
 
 
32
enum RTSPClientState {
 
33
    RTSP_STATE_IDLE,
 
34
    RTSP_STATE_PLAYING,
 
35
    RTSP_STATE_PAUSED,
 
36
};
 
37
 
34
38
typedef struct RTSPState {
35
39
    URLContext *rtsp_hd; /* RTSP TCP connexion handle */
 
40
    int nb_rtsp_streams;
 
41
    struct RTSPStream **rtsp_streams;
 
42
 
 
43
    enum RTSPClientState state;
 
44
    int64_t seek_timestamp;
 
45
 
36
46
    /* XXX: currently we use unbuffered input */
37
47
    //    ByteIOContext rtsp_gb;
38
48
    int seq;        /* RTSP command sequence number */
39
49
    char session_id[512];
40
50
    enum RTSPProtocol protocol;
41
51
    char last_reply[2048]; /* XXX: allocate ? */
 
52
    RTPDemuxContext *cur_rtp;
42
53
} RTSPState;
43
54
 
44
55
typedef struct RTSPStream {
45
 
    AVFormatContext *ic;
 
56
    URLContext *rtp_handle; /* RTP stream handle */
 
57
    RTPDemuxContext *rtp_ctx; /* RTP parse context */
 
58
 
 
59
    int stream_index; /* corresponding stream index, if any. -1 if none (MPEG2TS case) */
46
60
    int interleaved_min, interleaved_max;  /* interleave ids, if TCP transport */
47
61
    char control_url[1024]; /* url for this stream (from SDP) */
48
62
 
50
64
    struct in_addr sdp_ip; /* IP address  (from SDP content - not used in RTSP) */
51
65
    int sdp_ttl;  /* IP TTL (from SDP content - not used in RTSP) */
52
66
    int sdp_payload_type; /* payload type - only used in SDP */
 
67
    rtp_payload_data_t rtp_payload_data; /* rtp payload parsing infos from SDP */
 
68
 
 
69
    RTPDynamicProtocolHandler *dynamic_handler; ///< Only valid if it's a dynamic protocol. (This is the handler structure)
 
70
    void *dynamic_protocol_context; ///< Only valid if it's a dynamic protocol. (This is any private data associated with the dynamic protocol)
53
71
} RTSPStream;
54
72
 
 
73
static int rtsp_read_play(AVFormatContext *s);
 
74
 
55
75
/* XXX: currently, the only way to change the protocols consists in
56
76
   changing this variable */
57
 
#if 1
58
 
int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP) | (1 << RTSP_PROTOCOL_RTP_UDP) | (1 << RTSP_PROTOCOL_RTP_UDP_MULTICAST);
59
 
#else
60
 
/* try it if a proxy is used */
61
 
int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP);
62
 
#endif
63
77
 
64
 
/* if non zero, then set a range for RTP ports */
65
 
int rtsp_rtp_port_min = 0;
66
 
int rtsp_rtp_port_max = 0;
 
78
int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_UDP);
67
79
 
68
80
FFRTSPCallback *ff_rtsp_callback = NULL;
69
81
 
88
100
    *pp = p;
89
101
}
90
102
 
91
 
static void get_word_sep(char *buf, int buf_size, const char *sep, 
 
103
static void get_word_sep(char *buf, int buf_size, const char *sep,
92
104
                         const char **pp)
93
105
{
94
106
    const char *p;
95
107
    char *q;
96
108
 
97
109
    p = *pp;
 
110
    if (*p == '/')
 
111
        p++;
98
112
    skip_spaces(&p);
99
113
    q = buf;
100
114
    while (!strchr(sep, *p) && *p != '\0') {
127
141
 
128
142
/* parse the rtpmap description: <codec_name>/<clock_rate>[/<other
129
143
   params>] */
130
 
static int sdp_parse_rtpmap(AVCodecContext *codec, const char *p)
 
144
static int sdp_parse_rtpmap(AVCodecContext *codec, RTSPStream *rtsp_st, int payload_type, const char *p)
131
145
{
132
146
    char buf[256];
 
147
    int i;
 
148
    AVCodec *c;
 
149
    const char *c_name;
133
150
 
134
 
    /* codec name */
 
151
    /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and
 
152
       see if we can handle this kind of payload */
135
153
    get_word_sep(buf, sizeof(buf), "/", &p);
136
 
    if (!strcmp(buf, "MP4V-ES")) {
137
 
        codec->codec_id = CODEC_ID_MPEG4;
 
154
    if (payload_type >= RTP_PT_PRIVATE) {
 
155
        RTPDynamicProtocolHandler *handler= RTPFirstDynamicPayloadHandler;
 
156
        while(handler) {
 
157
            if (!strcmp(buf, handler->enc_name) && (codec->codec_type == handler->codec_type)) {
 
158
                codec->codec_id = handler->codec_id;
 
159
                rtsp_st->dynamic_handler= handler;
 
160
                if(handler->open) {
 
161
                    rtsp_st->dynamic_protocol_context= handler->open();
 
162
                }
 
163
                break;
 
164
            }
 
165
            handler= handler->next;
 
166
        }
 
167
    } else {
 
168
        /* We are in a standard case ( from http://www.iana.org/assignments/rtp-parameters) */
 
169
        /* search into AVRtpPayloadTypes[] */
 
170
        for (i = 0; AVRtpPayloadTypes[i].pt >= 0; ++i)
 
171
            if (!strcmp(buf, AVRtpPayloadTypes[i].enc_name) && (codec->codec_type == AVRtpPayloadTypes[i].codec_type)){
 
172
                codec->codec_id = AVRtpPayloadTypes[i].codec_id;
 
173
                break;
 
174
            }
 
175
    }
 
176
 
 
177
    c = avcodec_find_decoder(codec->codec_id);
 
178
    if (c && c->name)
 
179
        c_name = c->name;
 
180
    else
 
181
        c_name = (char *)NULL;
 
182
 
 
183
    if (c_name) {
 
184
        get_word_sep(buf, sizeof(buf), "/", &p);
 
185
        i = atoi(buf);
 
186
        switch (codec->codec_type) {
 
187
            case CODEC_TYPE_AUDIO:
 
188
                av_log(codec, AV_LOG_DEBUG, " audio codec set to : %s\n", c_name);
 
189
                codec->sample_rate = RTSP_DEFAULT_AUDIO_SAMPLERATE;
 
190
                codec->channels = RTSP_DEFAULT_NB_AUDIO_CHANNELS;
 
191
                if (i > 0) {
 
192
                    codec->sample_rate = i;
 
193
                    get_word_sep(buf, sizeof(buf), "/", &p);
 
194
                    i = atoi(buf);
 
195
                    if (i > 0)
 
196
                        codec->channels = i;
 
197
                    // TODO: there is a bug here; if it is a mono stream, and less than 22000Hz, faad upconverts to stereo and twice the
 
198
                    //  frequency.  No problem, but the sample rate is being set here by the sdp line.  Upcoming patch forthcoming. (rdm)
 
199
                }
 
200
                av_log(codec, AV_LOG_DEBUG, " audio samplerate set to : %i\n", codec->sample_rate);
 
201
                av_log(codec, AV_LOG_DEBUG, " audio channels set to : %i\n", codec->channels);
 
202
                break;
 
203
            case CODEC_TYPE_VIDEO:
 
204
                av_log(codec, AV_LOG_DEBUG, " video codec set to : %s\n", c_name);
 
205
                break;
 
206
            default:
 
207
                break;
 
208
        }
138
209
        return 0;
139
 
    } else {
140
 
        return -1;
141
210
    }
 
211
 
 
212
    return -1;
142
213
}
143
214
 
144
215
/* return the length and optionnaly the data */
170
241
    return len;
171
242
}
172
243
 
173
 
static void sdp_parse_fmtp(AVCodecContext *codec, const char *p)
 
244
static void sdp_parse_fmtp_config(AVCodecContext *codec, char *attr, char *value)
174
245
{
175
 
    char attr[256];
176
 
    char value[4096];
177
 
    int len;
178
 
 
179
 
    /* loop on each attribute */
180
 
    for(;;) {
181
 
        skip_spaces(&p);
182
 
        if (*p == '\0')
183
 
            break;
184
 
        get_word_sep(attr, sizeof(attr), "=", &p);
185
 
        if (*p == '=') 
186
 
            p++;
187
 
        get_word_sep(value, sizeof(value), ";", &p);
188
 
        if (*p == ';')
189
 
            p++;
190
 
        /* handle MPEG4 video */
191
 
        switch(codec->codec_id) {
 
246
    switch (codec->codec_id) {
192
247
        case CODEC_ID_MPEG4:
 
248
        case CODEC_ID_AAC:
193
249
            if (!strcmp(attr, "config")) {
194
250
                /* decode the hexa encoded parameter */
195
 
                len = hex_to_data(NULL, value);
196
 
                codec->extradata = av_mallocz(len);
 
251
                int len = hex_to_data(NULL, value);
 
252
                codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
197
253
                if (!codec->extradata)
198
 
                    goto fail;
 
254
                    return;
199
255
                codec->extradata_size = len;
200
256
                hex_to_data(codec->extradata, value);
201
257
            }
202
258
            break;
203
259
        default:
204
 
            /* ignore data for other codecs */
205
260
            break;
 
261
    }
 
262
    return;
 
263
}
 
264
 
 
265
typedef struct attrname_map
 
266
{
 
267
    const char *str;
 
268
    uint16_t type;
 
269
    uint32_t offset;
 
270
} attrname_map_t;
 
271
 
 
272
/* All known fmtp parmeters and the corresping RTPAttrTypeEnum */
 
273
#define ATTR_NAME_TYPE_INT 0
 
274
#define ATTR_NAME_TYPE_STR 1
 
275
static attrname_map_t attr_names[]=
 
276
{
 
277
    {"SizeLength",       ATTR_NAME_TYPE_INT, offsetof(rtp_payload_data_t, sizelength)},
 
278
    {"IndexLength",      ATTR_NAME_TYPE_INT, offsetof(rtp_payload_data_t, indexlength)},
 
279
    {"IndexDeltaLength", ATTR_NAME_TYPE_INT, offsetof(rtp_payload_data_t, indexdeltalength)},
 
280
    {"profile-level-id", ATTR_NAME_TYPE_INT, offsetof(rtp_payload_data_t, profile_level_id)},
 
281
    {"StreamType",       ATTR_NAME_TYPE_INT, offsetof(rtp_payload_data_t, streamtype)},
 
282
    {"mode",             ATTR_NAME_TYPE_STR, offsetof(rtp_payload_data_t, mode)},
 
283
    {NULL, -1, -1},
 
284
};
 
285
 
 
286
/** parse the attribute line from the fmtp a line of an sdp resonse.  This is broken out as a function
 
287
* because it is used in rtp_h264.c, which is forthcoming.
 
288
*/
 
289
int rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, char *value, int value_size)
 
290
{
 
291
    skip_spaces(p);
 
292
    if(**p)
 
293
    {
 
294
        get_word_sep(attr, attr_size, "=", p);
 
295
        if (**p == '=')
 
296
            (*p)++;
 
297
        get_word_sep(value, value_size, ";", p);
 
298
        if (**p == ';')
 
299
            (*p)++;
 
300
        return 1;
 
301
    }
 
302
    return 0;
 
303
}
 
304
 
 
305
/* parse a SDP line and save stream attributes */
 
306
static void sdp_parse_fmtp(AVStream *st, const char *p)
 
307
{
 
308
    char attr[256];
 
309
    char value[4096];
 
310
    int i;
 
311
 
 
312
    RTSPStream *rtsp_st = st->priv_data;
 
313
    AVCodecContext *codec = st->codec;
 
314
    rtp_payload_data_t *rtp_payload_data = &rtsp_st->rtp_payload_data;
 
315
 
 
316
    /* loop on each attribute */
 
317
    while(rtsp_next_attr_and_value(&p, attr, sizeof(attr), value, sizeof(value)))
 
318
    {
 
319
        /* grab the codec extra_data from the config parameter of the fmtp line */
 
320
        sdp_parse_fmtp_config(codec, attr, value);
 
321
        /* Looking for a known attribute */
 
322
        for (i = 0; attr_names[i].str; ++i) {
 
323
            if (!strcasecmp(attr, attr_names[i].str)) {
 
324
                if (attr_names[i].type == ATTR_NAME_TYPE_INT)
 
325
                    *(int *)((char *)rtp_payload_data + attr_names[i].offset) = atoi(value);
 
326
                else if (attr_names[i].type == ATTR_NAME_TYPE_STR)
 
327
                    *(char **)((char *)rtp_payload_data + attr_names[i].offset) = av_strdup(value);
 
328
            }
206
329
        }
207
 
    fail: ;
208
 
        //        printf("'%s' = '%s'\n", attr, value);
209
 
    }
 
330
    }
 
331
}
 
332
 
 
333
/** Parse a string \p in the form of Range:npt=xx-xx, and determine the start
 
334
 *  and end time.
 
335
 *  Used for seeking in the rtp stream.
 
336
 */
 
337
static void rtsp_parse_range_npt(const char *p, int64_t *start, int64_t *end)
 
338
{
 
339
    char buf[256];
 
340
 
 
341
    skip_spaces(&p);
 
342
    if (!stristart(p, "npt=", &p))
 
343
        return;
 
344
 
 
345
    *start = AV_NOPTS_VALUE;
 
346
    *end = AV_NOPTS_VALUE;
 
347
 
 
348
    get_word_sep(buf, sizeof(buf), "-", &p);
 
349
    *start = parse_date(buf, 1);
 
350
    if (*p == '-') {
 
351
        p++;
 
352
        get_word_sep(buf, sizeof(buf), "-", &p);
 
353
        *end = parse_date(buf, 1);
 
354
    }
 
355
//    av_log(NULL, AV_LOG_DEBUG, "Range Start: %lld\n", *start);
 
356
//    av_log(NULL, AV_LOG_DEBUG, "Range End: %lld\n", *end);
210
357
}
211
358
 
212
359
typedef struct SDPParseState {
218
365
static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
219
366
                           int letter, const char *buf)
220
367
{
 
368
    RTSPState *rt = s->priv_data;
221
369
    char buf1[64], st_type[64];
222
370
    const char *p;
223
371
    int codec_type, payload_type, i;
280
428
        rtsp_st = av_mallocz(sizeof(RTSPStream));
281
429
        if (!rtsp_st)
282
430
            return;
283
 
        st = av_new_stream(s, s->nb_streams);
284
 
        if (!st) 
285
 
            return;
286
 
        st->priv_data = rtsp_st;
 
431
        rtsp_st->stream_index = -1;
 
432
        dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st);
287
433
 
288
434
        rtsp_st->sdp_ip = s1->default_ip;
289
435
        rtsp_st->sdp_ttl = s1->default_ttl;
290
436
 
291
 
        st->codec.codec_type = codec_type;
292
 
 
293
437
        get_word(buf1, sizeof(buf1), &p); /* port */
294
438
        rtsp_st->sdp_port = atoi(buf1);
295
439
 
296
440
        get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */
297
 
        
 
441
 
298
442
        /* XXX: handle list of formats */
299
443
        get_word(buf1, sizeof(buf1), &p); /* format list */
300
444
        rtsp_st->sdp_payload_type = atoi(buf1);
301
 
        if (rtsp_st->sdp_payload_type < 96) {
302
 
            /* if standard payload type, we can find the codec right now */
303
 
            rtp_get_codec_info(&st->codec, rtsp_st->sdp_payload_type);
 
445
 
 
446
        if (!strcmp(AVRtpPayloadTypes[rtsp_st->sdp_payload_type].enc_name, "MP2T")) {
 
447
            /* no corresponding stream */
 
448
        } else {
 
449
            st = av_new_stream(s, 0);
 
450
            if (!st)
 
451
                return;
 
452
            st->priv_data = rtsp_st;
 
453
            rtsp_st->stream_index = st->index;
 
454
            st->codec->codec_type = codec_type;
 
455
            if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
 
456
                /* if standard payload type, we can find the codec right now */
 
457
                rtp_get_codec_info(st->codec, rtsp_st->sdp_payload_type);
 
458
            }
304
459
        }
305
 
 
306
460
        /* put a default control url */
307
461
        pstrcpy(rtsp_st->control_url, sizeof(rtsp_st->control_url), s->filename);
308
462
        break;
312
466
            /* get the control url */
313
467
            st = s->streams[s->nb_streams - 1];
314
468
            rtsp_st = st->priv_data;
315
 
            
 
469
 
316
470
            /* XXX: may need to add full url resolution */
317
 
            url_split(proto, sizeof(proto), NULL, 0, NULL, NULL, 0, p);
 
471
            url_split(proto, sizeof(proto), NULL, 0, NULL, 0, NULL, NULL, 0, p);
318
472
            if (proto[0] == '\0') {
319
473
                /* relative control URL */
320
474
                pstrcat(rtsp_st->control_url, sizeof(rtsp_st->control_url), "/");
324
478
            }
325
479
        } else if (strstart(p, "rtpmap:", &p)) {
326
480
            /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
327
 
            get_word(buf1, sizeof(buf1), &p); 
 
481
            get_word(buf1, sizeof(buf1), &p);
328
482
            payload_type = atoi(buf1);
329
483
            for(i = 0; i < s->nb_streams;i++) {
330
484
                st = s->streams[i];
331
485
                rtsp_st = st->priv_data;
332
486
                if (rtsp_st->sdp_payload_type == payload_type) {
333
 
                    sdp_parse_rtpmap(&st->codec, p);
 
487
                    sdp_parse_rtpmap(st->codec, rtsp_st, payload_type, p);
334
488
                }
335
489
            }
336
490
        } else if (strstart(p, "fmtp:", &p)) {
337
491
            /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */
338
 
            get_word(buf1, sizeof(buf1), &p); 
339
 
            payload_type = atoi(buf1);
340
 
            for(i = 0; i < s->nb_streams;i++) {
341
 
                st = s->streams[i];
342
 
                rtsp_st = st->priv_data;
343
 
                if (rtsp_st->sdp_payload_type == payload_type) {
344
 
                    sdp_parse_fmtp(&st->codec, p);
345
 
                }
346
 
            }
 
492
            get_word(buf1, sizeof(buf1), &p);
 
493
            payload_type = atoi(buf1);
 
494
            for(i = 0; i < s->nb_streams;i++) {
 
495
                st = s->streams[i];
 
496
                rtsp_st = st->priv_data;
 
497
                if (rtsp_st->sdp_payload_type == payload_type) {
 
498
                    if(rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->parse_sdp_a_line) {
 
499
                        if(!rtsp_st->dynamic_handler->parse_sdp_a_line(st, rtsp_st->dynamic_protocol_context, buf)) {
 
500
                            sdp_parse_fmtp(st, p);
 
501
                        }
 
502
                    } else {
 
503
                        sdp_parse_fmtp(st, p);
 
504
                    }
 
505
                }
 
506
            }
 
507
        } else if(strstart(p, "framesize:", &p)) {
 
508
            // let dynamic protocol handlers have a stab at the line.
 
509
            get_word(buf1, sizeof(buf1), &p);
 
510
            payload_type = atoi(buf1);
 
511
            for(i = 0; i < s->nb_streams;i++) {
 
512
                st = s->streams[i];
 
513
                rtsp_st = st->priv_data;
 
514
                if (rtsp_st->sdp_payload_type == payload_type) {
 
515
                    if(rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->parse_sdp_a_line) {
 
516
                        rtsp_st->dynamic_handler->parse_sdp_a_line(st, rtsp_st->dynamic_protocol_context, buf);
 
517
                    }
 
518
                }
 
519
            }
 
520
        } else if(strstart(p, "range:", &p)) {
 
521
            int64_t start, end;
 
522
 
 
523
            // this is so that seeking on a streamed file can work.
 
524
            rtsp_parse_range_npt(p, &start, &end);
 
525
            s->start_time= start;
 
526
            s->duration= (end==AV_NOPTS_VALUE)?AV_NOPTS_VALUE:end-start; // AV_NOPTS_VALUE means live broadcast (and can't seek)
347
527
        }
348
528
        break;
349
529
    }
355
535
    int letter;
356
536
    char buf[1024], *q;
357
537
    SDPParseState sdp_parse_state, *s1 = &sdp_parse_state;
358
 
    
 
538
 
359
539
    memset(s1, 0, sizeof(SDPParseState));
360
540
    p = content;
361
541
    for(;;) {
414
594
    char parameter[16];
415
595
    RTSPTransportField *th;
416
596
    char buf[256];
417
 
    
 
597
 
418
598
    reply->nb_transports = 0;
419
 
    
 
599
 
420
600
    for(;;) {
421
601
        skip_spaces(&p);
422
602
        if (*p == '\0')
424
604
 
425
605
        th = &reply->transports[reply->nb_transports];
426
606
 
427
 
        get_word_sep(transport_protocol, sizeof(transport_protocol), 
 
607
        get_word_sep(transport_protocol, sizeof(transport_protocol),
428
608
                     "/", &p);
429
609
        if (*p == '/')
430
610
            p++;
432
612
        lower_transport[0] = '\0';
433
613
        if (*p == '/') {
434
614
            p++;
435
 
            get_word_sep(lower_transport, sizeof(lower_transport), 
 
615
            get_word_sep(lower_transport, sizeof(lower_transport),
436
616
                         ";,", &p);
437
617
        }
438
618
        if (!strcasecmp(lower_transport, "TCP"))
439
619
            th->protocol = RTSP_PROTOCOL_RTP_TCP;
440
620
        else
441
621
            th->protocol = RTSP_PROTOCOL_RTP_UDP;
442
 
        
 
622
 
443
623
        if (*p == ';')
444
624
            p++;
445
625
        /* get each parameter */
453
633
            } else if (!strcmp(parameter, "client_port")) {
454
634
                if (*p == '=') {
455
635
                    p++;
456
 
                    rtsp_parse_range(&th->client_port_min, 
 
636
                    rtsp_parse_range(&th->client_port_min,
457
637
                                     &th->client_port_max, &p);
458
638
                }
459
639
            } else if (!strcmp(parameter, "server_port")) {
460
640
                if (*p == '=') {
461
641
                    p++;
462
 
                    rtsp_parse_range(&th->server_port_min, 
 
642
                    rtsp_parse_range(&th->server_port_min,
463
643
                                     &th->server_port_max, &p);
464
644
                }
465
645
            } else if (!strcmp(parameter, "interleaved")) {
466
646
                if (*p == '=') {
467
647
                    p++;
468
 
                    rtsp_parse_range(&th->interleaved_min, 
 
648
                    rtsp_parse_range(&th->interleaved_min,
469
649
                                     &th->interleaved_max, &p);
470
650
                }
471
651
            } else if (!strcmp(parameter, "multicast")) {
482
662
                if (*p == '=') {
483
663
                    p++;
484
664
                    get_word_sep(buf, sizeof(buf), ";,", &p);
485
 
                    if (inet_aton(buf, &ipaddr)) 
 
665
                    if (inet_aton(buf, &ipaddr))
486
666
                        th->destination = ntohl(ipaddr.s_addr);
487
667
                }
488
668
            }
512
692
        rtsp_parse_transport(reply, p);
513
693
    } else if (stristart(p, "CSeq:", &p)) {
514
694
        reply->seq = strtol(p, NULL, 10);
515
 
    }
 
695
    } else if (stristart(p, "Range:", &p)) {
 
696
        rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end);
 
697
    }
 
698
}
 
699
 
 
700
static int url_readbuf(URLContext *h, unsigned char *buf, int size)
 
701
{
 
702
    int ret, len;
 
703
 
 
704
    len = 0;
 
705
    while (len < size) {
 
706
        ret = url_read(h, buf+len, size-len);
 
707
        if (ret < 1)
 
708
            return ret;
 
709
        len += ret;
 
710
    }
 
711
    return len;
516
712
}
517
713
 
518
714
/* skip a RTP/TCP interleaved packet */
522
718
    int ret, len, len1;
523
719
    uint8_t buf[1024];
524
720
 
525
 
    ret = url_read(rt->rtsp_hd, buf, 3);
 
721
    ret = url_readbuf(rt->rtsp_hd, buf, 3);
526
722
    if (ret != 3)
527
723
        return;
528
724
    len = (buf[1] << 8) | buf[2];
534
730
        len1 = len;
535
731
        if (len1 > sizeof(buf))
536
732
            len1 = sizeof(buf);
537
 
        ret = url_read(rt->rtsp_hd, buf, len1);
 
733
        ret = url_readbuf(rt->rtsp_hd, buf, len1);
538
734
        if (ret != len1)
539
735
            return;
540
736
        len -= len1;
541
737
    }
542
738
}
543
739
 
544
 
static void rtsp_send_cmd(AVFormatContext *s, 
545
 
                          const char *cmd, RTSPHeader *reply, 
 
740
static void rtsp_send_cmd(AVFormatContext *s,
 
741
                          const char *cmd, RTSPHeader *reply,
546
742
                          unsigned char **content_ptr)
547
743
{
548
744
    RTSPState *rt = s->priv_data;
574
770
    for(;;) {
575
771
        q = buf;
576
772
        for(;;) {
577
 
            if (url_read(rt->rtsp_hd, &ch, 1) != 1)
 
773
            if (url_readbuf(rt->rtsp_hd, &ch, 1) != 1)
578
774
                break;
579
775
            if (ch == '\n')
580
776
                break;
606
802
        }
607
803
        line_count++;
608
804
    }
609
 
    
 
805
 
610
806
    if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0')
611
807
        pstrcpy(rt->session_id, sizeof(rt->session_id), reply->session_id);
612
 
    
 
808
 
613
809
    content_length = reply->content_length;
614
810
    if (content_length > 0) {
615
811
        /* leave some room for a trailing '\0' (useful for simple parsing) */
616
812
        content = av_malloc(content_length + 1);
617
 
        url_read(rt->rtsp_hd, content, content_length);
 
813
        (void)url_readbuf(rt->rtsp_hd, content, content_length);
618
814
        content[content_length] = '\0';
619
815
    }
620
816
    if (content_ptr)
629
825
}
630
826
 
631
827
 
 
828
/* close and free RTSP streams */
 
829
static void rtsp_close_streams(RTSPState *rt)
 
830
{
 
831
    int i;
 
832
    RTSPStream *rtsp_st;
 
833
 
 
834
    for(i=0;i<rt->nb_rtsp_streams;i++) {
 
835
        rtsp_st = rt->rtsp_streams[i];
 
836
        if (rtsp_st) {
 
837
            if (rtsp_st->rtp_ctx)
 
838
                rtp_parse_close(rtsp_st->rtp_ctx);
 
839
            if (rtsp_st->rtp_handle)
 
840
                url_close(rtsp_st->rtp_handle);
 
841
            if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context)
 
842
                rtsp_st->dynamic_handler->close(rtsp_st->dynamic_protocol_context);
 
843
        }
 
844
        av_free(rtsp_st);
 
845
    }
 
846
    av_free(rt->rtsp_streams);
 
847
}
 
848
 
632
849
static int rtsp_read_header(AVFormatContext *s,
633
850
                            AVFormatParameters *ap)
634
851
{
635
852
    RTSPState *rt = s->priv_data;
636
853
    char host[1024], path[1024], tcpname[1024], cmd[2048];
637
854
    URLContext *rtsp_hd;
638
 
    int port, i, ret, err;
 
855
    int port, i, j, ret, err;
639
856
    RTSPHeader reply1, *reply = &reply1;
640
857
    unsigned char *content = NULL;
641
 
    AVStream *st;
642
858
    RTSPStream *rtsp_st;
643
859
    int protocol_mask;
 
860
    AVStream *st;
644
861
 
645
862
    /* extract hostname and port */
646
 
    url_split(NULL, 0,
 
863
    url_split(NULL, 0, NULL, 0,
647
864
              host, sizeof(host), &port, path, sizeof(path), s->filename);
648
865
    if (port < 0)
649
866
        port = RTSP_DEFAULT_PORT;
654
871
        return AVERROR_IO;
655
872
    rt->rtsp_hd = rtsp_hd;
656
873
    rt->seq = 0;
657
 
    
 
874
 
658
875
    /* describe the stream */
659
 
    snprintf(cmd, sizeof(cmd), 
 
876
    snprintf(cmd, sizeof(cmd),
660
877
             "DESCRIBE %s RTSP/1.0\r\n"
661
878
             "Accept: application/sdp\r\n",
662
879
             s->filename);
669
886
        err = AVERROR_INVALIDDATA;
670
887
        goto fail;
671
888
    }
672
 
        
 
889
 
673
890
    /* now we got the SDP description, we parse it */
674
891
    ret = sdp_parse(s, (const char *)content);
675
892
    av_freep(&content);
677
894
        err = AVERROR_INVALIDDATA;
678
895
        goto fail;
679
896
    }
680
 
    
 
897
 
681
898
    protocol_mask = rtsp_default_protocols;
682
899
 
683
900
    /* for each stream, make the setup request */
684
901
    /* XXX: we assume the same server is used for the control of each
685
902
       RTSP stream */
686
 
    for(i=0;i<s->nb_streams;i++) {
 
903
 
 
904
    for(j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) {
687
905
        char transport[2048];
688
 
        AVInputFormat *fmt;
689
906
 
690
 
        st = s->streams[i];
691
 
        rtsp_st = st->priv_data;
 
907
        rtsp_st = rt->rtsp_streams[i];
692
908
 
693
909
        /* compute available transports */
694
910
        transport[0] = '\0';
696
912
        /* RTP/UDP */
697
913
        if (protocol_mask & (1 << RTSP_PROTOCOL_RTP_UDP)) {
698
914
            char buf[256];
699
 
            int j;
700
915
 
701
916
            /* first try in specified port range */
702
 
            if (rtsp_rtp_port_min != 0) {
703
 
                for(j=rtsp_rtp_port_min;j<=rtsp_rtp_port_max;j++) {
 
917
            if (RTSP_RTP_PORT_MIN != 0) {
 
918
                while(j <= RTSP_RTP_PORT_MAX) {
704
919
                    snprintf(buf, sizeof(buf), "rtp://?localport=%d", j);
705
 
                    if (!av_open_input_file(&rtsp_st->ic, buf, 
706
 
                                            &rtp_demux, 0, NULL))
 
920
                    if (url_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0) {
 
921
                        j += 2; /* we will use two port by rtp stream (rtp and rtcp) */
707
922
                        goto rtp_opened;
 
923
                    }
708
924
                }
709
925
            }
710
926
 
711
 
            /* then try on any port */
712
 
            if (av_open_input_file(&rtsp_st->ic, "rtp://", 
713
 
                                       &rtp_demux, 0, NULL) < 0) {
714
 
                    err = AVERROR_INVALIDDATA;
715
 
                    goto fail;
716
 
            }
 
927
/*            then try on any port
 
928
**            if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) {
 
929
**                err = AVERROR_INVALIDDATA;
 
930
**                goto fail;
 
931
**            }
 
932
*/
717
933
 
718
934
        rtp_opened:
719
 
            port = rtp_get_local_port(url_fileno(&rtsp_st->ic->pb));
 
935
            port = rtp_get_local_port(rtsp_st->rtp_handle);
720
936
            if (transport[0] != '\0')
721
937
                pstrcat(transport, sizeof(transport), ",");
722
938
            snprintf(transport + strlen(transport), sizeof(transport) - strlen(transport) - 1,
725
941
        }
726
942
 
727
943
        /* RTP/TCP */
728
 
        if (protocol_mask & (1 << RTSP_PROTOCOL_RTP_TCP)) {
 
944
        else if (protocol_mask & (1 << RTSP_PROTOCOL_RTP_TCP)) {
729
945
            if (transport[0] != '\0')
730
946
                pstrcat(transport, sizeof(transport), ",");
731
947
            snprintf(transport + strlen(transport), sizeof(transport) - strlen(transport) - 1,
732
948
                     "RTP/AVP/TCP");
733
949
        }
734
950
 
735
 
        if (protocol_mask & (1 << RTSP_PROTOCOL_RTP_UDP_MULTICAST)) {
 
951
        else if (protocol_mask & (1 << RTSP_PROTOCOL_RTP_UDP_MULTICAST)) {
736
952
            if (transport[0] != '\0')
737
953
                pstrcat(transport, sizeof(transport), ",");
738
 
            snprintf(transport + strlen(transport), 
 
954
            snprintf(transport + strlen(transport),
739
955
                     sizeof(transport) - strlen(transport) - 1,
740
956
                     "RTP/AVP/UDP;multicast");
741
957
        }
742
 
        snprintf(cmd, sizeof(cmd), 
 
958
        snprintf(cmd, sizeof(cmd),
743
959
                 "SETUP %s RTSP/1.0\r\n"
744
960
                 "Transport: %s\r\n",
745
961
                 rtsp_st->control_url, transport);
763
979
        /* close RTP connection if not choosen */
764
980
        if (reply->transports[0].protocol != RTSP_PROTOCOL_RTP_UDP &&
765
981
            (protocol_mask & (1 << RTSP_PROTOCOL_RTP_UDP))) {
766
 
            av_close_input_file(rtsp_st->ic);
767
 
            rtsp_st->ic = NULL;
 
982
            url_close(rtsp_st->rtp_handle);
 
983
            rtsp_st->rtp_handle = NULL;
768
984
        }
769
985
 
770
986
        switch(reply->transports[0].protocol) {
771
987
        case RTSP_PROTOCOL_RTP_TCP:
772
 
            fmt = &rtp_demux;
773
 
            if (av_open_input_file(&rtsp_st->ic, "null", fmt, 0, NULL) < 0) {
774
 
                err = AVERROR_INVALIDDATA;
775
 
                goto fail;
776
 
            }
777
988
            rtsp_st->interleaved_min = reply->transports[0].interleaved_min;
778
989
            rtsp_st->interleaved_max = reply->transports[0].interleaved_max;
779
990
            break;
780
 
            
 
991
 
781
992
        case RTSP_PROTOCOL_RTP_UDP:
782
993
            {
783
994
                char url[1024];
784
 
                
 
995
 
785
996
                /* XXX: also use address if specified */
786
 
                snprintf(url, sizeof(url), "rtp://%s:%d", 
 
997
                snprintf(url, sizeof(url), "rtp://%s:%d",
787
998
                         host, reply->transports[0].server_port_min);
788
 
                if (rtp_set_remote_url(url_fileno(&rtsp_st->ic->pb), url) < 0) {
 
999
                if (rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
789
1000
                    err = AVERROR_INVALIDDATA;
790
1001
                    goto fail;
791
1002
                }
796
1007
                char url[1024];
797
1008
                int ttl;
798
1009
 
799
 
                fmt = &rtp_demux;
800
1010
                ttl = reply->transports[0].ttl;
801
1011
                if (!ttl)
802
1012
                    ttl = 16;
803
 
                snprintf(url, sizeof(url), "rtp://%s:%d?multicast=1&ttl=%d", 
804
 
                         host, 
 
1013
                snprintf(url, sizeof(url), "rtp://%s:%d?multicast=1&ttl=%d",
 
1014
                         host,
805
1015
                         reply->transports[0].server_port_min,
806
1016
                         ttl);
807
 
                if (av_open_input_file(&rtsp_st->ic, url, fmt, 0, NULL) < 0) {
 
1017
                if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
808
1018
                    err = AVERROR_INVALIDDATA;
809
1019
                    goto fail;
810
1020
                }
811
1021
            }
812
1022
            break;
813
1023
        }
 
1024
        /* open the RTP context */
 
1025
        st = NULL;
 
1026
        if (rtsp_st->stream_index >= 0)
 
1027
            st = s->streams[rtsp_st->stream_index];
 
1028
        if (!st)
 
1029
            s->ctx_flags |= AVFMTCTX_NOHEADER;
 
1030
        rtsp_st->rtp_ctx = rtp_parse_open(s, st, rtsp_st->rtp_handle, rtsp_st->sdp_payload_type, &rtsp_st->rtp_payload_data);
 
1031
 
 
1032
        if (!rtsp_st->rtp_ctx) {
 
1033
            err = AVERROR_NOMEM;
 
1034
            goto fail;
 
1035
        } else {
 
1036
            if(rtsp_st->dynamic_handler) {
 
1037
                rtsp_st->rtp_ctx->dynamic_protocol_context= rtsp_st->dynamic_protocol_context;
 
1038
                rtsp_st->rtp_ctx->parse_packet= rtsp_st->dynamic_handler->parse_packet;
 
1039
            }
 
1040
        }
814
1041
    }
815
1042
 
816
1043
    /* use callback if available to extend setup */
817
1044
    if (ff_rtsp_callback) {
818
 
        if (ff_rtsp_callback(RTSP_ACTION_CLIENT_SETUP, rt->session_id, 
 
1045
        if (ff_rtsp_callback(RTSP_ACTION_CLIENT_SETUP, rt->session_id,
819
1046
                             NULL, 0, rt->last_reply) < 0) {
820
1047
            err = AVERROR_INVALIDDATA;
821
1048
            goto fail;
822
1049
        }
823
1050
    }
824
 
                         
825
 
    /* start playing */
826
 
    snprintf(cmd, sizeof(cmd), 
827
 
             "PLAY %s RTSP/1.0\r\n"
828
 
             "Range: npt=0-\r\n",
829
 
             s->filename);
830
 
    rtsp_send_cmd(s, cmd, reply, NULL);
831
 
    if (reply->status_code != RTSP_STATUS_OK) {
832
 
        err = AVERROR_INVALIDDATA;
833
 
        goto fail;
834
 
    }
835
 
 
836
 
#if 0
837
 
    /* open TCP with bufferized input */
838
 
    if (rt->protocol == RTSP_PROTOCOL_RTP_TCP) {
839
 
        if (url_fdopen(&rt->rtsp_gb, rt->rtsp_hd) < 0) {
840
 
            err = AVERROR_NOMEM;
 
1051
 
 
1052
 
 
1053
    rt->state = RTSP_STATE_IDLE;
 
1054
    rt->seek_timestamp = 0; /* default is to start stream at position
 
1055
                               zero */
 
1056
    if (ap->initial_pause) {
 
1057
        /* do not start immediately */
 
1058
    } else {
 
1059
        if (rtsp_read_play(s) < 0) {
 
1060
            err = AVERROR_INVALIDDATA;
841
1061
            goto fail;
842
1062
        }
843
1063
    }
844
 
#endif
845
 
 
846
1064
    return 0;
847
1065
 fail:
848
 
    for(i=0;i<s->nb_streams;i++) {
849
 
        st = s->streams[i];
850
 
        rtsp_st = st->priv_data;
851
 
        if (rtsp_st) {
852
 
            if (rtsp_st->ic)
853
 
                av_close_input_file(rtsp_st->ic);
854
 
        }
855
 
        av_free(rtsp_st);
856
 
    }
 
1066
    rtsp_close_streams(rt);
857
1067
    av_freep(&content);
858
1068
    url_close(rt->rtsp_hd);
859
1069
    return err;
860
1070
}
861
1071
 
862
 
static int tcp_read_packet(AVFormatContext *s,
863
 
                           AVPacket *pkt)
 
1072
static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
 
1073
                           uint8_t *buf, int buf_size)
864
1074
{
865
1075
    RTSPState *rt = s->priv_data;
866
1076
    int id, len, i, ret;
867
 
    AVStream *st;
868
1077
    RTSPStream *rtsp_st;
869
 
    uint8_t buf[RTP_MAX_PACKET_LENGTH];
870
1078
 
871
1079
#ifdef DEBUG_RTP_TCP
872
1080
    printf("tcp_read_packet:\n");
873
1081
#endif
874
1082
 redo:
875
1083
    for(;;) {
876
 
        ret = url_read(rt->rtsp_hd, buf, 1);
 
1084
        ret = url_readbuf(rt->rtsp_hd, buf, 1);
877
1085
#ifdef DEBUG_RTP_TCP
878
1086
        printf("ret=%d c=%02x [%c]\n", ret, buf[0], buf[0]);
879
1087
#endif
880
1088
        if (ret != 1)
881
 
            return AVERROR_IO;
 
1089
            return -1;
882
1090
        if (buf[0] == '$')
883
1091
            break;
884
1092
    }
885
 
    ret = url_read(rt->rtsp_hd, buf, 3);
 
1093
    ret = url_readbuf(rt->rtsp_hd, buf, 3);
886
1094
    if (ret != 3)
887
 
        return AVERROR_IO;
 
1095
        return -1;
888
1096
    id = buf[0];
889
1097
    len = (buf[1] << 8) | buf[2];
890
1098
#ifdef DEBUG_RTP_TCP
891
1099
    printf("id=%d len=%d\n", id, len);
892
1100
#endif
893
 
    if (len > RTP_MAX_PACKET_LENGTH || len < 12)
 
1101
    if (len > buf_size || len < 12)
894
1102
        goto redo;
895
1103
    /* get the data */
896
 
    ret = url_read(rt->rtsp_hd, buf, len);
 
1104
    ret = url_readbuf(rt->rtsp_hd, buf, len);
897
1105
    if (ret != len)
898
 
        return AVERROR_IO;
899
 
        
 
1106
        return -1;
 
1107
 
900
1108
    /* find the matching stream */
901
 
    for(i = 0; i < s->nb_streams; i++) {
902
 
        st = s->streams[i];
903
 
        rtsp_st = st->priv_data;
904
 
        if (id >= rtsp_st->interleaved_min && 
905
 
            id <= rtsp_st->interleaved_max) 
 
1109
    for(i = 0; i < rt->nb_rtsp_streams; i++) {
 
1110
        rtsp_st = rt->rtsp_streams[i];
 
1111
        if (id >= rtsp_st->interleaved_min &&
 
1112
            id <= rtsp_st->interleaved_max)
906
1113
            goto found;
907
1114
    }
908
1115
    goto redo;
909
1116
 found:
910
 
    ret = rtp_parse_packet(rtsp_st->ic, pkt, buf, len);
911
 
    if (ret < 0)
912
 
        goto redo;
913
 
    pkt->stream_index = i;
914
 
    return ret;
 
1117
    *prtsp_st = rtsp_st;
 
1118
    return len;
915
1119
}
916
1120
 
917
 
/* NOTE: output one packet at a time. May need to add a small fifo */
918
 
static int udp_read_packet(AVFormatContext *s,
919
 
                           AVPacket *pkt)
 
1121
static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
 
1122
                           uint8_t *buf, int buf_size)
920
1123
{
921
 
    AVFormatContext *ic;
922
 
    AVStream *st;
 
1124
    RTSPState *rt = s->priv_data;
923
1125
    RTSPStream *rtsp_st;
924
1126
    fd_set rfds;
925
1127
    int fd1, fd2, fd_max, n, i, ret;
926
 
    char buf[RTP_MAX_PACKET_LENGTH];
927
1128
    struct timeval tv;
928
1129
 
929
1130
    for(;;) {
930
1131
        if (url_interrupt_cb())
931
 
            return -EIO;
 
1132
            return -1;
932
1133
        FD_ZERO(&rfds);
933
1134
        fd_max = -1;
934
 
        for(i = 0; i < s->nb_streams; i++) {
935
 
            st = s->streams[i];
936
 
            rtsp_st = st->priv_data;
937
 
            ic = rtsp_st->ic;
 
1135
        for(i = 0; i < rt->nb_rtsp_streams; i++) {
 
1136
            rtsp_st = rt->rtsp_streams[i];
938
1137
            /* currently, we cannot probe RTCP handle because of blocking restrictions */
939
 
            rtp_get_file_handles(url_fileno(&ic->pb), &fd1, &fd2);
 
1138
            rtp_get_file_handles(rtsp_st->rtp_handle, &fd1, &fd2);
940
1139
            if (fd1 > fd_max)
941
1140
                fd_max = fd1;
942
1141
            FD_SET(fd1, &rfds);
943
1142
        }
944
 
        /* XXX: also add proper API to abort */
945
1143
        tv.tv_sec = 0;
946
1144
        tv.tv_usec = 100 * 1000;
947
1145
        n = select(fd_max + 1, &rfds, NULL, NULL, &tv);
948
1146
        if (n > 0) {
949
 
            for(i = 0; i < s->nb_streams; i++) {
950
 
                st = s->streams[i];
951
 
                rtsp_st = st->priv_data;
952
 
                ic = rtsp_st->ic;
953
 
                rtp_get_file_handles(url_fileno(&ic->pb), &fd1, &fd2);
 
1147
            for(i = 0; i < rt->nb_rtsp_streams; i++) {
 
1148
                rtsp_st = rt->rtsp_streams[i];
 
1149
                rtp_get_file_handles(rtsp_st->rtp_handle, &fd1, &fd2);
954
1150
                if (FD_ISSET(fd1, &rfds)) {
955
 
                    ret = url_read(url_fileno(&ic->pb), buf, sizeof(buf));
956
 
                    if (ret >= 0 && 
957
 
                        rtp_parse_packet(ic, pkt, buf, ret) == 0) {
958
 
                        pkt->stream_index = i;
 
1151
                    ret = url_read(rtsp_st->rtp_handle, buf, buf_size);
 
1152
                    if (ret > 0) {
 
1153
                        *prtsp_st = rtsp_st;
959
1154
                        return ret;
960
1155
                    }
961
1156
                }
968
1163
                            AVPacket *pkt)
969
1164
{
970
1165
    RTSPState *rt = s->priv_data;
971
 
    int ret;
972
 
 
 
1166
    RTSPStream *rtsp_st;
 
1167
    int ret, len;
 
1168
    uint8_t buf[RTP_MAX_PACKET_LENGTH];
 
1169
 
 
1170
    /* get next frames from the same RTP packet */
 
1171
    if (rt->cur_rtp) {
 
1172
        ret = rtp_parse_packet(rt->cur_rtp, pkt, NULL, 0);
 
1173
        if (ret == 0) {
 
1174
            rt->cur_rtp = NULL;
 
1175
            return 0;
 
1176
        } else if (ret == 1) {
 
1177
            return 0;
 
1178
        } else {
 
1179
            rt->cur_rtp = NULL;
 
1180
        }
 
1181
    }
 
1182
 
 
1183
    /* read next RTP packet */
 
1184
 redo:
973
1185
    switch(rt->protocol) {
974
1186
    default:
975
1187
    case RTSP_PROTOCOL_RTP_TCP:
976
 
        ret = tcp_read_packet(s, pkt);
 
1188
        len = tcp_read_packet(s, &rtsp_st, buf, sizeof(buf));
977
1189
        break;
978
1190
    case RTSP_PROTOCOL_RTP_UDP:
979
 
        ret = udp_read_packet(s, pkt);
 
1191
    case RTSP_PROTOCOL_RTP_UDP_MULTICAST:
 
1192
        len = udp_read_packet(s, &rtsp_st, buf, sizeof(buf));
 
1193
        if (rtsp_st->rtp_ctx)
 
1194
            rtp_check_and_send_back_rr(rtsp_st->rtp_ctx, len);
980
1195
        break;
981
1196
    }
982
 
    return ret;
 
1197
    if (len < 0)
 
1198
        return AVERROR_IO;
 
1199
    ret = rtp_parse_packet(rtsp_st->rtp_ctx, pkt, buf, len);
 
1200
    if (ret < 0)
 
1201
        goto redo;
 
1202
    if (ret == 1) {
 
1203
        /* more packets may follow, so we save the RTP context */
 
1204
        rt->cur_rtp = rtsp_st->rtp_ctx;
 
1205
    }
 
1206
    return 0;
 
1207
}
 
1208
 
 
1209
static int rtsp_read_play(AVFormatContext *s)
 
1210
{
 
1211
    RTSPState *rt = s->priv_data;
 
1212
    RTSPHeader reply1, *reply = &reply1;
 
1213
    char cmd[1024];
 
1214
 
 
1215
    av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
 
1216
 
 
1217
    if (rt->state == RTSP_STATE_PAUSED) {
 
1218
        snprintf(cmd, sizeof(cmd),
 
1219
                 "PLAY %s RTSP/1.0\r\n",
 
1220
                 s->filename);
 
1221
    } else {
 
1222
        snprintf(cmd, sizeof(cmd),
 
1223
                 "PLAY %s RTSP/1.0\r\n"
 
1224
                 "Range: npt=%0.3f-\r\n",
 
1225
                 s->filename,
 
1226
                 (double)rt->seek_timestamp / AV_TIME_BASE);
 
1227
    }
 
1228
    rtsp_send_cmd(s, cmd, reply, NULL);
 
1229
    if (reply->status_code != RTSP_STATUS_OK) {
 
1230
        return -1;
 
1231
    } else {
 
1232
        rt->state = RTSP_STATE_PLAYING;
 
1233
        return 0;
 
1234
    }
983
1235
}
984
1236
 
985
1237
/* pause the stream */
986
 
int rtsp_pause(AVFormatContext *s)
 
1238
static int rtsp_read_pause(AVFormatContext *s)
987
1239
{
988
 
    RTSPState *rt;
 
1240
    RTSPState *rt = s->priv_data;
989
1241
    RTSPHeader reply1, *reply = &reply1;
990
1242
    char cmd[1024];
991
1243
 
992
 
    if (s->iformat != &rtsp_demux)
993
 
        return -1;
994
 
    
995
1244
    rt = s->priv_data;
996
 
    
997
 
    snprintf(cmd, sizeof(cmd), 
 
1245
 
 
1246
    if (rt->state != RTSP_STATE_PLAYING)
 
1247
        return 0;
 
1248
 
 
1249
    snprintf(cmd, sizeof(cmd),
998
1250
             "PAUSE %s RTSP/1.0\r\n",
999
1251
             s->filename);
1000
1252
    rtsp_send_cmd(s, cmd, reply, NULL);
1001
1253
    if (reply->status_code != RTSP_STATUS_OK) {
1002
1254
        return -1;
1003
1255
    } else {
 
1256
        rt->state = RTSP_STATE_PAUSED;
1004
1257
        return 0;
1005
1258
    }
1006
1259
}
1007
1260
 
1008
 
/* resume the stream */
1009
 
int rtsp_resume(AVFormatContext *s)
 
1261
static int rtsp_read_seek(AVFormatContext *s, int stream_index,
 
1262
                          int64_t timestamp, int flags)
1010
1263
{
1011
 
    RTSPState *rt;
1012
 
    RTSPHeader reply1, *reply = &reply1;
1013
 
    char cmd[1024];
 
1264
    RTSPState *rt = s->priv_data;
1014
1265
 
1015
 
    if (s->iformat != &rtsp_demux)
1016
 
        return -1;
1017
 
    
1018
 
    rt = s->priv_data;
1019
 
    
1020
 
    snprintf(cmd, sizeof(cmd), 
1021
 
             "PLAY %s RTSP/1.0\r\n",
1022
 
             s->filename);
1023
 
    rtsp_send_cmd(s, cmd, reply, NULL);
1024
 
    if (reply->status_code != RTSP_STATUS_OK) {
1025
 
        return -1;
1026
 
    } else {
1027
 
        return 0;
 
1266
    rt->seek_timestamp = timestamp;
 
1267
    switch(rt->state) {
 
1268
    default:
 
1269
    case RTSP_STATE_IDLE:
 
1270
        break;
 
1271
    case RTSP_STATE_PLAYING:
 
1272
        if (rtsp_read_play(s) != 0)
 
1273
            return -1;
 
1274
        break;
 
1275
    case RTSP_STATE_PAUSED:
 
1276
        rt->state = RTSP_STATE_IDLE;
 
1277
        break;
1028
1278
    }
 
1279
    return 0;
1029
1280
}
1030
1281
 
1031
1282
static int rtsp_read_close(AVFormatContext *s)
1032
1283
{
1033
1284
    RTSPState *rt = s->priv_data;
1034
 
    AVStream *st;
1035
 
    RTSPStream *rtsp_st;
1036
1285
    RTSPHeader reply1, *reply = &reply1;
1037
 
    int i;
1038
1286
    char cmd[1024];
1039
1287
 
1040
1288
#if 0
1043
1291
        url_fclose(&rt->rtsp_gb);
1044
1292
    }
1045
1293
#endif
1046
 
    snprintf(cmd, sizeof(cmd), 
 
1294
    snprintf(cmd, sizeof(cmd),
1047
1295
             "TEARDOWN %s RTSP/1.0\r\n",
1048
1296
             s->filename);
1049
1297
    rtsp_send_cmd(s, cmd, reply, NULL);
1050
1298
 
1051
1299
    if (ff_rtsp_callback) {
1052
 
        ff_rtsp_callback(RTSP_ACTION_CLIENT_TEARDOWN, rt->session_id, 
 
1300
        ff_rtsp_callback(RTSP_ACTION_CLIENT_TEARDOWN, rt->session_id,
1053
1301
                         NULL, 0, NULL);
1054
1302
    }
1055
1303
 
1056
 
    for(i=0;i<s->nb_streams;i++) {
1057
 
        st = s->streams[i];
1058
 
        rtsp_st = st->priv_data;
1059
 
        if (rtsp_st) {
1060
 
            if (rtsp_st->ic)
1061
 
                av_close_input_file(rtsp_st->ic);
1062
 
        }
1063
 
        av_free(rtsp_st);
1064
 
    }
 
1304
    rtsp_close_streams(rt);
1065
1305
    url_close(rt->rtsp_hd);
1066
1306
    return 0;
1067
1307
}
1068
1308
 
1069
 
AVInputFormat rtsp_demux = {
 
1309
AVInputFormat rtsp_demuxer = {
1070
1310
    "rtsp",
1071
1311
    "RTSP input format",
1072
1312
    sizeof(RTSPState),
1074
1314
    rtsp_read_header,
1075
1315
    rtsp_read_packet,
1076
1316
    rtsp_read_close,
 
1317
    rtsp_read_seek,
1077
1318
    .flags = AVFMT_NOFILE,
 
1319
    .read_play = rtsp_read_play,
 
1320
    .read_pause = rtsp_read_pause,
1078
1321
};
1079
1322
 
1080
1323
static int sdp_probe(AVProbeData *p1)
1081
1324
{
1082
 
    const char *p;
 
1325
    const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
1083
1326
 
1084
1327
    /* we look for a line beginning "c=IN IP4" */
1085
 
    p = p1->buf;
1086
 
    while (*p != '\0') {
1087
 
        if (strstart(p, "c=IN IP4", NULL))
 
1328
    while (p < p_end && *p != '\0') {
 
1329
        if (p + sizeof("c=IN IP4") - 1 < p_end && strstart(p, "c=IN IP4", NULL))
1088
1330
            return AVPROBE_SCORE_MAX / 2;
1089
 
        p = strchr(p, '\n');
1090
 
        if (!p)
 
1331
 
 
1332
        while(p < p_end - 1 && *p != '\n') p++;
 
1333
        if (++p >= p_end)
1091
1334
            break;
1092
 
        p++;
1093
1335
        if (*p == '\r')
1094
1336
            p++;
1095
1337
    }
1101
1343
static int sdp_read_header(AVFormatContext *s,
1102
1344
                           AVFormatParameters *ap)
1103
1345
{
1104
 
    AVStream *st;
 
1346
    RTSPState *rt = s->priv_data;
1105
1347
    RTSPStream *rtsp_st;
1106
1348
    int size, i, err;
1107
1349
    char *content;
1108
1350
    char url[1024];
 
1351
    AVStream *st;
1109
1352
 
1110
1353
    /* read the whole sdp file */
1111
1354
    /* XXX: better loading */
1121
1364
    av_free(content);
1122
1365
 
1123
1366
    /* open each RTP stream */
1124
 
    for(i=0;i<s->nb_streams;i++) {
1125
 
        st = s->streams[i];
1126
 
        rtsp_st = st->priv_data;
1127
 
        
1128
 
        snprintf(url, sizeof(url), "rtp://%s:%d?multicast=1&ttl=%d", 
1129
 
                 inet_ntoa(rtsp_st->sdp_ip), 
 
1367
    for(i=0;i<rt->nb_rtsp_streams;i++) {
 
1368
        rtsp_st = rt->rtsp_streams[i];
 
1369
 
 
1370
        snprintf(url, sizeof(url), "rtp://%s:%d?multicast=1&ttl=%d",
 
1371
                 inet_ntoa(rtsp_st->sdp_ip),
1130
1372
                 rtsp_st->sdp_port,
1131
1373
                 rtsp_st->sdp_ttl);
1132
 
        if (av_open_input_file(&rtsp_st->ic, url, &rtp_demux, 0, NULL) < 0) {
 
1374
        if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {
1133
1375
            err = AVERROR_INVALIDDATA;
1134
1376
            goto fail;
1135
1377
        }
 
1378
        /* open the RTP context */
 
1379
        st = NULL;
 
1380
        if (rtsp_st->stream_index >= 0)
 
1381
            st = s->streams[rtsp_st->stream_index];
 
1382
        if (!st)
 
1383
            s->ctx_flags |= AVFMTCTX_NOHEADER;
 
1384
        rtsp_st->rtp_ctx = rtp_parse_open(s, st, rtsp_st->rtp_handle, rtsp_st->sdp_payload_type, &rtsp_st->rtp_payload_data);
 
1385
        if (!rtsp_st->rtp_ctx) {
 
1386
            err = AVERROR_NOMEM;
 
1387
            goto fail;
 
1388
        } else {
 
1389
            if(rtsp_st->dynamic_handler) {
 
1390
                rtsp_st->rtp_ctx->dynamic_protocol_context= rtsp_st->dynamic_protocol_context;
 
1391
                rtsp_st->rtp_ctx->parse_packet= rtsp_st->dynamic_handler->parse_packet;
 
1392
            }
 
1393
        }
1136
1394
    }
1137
1395
    return 0;
1138
1396
 fail:
1139
 
    for(i=0;i<s->nb_streams;i++) {
1140
 
        st = s->streams[i];
1141
 
        rtsp_st = st->priv_data;
1142
 
        if (rtsp_st) {
1143
 
            if (rtsp_st->ic)
1144
 
                av_close_input_file(rtsp_st->ic);
1145
 
        }
1146
 
        av_free(rtsp_st);
1147
 
    }
 
1397
    rtsp_close_streams(rt);
1148
1398
    return err;
1149
1399
}
1150
1400
 
1151
1401
static int sdp_read_packet(AVFormatContext *s,
1152
1402
                            AVPacket *pkt)
1153
1403
{
1154
 
    return udp_read_packet(s, pkt);
 
1404
    return rtsp_read_packet(s, pkt);
1155
1405
}
1156
1406
 
1157
1407
static int sdp_read_close(AVFormatContext *s)
1158
1408
{
1159
 
    AVStream *st;
1160
 
    RTSPStream *rtsp_st;
1161
 
    int i;
1162
 
 
1163
 
    for(i=0;i<s->nb_streams;i++) {
1164
 
        st = s->streams[i];
1165
 
        rtsp_st = st->priv_data;
1166
 
        if (rtsp_st) {
1167
 
            if (rtsp_st->ic)
1168
 
                av_close_input_file(rtsp_st->ic);
1169
 
        }
1170
 
        av_free(rtsp_st);
1171
 
    }
 
1409
    RTSPState *rt = s->priv_data;
 
1410
    rtsp_close_streams(rt);
1172
1411
    return 0;
1173
1412
}
1174
1413
 
1175
 
 
1176
 
static AVInputFormat sdp_demux = {
 
1414
#ifdef CONFIG_SDP_DEMUXER
 
1415
AVInputFormat sdp_demuxer = {
1177
1416
    "sdp",
1178
1417
    "SDP",
1179
1418
    sizeof(RTSPState),
1182
1421
    sdp_read_packet,
1183
1422
    sdp_read_close,
1184
1423
};
1185
 
 
 
1424
#endif
1186
1425
 
1187
1426
/* dummy redirector format (used directly in av_open_input_file now) */
1188
1427
static int redir_probe(AVProbeData *pd)
1237
1476
        return 0;
1238
1477
}
1239
1478
 
1240
 
AVInputFormat redir_demux = {
 
1479
AVInputFormat redir_demuxer = {
1241
1480
    "redir",
1242
1481
    "Redirector format",
1243
1482
    0,
1246
1485
    NULL,
1247
1486
    NULL,
1248
1487
};
1249
 
 
1250
 
int rtsp_init(void)
1251
 
{
1252
 
    av_register_input_format(&rtsp_demux);
1253
 
    av_register_input_format(&redir_demux);
1254
 
    av_register_input_format(&sdp_demux);
1255
 
    return 0;
1256
 
}