Statistics
| Branch: | Revision:

ffmpeg / libavformat / rtspdec.c @ dce37564

History | View | Annotate | Download (12.7 KB)

1
/*
2
 * RTSP demuxer
3
 * Copyright (c) 2002 Fabrice Bellard
4
 *
5
 * This file is part of Libav.
6
 *
7
 * Libav is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * 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
 * Libav is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with Libav; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

    
22
#include "libavutil/avstring.h"
23
#include "libavutil/intreadwrite.h"
24
#include "avformat.h"
25

    
26
#include "internal.h"
27
#include "network.h"
28
#include "os_support.h"
29
#include "rtsp.h"
30
#include "rdt.h"
31
#include "url.h"
32

    
33
//#define DEBUG
34
//#define DEBUG_RTP_TCP
35

    
36
static int rtsp_read_play(AVFormatContext *s)
37
{
38
    RTSPState *rt = s->priv_data;
39
    RTSPMessageHeader reply1, *reply = &reply1;
40
    int i;
41
    char cmd[1024];
42

    
43
    av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
44
    rt->nb_byes = 0;
45

    
46
    if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
47
        if (rt->transport == RTSP_TRANSPORT_RTP) {
48
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
49
                RTSPStream *rtsp_st = rt->rtsp_streams[i];
50
                RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
51
                if (!rtpctx)
52
                    continue;
53
                ff_rtp_reset_packet_queue(rtpctx);
54
                rtpctx->last_rtcp_ntp_time  = AV_NOPTS_VALUE;
55
                rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
56
                rtpctx->base_timestamp      = 0;
57
                rtpctx->rtcp_ts_offset      = 0;
58
            }
59
        }
60
        if (rt->state == RTSP_STATE_PAUSED) {
61
            cmd[0] = 0;
62
        } else {
63
            snprintf(cmd, sizeof(cmd),
64
                     "Range: npt=%"PRId64".%03"PRId64"-\r\n",
65
                     rt->seek_timestamp / AV_TIME_BASE,
66
                     rt->seek_timestamp / (AV_TIME_BASE / 1000) % 1000);
67
        }
68
        ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
69
        if (reply->status_code != RTSP_STATUS_OK) {
70
            return -1;
71
        }
72
        if (rt->transport == RTSP_TRANSPORT_RTP &&
73
            reply->range_start != AV_NOPTS_VALUE) {
74
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
75
                RTSPStream *rtsp_st = rt->rtsp_streams[i];
76
                RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
77
                AVStream *st = NULL;
78
                if (!rtpctx || rtsp_st->stream_index < 0)
79
                    continue;
80
                st = s->streams[rtsp_st->stream_index];
81
                rtpctx->range_start_offset =
82
                    av_rescale_q(reply->range_start, AV_TIME_BASE_Q,
83
                                 st->time_base);
84
            }
85
        }
86
    }
87
    rt->state = RTSP_STATE_STREAMING;
88
    return 0;
89
}
90

    
91
/* pause the stream */
92
static int rtsp_read_pause(AVFormatContext *s)
93
{
94
    RTSPState *rt = s->priv_data;
95
    RTSPMessageHeader reply1, *reply = &reply1;
96

    
97
    if (rt->state != RTSP_STATE_STREAMING)
98
        return 0;
99
    else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
100
        ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
101
        if (reply->status_code != RTSP_STATUS_OK) {
102
            return -1;
103
        }
104
    }
105
    rt->state = RTSP_STATE_PAUSED;
106
    return 0;
107
}
108

    
109
int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply)
110
{
111
    RTSPState *rt = s->priv_data;
112
    char cmd[1024];
113
    unsigned char *content = NULL;
114
    int ret;
115

    
116
    /* describe the stream */
117
    snprintf(cmd, sizeof(cmd),
118
             "Accept: application/sdp\r\n");
119
    if (rt->server_type == RTSP_SERVER_REAL) {
120
        /**
121
         * The Require: attribute is needed for proper streaming from
122
         * Realmedia servers.
123
         */
124
        av_strlcat(cmd,
125
                   "Require: com.real.retain-entity-for-setup\r\n",
126
                   sizeof(cmd));
127
    }
128
    ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
129
    if (!content)
130
        return AVERROR_INVALIDDATA;
131
    if (reply->status_code != RTSP_STATUS_OK) {
132
        av_freep(&content);
133
        return AVERROR_INVALIDDATA;
134
    }
135

    
136
    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
137
    /* now we got the SDP description, we parse it */
138
    ret = ff_sdp_parse(s, (const char *)content);
139
    av_freep(&content);
140
    if (ret < 0)
141
        return ret;
142

    
143
    return 0;
144
}
145

    
146
static int rtsp_probe(AVProbeData *p)
147
{
148
    if (av_strstart(p->filename, "rtsp:", NULL))
149
        return AVPROBE_SCORE_MAX;
150
    return 0;
151
}
152

    
153
static int rtsp_read_header(AVFormatContext *s,
154
                            AVFormatParameters *ap)
