FFmpeg
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/intreadwrite.h"
26 #include "libavutil/mathematics.h"
27 #include "libavutil/mem.h"
28 #include "libavutil/random_seed.h"
29 #include "libavutil/time.h"
30 #include "avformat.h"
31 #include "demux.h"
32 
33 #include "internal.h"
34 #include "network.h"
35 #include "os_support.h"
36 #include "rtpproto.h"
37 #include "rtsp.h"
38 #include "rdt.h"
39 #include "tls.h"
40 #include "url.h"
41 #include "version.h"
42 
43 static const struct RTSPStatusMessage {
45  const char *message;
46 } status_messages[] = {
47  { RTSP_STATUS_OK, "OK" },
48  { RTSP_STATUS_METHOD, "Method Not Allowed" },
49  { RTSP_STATUS_BANDWIDTH, "Not Enough Bandwidth" },
50  { RTSP_STATUS_SESSION, "Session Not Found" },
51  { RTSP_STATUS_STATE, "Method Not Valid in This State" },
52  { RTSP_STATUS_AGGREGATE, "Aggregate operation not allowed" },
53  { RTSP_STATUS_ONLY_AGGREGATE, "Only aggregate operation allowed" },
54  { RTSP_STATUS_TRANSPORT, "Unsupported transport" },
55  { RTSP_STATUS_INTERNAL, "Internal Server Error" },
56  { RTSP_STATUS_SERVICE, "Service Unavailable" },
57  { RTSP_STATUS_VERSION, "RTSP Version not supported" },
58  { 0, "NULL" }
59 };
60 
62 {
63  RTSPState *rt = s->priv_data;
64 
65  if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN))
66  ff_rtsp_send_cmd_async(s, "TEARDOWN", rt->control_uri, NULL);
67 
71  rt->real_setup = NULL;
73  return 0;
74 }
75 
76 static inline int read_line(AVFormatContext *s, char *rbuf, const int rbufsize,
77  int *rbuflen)
78 {
79  RTSPState *rt = s->priv_data;
80  int idx = 0;
81  int ret = 0;
82  *rbuflen = 0;
83 
84  do {
85  ret = ffurl_read_complete(rt->rtsp_hd, rbuf + idx, 1);
86  if (ret <= 0)
87  return ret ? ret : AVERROR_EOF;
88  if (rbuf[idx] == '\r') {
89  /* Ignore */
90  } else if (rbuf[idx] == '\n') {
91  rbuf[idx] = '\0';
92  *rbuflen = idx;
93  return 0;
94  } else
95  idx++;
96  } while (idx < rbufsize);
97  av_log(s, AV_LOG_ERROR, "Message too long\n");
98  return AVERROR(EIO);
99 }
100 
102  const char *extracontent, uint16_t seq)
103 {
104  RTSPState *rt = s->priv_data;
105  char message[MAX_URL_SIZE];
106  int index = 0;
107  while (status_messages[index].code) {
108  if (status_messages[index].code == code) {
109  snprintf(message, sizeof(message), "RTSP/1.0 %d %s\r\n",
111  break;
112  }
113  index++;
114  }
115  if (!status_messages[index].code)
116  return AVERROR(EINVAL);
117  av_strlcatf(message, sizeof(message), "CSeq: %d\r\n", seq);
118  av_strlcatf(message, sizeof(message), "Server: %s\r\n", LIBAVFORMAT_IDENT);
119  if (extracontent)
120  av_strlcat(message, extracontent, sizeof(message));
121  av_strlcat(message, "\r\n", sizeof(message));
122  av_log(s, AV_LOG_TRACE, "Sending response:\n%s", message);
123  ffurl_write(rt->rtsp_hd_out, message, strlen(message));
124 
125  return 0;
126 }
127 
128 static inline int check_sessionid(AVFormatContext *s,
129  RTSPMessageHeader *request)
130 {
131  RTSPState *rt = s->priv_data;
132  unsigned char *session_id = rt->session_id;
133  if (!session_id[0]) {
134  av_log(s, AV_LOG_WARNING, "There is no session-id at the moment\n");
135  return 0;
136  }
137  if (strcmp(session_id, request->session_id)) {
138  av_log(s, AV_LOG_ERROR, "Unexpected session-id %s\n",
139  request->session_id);
142  }
143  return 0;
144 }
145 
147  RTSPMessageHeader *request,
148  const char *method)
149 {
150  RTSPState *rt = s->priv_data;
151  char rbuf[MAX_URL_SIZE];
152  int rbuflen, ret;
153  do {
154  ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
155  if (ret)
156  return ret;
157  if (rbuflen > 1) {
158  av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
159  ff_rtsp_parse_line(s, request, rbuf, rt, method);
160  }
161  } while (rbuflen > 0);
162  if (request->seq != rt->seq + 1) {
163  av_log(s, AV_LOG_ERROR, "Unexpected Sequence number %d\n",
164  request->seq);
165  return AVERROR(EINVAL);
166  }
167  if (rt->session_id[0] && strcmp(method, "OPTIONS")) {
168  ret = check_sessionid(s, request);
169  if (ret)
170  return ret;
171  }
172 
173  return 0;
174 }
175 
177 {
178  RTSPState *rt = s->priv_data;
179  RTSPMessageHeader request = { 0 };
180  char *sdp;
181  int ret;
182 
183  ret = rtsp_read_request(s, &request, "ANNOUNCE");
184  if (ret)
185  return ret;
186  rt->seq++;
187  if (strcmp(request.content_type, "application/sdp")) {
188  av_log(s, AV_LOG_ERROR, "Unexpected content type %s\n",
189  request.content_type);
192  }
193  if (request.content_length) {
194  sdp = av_malloc(request.content_length + 1);
195  if (!sdp)
196  return AVERROR(ENOMEM);
197 
198  /* Read SDP */
199  if (ffurl_read_complete(rt->rtsp_hd, sdp, request.content_length)
200  < request.content_length) {
202  "Unable to get complete SDP Description in ANNOUNCE\n");
204  av_free(sdp);
205  return AVERROR(EIO);
206  }
207  sdp[request.content_length] = '\0';
208  av_log(s, AV_LOG_VERBOSE, "SDP: %s\n", sdp);
209  ret = ff_sdp_parse(s, sdp);
210  av_free(sdp);
211  if (ret)
212  return ret;
214  return 0;
215  }
217  "Content-Length header value exceeds sdp allocated buffer (4KB)\n");
219  "Content-Length exceeds buffer size", request.seq);
220  return AVERROR(EIO);
221 }
222 
224 {
225  RTSPState *rt = s->priv_data;
226  RTSPMessageHeader request = { 0 };
227  int ret = 0;
228 
229  /* Parsing headers */
230  ret = rtsp_read_request(s, &request, "OPTIONS");
231  if (ret)
232  return ret;
233  rt->seq++;
234  /* Send Reply */
236  "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, RECORD\r\n",
237  request.seq);
238  return 0;
239 }
240 
241 static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl)
242 {
243  RTSPState *rt = s->priv_data;
244  RTSPMessageHeader request = { 0 };
245  int ret = 0;
246  char url[MAX_URL_SIZE];
247  RTSPStream *rtsp_st;
248  char responseheaders[MAX_URL_SIZE];
249  int localport = -1;
250  int transportidx = 0;
251  int streamid = 0;
252 
253  ret = rtsp_read_request(s, &request, "SETUP");
254  if (ret)
255  return ret;
256  rt->seq++;
257  if (!request.nb_transports) {
258  av_log(s, AV_LOG_ERROR, "No transport defined in SETUP\n");
259  return AVERROR_INVALIDDATA;
260  }
261  for (transportidx = 0; transportidx < request.nb_transports;
262  transportidx++) {
263  if (!request.transports[transportidx].mode_record ||
264  (request.transports[transportidx].lower_transport !=
266  request.transports[transportidx].lower_transport !=
268  av_log(s, AV_LOG_ERROR, "mode=record/receive not set or transport"
269  " protocol not supported (yet)\n");
270  return AVERROR_INVALIDDATA;
271  }
272  }
273  if (request.nb_transports > 1)
274  av_log(s, AV_LOG_WARNING, "More than one transport not supported, "
275  "using first of all\n");
276  for (streamid = 0; streamid < rt->nb_rtsp_streams; streamid++) {
277  if (!strcmp(rt->rtsp_streams[streamid]->control_url,
278  controlurl))
279  break;
280  }
281  if (streamid == rt->nb_rtsp_streams) {
282  av_log(s, AV_LOG_ERROR, "Unable to find requested track\n");
284  }
285  rtsp_st = rt->rtsp_streams[streamid];
286  localport = rt->rtp_port_min;
287 
288  /* check if the stream has already been setup */
289  if (rtsp_st->transport_priv) {
290  if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
292  else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP)
294  rtsp_st->transport_priv = NULL;
295  }
296  if (rtsp_st->rtp_handle)
297  ffurl_closep(&rtsp_st->rtp_handle);
298 
301  if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
303  return ret;
304  }
305  rtsp_st->interleaved_min = request.transports[0].interleaved_min;
306  rtsp_st->interleaved_max = request.transports[0].interleaved_max;
307  snprintf(responseheaders, sizeof(responseheaders), "Transport: "
308  "RTP/AVP/TCP;unicast;mode=record;interleaved=%d-%d"
309  "\r\n", request.transports[0].interleaved_min,
310  request.transports[0].interleaved_max);
311  } else {
312  do {
314  av_dict_set_int(&opts, "buffer_size", rt->buffer_size, 0);
315  ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
316  av_log(s, AV_LOG_TRACE, "Opening: %s\n", url);
318  &s->interrupt_callback, &opts,
319  s->protocol_whitelist, s->protocol_blacklist, NULL);
320  av_dict_free(&opts);
321  if (ret)
322  localport += 2;
323  } while (ret || localport > rt->rtp_port_max);
324  if (localport > rt->rtp_port_max) {
326  return ret;
327  }
328 
329  av_log(s, AV_LOG_TRACE, "Listening on: %d\n",
331  if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
333  return ret;
334  }
335 
336  localport = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
337  snprintf(responseheaders, sizeof(responseheaders), "Transport: "
338  "RTP/AVP/UDP;unicast;mode=record;source=%s;"
339  "client_port=%d-%d;server_port=%d-%d\r\n",
340  host, request.transports[0].client_port_min,
341  request.transports[0].client_port_max, localport,
342  localport + 1);
343  }
344 
345  /* Establish sessionid if not previously set */
346  /* Put this in a function? */
347  /* RFC 2326: session id must be at least 8 digits */
348  while (strlen(rt->session_id) < 8)
349  av_strlcatf(rt->session_id, 512, "%u", av_get_random_seed());
350 
351  av_strlcatf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
352  rt->session_id);
353  /* Send Reply */
354  rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
355 
356  rt->state = RTSP_STATE_PAUSED;
357  return 0;
358 }
359 
361 {
362  RTSPState *rt = s->priv_data;
363  RTSPMessageHeader request = { 0 };
364  int ret = 0;
365  char responseheaders[MAX_URL_SIZE];
366 
367  ret = rtsp_read_request(s, &request, "RECORD");
368  if (ret)
369  return ret;
370  ret = check_sessionid(s, &request);
371  if (ret)
372  return ret;
373  rt->seq++;
374  snprintf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
375  rt->session_id);
376  rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
377 
379  return 0;
380 }
381 
382 static inline int parse_command_line(AVFormatContext *s, const char *line,
383  int linelen, char *uri, int urisize,
384  char *method, int methodsize,
385  enum RTSPMethod *methodcode)
386 {
387  RTSPState *rt = s->priv_data;
388  const char *linept, *searchlinept;
389  linept = strchr(line, ' ');
390 
391  if (!linept) {
392  av_log(s, AV_LOG_ERROR, "Error parsing method string\n");
393  return AVERROR_INVALIDDATA;
394  }
395 
396  if (linept - line > methodsize - 1) {
397  av_log(s, AV_LOG_ERROR, "Method string too long\n");
398  return AVERROR(EIO);
399  }
400  memcpy(method, line, linept - line);
401  method[linept - line] = '\0';
402  linept++;
403  if (!strcmp(method, "ANNOUNCE"))
404  *methodcode = ANNOUNCE;
405  else if (!strcmp(method, "OPTIONS"))
406  *methodcode = OPTIONS;
407  else if (!strcmp(method, "RECORD"))
408  *methodcode = RECORD;
409  else if (!strcmp(method, "SETUP"))
410  *methodcode = SETUP;
411  else if (!strcmp(method, "PAUSE"))
412  *methodcode = PAUSE;
413  else if (!strcmp(method, "TEARDOWN"))
414  *methodcode = TEARDOWN;
415  else
416  *methodcode = UNKNOWN;
417  /* Check method with the state */
418  if (rt->state == RTSP_STATE_IDLE) {
419  if ((*methodcode != ANNOUNCE) && (*methodcode != OPTIONS)) {
420  av_log(s, AV_LOG_ERROR, "Unexpected command in Idle State %s\n",
421  line);
423  }
424  } else if (rt->state == RTSP_STATE_PAUSED) {
425  if ((*methodcode != OPTIONS) && (*methodcode != RECORD)
426  && (*methodcode != SETUP)) {
427  av_log(s, AV_LOG_ERROR, "Unexpected command in Paused State %s\n",
428  line);
430  }
431  } else if (rt->state == RTSP_STATE_STREAMING) {
432  if ((*methodcode != PAUSE) && (*methodcode != OPTIONS)
433  && (*methodcode != TEARDOWN)) {
434  av_log(s, AV_LOG_ERROR, "Unexpected command in Streaming State"
435  " %s\n", line);
437  }
438  } else {
439  av_log(s, AV_LOG_ERROR, "Unexpected State [%d]\n", rt->state);
440  return AVERROR_BUG;
441  }
442 
443  searchlinept = strchr(linept, ' ');
444  if (!searchlinept) {
445  av_log(s, AV_LOG_ERROR, "Error parsing message URI\n");
446  return AVERROR_INVALIDDATA;
447  }
448  if (searchlinept - linept > urisize - 1) {
449  av_log(s, AV_LOG_ERROR, "uri string length exceeded buffer size\n");
450  return AVERROR(EIO);
451  }
452  memcpy(uri, linept, searchlinept - linept);
453  uri[searchlinept - linept] = '\0';
454  if (strcmp(rt->control_uri, uri)) {
455  char host[128], path[512], auth[128];
456  int port;
457  char ctl_host[128], ctl_path[512], ctl_auth[128];
458  int ctl_port;
459  av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
460  path, sizeof(path), uri);
461  av_url_split(NULL, 0, ctl_auth, sizeof(ctl_auth), ctl_host,
462  sizeof(ctl_host), &ctl_port, ctl_path, sizeof(ctl_path),
463  rt->control_uri);
464  if (strcmp(host, ctl_host))
465  av_log(s, AV_LOG_INFO, "Host %s differs from expected %s\n",
466  host, ctl_host);
467  if (strcmp(path, ctl_path) && *methodcode != SETUP)
468  av_log(s, AV_LOG_WARNING, "WARNING: Path %s differs from expected"
469  " %s\n", path, ctl_path);
470  if (*methodcode == ANNOUNCE) {
472  "Updating control URI to %s\n", uri);
473  av_strlcpy(rt->control_uri, uri, sizeof(rt->control_uri));
474  }
475  }
476 
477  linept = searchlinept + 1;
478  if (!av_strstart(linept, "RTSP/1.0", NULL)) {
479  av_log(s, AV_LOG_ERROR, "Error parsing protocol or version\n");
481  }
482  return 0;
483 }
484 
486 {
487  RTSPState *rt = s->priv_data;
488  unsigned char rbuf[MAX_URL_SIZE];
489  unsigned char method[10];
490  char uri[500];
491  int ret;
492  int rbuflen = 0;
493  RTSPMessageHeader request = { 0 };
494  enum RTSPMethod methodcode;
495 
496  ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
497  if (ret < 0)
498  return ret;
499  av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
500  ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
501  sizeof(method), &methodcode);
502  if (ret) {
503  av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
504  return ret;
505  }
506 
507  ret = rtsp_read_request(s, &request, method);
508  if (ret)
509  return ret;
510  rt->seq++;
511  if (methodcode == PAUSE) {
512  rt->state = RTSP_STATE_PAUSED;
513  ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
514  // TODO: Missing date header in response
515  } else if (methodcode == OPTIONS) {
517  "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, "
518  "RECORD\r\n", request.seq);
519  } else if (methodcode == TEARDOWN) {
520  rt->state = RTSP_STATE_IDLE;
521  ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
522  }
523  return ret;
524 }
525 
527 {
528  RTSPState *rt = s->priv_data;
529  RTSPMessageHeader reply1, *reply = &reply1;
530  int i;
531  char cmd[MAX_URL_SIZE];
532 
533  av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
534  rt->nb_byes = 0;
535 
537  for (i = 0; i < rt->nb_rtsp_streams; i++) {
538  RTSPStream *rtsp_st = rt->rtsp_streams[i];
539  /* Try to initialize the connection state in a
540  * potential NAT router by sending dummy packets.
541  * RTP/RTCP dummy packets are used for RDT, too.
542  */
543  if (rtsp_st->rtp_handle &&
544  !(rt->server_type == RTSP_SERVER_WMS && i > 1))
546  }
547  }
548  if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
549  if (rt->transport == RTSP_TRANSPORT_RTP) {
550  for (i = 0; i < rt->nb_rtsp_streams; i++) {
551  RTSPStream *rtsp_st = rt->rtsp_streams[i];
552  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
553  if (!rtpctx)
554  continue;
558  rtpctx->base_timestamp = 0;
559  rtpctx->timestamp = 0;
560  rtpctx->unwrapped_timestamp = 0;
561  rtpctx->rtcp_ts_offset = 0;
562  }
563  }
564  if (rt->state == RTSP_STATE_PAUSED) {
565  cmd[0] = 0;
566  } else {
567  snprintf(cmd, sizeof(cmd),
568  "Range: npt=%"PRId64".%03"PRId64"-\r\n",
570  rt->seek_timestamp / (AV_TIME_BASE / 1000) % 1000);
571  }
572  ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
573  if (reply->status_code != RTSP_STATUS_OK) {
574  return ff_rtsp_averror(reply->status_code, -1);
575  }
576  if (rt->transport == RTSP_TRANSPORT_RTP &&
577  reply->range_start != AV_NOPTS_VALUE) {
578  for (i = 0; i < rt->nb_rtsp_streams; i++) {
579  RTSPStream *rtsp_st = rt->rtsp_streams[i];
580  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
581  AVStream *st = NULL;
582  if (!rtpctx || rtsp_st->stream_index < 0)
583  continue;
584 
585  st = s->streams[rtsp_st->stream_index];
586  rtpctx->range_start_offset =
588  st->time_base);
589  }
590  }
591  }
593  return 0;
594 }
595 
596 /* pause the stream */
598 {
599  RTSPState *rt = s->priv_data;
600  RTSPMessageHeader reply1, *reply = &reply1;
601 
602  if (rt->state != RTSP_STATE_STREAMING)
603  return 0;
604  else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
605  ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
606  if (reply->status_code != RTSP_STATUS_OK) {
607  return ff_rtsp_averror(reply->status_code, -1);
608  }
609  }
610  rt->state = RTSP_STATE_PAUSED;
611  return 0;
612 }
613 
615 {
616  RTSPState *rt = s->priv_data;
617  char cmd[MAX_URL_SIZE];
618  unsigned char *content = NULL;
619  int ret;
620 
621  /* describe the stream */
622  snprintf(cmd, sizeof(cmd),
623  "Accept: application/sdp\r\n");
624  if (rt->server_type == RTSP_SERVER_REAL) {
625  /**
626  * The Require: attribute is needed for proper streaming from
627  * Realmedia servers.
628  */
629  av_strlcat(cmd,
630  "Require: com.real.retain-entity-for-setup\r\n",
631  sizeof(cmd));
632  }
633  ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
634  if (reply->status_code != RTSP_STATUS_OK) {
635  av_freep(&content);
637  }
638  if (!content)
639  return AVERROR_INVALIDDATA;
640 
641  av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
642  /* now we got the SDP description, we parse it */
643  ret = ff_sdp_parse(s, (const char *)content);
644  av_freep(&content);
645  if (ret < 0)
646  return ret;
647 
648  return 0;
649 }
650 
652 {
653  RTSPState *rt = s->priv_data;
654  char proto[128], host[128], path[512], auth[128];
655  char uri[500];
656  int port;
657  int default_port = RTSP_DEFAULT_PORT;
658  char tcpname[500];
659  const char *lower_proto = "tcp";
660  unsigned char rbuf[MAX_URL_SIZE];
661  unsigned char method[10];
662  int rbuflen = 0;
663  int ret;
664  enum RTSPMethod methodcode;
665 
666  if (!ff_network_init())
667  return AVERROR(EIO);
668 
669  /* extract hostname and port */
670  av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
671  &port, path, sizeof(path), s->url);
672 
673  /* ff_url_join. No authorization by now (NULL) */
674  ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL, host,
675  port, "%s", path);
676 
677  if (!strcmp(proto, "rtsps")) {
678  lower_proto = "tls";
679  default_port = RTSPS_DEFAULT_PORT;
680  }
681 
682  if (port < 0)
683  port = default_port;
684 
685  /* Create TCP connection */
686  ff_url_join(tcpname, sizeof(tcpname), lower_proto, NULL, host, port,
687  "?listen&listen_timeout=%d", rt->initial_timeout * 1000);
688 
690  &s->interrupt_callback, NULL,
691  s->protocol_whitelist, s->protocol_blacklist, NULL)) {
692  av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n");
693  goto fail;
694  }
695  rt->state = RTSP_STATE_IDLE;
696  rt->rtsp_hd_out = rt->rtsp_hd;
697  for (;;) { /* Wait for incoming RTSP messages */
698  ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
699  if (ret < 0)
700  goto fail;
701  av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
702  ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
703  sizeof(method), &methodcode);
704  if (ret) {
705  av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
706  goto fail;
707  }
708 
709  if (methodcode == ANNOUNCE) {
711  rt->state = RTSP_STATE_PAUSED;
712  } else if (methodcode == OPTIONS) {
714  } else if (methodcode == RECORD) {
716  if (!ret)
717  return 0; // We are ready for streaming
718  } else if (methodcode == SETUP)
719  ret = rtsp_read_setup(s, host, uri);
720  if (ret) {
722  goto fail;
723  }
724  }
725 fail:
729  return ret;
730 }
731 
732 static int rtsp_probe(const AVProbeData *p)
733 {
734  if (
735 #if CONFIG_TLS_PROTOCOL
736  av_strstart(p->filename, "rtsps:", NULL) ||
737 #endif
738  av_strstart(p->filename, "satip:", NULL) ||
739  av_strstart(p->filename, "rtsp:", NULL))
740  return AVPROBE_SCORE_MAX;
741  return 0;
742 }
743 
745 {
746  RTSPState *rt = s->priv_data;
747  int ret;
748 
749  if (rt->initial_timeout > 0)
751 
752  if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
753  ret = rtsp_listen(s);
754  if (ret)
755  return ret;
756  } else {
757  ret = ff_rtsp_connect(s);
758  if (ret)
759  return ret;
760 
761  rt->real_setup_cache = !s->nb_streams ? NULL :
762  av_calloc(s->nb_streams, 2 * sizeof(*rt->real_setup_cache));
763  if (!rt->real_setup_cache && s->nb_streams) {
764  ret = AVERROR(ENOMEM);
765  goto fail;
766  }
767  rt->real_setup = rt->real_setup_cache + s->nb_streams;
768 
769  if (rt->initial_pause) {
770  /* do not start immediately */
771  } else {
772  ret = rtsp_read_play(s);
773  if (ret < 0)
774  goto fail;
775  }
776  }
777 
778  return 0;
779 
780 fail:
782  return ret;
783 }
784 
786  uint8_t *buf, int buf_size)
787 {
788  RTSPState *rt = s->priv_data;
789  int id, len, i, ret;
790  RTSPStream *rtsp_st;
791 
792  av_log(s, AV_LOG_TRACE, "tcp_read_packet:\n");
793 redo:
794  for (;;) {
795  RTSPMessageHeader reply;
796 
797  ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL);
798  if (ret < 0)
799  return ret;
800  if (ret == 1) /* received '$' */
801  break;
802  /* XXX: parse message */
803  if (rt->state != RTSP_STATE_STREAMING)
804  return 0;
805  }
806  ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
807  if (ret != 3)
808  return AVERROR(EIO);
809  id = buf[0];
810  len = AV_RB16(buf + 1);
811  av_log(s, AV_LOG_TRACE, "id=%d len=%d\n", id, len);
812  if (len > buf_size || len < 8)
813  goto redo;
814  /* get the data */
815  ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
816  if (ret != len)
817  return AVERROR(EIO);
818  if (rt->transport == RTSP_TRANSPORT_RDT &&
819  (ret = ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL)) < 0)
820  return ret;
821 
822  /* find the matching stream */
823  for (i = 0; i < rt->nb_rtsp_streams; i++) {
824  rtsp_st = rt->rtsp_streams[i];
825  if (id >= rtsp_st->interleaved_min &&
826  id <= rtsp_st->interleaved_max)
827  goto found;
828  }
829  goto redo;
830 found:
831  *prtsp_st = rtsp_st;
832  return len;
833 }
834 
836 {
837  RTSPState *rt = s->priv_data;
838  char host[1024];
839  int port;
840 
841  av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
842  s->url);
843  ff_rtsp_undo_setup(s, 0);
845  rt->real_challenge);
846 }
847 
849 {
850  RTSPState *rt = s->priv_data;
851  int ret;
852  RTSPMessageHeader reply1, *reply = &reply1;
853  char cmd[MAX_URL_SIZE];
854 
855 retry:
856  if (rt->server_type == RTSP_SERVER_REAL) {
857  int i;
858 
859  for (i = 0; i < s->nb_streams; i++)
860  rt->real_setup[i] = s->streams[i]->discard;
861 
862  if (!rt->need_subscription) {
863  if (memcmp (rt->real_setup, rt->real_setup_cache,
864  sizeof(enum AVDiscard) * s->nb_streams)) {
865  snprintf(cmd, sizeof(cmd),
866  "Unsubscribe: %s\r\n",
867  rt->last_subscription);
868  ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
869  cmd, reply, NULL);
870  if (reply->status_code != RTSP_STATUS_OK)
872  rt->need_subscription = 1;
873  }
874  }
875 
876  if (rt->need_subscription) {
877  int r, rule_nr, first = 1;
878 
879  memcpy(rt->real_setup_cache, rt->real_setup,
880  sizeof(enum AVDiscard) * s->nb_streams);
881  rt->last_subscription[0] = 0;
882 
883  snprintf(cmd, sizeof(cmd),
884  "Subscribe: ");
885  for (i = 0; i < rt->nb_rtsp_streams; i++) {
886  rule_nr = 0;
887  for (r = 0; r < s->nb_streams; r++) {
888  if (s->streams[r]->id == i) {
889  if (s->streams[r]->discard != AVDISCARD_ALL) {
890  if (!first)
891  av_strlcat(rt->last_subscription, ",",
892  sizeof(rt->last_subscription));
894  rt->last_subscription,
895  sizeof(rt->last_subscription), i, rule_nr);
896  first = 0;
897  }
898  rule_nr++;
899  }
900  }
901  }
902  av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
903  ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
904  cmd, reply, NULL);
905  if (reply->status_code != RTSP_STATUS_OK)
907  rt->need_subscription = 0;
908 
909  if (rt->state == RTSP_STATE_STREAMING)
910  rtsp_read_play (s);
911  }
912  }
913 
915  if (ret < 0) {
916  if (ret == AVERROR(ETIMEDOUT) && !rt->packets) {
919  RTSPMessageHeader reply1, *reply = &reply1;
920  av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
921  if (rtsp_read_pause(s) != 0)
922  return -1;
923  // TEARDOWN is required on Real-RTSP, but might make
924  // other servers close the connection.
925  if (rt->server_type == RTSP_SERVER_REAL)
926  ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
927  reply, NULL);
928  rt->session_id[0] = '\0';
929  if (resetup_tcp(s) == 0) {
930  rt->state = RTSP_STATE_IDLE;
931  rt->need_subscription = 1;
932  if (rtsp_read_play(s) != 0)
933  return -1;
934  goto retry;
935  }
936  }
937  }
938  return ret;
939  }
940  rt->packets++;
941 
942  if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
943  /* send dummy request to keep TCP connection alive */
944  if ((av_gettime_relative() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
945  rt->auth_state.stale) {
946  if (rt->server_type == RTSP_SERVER_WMS ||
947  (rt->server_type != RTSP_SERVER_REAL &&
949  ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
950  } else {
951  ff_rtsp_send_cmd_async(s, "OPTIONS", rt->control_uri, NULL);
952  }
953  /* The stale flag should be reset when creating the auth response in
954  * ff_rtsp_send_cmd_async, but reset it here just in case we never
955  * called the auth code (if we didn't have any credentials set). */
956  rt->auth_state.stale = 0;
957  }
958  }
959 
960  return 0;
961 }
962 
963 static int rtsp_read_seek(AVFormatContext *s, int stream_index,
964  int64_t timestamp, int flags)
965 {
966  RTSPState *rt = s->priv_data;
967  int ret;
968 
969  rt->seek_timestamp = av_rescale_q(timestamp,
970  s->streams[stream_index]->time_base,
972  switch(rt->state) {
973  default:
974  case RTSP_STATE_IDLE:
975  break;
977  if ((ret = rtsp_read_pause(s)) != 0)
978  return ret;
980  if ((ret = rtsp_read_play(s)) != 0)
981  return ret;
982  break;
983  case RTSP_STATE_PAUSED:
984  rt->state = RTSP_STATE_IDLE;
985  break;
986  }
987  return 0;
988 }
989 
990 static const AVClass rtsp_demuxer_class = {
991  .class_name = "RTSP demuxer",
992  .item_name = av_default_item_name,
993  .option = ff_rtsp_options,
994  .version = LIBAVUTIL_VERSION_INT,
995 };
996 
998  .p.name = "rtsp",
999  .p.long_name = NULL_IF_CONFIG_SMALL("RTSP input"),
1000  .p.flags = AVFMT_NOFILE,
1001  .p.priv_class = &rtsp_demuxer_class,
1002  .priv_data_size = sizeof(RTSPState),
1008  .read_play = rtsp_read_play,
1009  .read_pause = rtsp_read_pause,
1010 };
RTSPState::initial_timeout
int initial_timeout
Timeout to wait for incoming connections.
Definition: rtsp.h:401
RTSP_STATE_PAUSED
@ RTSP_STATE_PAUSED
initialized, but not receiving data
Definition: rtsp.h:205
ff_rdt_subscribe_rule
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:386
RTSPState::initial_pause
int initial_pause
Do not begin to play the stream immediately.
Definition: rtsp.h:373
ff_rtsp_read_reply
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...
RTSPState::last_cmd_time
int64_t last_cmd_time
timestamp of the last RTSP command that we sent to the RTSP server.
Definition: rtsp.h:263
av_gettime_relative
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
ff_rtsp_close_streams
void ff_rtsp_close_streams(AVFormatContext *s)
Close and free all streams within the RTSP (de)muxer.
Definition: rtsp.c:792
LIBAVFORMAT_IDENT
#define LIBAVFORMAT_IDENT
Definition: version.h:45
rtsp_read_request
static int rtsp_read_request(AVFormatContext *s, RTSPMessageHeader *request, const char *method)
Definition: rtspdec.c:146
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
RTSPStream::transport_priv
void * transport_priv
RTP/RDT parse context if input, RTP AVFormatContext if output.
Definition: rtsp.h:446
RTSPStream::rtp_handle
URLContext * rtp_handle
RTP stream handle (if UDP)
Definition: rtsp.h:445
message
Definition: api-threadmessage-test.c:47
RTSP_STATE_SEEKING
@ RTSP_STATE_SEEKING
initialized, requesting a seek
Definition: rtsp.h:206
RTSPMessageHeader::status_code
enum RTSPStatusCode status_code
response code from server
Definition: rtsp.h:133
ff_rtsp_send_cmd
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.
resetup_tcp
static int resetup_tcp(AVFormatContext *s)
Definition: rtspdec.c:835
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
AVIO_FLAG_READ_WRITE
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:619
rtsp_read_options
static int rtsp_read_options(AVFormatContext *s)
Definition: rtspdec.c:223
RTSP_TRANSPORT_RTP
@ RTSP_TRANSPORT_RTP
Standards-compliant RTP.
Definition: rtsp.h:60
RTSP_STATUS_METHOD
@ RTSP_STATUS_METHOD
Definition: rtspcodes.h:47
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
ffurl_write
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:202
RTSPState::get_parameter_supported
int get_parameter_supported
Whether the server supports the GET_PARAMETER method.
Definition: rtsp.h:368
ff_rtsp_averror
static int ff_rtsp_averror(enum RTSPStatusCode status_code, int default_averror)
Definition: rtspcodes.h:144
RTSPStream::interleaved_min
int interleaved_min
interleave IDs; copies of RTSPTransportField->interleaved_min/max for the selected transport.
Definition: rtsp.h:453
rtsp_read_setup
static int rtsp_read_setup(AVFormatContext *s, char *host, char *controlurl)
Definition: rtspdec.c:241
OPTIONS
@ OPTIONS
Definition: rtspcodes.h:132
rtsp_read_close
static int rtsp_read_close(AVFormatContext *s)
Definition: rtspdec.c:61
rtsp_send_reply
static int rtsp_send_reply(AVFormatContext *s, enum RTSPStatusCode code, const char *extracontent, uint16_t seq)
Definition: rtspdec.c:101
RTPDemuxContext::range_start_offset
int64_t range_start_offset
Definition: rtpdec.h:157
RTSPTransportField::lower_transport
enum RTSPLowerTransport lower_transport
network layer transport protocol; e.g.
Definition: rtsp.h:123
RTSPState::rtp_port_min
int rtp_port_min
Minimum and maximum local UDP ports.
Definition: rtsp.h:396
RTSPTransportField::interleaved_min
int interleaved_min
interleave ids, if TCP transport; each TCP/RTSP data packet starts with a '$', stream length and stre...
Definition: rtsp.h:95
RTSPTransportField::interleaved_max
int interleaved_max
Definition: rtsp.h:95
RTSPStream
Describe a single stream, as identified by a single m= line block in the SDP content.
Definition: rtsp.h:444
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
UNKNOWN
@ UNKNOWN
Definition: ftp.c:39
ff_rtsp_send_cmd_async
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.
RTSPState::real_challenge
char real_challenge[64]
the "RealChallenge1:" field from the server
Definition: rtsp.h:278
mathematics.h
AVDictionary
Definition: dict.c:34
ff_network_close
void ff_network_close(void)
Definition: network.c:121
RTSPMessageHeader::nb_transports
int nb_transports
number of items in the 'transports' variable below
Definition: rtsp.h:136
RTSP_SERVER_REAL
@ RTSP_SERVER_REAL
Realmedia-style server.
Definition: rtsp.h:215
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
RTSPState::seek_timestamp
int64_t seek_timestamp
the seek value requested when calling av_seek_frame().
Definition: rtsp.h:247
ANNOUNCE
@ ANNOUNCE
Definition: rtspcodes.h:131
os_support.h
ff_network_init
int ff_network_init(void)
Definition: network.c:63
ff_sdp_parse
int ff_sdp_parse(AVFormatContext *s, const char *content)
Parse an SDP description of streams by populating an RTSPState struct within the AVFormatContext; als...
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
av_get_random_seed
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
Definition: random_seed.c:167
ff_rtp_send_punch_packets
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
TEARDOWN
@ TEARDOWN
Definition: rtspcodes.h:136
check_sessionid
static int check_sessionid(AVFormatContext *s, RTSPMessageHeader *request)
Definition: rtspdec.c:128
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
RTSP_STATUS_BANDWIDTH
@ RTSP_STATUS_BANDWIDTH
Definition: rtspcodes.h:59
fail
#define fail()
Definition: checkasm.h:185
ff_rtp_get_local_rtp_port
int ff_rtp_get_local_rtp_port(URLContext *h)
Return the local rtp port used by the RTP connection.
Definition: rtpproto.c:538
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
RTSPState::nb_rtsp_streams
int nb_rtsp_streams
number of items in the 'rtsp_streams' variable
Definition: rtsp.h:231
read_line
static int read_line(AVFormatContext *s, char *rbuf, const int rbufsize, int *rbuflen)
Definition: rtspdec.c:76
rtsp_read_header
static int rtsp_read_header(AVFormatContext *s)
Definition: rtspdec.c:744
rtsp_read_packet
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: rtspdec.c:848
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
AVERROR_OPTION_NOT_FOUND
#define AVERROR_OPTION_NOT_FOUND
Option not found.
Definition: error.h:63
ff_rtsp_setup_input_streams
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:614
RTSPStatusMessage::message
const char * message
Definition: rtspdec.c:45
RTSPMessageHeader::content_length
int content_length
length of the data following this header
Definition: rtsp.h:131
RTSP_TRANSPORT_RDT
@ RTSP_TRANSPORT_RDT
Realmedia Data Transport.
Definition: rtsp.h:61
ff_rtsp_tcp_read_packet
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:785
RTSP_STATE_STREAMING
@ RTSP_STATE_STREAMING
initialized and sending/receiving data
Definition: rtsp.h:204
rtsp.h
RTSPState::lower_transport_mask
int lower_transport_mask
A mask with all requested transport methods.
Definition: rtsp.h:352
RTSPMethod
RTSPMethod
Definition: rtspcodes.h:129
RTSPStream::stream_index
int stream_index
corresponding stream index, if any.
Definition: rtsp.h:449
ff_rdt_parse_close
void ff_rdt_parse_close(RDTDemuxContext *s)
Definition: rdt.c:80
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
ff_rdt_parse_header
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)
Parse RDT-style packet header.
RTSPState::rtsp_hd_out
URLContext * rtsp_hd_out
Additional output handle, used when input and output are done separately, eg for HTTP tunneling.
Definition: rtsp.h:336
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:206
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
RTSP_FLAG_LISTEN
#define RTSP_FLAG_LISTEN
Wait for incoming connections.
Definition: rtsp.h:427
ff_rtsp_parse_streaming_commands
int ff_rtsp_parse_streaming_commands(AVFormatContext *s)
Parse RTSP commands (OPTIONS, PAUSE and TEARDOWN) during streaming in listen mode.
Definition: rtspdec.c:485
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
ffurl_open_whitelist
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:362
RTSP_STATUS_STATE
@ RTSP_STATUS_STATE
Definition: rtspcodes.h:61
RTSP_STATUS_TRANSPORT
@ RTSP_STATUS_TRANSPORT
Definition: rtspcodes.h:67
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
RTSPState::nb_byes
int nb_byes
Definition: rtsp.h:344
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:553
RTSPState::control_uri
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:325
AVProbeData::filename
const char * filename
Definition: avformat.h:452
RTSPMessageHeader::transports
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
ff_url_join
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
RTSP_STATUS_VERSION
@ RTSP_STATUS_VERSION
Definition: rtspcodes.h:74
ff_rtsp_undo_setup
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:760
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
RTSPState::buffer_size
int buffer_size
Definition: rtsp.h:419
ff_rtsp_open_transport_ctx
int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
Open RTSP transport context.
Definition: rtsp.c:828
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_rtsp_fetch_packet
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...
RTSP_STATUS_INTERNAL
@ RTSP_STATUS_INTERNAL
Definition: rtspcodes.h:69
RTSPMessageHeader::seq
int seq
sequence number
Definition: rtsp.h:146
parse_command_line
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:382
if
if(ret)
Definition: filter_design.txt:179
AVDISCARD_ALL
@ AVDISCARD_ALL
discard all
Definition: defs.h:220
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
internal.h
opts
AVDictionary * opts
Definition: movenc.c:51
RTSPState::session_id
char session_id[512]
copy of RTSPMessageHeader->session_id, i.e.
Definition: rtsp.h:253
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:550
RTSP_STATUS_OK
@ RTSP_STATUS_OK
Definition: rtspcodes.h:33
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
AVStream::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avformat.h:782
NULL
#define NULL
Definition: coverity.c:32
RTSPState::rtsp_hd
URLContext * rtsp_hd
Definition: rtsp.h:228
RECORD
@ RECORD
Definition: rtspcodes.h:140
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
rtsp_probe
static int rtsp_probe(const AVProbeData *p)
Definition: rtspdec.c:732
RTSPState::real_setup
enum AVDiscard * real_setup
current stream setup.
Definition: rtsp.h:304
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
RTSP_STATUS_SESSION
@ RTSP_STATUS_SESSION
Definition: rtspcodes.h:60
rtsp_read_play
static int rtsp_read_play(AVFormatContext *s)
Definition: rtspdec.c:526
RTPDemuxContext::rtcp_ts_offset
int64_t rtcp_ts_offset
Definition: rtpdec.h:180
time.h
RTSPState::state
enum RTSPClientState state
indicator of whether we are currently receiving data from the server.
Definition: rtsp.h:239
RTPDemuxContext::last_rtcp_ntp_time
uint64_t last_rtcp_ntp_time
Definition: rtpdec.h:176
rtsp_read_record
static int rtsp_read_record(AVFormatContext *s)
Definition: rtspdec.c:360
index
int index
Definition: gxfenc.c:90
ff_rtp_parse_close
void ff_rtp_parse_close(RTPDemuxContext *s)
Definition: rtpdec.c:958
rtsp_listen
static int rtsp_listen(AVFormatContext *s)
Definition: rtspdec.c:651
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
RTSPState::rtsp_flags
int rtsp_flags
Various option flags for the RTSP muxer/demuxer.
Definition: rtsp.h:386
ff_rtsp_options
const AVOption ff_rtsp_options[]
Definition: rtsp.c:86
ff_rtsp_close_connections
void ff_rtsp_close_connections(AVFormatContext *s)
Close all connection handles within the RTSP (de)muxer.
RTSPState
Private data for the RTSP demuxer.
Definition: rtsp.h:226
RTSPState::lower_transport
enum RTSPLowerTransport lower_transport
the negotiated network layer transport protocol; e.g.
Definition: rtsp.h:270
RTSPMessageHeader::range_start
int64_t range_start
Time range of the streams that the server will stream.
Definition: rtsp.h:140
RTPDemuxContext::first_rtcp_ntp_time
uint64_t first_rtcp_ntp_time
Definition: rtpdec.h:178
RTSPState::rtsp_streams
struct RTSPStream ** rtsp_streams
streams in this session
Definition: rtsp.h:233
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
RTSPState::seq
int seq
RTSP command sequence number.
Definition: rtsp.h:249
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:468
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:41
RTSPState::auth_state
HTTPAuthState auth_state
authentication state
Definition: rtsp.h:284
RTPDemuxContext::unwrapped_timestamp
int64_t unwrapped_timestamp
Definition: rtpdec.h:156
line
Definition: graph2dot.c:48
ff_rtsp_parse_line
void ff_rtsp_parse_line(AVFormatContext *s, RTSPMessageHeader *reply, const char *buf, RTSPState *rt, const char *method)
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:223
av_strstart
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
RTSPState::last_subscription
char last_subscription[1024]
the last value of the "SET_PARAMETER Subscribe:" RTSP command.
Definition: rtsp.h:309
RTSPState::timeout
int timeout
copy of RTSPMessageHeader->timeout, i.e.
Definition: rtsp.h:258
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
RTSPTransportField::client_port_max
int client_port_max
Definition: rtsp.h:103
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
code
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
Definition: filter_design.txt:178
AV_TIME_BASE
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
RTSPState::need_subscription
int need_subscription
The following are used for Real stream selection.
Definition: rtsp.h:296
rtsp_read_seek
static int rtsp_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: rtspdec.c:963
rtpproto.h
av_url_split
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:346
url.h
RTSP_LOWER_TRANSPORT_TCP
@ RTSP_LOWER_TRANSPORT_TCP
TCP; interleaved in RTSP.
Definition: rtsp.h:41
demux.h
status_messages
static const struct RTSPStatusMessage status_messages[]
len
int len
Definition: vorbis_enc_data.h:426
RTSP_STATUS_AGGREGATE
@ RTSP_STATUS_AGGREGATE
Definition: rtspcodes.h:65
RTPDemuxContext
Definition: rtpdec.h:148
RTPDemuxContext::timestamp
uint32_t timestamp
Definition: rtpdec.h:154
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
RTSPTransportField::client_port_min
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
rtsp_demuxer_class
static const AVClass rtsp_demuxer_class
Definition: rtspdec.c:990
version.h
RTSPState::rtp_port_max
int rtp_port_max
Definition: rtsp.h:396
rtsp_read_announce
static int rtsp_read_announce(AVFormatContext *s)
Definition: rtspdec.c:176
ffurl_closep
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition: avio.c:588
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
av_strlcat
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
avformat.h
RTSPStatusMessage
Definition: rtspdec.c:43
network.h
id
enum AVCodecID id
Definition: dts2pts.c:365
HTTPAuthState::stale
int stale
Auth ok, but needs to be resent with a new nonce.
Definition: httpauth.h:71
tls.h
RTSP_DEFAULT_PORT
#define RTSP_DEFAULT_PORT
Definition: rtsp.h:75
RTSPState::transport
enum RTSPTransport transport
the negotiated data/packet transport protocol; e.g.
Definition: rtsp.h:266
random_seed.h
MAX_URL_SIZE
#define MAX_URL_SIZE
Definition: internal.h:30
RTPDemuxContext::base_timestamp
uint32_t base_timestamp
Definition: rtpdec.h:155
RTSPStream::control_url
char control_url[MAX_URL_SIZE]
url for this stream (from SDP)
Definition: rtsp.h:455
AVERROR_STREAM_NOT_FOUND
#define AVERROR_STREAM_NOT_FOUND
Stream not found.
Definition: error.h:67
SETUP
@ SETUP
Definition: rtspcodes.h:133
RTSPStream::interleaved_max
int interleaved_max
Definition: rtsp.h:453
RTSPStatusCode
RTSPStatusCode
RTSP handling.
Definition: rtspcodes.h:31
RTSP_SERVER_WMS
@ RTSP_SERVER_WMS
Windows Media server.
Definition: rtsp.h:216
PAUSE
@ PAUSE
Definition: rtspcodes.h:135
RTSP_STATUS_SERVICE
@ RTSP_STATUS_SERVICE
Definition: rtspcodes.h:72
ff_rtsp_demuxer
const FFInputFormat ff_rtsp_demuxer
Definition: rtspdec.c:997
RTSPMessageHeader
This describes the server response to each RTSP command.
Definition: rtsp.h:129
av_dict_set_int
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:167
RTSPState::real_setup_cache
enum AVDiscard * real_setup_cache
stream setup during the last frame read.
Definition: rtsp.h:300
RTSP_STATE_IDLE
@ RTSP_STATE_IDLE
not initialized
Definition: rtsp.h:203
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
mem.h
RTSP_STATUS_ONLY_AGGREGATE
@ RTSP_STATUS_ONLY_AGGREGATE
Definition: rtspcodes.h:66
ffurl_read_complete
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:557
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
rdt.h
AVPacket
This structure stores compressed data.
Definition: packet.h:497
RTSPState::server_type
enum RTSPServerType server_type
brand of server that we're talking to; e.g.
Definition: rtsp.h:275
RTSPMessageHeader::content_type
char content_type[64]
Content type header.
Definition: rtsp.h:189
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
FFInputFormat
Definition: demux.h:37
ff_rtp_reset_packet_queue
void ff_rtp_reset_packet_queue(RTPDemuxContext *s)
Definition: rtpdec.c:781
RTSPState::packets
uint64_t packets
The number of returned packets.
Definition: rtsp.h:357
RTSPTransportField::mode_record
int mode_record
transport set to record data
Definition: rtsp.h:114
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
av_strlcpy
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
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
RTSPMessageHeader::session_id
char session_id[512]
the "Session:" field.
Definition: rtsp.h:150
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_rtsp_make_setup_request
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.
RTSPStatusMessage::code
enum RTSPStatusCode code
Definition: rtspdec.c:44
avstring.h
AVDiscard
AVDiscard
Definition: defs.h:211
ff_rtsp_connect
int ff_rtsp_connect(AVFormatContext *s)
Connect to the RTSP server and set up the individual media streams.
AVERROR_PROTOCOL_NOT_FOUND
#define AVERROR_PROTOCOL_NOT_FOUND
Protocol not found.
Definition: error.h:65
snprintf
#define snprintf
Definition: snprintf.h:34
rtsp_read_pause
static int rtsp_read_pause(AVFormatContext *s)
Definition: rtspdec.c:597
RTSPS_DEFAULT_PORT
#define RTSPS_DEFAULT_PORT
Definition: rtsp.h:76
RTSP_LOWER_TRANSPORT_UDP
@ RTSP_LOWER_TRANSPORT_UDP
UDP/unicast.
Definition: rtsp.h:40
line
The official guide to swscale for confused that consecutive non overlapping rectangles of slice_bottom special converter These generally are unscaled converters of common like for each output line the vertical scaler pulls lines from a ring buffer When the ring buffer does not contain the wanted line
Definition: swscale.txt:40
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98