FFmpeg
Loading...
Searching...
No Matches
rtspdec.c
Go to the documentation of this file.
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 "config_components.h"
23
24#include "libavutil/avstring.h"
25#include "libavutil/avassert.h"
28#include "libavutil/mem.h"
30#include "libavutil/time.h"
31#include "avformat.h"
32#include "demux.h"
33
34#include "internal.h"
35#include "network.h"
36#include "os_support.h"
37#include "rtpproto.h"
38#include "rtsp.h"
39#include "rdt.h"
40#include "tls.h"
41#include "url.h"
42#include "version.h"
43
44static const struct RTSPStatusMessage {
46 const char *message;
47} status_messages[] = {
48 { RTSP_STATUS_OK, "OK" },
49 { RTSP_STATUS_METHOD, "Method Not Allowed" },
50 { RTSP_STATUS_BANDWIDTH, "Not Enough Bandwidth" },
51 { RTSP_STATUS_SESSION, "Session Not Found" },
52 { RTSP_STATUS_STATE, "Method Not Valid in This State" },
53 { RTSP_STATUS_AGGREGATE, "Aggregate operation not allowed" },
54 { RTSP_STATUS_ONLY_AGGREGATE, "Only aggregate operation allowed" },
55 { RTSP_STATUS_TRANSPORT, "Unsupported transport" },
56 { RTSP_STATUS_INTERNAL, "Internal Server Error" },
57 { RTSP_STATUS_SERVICE, "Service Unavailable" },
58 { RTSP_STATUS_VERSION, "RTSP Version not supported" },
59 { 0, "NULL" }
60};
61
63{
64 RTSPState *rt = s->priv_data;
65
66 if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN))
67 ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
68
72 rt->real_setup = NULL;
74 return 0;
75}
76
77static inline int read_line(AVFormatContext *s, char *rbuf, const int rbufsize,
78 int *rbuflen)
79{
80 RTSPState *rt = s->priv_data;
81 int idx = 0;
82 int ret = 0;
83 *rbuflen = 0;
84
85 do {
86 ret = ffurl_read_complete(rt->rtsp_hd, rbuf + idx, 1);
87 if (ret <= 0)
88 return ret ? ret : AVERROR_EOF;
89 if (rbuf[idx] == '\r') {
90 /* Ignore */
91 } else if (rbuf[idx] == '\n') {
92 rbuf[idx] = '\0';
93 *rbuflen = idx;
94 return 0;
95 } else
96 idx++;
97 } while (idx < rbufsize);
98 av_log(s, AV_LOG_ERROR, "Message too long\n");
99 return AVERROR(EIO);
100}
101
103 const char *extracontent, uint16_t seq)
104{
105 RTSPState *rt = s->priv_data;
106 char message[MAX_URL_SIZE];
107 int index = 0;
108 while (status_messages[index].code) {
109 if (status_messages[index].code == code) {
110 snprintf(message, sizeof(message), "RTSP/1.0 %d %s\r\n",
112 break;
113 }
114 index++;
115 }
117 return AVERROR(EINVAL);
118 av_strlcatf(message, sizeof(message), "CSeq: %d\r\n", seq);
119 av_strlcatf(message, sizeof(message), "Server: %s\r\n", LIBAVFORMAT_IDENT);
120 if (extracontent)
121 av_strlcat(message, extracontent, sizeof(message));
122 av_strlcat(message, "\r\n", sizeof(message));
123 av_log(s, AV_LOG_TRACE, "Sending response:\n%s", message);
124 ffurl_write(rt->rtsp_hd_out, message, strlen(message));
125
126 return 0;
127}
128
130 RTSPMessageHeader *request)
131{
132 RTSPState *rt = s->priv_data;
133 unsigned char *session_id = rt->session_id;
134 if (!session_id[0]) {
135 av_log(s, AV_LOG_WARNING, "There is no session-id at the moment\n");
136 return 0;
137 }
138 if (strcmp(session_id, request->session_id)) {
139 av_log(s, AV_LOG_ERROR, "Unexpected session-id %s\n",
140 request->session_id);
143 }
144 return 0;
145}
146
148 RTSPMessageHeader *request,
149 const char *method)
150{
151 RTSPState *rt = s->priv_data;
152 char rbuf[MAX_URL_SIZE];
153 int rbuflen, ret;
154 do {
155 ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
156 if (ret)
157 return ret;
158 if (rbuflen > 1) {
159 av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
160 ff_rtsp_parse_line(s, request, rbuf, rt, method);
161 }
162 } while (rbuflen > 0);
163 if (request->seq != rt->seq + 1) {
164 av_log(s, AV_LOG_ERROR, "Unexpected Sequence number %d\n",
165 request->seq);
166 return AVERROR(EINVAL);
167 }
168 if (rt->session_id[0] && strcmp(method, "OPTIONS")) {
169 ret = check_sessionid(s, request);
170 if (ret)
171 return ret;
172 }
173
174 return 0;
175}
176
178{
179 RTSPState *rt = s->priv_data;
180 RTSPMessageHeader request = { 0 };
181 char *sdp;
182 int ret;
183
184 ret = rtsp_read_request(s, &request, "ANNOUNCE");
185 if (ret)
186 return ret;
187 rt->seq++;
188 if (strcmp(request.content_type, "application/sdp")) {
189 av_log(s, AV_LOG_ERROR, "Unexpected content type %s\n",
190 request.content_type);
193 }
194 if (request.content_length > 0 && request.content_length <= SDP_MAX_SIZE) {
195 sdp = av_malloc(request.content_length + 1);
196 if (!sdp)
197 return AVERROR(ENOMEM);
198
199 /* Read SDP */
200 if (ffurl_read_complete(rt->rtsp_hd, sdp, request.content_length)
201 < request.content_length) {
203 "Unable to get complete SDP Description in ANNOUNCE\n");
205 av_free(sdp);
206 return AVERROR(EIO);
207 }
208 sdp[request.content_length] = '\0';
209 av_log(s, AV_LOG_VERBOSE, "SDP: %s\n", sdp);
210 ret = ff_sdp_parse(s, sdp);
211 av_free(sdp);
212 if (ret)
213 return ret;
215 return 0;
216 }
218 "Invalid ANNOUNCE Content-Length %d\n", request.content_length);
220 "Invalid Content-Length", request.seq);
221 return AVERROR_INVALIDDATA;
222}
223
225{
226 RTSPState *rt = s->priv_data;
227 RTSPMessageHeader request = { 0 };
228 int ret = 0;
229
230 /* Parsing headers */
231 ret = rtsp_read_request(s, &request, "OPTIONS");
232 if (ret)
233 return ret;
234 rt->seq++;
235 /* Send Reply */
237 "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, RECORD\r\n",
238 request.seq);
239 return 0;
240}
241
242static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl)
243{
244 RTSPState *rt = s->priv_data;
245 RTSPMessageHeader request = { 0 };
246 int ret = 0;
247 char url[MAX_URL_SIZE];
248 RTSPStream *rtsp_st;
249 char responseheaders[MAX_URL_SIZE];
250 int localport = -1;
251 int transportidx = 0;
252 int streamid = 0;
253
254 ret = rtsp_read_request(s, &request, "SETUP");
255 if (ret)
256 return ret;
257 rt->seq++;
258 if (!request.nb_transports) {
259 av_log(s, AV_LOG_ERROR, "No transport defined in SETUP\n");
260 return AVERROR_INVALIDDATA;
261 }
262 for (transportidx = 0; transportidx < request.nb_transports;
263 transportidx++) {
264 if (!request.transports[transportidx].mode_record ||
265 (request.transports[transportidx].lower_transport !=
267 request.transports[transportidx].lower_transport !=
269 av_log(s, AV_LOG_ERROR, "mode=record/receive not set or transport"
270 " protocol not supported (yet)\n");
271 return AVERROR_INVALIDDATA;
272 }
273 }
274 if (request.nb_transports > 1)
275 av_log(s, AV_LOG_WARNING, "More than one transport not supported, "
276 "using first of all\n");
277 for (streamid = 0; streamid < rt->nb_rtsp_streams; streamid++) {
278 if (!strcmp(rt->rtsp_streams[streamid]->control_url,
279 controlurl))
280 break;
281 }
282 if (streamid == rt->nb_rtsp_streams) {
283 av_log(s, AV_LOG_ERROR, "Unable to find requested track\n");
285 }
286 rtsp_st = rt->rtsp_streams[streamid];
287 localport = rt->rtp_port_min;
288
289 /* check if the stream has already been setup */
290 if (rtsp_st->transport_priv) {
291 if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
293 else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP)
295 rtsp_st->transport_priv = NULL;
296 }
297 if (rtsp_st->rtp_handle)
298 ffurl_closep(&rtsp_st->rtp_handle);
299
302 if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
304 return ret;
305 }
306 rtsp_st->interleaved_min = request.transports[0].interleaved_min;
307 rtsp_st->interleaved_max = request.transports[0].interleaved_max;
308 snprintf(responseheaders, sizeof(responseheaders), "Transport: "
309 "RTP/AVP/TCP;unicast;mode=record;interleaved=%d-%d"
310 "\r\n", request.transports[0].interleaved_min,
311 request.transports[0].interleaved_max);
312 } else {
313 do {
315 av_dict_set_int(&opts, "buffer_size", rt->buffer_size, 0);
316 ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
317 av_log(s, AV_LOG_TRACE, "Opening: %s\n", url);
319 &s->interrupt_callback, &opts,
320 s->protocol_whitelist, s->protocol_blacklist, NULL);
322 if (ret)
323 localport += 2;
324 } while (ret || localport > rt->rtp_port_max);
325 if (localport > rt->rtp_port_max) {
327 return ret;
328 }
329
330 av_log(s, AV_LOG_TRACE, "Listening on: %d\n",
332 if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
334 return ret;
335 }
336
337 localport = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
338 snprintf(responseheaders, sizeof(responseheaders), "Transport: "
339 "RTP/AVP/UDP;unicast;mode=record;source=%s;"
340 "client_port=%d-%d;server_port=%d-%d\r\n",
341 host, request.transports[0].client_port_min,
342 request.transports[0].client_port_max, localport,
343 localport + 1);
344 }
345
346 /* Establish sessionid if not previously set */
347 /* Put this in a function? */
348 /* RFC 2326: session id must be at least 8 digits */
349 while (strlen(rt->session_id) < 8)
350 av_strlcatf(rt->session_id, 512, "%u", av_get_random_seed());
351
352 av_strlcatf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
353 rt->session_id);
354 /* Send Reply */
355 rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
356
358 return 0;
359}
360
362{
363 RTSPState *rt = s->priv_data;
364 RTSPMessageHeader request = { 0 };
365 int ret = 0;
366 char responseheaders[MAX_URL_SIZE];
367
368 ret = rtsp_read_request(s, &request, "RECORD");
369 if (ret)
370 return ret;
371 ret = check_sessionid(s, &request);
372 if (ret)
373 return ret;
374 rt->seq++;
375 snprintf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
376 rt->session_id);
377 rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
378
380 return 0;
381}
382
383static inline int parse_command_line(AVFormatContext *s, const char *line,
384 int linelen, char *uri, int urisize,
385 char *method, int methodsize,
386 enum RTSPMethod *methodcode)
387{
388 RTSPState *rt = s->priv_data;
389 const char *linept, *searchlinept;
390 linept = strchr(line, ' ');
391
392 if (!linept) {
393 av_log(s, AV_LOG_ERROR, "Error parsing method string\n");
394 return AVERROR_INVALIDDATA;
395 }
396
397 if (linept - line > methodsize - 1) {
398 av_log(s, AV_LOG_ERROR, "Method string too long\n");
399 return AVERROR(EIO);
400 }
401 memcpy(method, line, linept - line);
402 method[linept - line] = '\0';
403 linept++;
404 if (!strcmp(method, "ANNOUNCE"))
405 *methodcode = ANNOUNCE;
406 else if (!strcmp(method, "OPTIONS"))
407 *methodcode = OPTIONS;
408 else if (!strcmp(method, "RECORD"))
409 *methodcode = RECORD;
410 else if (!strcmp(method, "SETUP"))
411 *methodcode = SETUP;
412 else if (!strcmp(method, "PAUSE"))
413 *methodcode = PAUSE;
414 else if (!strcmp(method, "TEARDOWN"))
415 *methodcode = TEARDOWN;
416 else
417 *methodcode = UNKNOWN;
418 /* Check method with the state */
419 if (rt->state == RTSP_STATE_IDLE) {
420 if ((*methodcode != ANNOUNCE) && (*methodcode != OPTIONS)) {
421 av_log(s, AV_LOG_ERROR, "Unexpected command in Idle State %s\n",
422 line);
424 }
425 } else if (rt->state == RTSP_STATE_PAUSED) {
426 if ((*methodcode != OPTIONS) && (*methodcode != RECORD)
427 && (*methodcode != SETUP)) {
428 av_log(s, AV_LOG_ERROR, "Unexpected command in Paused State %s\n",
429 line);
431 }
432 } else if (rt->state == RTSP_STATE_STREAMING) {
433 if ((*methodcode != PAUSE) && (*methodcode != OPTIONS)
434 && (*methodcode != TEARDOWN)) {
435 av_log(s, AV_LOG_ERROR, "Unexpected command in Streaming State"
436 " %s\n", line);
438 }
439 } else {
440 av_log(s, AV_LOG_ERROR, "Unexpected State [%d]\n", rt->state);
441 return AVERROR_BUG;
442 }
443
444 searchlinept = strchr(linept, ' ');
445 if (!searchlinept) {
446 av_log(s, AV_LOG_ERROR, "Error parsing message URI\n");
447 return AVERROR_INVALIDDATA;
448 }
449 if (searchlinept - linept > urisize - 1) {
450 av_log(s, AV_LOG_ERROR, "uri string length exceeded buffer size\n");
451 return AVERROR(EIO);
452 }
453 memcpy(uri, linept, searchlinept - linept);
454 uri[searchlinept - linept] = '\0';
455 if (strcmp(rt->control_uri, uri)) {
456 char host[128], path[512], auth[128];
457 int port;
458 char ctl_host[128], ctl_path[512], ctl_auth[128];
459 int ctl_port;
460 av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
461 path, sizeof(path), uri);
462 av_url_split(NULL, 0, ctl_auth, sizeof(ctl_auth), ctl_host,
463 sizeof(ctl_host), &ctl_port, ctl_path, sizeof(ctl_path),
464 rt->control_uri);
465 if (strcmp(host, ctl_host))
466 av_log(s, AV_LOG_INFO, "Host %s differs from expected %s\n",
467 host, ctl_host);
468 if (strcmp(path, ctl_path) && *methodcode != SETUP)
469 av_log(s, AV_LOG_WARNING, "WARNING: Path %s differs from expected"
470 " %s\n", path, ctl_path);
471 if (*methodcode == ANNOUNCE) {
473 "Updating control URI to %s\n", uri);
474 av_strlcpy(rt->control_uri, uri, sizeof(rt->control_uri));
475 }
476 }
477
478 linept = searchlinept + 1;
479 if (!av_strstart(linept, "RTSP/1.0", NULL)) {
480 av_log(s, AV_LOG_ERROR, "Error parsing protocol or version\n");
482 }
483 return 0;
484}
485
487{
488 RTSPState *rt = s->priv_data;
489 unsigned char rbuf[MAX_URL_SIZE];
490 unsigned char method[10];
491 char uri[500];
492 int ret;
493 int rbuflen = 0;
494 RTSPMessageHeader request = { 0 };
495 enum RTSPMethod methodcode;
496
497 ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
498 if (ret < 0)
499 return ret;
500 av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
501 ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
502 sizeof(method), &methodcode);
503 if (ret) {
504 av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
505 return ret;
506 }
507
508 ret = rtsp_read_request(s, &request, method);
509 if (ret)
510 return ret;
511 rt->seq++;
512 if (methodcode == PAUSE) {
514 ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
515 // TODO: Missing date header in response
516 } else if (methodcode == OPTIONS) {
518 "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, "
519 "RECORD\r\n", request.seq);
520 } else if (methodcode == TEARDOWN) {
522 ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
523 }
524 return ret;
525}
526
528{
529 RTSPState *rt = s->priv_data;
530 RTSPMessageHeader reply1, *reply = &reply1;
531 int i;
532 char cmd[MAX_URL_SIZE];
533
534 av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
535 rt->nb_byes = 0;
536
538 for (i = 0; i < rt->nb_rtsp_streams; i++) {
539 RTSPStream *rtsp_st = rt->rtsp_streams[i];
540 /* Try to initialize the connection state in a
541 * potential NAT router by sending dummy packets.
542 * RTP/RTCP dummy packets are used for RDT, too.
543 */
544 if (rtsp_st->rtp_handle &&
545 !(rt->server_type == RTSP_SERVER_WMS && i > 1))
547 }
548 }
549 if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
550 if (rt->transport == RTSP_TRANSPORT_RTP) {
551 for (i = 0; i < rt->nb_rtsp_streams; i++) {
552 RTSPStream *rtsp_st = rt->rtsp_streams[i];
553 RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
554 if (!rtpctx)
555 continue;
559 rtpctx->base_timestamp = 0;
560 rtpctx->timestamp = 0;
561 rtpctx->unwrapped_timestamp = 0;
562 rtpctx->rtcp_ts_offset = 0;
563 }
564 }
565 if (rt->state == RTSP_STATE_PAUSED) {
566 cmd[0] = 0;
567 } else {
568 snprintf(cmd, sizeof(cmd),
569 "Range: npt=%"PRId64".%03"PRId64"-\r\n",
571 rt->seek_timestamp / (AV_TIME_BASE / 1000) % 1000);
572 }
573 ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
574 if (reply->status_code != RTSP_STATUS_OK) {
575 return ff_rtsp_averror(reply->status_code, -1);
576 }
577 if (rt->transport == RTSP_TRANSPORT_RTP &&
578 reply->range_start != AV_NOPTS_VALUE) {
579 for (i = 0; i < rt->nb_rtsp_streams; i++) {
580 RTSPStream *rtsp_st = rt->rtsp_streams[i];
581 RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
582 AVStream *st = NULL;
583 if (!rtpctx || rtsp_st->stream_index < 0)
584 continue;
585
586 st = s->streams[rtsp_st->stream_index];
587 rtpctx->range_start_offset =
589 st->time_base);
590 }
591 }
592 }
594 return 0;
595}
596
597/* pause the stream */
599{
600 RTSPState *rt = s->priv_data;
601 RTSPMessageHeader reply1, *reply = &reply1;
602
603 if (rt->state != RTSP_STATE_STREAMING)
604 return 0;
605 else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
606 ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
607 if (reply->status_code != RTSP_STATUS_OK) {
608 return ff_rtsp_averror(reply->status_code, -1);
609 }
610 }
612 return 0;
613}
614
617{
618 switch (state) {
620 return rtsp_read_play(s);
622 return rtsp_read_pause(s);
623 default:
624 return AVERROR(ENOTSUP);
625 }
626}
627
628static char *dict_to_headers(AVDictionary *headers)
629{
630 char *buf;
631 AVBPrint bprint;
633
635 while ((header = av_dict_iterate(headers, header))) {
636 av_bprintf(&bprint, "%s: %s\r\n", header->key, header->value);
637 }
638
639 av_bprint_finalize(&bprint, &buf);
640 return buf;
641}
642
643static int rtsp_submit_command(struct AVFormatContext *s, enum AVFormatCommandID id, void *data)
644{
646 return AVERROR(ENOTSUP);
647 if (!data)
648 return AVERROR(EINVAL);
649
650 RTSPState *rt = s->priv_data;
652
653 if (rt->state == RTSP_STATE_IDLE)
654 // Not ready to send a SET_PARAMETERS command yet
655 return AVERROR(EAGAIN);
656
657 av_log(s, AV_LOG_DEBUG, "Sending SET_PARAMETER command to %s\n", rt->control_uri);
658 char *headers = dict_to_headers(req->headers);
659
660 int ret = ff_rtsp_send_cmd_with_content_async_stored(s, "SET_PARAMETER",
661 rt->control_uri, headers, req->body, req->body_len);
662 av_free(headers);
663
664 if (ret != 0)
665 av_log(s, AV_LOG_ERROR, "Failure sending SET_PARAMETER command: %s\n", av_err2str(ret));
666
667 return ret;
668}
669
670static int rtsp_read_command_reply(AVFormatContext *s, enum AVFormatCommandID id, void **data_out)
671{
673 return AVERROR(ENOTSUP);
674 if (!data_out)
675 return AVERROR(EINVAL);
676
677 unsigned char *body;
678 RTSPMessageHeader *reply;
679 int ret = ff_rtsp_read_reply_async_stored(s, &reply, &body);
680 if (ret < 0)
681 return ret;
682
683 AVRTSPResponse *res = av_malloc(sizeof(*res));
684 if (!res) {
685 av_free(body);
686 av_free(reply);
687 return AVERROR(ENOMEM);
688 }
689
690 res->status_code = reply->status_code;
691 res->body_len = reply->content_length;
692 res->body = body;
693
694 res->reason = av_strdup(reply->reason);
695 if (!res->reason) {
696 av_free(res->body);
697 av_free(res);
698 av_free(reply);
699 return AVERROR(ENOMEM);
700 }
701
702 av_free(reply);
703 *data_out = res;
704 return 0;
705}
706
709 enum AVFormatCommandID id, void *data)
710{
711 switch (opt) {
713 return rtsp_submit_command(s, id, data);
715 return rtsp_read_command_reply(s, id, data);
716 default:
717 av_unreachable("Invalid command option");
718 }
719}
720
722{
723 RTSPState *rt = s->priv_data;
724 char cmd[MAX_URL_SIZE];
725 unsigned char *content = NULL;
726 int ret;
727
728 /* describe the stream */
729 snprintf(cmd, sizeof(cmd),
730 "Accept: application/sdp\r\n");
731 if (rt->server_type == RTSP_SERVER_REAL) {
732 /**
733 * The Require: attribute is needed for proper streaming from
734 * Realmedia servers.
735 */
736 av_strlcat(cmd,
737 "Require: com.real.retain-entity-for-setup\r\n",
738 sizeof(cmd));
739 }
740 ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
741 if (reply->status_code != RTSP_STATUS_OK) {
742 av_freep(&content);
744 }
745 if (!content)
746 return AVERROR_INVALIDDATA;
747
748 av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
749 /* now we got the SDP description, we parse it */
750 ret = ff_sdp_parse(s, (const char *)content);
751 av_freep(&content);
752 if (ret < 0)
753 return ret;
754
755 return 0;
756}
757
759{
760 RTSPState *rt = s->priv_data;
761 char proto[128], host[128], path[512], auth[128];
762 char uri[500];
763 int port;
764 int default_port = RTSP_DEFAULT_PORT;
765 char tcpname[500];
766 const char *lower_proto = "tcp";
767 unsigned char rbuf[MAX_URL_SIZE];
768 unsigned char method[10];
769 int rbuflen = 0;
770 int ret;
771 enum RTSPMethod methodcode;
772
773 if ((ret = ff_network_init()) < 0)
774 return ret;
775
776 /* extract hostname and port */
777 av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
778 &port, path, sizeof(path), s->url);
779
780 /* ff_url_join. No authorization by now (NULL) */
781 ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL, host,
782 port, "%s", path);
783
784 if (!strcmp(proto, "rtsps")) {
785 lower_proto = "tls";
786 default_port = RTSPS_DEFAULT_PORT;
787 }
788
789 if (port < 0)
790 port = default_port;
791
792 /* Create TCP connection */
793 ff_url_join(tcpname, sizeof(tcpname), lower_proto, NULL, host, port,
794 "?listen&listen_timeout=%d", rt->initial_timeout * 1000);
795
796 if (ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
797 &s->interrupt_callback, NULL,
798 s->protocol_whitelist, s->protocol_blacklist, NULL)) {
799 av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n");
800 goto fail;
801 }
803 rt->rtsp_hd_out = rt->rtsp_hd;
804 for (;;) { /* Wait for incoming RTSP messages */
805 ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
806 if (ret < 0)
807 goto fail;
808 av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
809 ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
810 sizeof(method), &methodcode);
811 if (ret) {
812 av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
813 goto fail;
814 }
815
816 if (methodcode == ANNOUNCE) {
817 ret = rtsp_read_announce(s);
819 } else if (methodcode == OPTIONS) {
820 ret = rtsp_read_options(s);
821 } else if (methodcode == RECORD) {
822 ret = rtsp_read_record(s);
823 if (!ret)
824 return 0; // We are ready for streaming
825 } else if (methodcode == SETUP)
826 ret = rtsp_read_setup(s, host, uri);
827 if (ret) {
829 goto fail;
830 }
831 }
832fail:
836 return ret;
837}
838
839static int rtsp_probe(const AVProbeData *p)
840{
841 if (
842#if CONFIG_TLS_PROTOCOL
843 av_strstart(p->filename, "rtsps:", NULL) ||
844#endif
845 av_strstart(p->filename, "satip:", NULL) ||
846 av_strstart(p->filename, "rtsp:", NULL))
847 return AVPROBE_SCORE_MAX;
848 return 0;
849}
850
852{
853 RTSPState *rt = s->priv_data;
854 int ret;
855
856 if (rt->initial_timeout > 0)
858
859 if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
860 ret = rtsp_listen(s);
861 if (ret)
862 return ret;
863 } else {
864 ret = ff_rtsp_connect(s);
865 if (ret)
866 return ret;
867
868 rt->real_setup_cache = !s->nb_streams ? NULL :
869 av_calloc(s->nb_streams, 2 * sizeof(*rt->real_setup_cache));
870 if (!rt->real_setup_cache && s->nb_streams) {
871 ret = AVERROR(ENOMEM);
872 goto fail;
873 }
874 rt->real_setup = rt->real_setup_cache + s->nb_streams;
875
876 if (rt->initial_pause) {
877 /* do not start immediately */
878 } else {
879 ret = rtsp_read_play(s);
880 if (ret < 0)
881 goto fail;
882 }
883 }
884
885 return 0;
886
887fail:
889 return ret;
890}
891
893 uint8_t *buf, int buf_size)
894{
895 RTSPState *rt = s->priv_data;
896 int id, len, i, ret;
897 RTSPStream *rtsp_st;
898
899 av_log(s, AV_LOG_TRACE, "tcp_read_packet:\n");
900redo:
901 for (;;) {
902 RTSPMessageHeader reply;
903
904 ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL);
905 if (ret < 0)
906 return ret;
907 if (ret == 1) /* received '$' */
908 break;
909 /* XXX: parse message */
910 if (rt->state != RTSP_STATE_STREAMING)
911 return 0;
912 }
913 ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
914 if (ret != 3)
915 return AVERROR(EIO);
916 rt->pending_packet = 0;
917 id = buf[0];
918 len = AV_RB16(buf + 1);
919 av_log(s, AV_LOG_TRACE, "id=%d len=%d\n", id, len);
920 if (len > buf_size || len < 8)
921 goto redo;
922 /* get the data */
923 ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
924 if (ret != len)
925 return AVERROR(EIO);
926 if (rt->transport == RTSP_TRANSPORT_RDT &&
927 (ret = ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL)) < 0)
928 return ret;
929
930 /* find the matching stream */
931 for (i = 0; i < rt->nb_rtsp_streams; i++) {
932 rtsp_st = rt->rtsp_streams[i];
933 if (id >= rtsp_st->interleaved_min &&
934 id <= rtsp_st->interleaved_max)
935 goto found;
936 }
937 goto redo;
938found:
939 *prtsp_st = rtsp_st;
940 return len;
941}
942
944{
945 RTSPState *rt = s->priv_data;
946 char host[1024];
947 int port;
948
949 av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
950 s->url);
953 rt->real_challenge);
954}
955
957{
958 RTSPState *rt = s->priv_data;
959 int ret;
960 RTSPMessageHeader reply1, *reply = &reply1;
961 char cmd[MAX_URL_SIZE];
962
963retry:
964 if (rt->server_type == RTSP_SERVER_REAL) {
965 int i;
966
967 for (i = 0; i < s->nb_streams; i++)
968 rt->real_setup[i] = s->streams[i]->discard;
969
970 if (!rt->need_subscription) {
971 if (memcmp (rt->real_setup, rt->real_setup_cache,
972 sizeof(enum AVDiscard) * s->nb_streams)) {
973 snprintf(cmd, sizeof(cmd),
974 "Unsubscribe: %s\r\n",
976 ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
977 cmd, reply, NULL);
978 if (reply->status_code != RTSP_STATUS_OK)
980 rt->need_subscription = 1;
981 }
982 }
983
984 if (rt->need_subscription) {
985 int r, rule_nr, first = 1;
986
987 memcpy(rt->real_setup_cache, rt->real_setup,
988 sizeof(enum AVDiscard) * s->nb_streams);
989 rt->last_subscription[0] = 0;
990
991 snprintf(cmd, sizeof(cmd),
992 "Subscribe: ");
993 for (i = 0; i < rt->nb_rtsp_streams; i++) {
994 rule_nr = 0;
995 for (r = 0; r < s->nb_streams; r++) {
996 if (s->streams[r]->id == i) {
997 if (s->streams[r]->discard != AVDISCARD_ALL) {
998 if (!first)
1000 sizeof(rt->last_subscription));
1003 sizeof(rt->last_subscription), i, rule_nr);
1004 first = 0;
1005 }
1006 rule_nr++;
1007 }
1008 }
1009 }
1010 av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
1011 ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
1012 cmd, reply, NULL);
1013 if (reply->status_code != RTSP_STATUS_OK)
1015 rt->need_subscription = 0;
1016
1017 if (rt->state == RTSP_STATE_STREAMING)
1018 rtsp_read_play (s);
1019 }
1020 }
1021
1022 ret = ff_rtsp_fetch_packet(s, pkt);
1023 if (ret < 0) {
1024 if (ret == AVERROR(ETIMEDOUT) && !rt->packets) {
1027 RTSPMessageHeader reply1, *reply = &reply1;
1028 av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
1029 if (rtsp_read_pause(s) != 0)
1030 return -1;
1031 // TEARDOWN is required on Real-RTSP, but might make
1032 // other servers close the connection.
1033 if (rt->server_type == RTSP_SERVER_REAL)
1034 ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
1035 reply, NULL);
1036 rt->session_id[0] = '\0';
1037 if (resetup_tcp(s) == 0) {
1038 rt->state = RTSP_STATE_IDLE;
1039 rt->need_subscription = 1;
1040 if (rtsp_read_play(s) != 0)
1041 return -1;
1042 goto retry;
1043 }
1044 }
1045 }
1046 return ret;
1047 }
1048 rt->packets++;
1049
1050 if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
1051 /* send dummy request to keep TCP connection alive */
1052 if ((av_gettime_relative() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
1053 rt->auth_state.stale) {
1054 if (rt->server_type == RTSP_SERVER_WMS ||
1055 (rt->server_type != RTSP_SERVER_REAL &&
1057 ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
1058 } else {
1059 ff_rtsp_send_cmd_async(s, "OPTIONS", rt->control_uri, NULL);
1060 }
1061 /* The stale flag should be reset when creating the auth response in
1062 * ff_rtsp_send_cmd_async, but reset it here just in case we never
1063 * called the auth code (if we didn't have any credentials set). */
1064 rt->auth_state.stale = 0;
1065 }
1066 }
1067
1068 return 0;
1069}
1070
1071static int rtsp_read_seek(AVFormatContext *s, int stream_index,
1072 int64_t timestamp, int flags)
1073{
1074 RTSPState *rt = s->priv_data;
1075 int ret;
1076
1077 rt->seek_timestamp = av_rescale_q(timestamp,
1078 s->streams[stream_index]->time_base,
1080 switch(rt->state) {
1081 default:
1082 case RTSP_STATE_IDLE:
1083 break;
1085 if ((ret = rtsp_read_pause(s)) != 0)
1086 return ret;
1088 if ((ret = rtsp_read_play(s)) != 0)
1089 return ret;
1090 break;
1091 case RTSP_STATE_PAUSED:
1092 rt->state = RTSP_STATE_IDLE;
1093 break;
1094 }
1095 return 0;
1096}
1097
1099 .class_name = "RTSP demuxer",
1100 .item_name = av_default_item_name,
1101 .option = ff_rtsp_options,
1102 .version = LIBAVUTIL_VERSION_INT,
1103};
1104
1106 .p.name = "rtsp",
1107 .p.long_name = NULL_IF_CONFIG_SMALL("RTSP input"),
1108 .p.flags = AVFMT_NOFILE,
1109 .p.priv_class = &rtsp_demuxer_class,
1110 .priv_data_size = sizeof(RTSPState),
1116 .read_set_state = rtsp_read_set_state,
1117 .handle_command = rtsp_handle_command,
1118};
const FFInputFormat ff_rtsp_demuxer
Definition rtspdec.c:1105
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition avassert.h:109
Main libavformat public API header.
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:483
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition avformat.h:488
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist, URLContext *parent)
Create an URLContext for accessing to the resource indicated by url, and open it.
Definition avio.c:461
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition avio.c:656
int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)
Read as many bytes as possible (up to size), calling the read function multiple times if necessary.
Definition avio.c:625
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition avio.h:619
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition avstring.c:103
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition bprint.c:122
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition bprint.c:69
#define AV_BPRINT_SIZE_UNLIMITED
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
FFInputFormatStreamState
Input format stream state The stream states to be used for FFInputFormat::read_set_state.
Definition demux.h:51
@ FF_INFMT_STATE_PLAY
Definition demux.h:52
@ FF_INFMT_STATE_PAUSE
Definition demux.h:53
FFInputFormatCommandOption
Command handling options Different options influencing the behaviour of the FFInputFormat::handle_com...
Definition demux.h:61
@ FF_INFMT_COMMAND_GET_REPLY
Definition demux.h:63
@ FF_INFMT_COMMAND_SUBMIT
Definition demux.h:62
static AVPacket * pkt
enum AVCodecID id
Definition dts2pts.c:607
static struct @346255127015250356166251341105367306144006377143 state
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
@ UNKNOWN
Definition ftp.c:39
#define fail
Definition test.h:479
AVDiscard
Definition defs.h:223
@ AVDISCARD_ALL
discard all
Definition defs.h:232
AVFormatCommandID
Command IDs that can be sent to the demuxer.
Definition avformat.h:2518
@ AVFORMAT_COMMAND_RTSP_SET_PARAMETER
Send a RTSP SET_PARAMETER request to the server.
Definition avformat.h:2529
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition utils.c:361
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition bprint.c:235
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
const AVDictionaryEntry * av_dict_iterate(const AVDictionary *m, const AVDictionaryEntry *prev)
Iterate over a dictionary.
Definition dict.c:42
int av_dict_set_int(AVDictionary **pm, const char *key, int64_t value, int flags)
Convenience wrapper for av_dict_set() that converts the value to a string and stores it.
Definition dict.c:177
#define AVERROR_PROTOCOL_NOT_FOUND
Protocol not found.
Definition error.h:65
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition error.h:52
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_STREAM_NOT_FOUND
Stream not found.
Definition error.h:67
#define AVERROR_EOF
End of file.
Definition error.h:57
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
#define AVERROR_OPTION_NOT_FOUND
Option not found.
Definition error.h:63
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition log.h:236
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition avstring.c:95
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition avstring.c:36
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition avstring.c:85
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_TIME_BASE
Internal time base represented as integer.
Definition avutil.h:253
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition avutil.h:263
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
int index
Definition gxfenc.c:90
#define r
Definition input.c:42
#define AV_RB16(p)
#define MAX_URL_SIZE
Definition internal.h:30
Libavformat version macros.
#define LIBAVFORMAT_IDENT
Definition version.h:45
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
static av_cold int read_close(AVFormatContext *ctx)
Definition libcdio.c:143
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition libcdio.c:151
static void body(uint32_t ABCD[4], const uint8_t *src, size_t nblocks)
Definition md5.c:103
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
const char data[16]
Definition mxf.c:149
int ff_network_init(void)
Initialize the network subsystem.
Definition network.c:63
void ff_network_close(void)
Definition network.c:121
#define av_strdup(s)
Definition ops_static.c:55
#define av_malloc(s)
Definition ops_static.c:52
miscellaneous OS support macros and functions.
void ff_rdt_parse_close(RDTDemuxContext *s)
Definition rdt.c:80
int ff_rdt_parse_header(const uint8_t *buf, int len, int *pset_id, int *pseq_no, int *pstream_id, int *pis_keyframe, uint32_t *ptimestamp)
Actual data handling.
Definition rdt.c:192
void ff_rdt_subscribe_rule(char *cmd, int size, int stream_nr, int rule_nr)
Add subscription information to Subscribe parameter string.
Definition rdt.c:388
void ff_rtp_parse_close(RTPDemuxContext *s)
Definition rtpdec.c:938
void ff_rtp_send_punch_packets(URLContext *rtp_handle)
Send a dummy packet on both port pairs to set up the connection state in potential NAT routers,...
Definition rtpdec.c:415
void ff_rtp_reset_packet_queue(RTPDemuxContext *s)
Definition rtpdec.c:761
int ff_rtp_get_local_rtp_port(URLContext *h)
Return the local rtp port used by the RTP connection.
Definition rtpproto.c:514
int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
Open RTSP transport context.
Definition rtsp.c:869
const AVOption ff_rtsp_options[]
Definition rtsp.c:87
void ff_rtsp_close_streams(AVFormatContext *s)
Close and free all streams within the RTSP (de)muxer.
Definition rtsp.c:833
void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
Undo the effect of ff_rtsp_make_setup_request, close the transport_priv and rtp_handle fields.
Definition rtsp.c:800
int ff_sdp_parse(AVFormatContext *s, const char *content)
Parse an SDP description of streams by populating an RTSPState struct within the AVFormatContext; als...
#define RTSP_FLAG_LISTEN
Wait for incoming connections.
Definition rtsp.h:460
@ RTSP_SERVER_WMS
Windows Media server.
Definition rtsp.h:216
@ RTSP_SERVER_REAL
Realmedia-style server.
Definition rtsp.h:215
int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url, const char *headers, RTSPMessageHeader *reply, unsigned char **content_ptr)
Send a command to the RTSP server and wait for the reply.
int ff_rtsp_send_cmd_with_content_async_stored(AVFormatContext *s, const char *method, const char *url, const char *headers, const unsigned char *send_content, int send_content_length)
Send a command to the RTSP server, storing the reply on future reads.
int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply, unsigned char **content_ptr, int return_on_interleaved_data, const char *method)
Read a RTSP message from the server, or prepare to read data packets if we're reading data interleave...
int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, int lower_transport, const char *real_challenge)
Do the SETUP requests for each stream for the chosen lower transport mode.
int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method, const char *url, const char *headers)
Send a command to the RTSP server without waiting for the reply.
int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
Receive one packet from the RTSPStreams set up in the AVFormatContext (which should contain a RTSPSta...
void ff_rtsp_parse_line(AVFormatContext *s, RTSPMessageHeader *reply, const char *buf, RTSPState *rt, const char *method)
#define RTSPS_DEFAULT_PORT
Definition rtsp.h:76
@ RTSP_LOWER_TRANSPORT_TCP
TCP; interleaved in RTSP.
Definition rtsp.h:41
@ RTSP_LOWER_TRANSPORT_UDP
UDP/unicast.
Definition rtsp.h:40
int ff_rtsp_read_reply_async_stored(AVFormatContext *s, RTSPMessageHeader **reply, unsigned char **content_ptr)
Retrieve a previously stored RTSP reply message from the server.
void ff_rtsp_close_connections(AVFormatContext *s)
Close all connection handles within the RTSP (de)muxer.
@ RTSP_STATE_SEEKING
initialized, requesting a seek
Definition rtsp.h:206
@ RTSP_STATE_STREAMING
initialized and sending/receiving data
Definition rtsp.h:204
@ RTSP_STATE_PAUSED
initialized, but not receiving data
Definition rtsp.h:205
@ RTSP_STATE_IDLE
not initialized
Definition rtsp.h:203
#define SDP_MAX_SIZE
Definition rtsp.h:81
#define RTSP_DEFAULT_PORT
Definition rtsp.h:75
int ff_rtsp_connect(AVFormatContext *s)
Connect to the RTSP server and set up the individual media streams.
@ RTSP_TRANSPORT_RTP
Standards-compliant RTP.
Definition rtsp.h:60
@ RTSP_TRANSPORT_RDT
Realmedia Data Transport.
Definition rtsp.h:61
RTSPStatusCode
RTSP handling.
Definition rtspcodes.h:31
@ RTSP_STATUS_METHOD
Definition rtspcodes.h:47
@ RTSP_STATUS_SESSION
Definition rtspcodes.h:60
@ RTSP_STATUS_OK
Definition rtspcodes.h:33
@ RTSP_STATUS_VERSION
Definition rtspcodes.h:74
@ RTSP_STATUS_BANDWIDTH
Definition rtspcodes.h:59
@ RTSP_STATUS_STATE
Definition rtspcodes.h:61
@ RTSP_STATUS_SERVICE
Definition rtspcodes.h:72
@ RTSP_STATUS_TRANSPORT
Definition rtspcodes.h:67
@ RTSP_STATUS_AGGREGATE
Definition rtspcodes.h:65
@ RTSP_STATUS_ONLY_AGGREGATE
Definition rtspcodes.h:66
@ RTSP_STATUS_INTERNAL
Definition rtspcodes.h:69
static int ff_rtsp_averror(enum RTSPStatusCode status_code, int default_averror)
Definition rtspcodes.h:144
RTSPMethod
Definition rtspcodes.h:129
@ TEARDOWN
Definition rtspcodes.h:136
@ OPTIONS
Definition rtspcodes.h:132
@ ANNOUNCE
Definition rtspcodes.h:131
@ PAUSE
Definition rtspcodes.h:135
@ SETUP
Definition rtspcodes.h:133
@ RECORD
Definition rtspcodes.h:140
static int rtsp_probe(const AVProbeData *p)
Definition rtspdec.c:839
static int resetup_tcp(AVFormatContext *s)
Definition rtspdec.c:943
static int check_sessionid(AVFormatContext *s, RTSPMessageHeader *request)
Definition rtspdec.c:129
int ff_rtsp_setup_input_streams(AVFormatContext *s, RTSPMessageHeader *reply)
Get the description of the stream and set up the RTSPStream child objects.
Definition rtspdec.c:721
static int rtsp_read_setup(AVFormatContext *s, char *host, char *controlurl)
Definition rtspdec.c:242
static int rtsp_read_close(AVFormatContext *s)
Definition rtspdec.c:62
static int rtsp_read_options(AVFormatContext *s)
Definition rtspdec.c:224
static int read_line(AVFormatContext *s, char *rbuf, const int rbufsize, int *rbuflen)
Definition rtspdec.c:77
static int parse_command_line(AVFormatContext *s, const char *line, int linelen, char *uri, int urisize, char *method, int methodsize, enum RTSPMethod *methodcode)
Definition rtspdec.c:383
static int rtsp_read_set_state(AVFormatContext *s, enum FFInputFormatStreamState state)
Definition rtspdec.c:615
static int rtsp_send_reply(AVFormatContext *s, enum RTSPStatusCode code, const char *extracontent, uint16_t seq)
Definition rtspdec.c:102
static int rtsp_read_request(AVFormatContext *s, RTSPMessageHeader *request, const char *method)
Definition rtspdec.c:147
static int rtsp_read_record(AVFormatContext *s)
Definition rtspdec.c:361
static int rtsp_read_header(AVFormatContext *s)
Definition rtspdec.c:851
static const AVClass rtsp_demuxer_class
Definition rtspdec.c:1098
static int rtsp_handle_command(struct AVFormatContext *s, enum FFInputFormatCommandOption opt, enum AVFormatCommandID id, void *data)
Definition rtspdec.c:707
int ff_rtsp_parse_streaming_commands(AVFormatContext *s)
Parse RTSP commands (OPTIONS, PAUSE and TEARDOWN) during streaming in listen mode.
Definition rtspdec.c:486
static const struct RTSPStatusMessage status_messages[]
static int rtsp_read_announce(AVFormatContext *s)
Definition rtspdec.c:177
static int rtsp_read_play(AVFormatContext *s)
Definition rtspdec.c:527
static int rtsp_read_command_reply(AVFormatContext *s, enum AVFormatCommandID id, void **data_out)
Definition rtspdec.c:670
static int rtsp_submit_command(struct AVFormatContext *s, enum AVFormatCommandID id, void *data)
Definition rtspdec.c:643
int ff_rtsp_tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, uint8_t *buf, int buf_size)
Receive one RTP packet from an TCP interleaved RTSP stream.
Definition rtspdec.c:892
static int rtsp_listen(AVFormatContext *s)
Definition rtspdec.c:758
static int rtsp_read_pause(AVFormatContext *s)
Definition rtspdec.c:598
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition rtspdec.c:956
static int rtsp_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition rtspdec.c:1071
static char * dict_to_headers(AVDictionary *headers)
Definition rtspdec.c:628
static const uint8_t header[24]
Definition sdr2.c:68
#define snprintf
Definition snprintf.h:34
const uint8_t * code
Definition spdifenc.c:433
Describe the class of an AVClass context structure.
Definition log.h:76
Format I/O context.
Definition avformat.h:1333
This structure stores compressed data.
Definition packet.h:580
This structure contains the data a format has to probe a file.
Definition avformat.h:471
uint64_t ntp_timestamp
NTP time when the report was sent.
Definition defs.h:347
size_t body_len
Body payload size.
Definition avformat.h:2541
AVDictionary * headers
Headers sent in the request to the server.
Definition avformat.h:2536
char * body
Body payload.
Definition avformat.h:2546
int status_code
Response status code from server.
Definition avformat.h:2553
size_t body_len
Body payload size.
Definition avformat.h:2564
unsigned char * body
Body payload.
Definition avformat.h:2569
char * reason
Reason phrase from the server, describing the status in a human-readable way.
Definition avformat.h:2559
Stream structure.
Definition avformat.h:766
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avformat.h:805
int stale
Auth ok, but needs to be resent with a new nonce.
Definition httpauth.h:71
uint64_t first_rtcp_ntp_time
Definition rtpdec.h:177
uint32_t base_timestamp
Definition rtpdec.h:155
int64_t unwrapped_timestamp
Definition rtpdec.h:156
int64_t rtcp_ts_offset
Definition rtpdec.h:178
AVRTCPSenderReport last_sr
Last RTCP SR data.
Definition rtpdec.h:179
int64_t range_start_offset
Definition rtpdec.h:157
uint32_t timestamp
Definition rtpdec.h:154
This describes the server response to each RTSP command.
Definition rtsp.h:129
char reason[256]
The "reason" is meant to specify better the meaning of the error code returned.
Definition rtsp.h:184
int64_t range_start
Time range of the streams that the server will stream.
Definition rtsp.h:140
char session_id[512]
the "Session:" field.
Definition rtsp.h:150
enum RTSPStatusCode status_code
response code from server
Definition rtsp.h:133
int seq
sequence number
Definition rtsp.h:146
char content_type[64]
Content type header.
Definition rtsp.h:189
RTSPTransportField transports[RTSP_MAX_TRANSPORTS]
describes the complete "Transport:" line of the server in response to a SETUP RTSP command by the cli...
Definition rtsp.h:144
int nb_transports
number of items in the 'transports' variable below
Definition rtsp.h:136
int content_length
length of the data following this header
Definition rtsp.h:131
Private data for the RTSP demuxer.
Definition rtsp.h:226
char real_challenge[64]
the "RealChallenge1:" field from the server
Definition rtsp.h:278
int nb_rtsp_streams
number of items in the 'rtsp_streams' variable
Definition rtsp.h:231
enum RTSPTransport transport
the negotiated data/packet transport protocol; e.g.
Definition rtsp.h:266
int rtp_port_max
Definition rtsp.h:418
char last_subscription[1024]
the last value of the "SET_PARAMETER Subscribe:" RTSP command.
Definition rtsp.h:331
int timeout
copy of RTSPMessageHeader->timeout, i.e.
Definition rtsp.h:258
HTTPAuthState auth_state
authentication state
Definition rtsp.h:284
int initial_timeout
Timeout to wait for incoming connections.
Definition rtsp.h:423
URLContext * rtsp_hd_out
Additional output handle, used when input and output are done separately, eg for HTTP tunneling.
Definition rtsp.h:358
int lower_transport_mask
A mask with all requested transport methods.
Definition rtsp.h:374
enum AVDiscard * real_setup
current stream setup.
Definition rtsp.h:326
enum RTSPLowerTransport lower_transport
the negotiated network layer transport protocol; e.g.
Definition rtsp.h:270
int64_t last_cmd_time
timestamp of the last RTSP command that we sent to the RTSP server.
Definition rtsp.h:263
int need_subscription
The following are used for Real stream selection.
Definition rtsp.h:318
char session_id[512]
copy of RTSPMessageHeader->session_id, i.e.
Definition rtsp.h:253
int pending_packet
Indicates if a packet is pending to be read (useful for interleaved reads)
Definition rtsp.h:309
enum RTSPServerType server_type
brand of server that we're talking to; e.g.
Definition rtsp.h:275
int rtsp_flags
Various option flags for the RTSP muxer/demuxer.
Definition rtsp.h:408
int64_t seek_timestamp
the seek value requested when calling av_seek_frame().
Definition rtsp.h:247
char control_uri[MAX_URL_SIZE]
some MS RTSP streams contain a URL in the SDP that we need to use for all subsequent RTSP requests,...
Definition rtsp.h:347
int buffer_size
Definition rtsp.h:441
URLContext * rtsp_hd
Definition rtsp.h:228
int rtp_port_min
Minimum and maximum local UDP ports.
Definition rtsp.h:418
uint64_t packets
The number of returned packets.
Definition rtsp.h:379
enum RTSPClientState state
indicator of whether we are currently receiving data from the server.
Definition rtsp.h:239
enum AVDiscard * real_setup_cache
stream setup during the last frame read.
Definition rtsp.h:322
int initial_pause
Do not begin to play the stream immediately.
Definition rtsp.h:395
int seq
RTSP command sequence number.
Definition rtsp.h:249
int nb_byes
Definition rtsp.h:366
struct RTSPStream ** rtsp_streams
streams in this session
Definition rtsp.h:233
int get_parameter_supported
Whether the server supports the GET_PARAMETER method.
Definition rtsp.h:390
enum RTSPStatusCode code
Definition rtspdec.c:45
const char * message
Definition rtspdec.c:46
Describe a single stream, as identified by a single m= line block in the SDP content.
Definition rtsp.h:477
int interleaved_min
interleave IDs; copies of RTSPTransportField->interleaved_min/max for the selected transport.
Definition rtsp.h:486
char control_url[MAX_URL_SIZE]
url for this stream (from SDP)
Definition rtsp.h:488
URLContext * rtp_handle
RTP stream handle (if UDP)
Definition rtsp.h:478
int interleaved_max
Definition rtsp.h:486
int stream_index
corresponding stream index, if any.
Definition rtsp.h:482
void * transport_priv
RTP/RDT parse context if input, RTP AVFormatContext if output.
Definition rtsp.h:479
int interleaved_max
Definition rtsp.h:95
int client_port_min
UDP client ports; these should be the local ports of the UDP RTP (and RTCP) sockets over which we rec...
Definition rtsp.h:103
int mode_record
transport set to record data
Definition rtsp.h:114
int client_port_max
Definition rtsp.h:103
enum RTSPLowerTransport lower_transport
network layer transport protocol; e.g.
Definition rtsp.h:123
int interleaved_min
interleave ids, if TCP transport; each TCP/RTSP data packet starts with a '$', stream length and stre...
Definition rtsp.h:95
#define av_free(p)
#define av_freep(p)
#define av_log(a,...)
static AVDictionary * opts
Definition movenc.c:51
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition time.c:57
int ff_url_join(char *str, int size, const char *proto, const char *authorization, const char *hostname, int port, const char *fmt,...)
Definition url.c:40
unbuffered private I/O API
static int ffurl_write(URLContext *h, const uint8_t *buf, int size)
Write size bytes from buf to the resource accessed by h.
Definition url.h:204
int len