155
{
156
    RTSPState *rt = s->priv_data;
157
    int ret;
158

    
159
    ret = ff_rtsp_connect(s);
160
    if (ret)
161
        return ret;
162

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

    
168
    if (ap->initial_pause) {
169
         /* do not start immediately */
170
    } else {
171
         if (rtsp_read_play(s) < 0) {
172
            ff_rtsp_close_streams(s);
173
            ff_rtsp_close_connections(s);
174
            return AVERROR_INVALIDDATA;
175
        }
176
    }
177

    
178
    return 0;
179
}
180

    
181
int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
182
                            uint8_t *buf, int buf_size)
183
{
184
    RTSPState *rt = s->priv_data;
185
    int id, len, i, ret;
186
    RTSPStream *rtsp_st;
187

    
188
#ifdef DEBUG_RTP_TCP
189
    av_dlog(s, "tcp_read_packet:\n");
190
#endif
191
redo:
192
    for (;;) {
193
        RTSPMessageHeader reply;
194

    
195
        ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL);
196
        if (ret < 0)
197
            return ret;
198
        if (ret == 1) /* received '$' */
199
            break;
200
        /* XXX: parse message */
201
        if (rt->state != RTSP_STATE_STREAMING)
202
            return 0;
203
    }
204
    ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
205
    if (ret != 3)
206
        return -1;
207
    id  = buf[0];
208
    len = AV_RB16(buf + 1);
209
#ifdef DEBUG_RTP_TCP
210
    av_dlog(s, "id=%d len=%d\n", id, len);
211
#endif
212
    if (len > buf_size || len < 12)
213
        goto redo;
214
    /* get the data */
215
    ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
216
    if (ret != len)
217
        return -1;
218
    if (rt->transport == RTSP_TRANSPORT_RDT &&
219
        ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0)
220
        return -1;
221

    
222
    /* find the matching stream */
223
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
224
        rtsp_st = rt->rtsp_streams[i];
225
        if (id >= rtsp_st->interleaved_min &&
226
            id <= rtsp_st->interleaved_max)
227
            goto found;
228
    }
229
    goto redo;
230
found:
231
    *prtsp_st = rtsp_st;
232
    return len;
233
}
234

    
235
static int resetup_tcp(AVFormatContext *s)
236
{
237
    RTSPState *rt = s->priv_data;
238
    char host[1024];
239
    int port;
240

    
241
    av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
242
                 s->filename);
243
    ff_rtsp_undo_setup(s);
244
    return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP,
245
                                      rt->real_challenge);
246
}
247

    
248
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
249
{
250
    RTSPState *rt = s->priv_data;
251
    int ret;
252
    RTSPMessageHeader reply1, *reply = &reply1;
253
    char cmd[1024];
254

    
255
retry:
256
    if (rt->server_type == RTSP_SERVER_REAL) {
257
        int i;
258

    
259
        for (i = 0; i < s->nb_streams; i++)
260
            rt->real_setup[i] = s->streams[i]->discard;
261

    
262
        if (!rt->need_subscription) {
263
            if (memcmp (rt->real_setup, rt->real_setup_cache,
264
                        sizeof(enum AVDiscard) * s->nb_streams)) {
265
                snprintf(cmd, sizeof(cmd),
266
                         "Unsubscribe: %s\r\n",
267
                         rt->last_subscription);
268
                ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
269
                                 cmd, reply, NULL);
270
                if (reply->status_code != RTSP_STATUS_OK)
271
                    return AVERROR_INVALIDDATA;
272
                rt->need_subscription = 1;
273
            }
274
        }
275

    
276
        if (rt->need_subscription) {
277
            int r, rule_nr, first = 1;
278

    
279
            memcpy(rt->real_setup_cache, rt->real_setup,
280
                   sizeof(enum AVDiscard) * s->nb_streams);
281
            rt->last_subscription[0] = 0;
282

    
283
            snprintf(cmd, sizeof(cmd),
284
                     "Subscribe: ");
285
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
286
                rule_nr = 0;
287
                for (r = 0; r < s->nb_streams; r++) {
288
                    if (s->streams[r]->id == i) {
289
                        if (s->streams[r]->discard != AVDISCARD_ALL) {
290
                            if (!first)
291
                                av_strlcat(rt->last_subscription, ",",
292
                                           sizeof(rt->last_subscription));
293
                            ff_rdt_subscribe_rule(
294
                                rt->last_subscription,
295
                                sizeof(rt->last_subscription), i, rule_nr);
296
                            first = 0;
297
                        }
298
                        rule_nr++;
299
                    }
300
                }
301
            }
302
            av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
303
            ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
304
                             cmd, reply, NULL);
