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",
105  code, status_messages[index].message);
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) {
192  av_log(s, AV_LOG_ERROR,
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;
202  rtsp_send_reply(s, RTSP_STATUS_OK, NULL, request.seq);
203  return 0;
204  }
205  av_log(s, AV_LOG_ERROR,
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  char buf[256];
293  snprintf(buf, sizeof(buf), "%d", rt->buffer_size);
294  av_dict_set(&opts, "buffer_size", buf, 0);
295  ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
296  av_log(s, AV_LOG_TRACE, "Opening: %s", url);
298  &s->interrupt_callback, &opts,
300  av_dict_free(&opts);
301  if (ret)
302  localport += 2;
303  } while (ret || localport > rt->rtp_port_max);
304  if (localport > rt->rtp_port_max) {
306  return ret;
307  }
308 
309  av_log(s, AV_LOG_TRACE, "Listening on: %d",
311  if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
313  return ret;
314  }
315 
316  localport = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
317  snprintf(responseheaders, sizeof(responseheaders), "Transport: "
318  "RTP/AVP/UDP;unicast;mode=receive;source=%s;"
319  "client_port=%d-%d;server_port=%d-%d\r\n",
320  host, request.transports[0].client_port_min,
321  request.transports[0].client_port_max, localport,
322  localport + 1);
323  }
324 
325  /* Establish sessionid if not previously set */
326  /* Put this in a function? */
327  /* RFC 2326: session id must be at least 8 digits */
328  while (strlen(rt->session_id) < 8)
329  av_strlcatf(rt->session_id, 512, "%u", av_get_random_seed());
330 
331  av_strlcatf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
332  rt->session_id);
333  /* Send Reply */
334  rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
335 
336  rt->state = RTSP_STATE_PAUSED;
337  return 0;
338 }
339 
341 {
342  RTSPState *rt = s->priv_data;
343  RTSPMessageHeader request = { 0 };
344  int ret = 0;
345  char responseheaders[1024];
346 
347  ret = rtsp_read_request(s, &request, "RECORD");
348  if (ret)
349  return ret;
350  ret = check_sessionid(s, &request);
351  if (ret)
352  return ret;
353  rt->seq++;
354  snprintf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
355  rt->session_id);
356  rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
357 
359  return 0;
360 }
361 
362 static inline int parse_command_line(AVFormatContext *s, const char *line,
363  int linelen, char *uri, int urisize,
364  char *method, int methodsize,
365  enum RTSPMethod *methodcode)
366 {
367  RTSPState *rt = s->priv_data;
368  const char *linept, *searchlinept;
369  linept = strchr(line, ' ');
370 
371  if (!linept) {
372  av_log(s, AV_LOG_ERROR, "Error parsing method string\n");
373  return AVERROR_INVALIDDATA;
374  }
375 
376  if (linept - line > methodsize - 1) {
377  av_log(s, AV_LOG_ERROR, "Method string too long\n");
378  return AVERROR(EIO);
379  }
380  memcpy(method, line, linept - line);
381  method[linept - line] = '\0';
382  linept++;
383  if (!strcmp(method, "ANNOUNCE"))
384  *methodcode = ANNOUNCE;
385  else if (!strcmp(method, "OPTIONS"))
386  *methodcode = OPTIONS;
387  else if (!strcmp(method, "RECORD"))
388  *methodcode = RECORD;
389  else if (!strcmp(method, "SETUP"))
390  *methodcode = SETUP;
391  else if (!strcmp(method, "PAUSE"))
392  *methodcode = PAUSE;
393  else if (!strcmp(method, "TEARDOWN"))
394  *methodcode = TEARDOWN;
395  else
396  *methodcode = UNKNOWN;
397  /* Check method with the state */
398  if (rt->state == RTSP_STATE_IDLE) {
399  if ((*methodcode != ANNOUNCE) && (*methodcode != OPTIONS)) {
400  av_log(s, AV_LOG_ERROR, "Unexpected command in Idle State %s\n",
401  line);
403  }
404  } else if (rt->state == RTSP_STATE_PAUSED) {
405  if ((*methodcode != OPTIONS) && (*methodcode != RECORD)
406  && (*methodcode != SETUP)) {
407  av_log(s, AV_LOG_ERROR, "Unexpected command in Paused State %s\n",
408  line);
410  }
411  } else if (rt->state == RTSP_STATE_STREAMING) {
412  if ((*methodcode != PAUSE) && (*methodcode != OPTIONS)
413  && (*methodcode != TEARDOWN)) {
414  av_log(s, AV_LOG_ERROR, "Unexpected command in Streaming State"
415  " %s\n", line);
417  }
418  } else {
419  av_log(s, AV_LOG_ERROR, "Unexpected State [%d]\n", rt->state);
420  return AVERROR_BUG;
421  }
422 
423  searchlinept = strchr(linept, ' ');
424  if (!searchlinept) {
425  av_log(s, AV_LOG_ERROR, "Error parsing message URI\n");
426  return AVERROR_INVALIDDATA;
427  }
428  if (searchlinept - linept > urisize - 1) {
429  av_log(s, AV_LOG_ERROR, "uri string length exceeded buffer size\n");
430  return AVERROR(EIO);
431  }
432  memcpy(uri, linept, searchlinept - linept);
433  uri[searchlinept - linept] = '\0';
434  if (strcmp(rt->control_uri, uri)) {
435  char host[128], path[512], auth[128];
436  int port;
437  char ctl_host[128], ctl_path[512], ctl_auth[128];
438  int ctl_port;
439  av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
440  path, sizeof(path), uri);
441  av_url_split(NULL, 0, ctl_auth, sizeof(ctl_auth), ctl_host,
442  sizeof(ctl_host), &ctl_port, ctl_path, sizeof(ctl_path),
443  rt->control_uri);
444  if (strcmp(host, ctl_host))
445  av_log(s, AV_LOG_INFO, "Host %s differs from expected %s\n",
446  host, ctl_host);
447  if (strcmp(path, ctl_path) && *methodcode != SETUP)
448  av_log(s, AV_LOG_WARNING, "WARNING: Path %s differs from expected"
449  " %s\n", path, ctl_path);
450  if (*methodcode == ANNOUNCE) {
451  av_log(s, AV_LOG_INFO,
452  "Updating control URI to %s\n", uri);
453  av_strlcpy(rt->control_uri, uri, sizeof(rt->control_uri));
454  }
455  }
456 
457  linept = searchlinept + 1;
458  if (!av_strstart(linept, "RTSP/1.0", NULL)) {
459  av_log(s, AV_LOG_ERROR, "Error parsing protocol or version\n");
461  }
462  return 0;
463 }
464 
466 {
467  RTSPState *rt = s->priv_data;
468  unsigned char rbuf[4096];
469  unsigned char method[10];
470  char uri[500];
471  int ret;
472  int rbuflen = 0;
473  RTSPMessageHeader request = { 0 };
474  enum RTSPMethod methodcode;
475 
476  ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
477  if (ret < 0)
478  return ret;
479  ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
480  sizeof(method), &methodcode);
481  if (ret) {
482  av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
483  return ret;
484  }
485 
486  ret = rtsp_read_request(s, &request, method);
487  if (ret)
488  return ret;
489  rt->seq++;
490  if (methodcode == PAUSE) {
491  rt->state = RTSP_STATE_PAUSED;
492  ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
493  // TODO: Missing date header in response
494  } else if (methodcode == OPTIONS) {
496  "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, "
497  "RECORD\r\n", request.seq);
498  } else if (methodcode == TEARDOWN) {
499  rt->state = RTSP_STATE_IDLE;
500  ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
501  }
502  return ret;
503 }
504 
506 {
507  RTSPState *rt = s->priv_data;
508  RTSPMessageHeader reply1, *reply = &reply1;
509  int i;
510  char cmd[1024];
511 
512  av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
513  rt->nb_byes = 0;
514 
516  for (i = 0; i < rt->nb_rtsp_streams; i++) {
517  RTSPStream *rtsp_st = rt->rtsp_streams[i];
518  /* Try to initialize the connection state in a
519  * potential NAT router by sending dummy packets.
520  * RTP/RTCP dummy packets are used for RDT, too.
521  */
522  if (rtsp_st->rtp_handle &&
523  !(rt->server_type == RTSP_SERVER_WMS && i > 1))
525  }
526  }
527  if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
528  if (rt->transport == RTSP_TRANSPORT_RTP) {
529  for (i = 0; i < rt->nb_rtsp_streams; i++) {
530  RTSPStream *rtsp_st = rt->rtsp_streams[i];
531  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
532  if (!rtpctx)
533  continue;
537  rtpctx->base_timestamp = 0;
538  rtpctx->timestamp = 0;
539  rtpctx->unwrapped_timestamp = 0;
540  rtpctx->rtcp_ts_offset = 0;
541  }
542  }
543  if (rt->state == RTSP_STATE_PAUSED) {
544  cmd[0] = 0;
545  } else {
546  snprintf(cmd, sizeof(cmd),
547  "Range: npt=%"PRId64".%03"PRId64"-\r\n",
549  rt->seek_timestamp / (AV_TIME_BASE / 1000) % 1000);
550  }
551  ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
552  if (reply->status_code != RTSP_STATUS_OK) {
553  return ff_rtsp_averror(reply->status_code, -1);
554  }
555  if (rt->transport == RTSP_TRANSPORT_RTP &&
556  reply->range_start != AV_NOPTS_VALUE) {
557  for (i = 0; i < rt->nb_rtsp_streams; i++) {
558  RTSPStream *rtsp_st = rt->rtsp_streams[i];
559  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
560  AVStream *st = NULL;
561  if (!rtpctx || rtsp_st->stream_index < 0)
562  continue;
563 
564  st = s->streams[rtsp_st->stream_index];
565  rtpctx->range_start_offset =
567  st->time_base);
568  }
569  }
570  }
572  return 0;
573 }
574 
575 /* pause the stream */
577 {
578  RTSPState *rt = s->priv_data;
579  RTSPMessageHeader reply1, *reply = &reply1;
580 
581  if (rt->state != RTSP_STATE_STREAMING)
582  return 0;
583  else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
584  ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
585  if (reply->status_code != RTSP_STATUS_OK) {
586  return ff_rtsp_averror(reply->status_code, -1);
587  }
588  }
589  rt->state = RTSP_STATE_PAUSED;
590  return 0;
591 }
592 
594 {
595  RTSPState *rt = s->priv_data;
596  char cmd[1024];
597  unsigned char *content = NULL;
598  int ret;
599 
600  /* describe the stream */
601  snprintf(cmd, sizeof(cmd),
602  "Accept: application/sdp\r\n");
603  if (rt->server_type == RTSP_SERVER_REAL) {
604  /**
605  * The Require: attribute is needed for proper streaming from
606  * Realmedia servers.
607  */
608  av_strlcat(cmd,
609  "Require: com.real.retain-entity-for-setup\r\n",
610  sizeof(cmd));
611  }
612  ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
613  if (reply->status_code != RTSP_STATUS_OK) {
614  av_freep(&content);
616  }
617  if (!content)
618  return AVERROR_INVALIDDATA;
619 
620  av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
621  /* now we got the SDP description, we parse it */
622  ret = ff_sdp_parse(s, (const char *)content);
623  av_freep(&content);
624  if (ret < 0)
625  return ret;
626 
627  return 0;
628 }
629 
631 {
632  RTSPState *rt = s->priv_data;
633  char proto[128], host[128], path[512], auth[128];
634  char uri[500];
635  int port;
636  int default_port = RTSP_DEFAULT_PORT;
637  char tcpname[500];
638  const char *lower_proto = "tcp";
639  unsigned char rbuf[4096];
640  unsigned char method[10];
641  int rbuflen = 0;
642  int ret;
643  enum RTSPMethod methodcode;
644 
645  /* extract hostname and port */
646  av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
647  &port, path, sizeof(path), s->url);
648 
649  /* ff_url_join. No authorization by now (NULL) */
650  ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL, host,
651  port, "%s", path);
652 
653  if (!strcmp(proto, "rtsps")) {
654  lower_proto = "tls";
655  default_port = RTSPS_DEFAULT_PORT;
656  }
657 
658  if (port < 0)
659  port = default_port;
660 
661  /* Create TCP connection */
662  ff_url_join(tcpname, sizeof(tcpname), lower_proto, NULL, host, port,
663  "?listen&listen_timeout=%d", rt->initial_timeout * 1000);
664 
665  if (ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
668  av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n");
669  return ret;
670  }
671  rt->state = RTSP_STATE_IDLE;
672  rt->rtsp_hd_out = rt->rtsp_hd;
673  for (;;) { /* Wait for incoming RTSP messages */
674  ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
675  if (ret < 0)
676  return ret;
677  ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
678  sizeof(method), &methodcode);
679  if (ret) {
680  av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
681  return ret;
682  }
683 
684  if (methodcode == ANNOUNCE) {
685  ret = rtsp_read_announce(s);
686  rt->state = RTSP_STATE_PAUSED;
687  } else if (methodcode == OPTIONS) {
688  ret = rtsp_read_options(s);
689  } else if (methodcode == RECORD) {
690  ret = rtsp_read_record(s);
691  if (!ret)
692  return 0; // We are ready for streaming
693  } else if (methodcode == SETUP)
694  ret = rtsp_read_setup(s, host, uri);
695  if (ret) {
696  ffurl_close(rt->rtsp_hd);
697  return AVERROR_INVALIDDATA;
698  }
699  }
700 }
701 
702 static int rtsp_probe(const AVProbeData *p)
703 {
704  if (
705 #if CONFIG_TLS_PROTOCOL
706  av_strstart(p->filename, "rtsps:", NULL) ||
707 #endif
708  av_strstart(p->filename, "rtsp:", NULL))
709  return AVPROBE_SCORE_MAX;
710  return 0;
711 }
712 
714 {
715  RTSPState *rt = s->priv_data;
716  int ret;
717 
718  if (rt->initial_timeout > 0)
720 
721  if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
722  ret = rtsp_listen(s);
723  if (ret)
724  return ret;
725  } else {
726  ret = ff_rtsp_connect(s);
727  if (ret)
728  return ret;
729 
730  rt->real_setup_cache = !s->nb_streams ? NULL :
731  av_mallocz_array(s->nb_streams, 2 * sizeof(*rt->real_setup_cache));
732  if (!rt->real_setup_cache && s->nb_streams)
733  return AVERROR(ENOMEM);
734  rt->real_setup = rt->real_setup_cache + s->nb_streams;
735 
736  if (rt->initial_pause) {
737  /* do not start immediately */
738  } else {
739  if ((ret = rtsp_read_play(s)) < 0) {
742  return ret;
743  }
744  }
745  }
746 
747  return 0;
748 }
749 
751  uint8_t *buf, int buf_size)
752 {
753  RTSPState *rt = s->priv_data;
754  int id, len, i, ret;
755  RTSPStream *rtsp_st;
756 
757  av_log(s, AV_LOG_TRACE, "tcp_read_packet:\n");
758 redo:
759  for (;;) {
760  RTSPMessageHeader reply;
761 
762  ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL);
763  if (ret < 0)
764  return ret;
765  if (ret == 1) /* received '$' */
766  break;
767  /* XXX: parse message */
768  if (rt->state != RTSP_STATE_STREAMING)
769  return 0;
770  }
771  ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
772  if (ret != 3)
773  return -1;
774  id = buf[0];
775  len = AV_RB16(buf + 1);
776  av_log(s, AV_LOG_TRACE, "id=%d len=%d\n", id, len);
777  if (len > buf_size || len < 8)
778  goto redo;
779  /* get the data */
780  ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
781  if (ret != len)
782  return -1;
783  if (rt->transport == RTSP_TRANSPORT_RDT &&
784  ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0)
785  return -1;
786 
787  /* find the matching stream */
788  for (i = 0; i < rt->nb_rtsp_streams; i++) {
789  rtsp_st = rt->rtsp_streams[i];
790  if (id >= rtsp_st->interleaved_min &&
791  id <= rtsp_st->interleaved_max)
792  goto found;
793  }
794  goto redo;
795 found:
796  *prtsp_st = rtsp_st;
797  return len;
798 }
799 
801 {
802  RTSPState *rt = s->priv_data;
803  char host[1024];
804  int port;
805 
806  av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
807  s->url);
808  ff_rtsp_undo_setup(s, 0);
810  rt->real_challenge);
811 }
812 
814 {
815  RTSPState *rt = s->priv_data;
816  int ret;
817  RTSPMessageHeader reply1, *reply = &reply1;
818  char cmd[1024];
819 
820 retry:
821  if (rt->server_type == RTSP_SERVER_REAL) {
822  int i;
823 
824  for (i = 0; i < s->nb_streams; i++)
825  rt->real_setup[i] = s->streams[i]->discard;
826 
827  if (!rt->need_subscription) {
828  if (memcmp (rt->real_setup, rt->real_setup_cache,
829  sizeof(enum AVDiscard) * s->nb_streams)) {
830  snprintf(cmd, sizeof(cmd),
831  "Unsubscribe: %s\r\n",
832  rt->last_subscription);
833  ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
834  cmd, reply, NULL);
835  if (reply->status_code != RTSP_STATUS_OK)
837  rt->need_subscription = 1;
838  }
839  }
840 
841  if (rt->need_subscription) {
842  int r, rule_nr, first = 1;
843 
844  memcpy(rt->real_setup_cache, rt->real_setup,
845  sizeof(enum AVDiscard) * s->nb_streams);
846  rt->last_subscription[0] = 0;
847 
848  snprintf(cmd, sizeof(cmd),
849  "Subscribe: ");
850  for (i = 0; i < rt->nb_rtsp_streams; i++) {
851  rule_nr = 0;
852  for (r = 0; r < s->nb_streams; r++) {
853  if (s->streams[r]->id == i) {
854  if (s->streams[r]->discard != AVDISCARD_ALL) {
855  if (!first)
856  av_strlcat(rt->last_subscription, ",",
857  sizeof(rt->last_subscription));
859  rt->last_subscription,
860  sizeof(rt->last_subscription), i, rule_nr);
861  first = 0;
862  }
863  rule_nr++;
864  }
865  }
866  }
867  av_strlcatf(cmd, sizeof(cmd), "%s\r\n", 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 = 0;
873 
874  if (rt->state == RTSP_STATE_STREAMING)
875  rtsp_read_play (s);
876  }
877  }
878 
879  ret = ff_rtsp_fetch_packet(s, pkt);
880  if (ret < 0) {
881  if (ret == AVERROR(ETIMEDOUT) && !rt->packets) {
884  RTSPMessageHeader reply1, *reply = &reply1;
885  av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
886  if (rtsp_read_pause(s) != 0)
887  return -1;
888  // TEARDOWN is required on Real-RTSP, but might make
889  // other servers close the connection.
890  if (rt->server_type == RTSP_SERVER_REAL)
891  ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
892  reply, NULL);
893  rt->session_id[0] = '\0';
894  if (resetup_tcp(s) == 0) {
895  rt->state = RTSP_STATE_IDLE;
896  rt->need_subscription = 1;
897  if (rtsp_read_play(s) != 0)
898  return -1;
899  goto retry;
900  }
901  }
902  }
903  return ret;
904  }
905  rt->packets++;
906 
907  if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
908  /* send dummy request to keep TCP connection alive */
909  if ((av_gettime_relative() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
910  rt->auth_state.stale) {
911  if (rt->server_type == RTSP_SERVER_WMS ||
912  (rt->server_type != RTSP_SERVER_REAL &&
914  ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
915  } else {
916  ff_rtsp_send_cmd_async(s, "OPTIONS", rt->control_uri, NULL);
917  }
918  /* The stale flag should be reset when creating the auth response in
919  * ff_rtsp_send_cmd_async, but reset it here just in case we never
920  * called the auth code (if we didn't have any credentials set). */
921  rt->auth_state.stale = 0;
922  }
923  }
924 
925  return 0;
926 }
927 
928 static int rtsp_read_seek(AVFormatContext *s, int stream_index,
929  int64_t timestamp, int flags)
930 {
931  RTSPState *rt = s->priv_data;
932  int ret;
933 
934  rt->seek_timestamp = av_rescale_q(timestamp,
935  s->streams[stream_index]->time_base,
937  switch(rt->state) {
938  default:
939  case RTSP_STATE_IDLE:
940  break;
942  if ((ret = rtsp_read_pause(s)) != 0)
943  return ret;
945  if ((ret = rtsp_read_play(s)) != 0)
946  return ret;
947  break;
948  case RTSP_STATE_PAUSED:
949  rt->state = RTSP_STATE_IDLE;
950  break;
951  }
952  return 0;
953 }
954 
955 static const AVClass rtsp_demuxer_class = {
956  .class_name = "RTSP demuxer",
957  .item_name = av_default_item_name,
958  .option = ff_rtsp_options,
959  .version = LIBAVUTIL_VERSION_INT,
960 };
961 
963  .name = "rtsp",
964  .long_name = NULL_IF_CONFIG_SMALL("RTSP input"),
965  .priv_data_size = sizeof(RTSPState),
971  .flags = AVFMT_NOFILE,
972  .read_play = rtsp_read_play,
973  .read_pause = rtsp_read_pause,
974  .priv_class = &rtsp_demuxer_class,
975 };
int interleaved_min
interleave ids, if TCP transport; each TCP/RTSP data packet starts with a &#39;$&#39;, stream length and stre...
Definition: rtsp.h:94
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:4742
int rtp_port_min
Minimum and maximum local UDP ports.
Definition: rtsp.h:389
#define NULL
Definition: coverity.c:32
Realmedia Data Transport.
Definition: rtsp.h:59
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static int rtsp_read_options(AVFormatContext *s)
Definition: rtspdec.c:212
int ff_rtp_get_local_rtp_port(URLContext *h)
Return the local rtp port used by the RTP connection.
Definition: rtpproto.c:521
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
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
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1636
static const struct RTSPStatusMessage status_messages[]
char content_type[64]
Content type header.
Definition: rtsp.h:188
static int rtsp_read_request(AVFormatContext *s, RTSPMessageHeader *request, const char *method)
Definition: rtspdec.c:141
static int rtsp_read_close(AVFormatContext *s)
Definition: rtspdec.c:56
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
const char * filename
Definition: avformat.h:447
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
static int rtsp_read_header(AVFormatContext *s)
Definition: rtspdec.c:713
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:421
#define RTSP_DEFAULT_PORT
Definition: rtsp.h:73
Windows Media server.
Definition: rtsp.h:210
int64_t range_start_offset
Definition: rtpdec.h:158
int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
Open RTSP transport context.
Definition: rtsp.c:808
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:153
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
enum AVDiscard * real_setup
current stream setup.
Definition: rtsp.h:297
static int resetup_tcp(AVFormatContext *s)
Definition: rtspdec.c:800
enum AVDiscard * real_setup_cache
stream setup during the last frame read.
Definition: rtsp.h:293
int mode_record
transport set to record data
Definition: rtsp.h:113
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:593
void ff_network_close(void)
Definition: network.c:116
UDP/unicast.
Definition: rtsp.h:38
int seq
sequence number
Definition: rtsp.h:145
initialized and sending/receiving data
Definition: rtsp.h:198
RTSPMethod
Definition: rtspcodes.h:129
char real_challenge[64]
the "RealChallenge1:" field from the server
Definition: rtsp.h:271
static int rtsp_read_pause(AVFormatContext *s)
Definition: rtspdec.c:576
const char * message
Definition: rtspdec.c:40
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:750
discard all
Definition: avcodec.h:814
static AVPacket pkt
uint64_t last_rtcp_ntp_time
Definition: rtpdec.h:177
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
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:87
#define RTSP_FLAG_LISTEN
Wait for incoming connections.
Definition: rtsp.h:421
char session_id[512]
copy of RTSPMessageHeader->session_id, i.e.
Definition: rtsp.h:246
int64_t seek_timestamp
the seek value requested when calling av_seek_frame().
Definition: rtsp.h:240
static int rtsp_send_reply(AVFormatContext *s, enum RTSPStatusCode code, const char *extracontent, uint16_t seq)
Definition: rtspdec.c:96
static int check_sessionid(AVFormatContext *s, RTSPMessageHeader *request)
Definition: rtspdec.c:123
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.
enum RTSPLowerTransport lower_transport
network layer transport protocol; e.g.
Definition: rtsp.h:122
This describes the server response to each RTSP command.
Definition: rtsp.h:128
Definition: ftp.c:34
enum RTSPStatusCode code
Definition: rtspdec.c:39
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
Format I/O context.
Definition: avformat.h:1358
int ff_rtsp_connect(AVFormatContext *s)
Connect to the RTSP server and set up the individual media streams.
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
uint64_t first_rtcp_ntp_time
Definition: rtpdec.h:179
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: rtspdec.c:813
int get_parameter_supported
Whether the server supports the GET_PARAMETER method.
Definition: rtsp.h:361
Standards-compliant RTP.
Definition: rtsp.h:58
uint8_t
char session_id[512]
the "Session:" field.
Definition: rtsp.h:149
miscellaneous OS support macros and functions.
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:202
void ff_rtp_reset_packet_queue(RTPDemuxContext *s)
Definition: rtpdec.c:710
int id
Format-specific stream ID.
Definition: avformat.h:888
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
int initial_timeout
Timeout to wait for incoming connections.
Definition: rtsp.h:394
static int read_line(AVFormatContext *s, char *rbuf, const int rbufsize, int *rbuflen)
Definition: rtspdec.c:71
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1426
URLContext * rtsp_hd_out
Additional output handle, used when input and output are done separately, eg for HTTP tunneling...
Definition: rtsp.h:329
static int rtsp_read_setup(AVFormatContext *s, char *host, char *controlurl)
Definition: rtspdec.c:230
#define AVERROR_PROTOCOL_NOT_FOUND
Protocol not found.
Definition: error.h:63
Describe a single stream, as identified by a single m= line block in the SDP content.
Definition: rtsp.h:438
char * protocol_whitelist
&#39;,&#39; separated list of allowed protocols.
Definition: avformat.h:1918
enum RTSPStatusCode status_code
response code from server
Definition: rtsp.h:132
#define AVERROR_EOF
End of file.
Definition: error.h:55
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
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.
static int rtsp_read_play(AVFormatContext *s)
Definition: rtspdec.c:505
static int ff_rtsp_averror(enum RTSPStatusCode status_code, int default_averror)
Definition: rtspcodes.h:144
#define av_log(a,...)
int nb_transports
number of items in the &#39;transports&#39; variable below
Definition: rtsp.h:135
void ff_rtsp_parse_line(AVFormatContext *s, RTSPMessageHeader *reply, const char *buf, RTSPState *rt, const char *method)
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
int ff_sdp_parse(AVFormatContext *s, const char *content)
Parse an SDP description of streams by populating an RTSPState struct within the AVFormatContext; als...
int ff_rtsp_parse_streaming_commands(AVFormatContext *s)
Parse RTSP commands (OPTIONS, PAUSE and TEARDOWN) during streaming in listen mode.
Definition: rtspdec.c:465
Private data for the RTSP demuxer.
Definition: rtsp.h:219
int64_t last_cmd_time
timestamp of the last RTSP command that we sent to the RTSP server.
Definition: rtsp.h:256
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int timeout
copy of RTSPMessageHeader->timeout, i.e.
Definition: rtsp.h:251
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
char * url
input or output URL.
Definition: avformat.h:1454
const char * r
Definition: vf_curves.c:114
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:197
const AVOption ff_rtsp_options[]
Definition: rtsp.c:83
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
Definition: dict.c:203
Definition: graph2dot.c:48
URLContext * rtsp_hd
Definition: rtsp.h:221
int64_t rtcp_ts_offset
Definition: rtpdec.h:181
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
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:362
struct RTSPStream ** rtsp_streams
streams in this session
Definition: rtsp.h:226
static int rtsp_read_record(AVFormatContext *s)
Definition: rtspdec.c:340
uint32_t timestamp
Definition: rtpdec.h:155
int stream_index
corresponding stream index, if any.
Definition: rtsp.h:443
int seq
RTSP command sequence number.
Definition: rtsp.h:242
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1414
AVDictionary * opts
Definition: movenc.c:50
#define LIBAVFORMAT_IDENT
Definition: version.h:46
int nb_rtsp_streams
number of items in the &#39;rtsp_streams&#39; variable
Definition: rtsp.h:224
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
static int rtsp_probe(const AVProbeData *p)
Definition: rtspdec.c:702
int content_length
length of the data following this header
Definition: rtsp.h:130
char last_subscription[1024]
the last value of the "SET_PARAMETER Subscribe:" RTSP command.
Definition: rtsp.h:302
#define s(width, name)
Definition: cbs_vp9.c:257
int stale
Auth ok, but needs to be resent with a new nonce.
Definition: httpauth.h:71
int ff_rdt_parse_header(const uint8_t *buf, int len, int *pset_id, int *pseq_no, int *pstream_id, int *pis_keyframe, uint32_t *ptimestamp)
Actual data handling.
Definition: rdt.c:190
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:530
if(ret)
Stream structure.
Definition: avformat.h:881
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
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:36
int nb_byes
Definition: rtsp.h:337
enum RTSPLowerTransport lower_transport
the negotiated network layer transport protocol; e.g.
Definition: rtsp.h:263
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
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:738
int rtp_port_max
Definition: rtsp.h:389
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
int64_t unwrapped_timestamp
Definition: rtpdec.h:157
enum RTSPTransport transport
the negotiated data/packet transport protocol; e.g.
Definition: rtsp.h:259
void * buf
Definition: avisynth_c.h:766
#define RTSPS_DEFAULT_PORT
Definition: rtsp.h:74
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:676
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:70
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
int rtsp_flags
Various option flags for the RTSP muxer/demuxer.
Definition: rtsp.h:379
int client_port_max
Definition: rtsp.h:102
Describe the class of an AVClass context structure.
Definition: log.h:67
AVInputFormat ff_rtsp_demuxer
Definition: rtspdec.c:962
int index
Definition: gxfenc.c:89
static int rtsp_listen(AVFormatContext *s)
Definition: rtspdec.c:630
not initialized
Definition: rtsp.h:197
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:101
void ff_rtsp_close_streams(AVFormatContext *s)
Close and free all streams within the RTSP (de)muxer.
Definition: rtsp.c:772
#define snprintf
Definition: snprintf.h:34
int buffer_size
Definition: rtsp.h:412
This structure contains the data a format has to probe a file.
Definition: avformat.h:446
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
int interleaved_max
Definition: rtsp.h:94
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
#define flags(name, subs,...)
Definition: cbs_av1.c:561
enum RTSPServerType server_type
brand of server that we&#39;re talking to; e.g.
Definition: rtsp.h:268
int ffurl_close(URLContext *h)
Definition: avio.c:467
RTSPStatusCode
RTSP handling.
Definition: rtspcodes.h:31
int64_t range_start
Time range of the streams that the server will stream.
Definition: rtsp.h:139
enum RTSPClientState state
indicator of whether we are currently receiving data from the server.
Definition: rtsp.h:232
static int read_probe(const AVProbeData *pd)
Definition: jvdec.c:55
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...
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:458
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
Main libavformat public API header.
static const AVClass rtsp_demuxer_class
Definition: rtspdec.c:955
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:33
initialized, requesting a seek
Definition: rtsp.h:200
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:463
int need_subscription
The following are used for Real stream selection.
Definition: rtsp.h:289
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:414
static int rtsp_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: rtspdec.c:928
uint32_t base_timestamp
Definition: rtpdec.h:156
initialized, but not receiving data
Definition: rtsp.h:199
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&#39;re reading data interleave...
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.
#define AVERROR_OPTION_NOT_FOUND
Option not found.
Definition: error.h:61
TCP; interleaved in RTSP.
Definition: rtsp.h:39
HTTPAuthState auth_state
authentication state
Definition: rtsp.h:277
int len
char control_url[1024]
url for this stream (from SDP)
Definition: rtsp.h:449
void * priv_data
Format private data.
Definition: avformat.h:1386
#define AVERROR_STREAM_NOT_FOUND
Stream not found.
Definition: error.h:65
uint64_t packets
The number of returned packets.
Definition: rtsp.h:350
AVDiscard
Definition: avcodec.h:805
char * protocol_blacklist
&#39;,&#39; separated list of disallowed protocols.
Definition: avformat.h:1953
Realmedia-style server.
Definition: rtsp.h:209
int lower_transport_mask
A mask with all requested transport methods.
Definition: rtsp.h:345
static int rtsp_read_announce(AVFormatContext *s)
Definition: rtspdec.c:171
#define av_freep(p)
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:654
unbuffered private I/O API
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
Definition: random_seed.c:120
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:910
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
int interleaved_max
Definition: rtsp.h:447
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:936
enum AVCodecID id
int interleaved_min
interleave IDs; copies of RTSPTransportField->interleaved_min/max for the selected transport...
Definition: rtsp.h:447
This structure stores compressed data.
Definition: avcodec.h:1457
void ff_rtsp_close_connections(AVFormatContext *s)
Close all connection handles within the RTSP (de)muxer.
URLContext * rtp_handle
RTP stream handle (if UDP)
Definition: rtsp.h:439
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
void * transport_priv
RTP/RDT parse context if input, RTP AVFormatContext if output.
Definition: rtsp.h:440
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
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:191
int initial_pause
Do not begin to play the stream immediately.
Definition: rtsp.h:366