Statistics
| Branch: | Revision:

ffmpeg / libavformat / rtspdec.c @ d2995eb9

History | View | Annotate | Download (11 KB)

1
/*
2
 * RTSP demuxer
3
 * Copyright (c) 2002 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg 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
 * FFmpeg 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 FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21

    
22
#include "libavutil/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

    
32
//#define DEBUG
33
//#define DEBUG_RTP_TCP
34

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

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

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

    
84
int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply)
85
{
86
    RTSPState *rt = s->priv_data;
87
    char cmd[1024];
88
    unsigned char *content = NULL;
89
    int ret;
90

    
91
    /* describe the stream */
92
    snprintf(cmd, sizeof(cmd),
93
             "Accept: application/sdp\r\n");
94
    if (rt->server_type == RTSP_SERVER_REAL) {
95
        /**
96
         * The Require: attribute is needed for proper streaming from
97
         * Realmedia servers.
98
         */
99
        av_strlcat(cmd,
100
                   "Require: com.real.retain-entity-for-setup\r\n",
101
                   sizeof(cmd));
102
    }
103
    ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
104
    if (!content)
105
        return AVERROR_INVALIDDATA;
106
    if (reply->status_code != RTSP_STATUS_OK) {
107
        av_freep(&content);
108
        return AVERROR_INVALIDDATA;
109
    }
110

    
111
    av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
112
    /* now we got the SDP description, we parse it */
113
    ret = ff_sdp_parse(s, (const char *)content);
114
    av_freep(&content);
115
    if (ret < 0)
116
        return AVERROR_INVALIDDATA;
117

    
118
    return 0;
119
}
120

    
121
static int rtsp_probe(AVProbeData *p)
122
{
123
    if (av_strstart(p->filename, "rtsp:", NULL))
124
        return AVPROBE_SCORE_MAX;
125
    return 0;
126
}
127

    
128
static int rtsp_read_header(AVFormatContext *s,
129
                            AVFormatParameters *ap)
130
{
131
    RTSPState *rt = s->priv_data;
132
    int ret;
133

    
134
    ret = ff_rtsp_connect(s);
135
    if (ret)
136
        return ret;
137

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

    
143
    if (ap->initial_pause) {
144
         /* do not start immediately */
145
    } else {
146
         if (rtsp_read_play(s) < 0) {
147
            ff_rtsp_close_streams(s);
148
            ff_rtsp_close_connections(s);
149
            return AVERROR_INVALIDDATA;
150
        }
151
    }
152

    
153
    return 0;
154
}
155

    
156
int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
157
                            uint8_t *buf, int buf_size)
158
{
159
    RTSPState *rt = s->priv_data;
160
    int id, len, i, ret;
161
    RTSPStream *rtsp_st;
162

    
163
#ifdef DEBUG_RTP_TCP
164
    dprintf(s, "tcp_read_packet:\n");
165
#endif
166
redo:
167
    for (;;) {
168
        RTSPMessageHeader reply;
169

    
170
        ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL);
171
        if (ret < 0)
172
            return ret;
173
        if (ret == 1) /* received '$' */
174
            break;
175
        /* XXX: parse message */
176
        if (rt->state != RTSP_STATE_STREAMING)
177
            return 0;
178
    }
179
    ret = url_read_complete(rt->rtsp_hd, buf, 3);
180
    if (ret != 3)
181
        return -1;
182
    id  = buf[0];
183
    len = AV_RB16(buf + 1);
184
#ifdef DEBUG_RTP_TCP
185
    dprintf(s, "id=%d len=%d\n", id, len);
186
#endif
187
    if (len > buf_size || len < 12)
188
        goto redo;
189
    /* get the data */
190
    ret = url_read_complete(rt->rtsp_hd, buf, len);
191
    if (ret != len)
192
        return -1;
193
    if (rt->transport == RTSP_TRANSPORT_RDT &&
194
        ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0)
195
        return -1;
196

    
197
    /* find the matching stream */
198
    for (i = 0; i < rt->nb_rtsp_streams; i++) {
199
        rtsp_st = rt->rtsp_streams[i];
200
        if (id >= rtsp_st->interleaved_min &&
201
            id <= rtsp_st->interleaved_max)
202
            goto found;
203
    }
204
    goto redo;
205
found:
206
    *prtsp_st = rtsp_st;
207
    return len;
