Statistics
| Branch: | Revision:

ffmpeg / libavformat / rtspdec.c @ 3df54c6b

History | View | Annotate | Download (11.1 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
    if (reply->content_base[0])
111
        av_strlcpy(rt->control_uri, reply->content_base,
112
                   sizeof(rt->control_uri));
113

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

    
121
    return 0;
122
}
123

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

    
131
static int rtsp_read_header(AVFormatContext *s,
132
                            AVFormatParameters *ap)
133
{
134
    RTSPState *rt = s->priv_data;
135
    int ret;
136

    
137
    ret = ff_rtsp_connect(s);
138
    if (ret)
139
        return ret;
140

    
141
    rt->real_setup_cache = av_mallocz(2 * s->nb_streams * sizeof(*rt->real_setup_cache));
142
    if (!rt->real_setup_cache)
143
        return AVERROR(ENOMEM);
144
    rt->real_setup = rt->real_setup_cache + s->nb_streams;
145

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

    
156
    return 0;
157
}
158

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

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

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

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

    
219
    if (rt->server_type == RTSP_SERVER_REAL) {
220
        int i;
221

    
222
        for (i = 0; i < s->nb_streams; i++)
223
            rt->real_setup[i] = s->streams[i]->discard;
224

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

    
239
        if (rt->need_subscription) {
240
            int r, rule_nr, first = 1;
241

    
242
            memcpy(rt->real_setup_cache, rt->real_setup,
243
                   sizeof(enum AVDiscard) * s->nb_streams);
244
            rt->last_subscription[0] = 0;
245

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

    
272
            if (rt->state == RTSP_STATE_STREAMING)
273
                rtsp_read_play (s);
274
        }
275
    }
276

    
277
    ret = ff_rtsp_fetch_packet(s, pkt);
278
    if (ret < 0)
279
        return ret;
280

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

    
290
    return 0;
291
}
292

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

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

    
311
static int rtsp_read_seek(AVFormatContext *s, int stream_index,
312
                          int64_t timestamp, int flags)
313
{
314
    RTSPState *rt = s->priv_data;
315

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

    
337
static int rtsp_read_close(AVFormatContext *s)
338
{
339
    RTSPState *rt = s->priv_data;
340

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

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

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