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 "libavutil/mathematics.h"
25#include "avformat.h"
26
27#include "internal.h"
28#include "network.h"
29#include "os_support.h"
30#include "rtsp.h"
31#include "rdt.h"
32#include "url.h"
33
34static int rtsp_read_play(AVFormatContext *s)
35{
36    RTSPState *rt = s->priv_data;
37    RTSPMessageHeader reply1, *reply = &reply1;
38    int i;
39    char cmd[1024];
40
41    av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
42    rt->nb_byes = 0;
43
44    if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
45        if (rt->transport == RTSP_TRANSPORT_RTP) {
46            for (i = 0; i < rt->nb_rtsp_streams; i++) {
47                RTSPStream *rtsp_st = rt->rtsp_streams[i];
48                RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
49                if (!rtpctx)
50                    continue;
51                ff_rtp_reset_packet_queue(rtpctx);
52                rtpctx->last_rtcp_ntp_time  = AV_NOPTS_VALUE;
53                rtpctx->first_rtcp_ntp_time = AV_NOPTS_VALUE;
54                rtpctx->base_timestamp      = 0;
55                rtpctx->timestamp           = 0;
56                rtpctx->unwrapped_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 */
92static 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
109int 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
146static int rtsp_probe(AVProbeData *p)
147{
148    if (av_strstart(p->filename, "rtsp:", NULL))
149        return AVPROBE_SCORE_MAX;
150    return 0;
151}
152
153static 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 (rt->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
181int 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    av_dlog(s, "tcp_read_packet:\n");
189redo:
190    for (;;) {
191        RTSPMessageHeader reply;
192
193        ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL);
194        if (ret < 0)
195            return ret;
196        if (ret == 1) /* received '$' */
197            break;
198        /* XXX: parse message */
199        if (rt->state != RTSP_STATE_STREAMING)
200            return 0;
201    }
202    ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
203    if (ret != 3)
204        return -1;
205    id  = buf[0];
206    len = AV_RB16(buf + 1);
207    av_dlog(s, "id=%d len=%d\n", id, len);
208    if (len > buf_size || len < 12)
209        goto redo;
210    /* get the data */
211    ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
212    if (ret != len)
213        return -1;
214    if (rt->transport == RTSP_TRANSPORT_RDT &&
215        ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0)
216        return -1;
217
218    /* find the matching stream */
219    for (i = 0; i < rt->nb_rtsp_streams; i++) {
220        rtsp_st = rt->rtsp_streams[i];
221        if (id >= rtsp_st->interleaved_min &&
222            id <= rtsp_st->interleaved_max)
223            goto found;
224    }
225    goto redo;
226found:
227    *prtsp_st = rtsp_st;
228    return len;
229}
230
231static int resetup_tcp(AVFormatContext *s)
232{
233    RTSPState *rt = s->priv_data;
234    char host[1024];
235    int port;
236
237    av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
238                 s->filename);
239    ff_rtsp_undo_setup(s);
240    return ff_rtsp_make_setup_request(s, host, port, RTSP_LOWER_TRANSPORT_TCP,
241                                      rt->real_challenge);
242}
243
244static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
245{
246    RTSPState *rt = s->priv_data;
247    int ret;
248    RTSPMessageHeader reply1, *reply = &reply1;
249    char cmd[1024];
250
251retry:
252    if (rt->server_type == RTSP_SERVER_REAL) {
253        int i;
254
255        for (i = 0; i < s->nb_streams; i++)
256            rt->real_setup[i] = s->streams[i]->discard;
257
258        if (!rt->need_subscription) {
259            if (memcmp (rt->real_setup, rt->real_setup_cache,
260                        sizeof(enum AVDiscard) * s->nb_streams)) {
261                snprintf(cmd, sizeof(cmd),
262                         "Unsubscribe: %s\r\n",
263                         rt->last_subscription);
264                ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
265                                 cmd, reply, NULL);
266                if (reply->status_code != RTSP_STATUS_OK)
267                    return AVERROR_INVALIDDATA;
268                rt->need_subscription = 1;
269            }
270        }
271
272        if (rt->need_subscription) {
273            int r, rule_nr, first = 1;
274
275            memcpy(rt->real_setup_cache, rt->real_setup,
276                   sizeof(enum AVDiscard) * s->nb_streams);
277            rt->last_subscription[0] = 0;
278
279            snprintf(cmd, sizeof(cmd),
280                     "Subscribe: ");
281            for (i = 0; i < rt->nb_rtsp_streams; i++) {
282                rule_nr = 0;
283                for (r = 0; r < s->nb_streams; r++) {
284                    if (s->streams[r]->id == i) {
285                        if (s->streams[r]->discard != AVDISCARD_ALL) {
286                            if (!first)
287                                av_strlcat(rt->last_subscription, ",",
288                                           sizeof(rt->last_subscription));
289                            ff_rdt_subscribe_rule(
290                                rt->last_subscription,
291                                sizeof(rt->last_subscription), i, rule_nr);
292                            first = 0;
293                        }
294                        rule_nr++;
295                    }
296                }
297            }
298            av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
299            ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
300                             cmd, reply, NULL);
301            if (reply->status_code != RTSP_STATUS_OK)
302                return AVERROR_INVALIDDATA;
303            rt->need_subscription = 0;
304
305            if (rt->state == RTSP_STATE_STREAMING)
306                rtsp_read_play (s);
307        }
308    }
309
310    ret = ff_rtsp_fetch_packet(s, pkt);
311    if (ret < 0) {
312        if (ret == AVERROR(ETIMEDOUT) && !rt->packets) {
313            if (rt->lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
314                rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP)) {
315                RTSPMessageHeader reply1, *reply = &reply1;
316                av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
317                if (rtsp_read_pause(s) != 0)
318                    return -1;
319                // TEARDOWN is required on Real-RTSP, but might make
320                // other servers close the connection.
321                if (rt->server_type == RTSP_SERVER_REAL)
322                    ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
323                                     reply, NULL);
324                rt->session_id[0] = '\0';
325                if (resetup_tcp(s) == 0) {
326                    rt->state = RTSP_STATE_IDLE;
327                    rt->need_subscription = 1;
328                    if (rtsp_read_play(s) != 0)
329                        return -1;
330                    goto retry;
331                }
332            }
333        }
334        return ret;
335    }
336    rt->packets++;
337
338    /* send dummy request to keep TCP connection alive */
339    if ((av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) {
340        if (rt->server_type == RTSP_SERVER_WMS ||
341           (rt->server_type != RTSP_SERVER_REAL &&
342            rt->get_parameter_supported)) {
343            ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
344        } else {
345            ff_rtsp_send_cmd_async(s, "OPTIONS", "*", NULL);
346        }
347    }
348
349    return 0;
350}
351
352static int rtsp_read_seek(AVFormatContext *s, int stream_index,
353                          int64_t timestamp, int flags)
354{
355    RTSPState *rt = s->priv_data;
356
357    rt->seek_timestamp = av_rescale_q(timestamp,
358                                      s->streams[stream_index]->time_base,
359                                      AV_TIME_BASE_Q);
360    switch(rt->state) {
361    default:
362    case RTSP_STATE_IDLE:
363        break;
364    case RTSP_STATE_STREAMING:
365        if (rtsp_read_pause(s) != 0)
366            return -1;
367        rt->state = RTSP_STATE_SEEKING;
368        if (rtsp_read_play(s) != 0)
369            return -1;
370        break;
371    case RTSP_STATE_PAUSED:
372        rt->state = RTSP_STATE_IDLE;
373        break;
374    }
375    return 0;
376}
377
378static int rtsp_read_close(AVFormatContext *s)
379{
380    RTSPState *rt = s->priv_data;
381
382    ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
383
384    ff_rtsp_close_streams(s);
385    ff_rtsp_close_connections(s);
386    ff_network_close();
387    rt->real_setup = NULL;
388    av_freep(&rt->real_setup_cache);
389    return 0;
390}
391
392const AVClass rtsp_demuxer_class = {
393    .class_name     = "RTSP demuxer",
394    .item_name      = av_default_item_name,
395    .option         = ff_rtsp_options,
396    .version        = LIBAVUTIL_VERSION_INT,
397};
398
399AVInputFormat ff_rtsp_demuxer = {
400    .name           = "rtsp",
401    .long_name      = NULL_IF_CONFIG_SMALL("RTSP input format"),
402    .priv_data_size = sizeof(RTSPState),
403    .read_probe     = rtsp_probe,
404    .read_header    = rtsp_read_header,
405    .read_packet    = rtsp_read_packet,
406    .read_close     = rtsp_read_close,
407    .read_seek      = rtsp_read_seek,
408    .flags = AVFMT_NOFILE,
409    .read_play = rtsp_read_play,
410    .read_pause = rtsp_read_pause,
411    .priv_class = &rtsp_demuxer_class,
412};
413