305
            if (reply->status_code != RTSP_STATUS_OK)
306
                return AVERROR_INVALIDDATA;
307
            rt->need_subscription = 0;
308

    
309
            if (rt->state == RTSP_STATE_STREAMING)
310
                rtsp_read_play (s);
311
        }
312
    }
313

    
314
    ret = ff_rtsp_fetch_packet(s, pkt);
315
    if (ret < 0) {
316
        if (ret == AVERROR(ETIMEDOUT) && !rt->packets) {
317
            if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
318
                rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP)) {
319
                RTSPMessageHeader reply1, *reply = &reply1;
320
                av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
321
                if (rtsp_read_pause(s) != 0)
322
                    return -1;
323
                // TEARDOWN is required on Real-RTSP, but might make
324
                // other servers close the connection.
325
                if (rt->server_type == RTSP_SERVER_REAL)
326
                    ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
327
                                     reply, NULL);
328
                rt->session_id[0] = '\0';
329
                if (resetup_tcp(s) == 0) {
330
                    rt->state = RTSP_STATE_IDLE;
331
                    rt->need_subscription = 1;
332
                    if (rtsp_read_play(s) != 0)
333
                        return -1;
334
                    goto retry;
335
                }
336
            }
337
        }
338
        return ret;
339
    }
340
    rt->packets++;
341

    
342
    /* send dummy request to keep TCP connection alive */
343
    if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {
344
        if (rt->server_type != RTSP_SERVER_REAL) {
345
            ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
346
        } else {
347
            ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);
348
        }
349
    }
350

    
351
    return 0;
352
}
353

    
354
static int rtsp_read_seek(AVFormatContext *s, int stream_index,
355
                          int64_t timestamp, int flags)
356
{
357
    RTSPState *rt = s->priv_data;
358

    
359
    rt->seek_timestamp = av_rescale_q(timestamp,
360
                                      s->streams[stream_index]->time_base,
361
                                      AV_TIME_BASE_Q);
362
    switch(rt->state) {
363
    default:
364
    case RTSP_STATE_IDLE:
365
        break;
366
    case RTSP_STATE_STREAMING:
367
        if (rtsp_read_pause(s) != 0)
368
            return -1;
369
        rt->state = RTSP_STATE_SEEKING;
370
        if (rtsp_read_play(s) != 0)
371
            return -1;
372
        break;
373
    case RTSP_STATE_PAUSED:
374
        rt->state = RTSP_STATE_IDLE;
375
        break;
376
    }
377
    return 0;
378
}
379

    
380
static int rtsp_read_close(AVFormatContext *s)
381
{
382
    RTSPState *rt = s->priv_data;
383

    
384
#if 0
385
    /* NOTE: it is valid to flush the buffer here */
386
    if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
387
        avio_close(&rt->rtsp_gb);
388
    }
389
#endif
390
    ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
391

    
392
    ff_rtsp_close_streams(s);
393
    ff_rtsp_close_connections(s);
394
    ff_network_close();
395
    rt->real_setup = NULL;
396
    av_freep(&rt->real_setup_cache);
397
    return 0;
398
}
399

    
400
AVInputFormat ff_rtsp_demuxer = {
401
    "rtsp",
402
    NULL_IF_CONFIG_SMALL("RTSP input format"),
403
    sizeof(RTSPState),
404
    rtsp_probe,
405
    rtsp_read_header,
406
    rtsp_read_packet,
407
    rtsp_read_close,
408
    rtsp_read_seek,
409
    .flags = AVFMT_NOFILE,
410
    .read_play = rtsp_read_play,
411
    .read_pause = rtsp_read_pause,
412
};