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