208
}
209
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
210
{
211
    RTSPState *rt = s->priv_data;
212
    int ret;
213
    RTSPMessageHeader reply1, *reply = &reply1;
214
    char cmd[1024];
215

    
216
    if (rt->server_type == RTSP_SERVER_REAL) {
217
        int i;
218

    
219
        for (i = 0; i < s->nb_streams; i++)
220
            rt->real_setup[i] = s->streams[i]->discard;
221

    
222
        if (!rt->need_subscription) {
223
            if (memcmp (rt->real_setup, rt->real_setup_cache,
224
                        sizeof(enum AVDiscard) * s->nb_streams)) {
225
                snprintf(cmd, sizeof(cmd),
226
                         "Unsubscribe: %s\r\n",
227
                         rt->last_subscription);
228
                ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
229
                                 cmd, reply, NULL);
230
                if (reply->status_code != RTSP_STATUS_OK)
231
                    return AVERROR_INVALIDDATA;
232
                rt->need_subscription = 1;
233
            }
234
        }
235

    
236
        if (rt->need_subscription) {
237
            int r, rule_nr, first = 1;
238

    
239
            memcpy(rt->real_setup_cache, rt->real_setup,
240
                   sizeof(enum AVDiscard) * s->nb_streams);
241
            rt->last_subscription[0] = 0;
242

    
243
            snprintf(cmd, sizeof(cmd),
244
                     "Subscribe: ");
245
            for (i = 0; i < rt->nb_rtsp_streams; i++) {
246
                rule_nr = 0;
247
                for (r = 0; r < s->nb_streams; r++) {
248
                    if (s->streams[r]->priv_data == rt->rtsp_streams[i]) {
249
                        if (s->streams[r]->discard != AVDISCARD_ALL) {
250
                            if (!first)
251
                                av_strlcat(rt->last_subscription, ",",
252
                                           sizeof(rt->last_subscription));
253
                            ff_rdt_subscribe_rule(
254
                                rt->last_subscription,
255
                                sizeof(rt->last_subscription), i, rule_nr);
256
                            first = 0;
257
                        }
258
                        rule_nr++;
259
                    }
260
                }
261
            }
262
            av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
263
            ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
264
                             cmd, reply, NULL);
265
            if (reply->status_code != RTSP_STATUS_OK)
266
                return AVERROR_INVALIDDATA;
267
            rt->need_subscription = 0;
268

    
269
            if (rt->state == RTSP_STATE_STREAMING)
270
                rtsp_read_play (s);
271
        }
272
    }
273

    
274
    ret = ff_rtsp_fetch_packet(s, pkt);
275
    if (ret < 0)
276
        return ret;
277

    
278
    /* send dummy request to keep TCP connection alive */
279
    if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {
280
        if (rt->server_type == RTSP_SERVER_WMS) {
281
            ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
282
        } else {
283
            ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);
284
        }
285
    }
286

    
287
    return 0;
288
}
289

    
290
/* pause the stream */
291
static int rtsp_read_pause(AVFormatContext *s)
292
{
293
    RTSPState *rt = s->priv_data;
294
    RTSPMessageHeader reply1, *reply = &reply1;
295

    
296
    if (rt->state != RTSP_STATE_STREAMING)
297
        return 0;
298
    else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
299
        ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
300
        if (reply->status_code != RTSP_STATUS_OK) {
301
            return -1;
302
        }
303
    }
304
    rt->state = RTSP_STATE_PAUSED;
305
    return 0;
306
}
307

    
308
static int rtsp_read_seek(AVFormatContext *s, int stream_index,
309
                          int64_t timestamp, int flags)
310
{
311
    RTSPState *rt = s->priv_data;
312

    
313
    rt->seek_timestamp = av_rescale_q(timestamp,
314
                                      s->streams[stream_index]->time_base,
315
                                      AV_TIME_BASE_Q);
316
    switch(rt->state) {
317
    default:
318
    case RTSP_STATE_IDLE:
319
        break;
320
    case RTSP_STATE_STREAMING:
321
        if (rtsp_read_pause(s) != 0)
322
            return -1;
323
        rt->state = RTSP_STATE_SEEKING;
324
        if (rtsp_read_play(s) != 0)
325
            return -1;
326
        break;
327
    case RTSP_STATE_PAUSED:
328
        rt->state = RTSP_STATE_IDLE;
329
        break;
330
    }
331
    return 0;
332
}
333

    
334
static int rtsp_read_close(AVFormatContext *s)
335
{
336
    RTSPState *rt = s->priv_data;
337

    
338
#if 0
339
    /* NOTE: it is valid to flush the buffer here */
340
    if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
341
        url_fclose(&rt->rtsp_gb);
342
    }
343
#endif
344
    ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
345

    
346
    ff_rtsp_close_streams(s);
347
    ff_rtsp_close_connections(s);
348
    ff_network_close();
349
    rt->real_setup = NULL;
350
    av_freep(&rt->real_setup_cache);
351
    return 0;
352
}
353

    
354
AVInputFormat rtsp_demuxer = {
355
    "rtsp",
356
    NULL_IF_CONFIG_SMALL("RTSP input format"),
357
    sizeof(RTSPState),
358
    rtsp_probe,
359
    rtsp_read_header,
360
    rtsp_read_packet,
361
    rtsp_read_close,
362
    rtsp_read_seek,
363
    .flags = AVFMT_NOFILE,
364
    .read_play = rtsp_read_play,
365
    .read_pause = rtsp_read_pause,
366
};