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[MAX_URL_SIZE];
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[MAX_URL_SIZE];
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[SDP_MAX_SIZE];
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[MAX_URL_SIZE];
236  RTSPStream *rtsp_st;
237  char responseheaders[MAX_URL_SIZE];
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 
277  /* check if the stream has already been setup */
278  if (rtsp_st->transport_priv) {
279  if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
281  else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP)
283  rtsp_st->transport_priv = NULL;
284  }
285  if (rtsp_st->rtp_handle)
286  ffurl_closep(&rtsp_st->rtp_handle);
287 
290  if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
292  return ret;
293  }
294  rtsp_st->interleaved_min = request.transports[0].interleaved_min;
295  rtsp_st->interleaved_max = request.transports[0].interleaved_max;
296  snprintf(responseheaders, sizeof(responseheaders), "Transport: "
297  "RTP/AVP/TCP;unicast;mode=receive;interleaved=%d-%d"
298  "\r\n", request.transports[0].interleaved_min,
299  request.transports[0].interleaved_max);
300  } else {
301  do {
303  av_dict_set_int(&opts, "buffer_size", rt->buffer_size, 0);
304  ff_url_join(url, sizeof(url), "rtp", NULL, host, localport, NULL);
305  av_log(s, AV_LOG_TRACE, "Opening: %s\n", url);
307  &s->interrupt_callback, &opts,
309  av_dict_free(&opts);
310  if (ret)
311  localport += 2;
312  } while (ret || localport > rt->rtp_port_max);
313  if (localport > rt->rtp_port_max) {
315  return ret;
316  }
317 
318  av_log(s, AV_LOG_TRACE, "Listening on: %d\n",
320  if ((ret = ff_rtsp_open_transport_ctx(s, rtsp_st))) {
322  return ret;
323  }
324 
325  localport = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
326  snprintf(responseheaders, sizeof(responseheaders), "Transport: "
327  "RTP/AVP/UDP;unicast;mode=receive;source=%s;"
328  "client_port=%d-%d;server_port=%d-%d\r\n",
329  host, request.transports[0].client_port_min,
330  request.transports[0].client_port_max, localport,
331  localport + 1);
332  }
333 
334  /* Establish sessionid if not previously set */
335  /* Put this in a function? */
336  /* RFC 2326: session id must be at least 8 digits */
337  while (strlen(rt->session_id) < 8)
338  av_strlcatf(rt->session_id, 512, "%u", av_get_random_seed());
339 
340  av_strlcatf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
341  rt->session_id);
342  /* Send Reply */
343  rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
344 
345  rt->state = RTSP_STATE_PAUSED;
346  return 0;
347 }
348 
350 {
351  RTSPState *rt = s->priv_data;
352  RTSPMessageHeader request = { 0 };
353  int ret = 0;
354  char responseheaders[MAX_URL_SIZE];
355 
356  ret = rtsp_read_request(s, &request, "RECORD");
357  if (ret)
358  return ret;
359  ret = check_sessionid(s, &request);
360  if (ret)
361  return ret;
362  rt->seq++;
363  snprintf(responseheaders, sizeof(responseheaders), "Session: %s\r\n",
364  rt->session_id);
365  rtsp_send_reply(s, RTSP_STATUS_OK, responseheaders, request.seq);
366 
368  return 0;
369 }
370 
371 static inline int parse_command_line(AVFormatContext *s, const char *line,
372  int linelen, char *uri, int urisize,
373  char *method, int methodsize,
374  enum RTSPMethod *methodcode)
375 {
376  RTSPState *rt = s->priv_data;
377  const char *linept, *searchlinept;
378  linept = strchr(line, ' ');
379 
380  if (!linept) {
381  av_log(s, AV_LOG_ERROR, "Error parsing method string\n");
382  return AVERROR_INVALIDDATA;
383  }
384 
385  if (linept - line > methodsize - 1) {
386  av_log(s, AV_LOG_ERROR, "Method string too long\n");
387  return AVERROR(EIO);
388  }
389  memcpy(method, line, linept - line);
390  method[linept - line] = '\0';
391  linept++;
392  if (!strcmp(method, "ANNOUNCE"))
393  *methodcode = ANNOUNCE;
394  else if (!strcmp(method, "OPTIONS"))
395  *methodcode = OPTIONS;
396  else if (!strcmp(method, "RECORD"))
397  *methodcode = RECORD;
398  else if (!strcmp(method, "SETUP"))
399  *methodcode = SETUP;
400  else if (!strcmp(method, "PAUSE"))
401  *methodcode = PAUSE;
402  else if (!strcmp(method, "TEARDOWN"))
403  *methodcode = TEARDOWN;
404  else
405  *methodcode = UNKNOWN;
406  /* Check method with the state */
407  if (rt->state == RTSP_STATE_IDLE) {
408  if ((*methodcode != ANNOUNCE) && (*methodcode != OPTIONS)) {
409  av_log(s, AV_LOG_ERROR, "Unexpected command in Idle State %s\n",
410  line);
412  }
413  } else if (rt->state == RTSP_STATE_PAUSED) {
414  if ((*methodcode != OPTIONS) && (*methodcode != RECORD)
415  && (*methodcode != SETUP)) {
416  av_log(s, AV_LOG_ERROR, "Unexpected command in Paused State %s\n",
417  line);
419  }
420  } else if (rt->state == RTSP_STATE_STREAMING) {
421  if ((*methodcode != PAUSE) && (*methodcode != OPTIONS)
422  && (*methodcode != TEARDOWN)) {
423  av_log(s, AV_LOG_ERROR, "Unexpected command in Streaming State"
424  " %s\n", line);
426  }
427  } else {
428  av_log(s, AV_LOG_ERROR, "Unexpected State [%d]\n", rt->state);
429  return AVERROR_BUG;
430  }
431 
432  searchlinept = strchr(linept, ' ');
433  if (!searchlinept) {
434  av_log(s, AV_LOG_ERROR, "Error parsing message URI\n");
435  return AVERROR_INVALIDDATA;
436  }
437  if (searchlinept - linept > urisize - 1) {
438  av_log(s, AV_LOG_ERROR, "uri string length exceeded buffer size\n");
439  return AVERROR(EIO);
440  }
441  memcpy(uri, linept, searchlinept - linept);
442  uri[searchlinept - linept] = '\0';
443  if (strcmp(rt->control_uri, uri)) {
444  char host[128], path[512], auth[128];
445  int port;
446  char ctl_host[128], ctl_path[512], ctl_auth[128];
447  int ctl_port;
448  av_url_split(NULL, 0, auth, sizeof(auth), host, sizeof(host), &port,
449  path, sizeof(path), uri);
450  av_url_split(NULL, 0, ctl_auth, sizeof(ctl_auth), ctl_host,
451  sizeof(ctl_host), &ctl_port, ctl_path, sizeof(ctl_path),
452  rt->control_uri);
453  if (strcmp(host, ctl_host))
454  av_log(s, AV_LOG_INFO, "Host %s differs from expected %s\n",
455  host, ctl_host);
456  if (strcmp(path, ctl_path) && *methodcode != SETUP)
457  av_log(s, AV_LOG_WARNING, "WARNING: Path %s differs from expected"
458  " %s\n", path, ctl_path);
459  if (*methodcode == ANNOUNCE) {
460  av_log(s, AV_LOG_INFO,
461  "Updating control URI to %s\n", uri);
462  av_strlcpy(rt->control_uri, uri, sizeof(rt->control_uri));
463  }
464  }
465 
466  linept = searchlinept + 1;
467  if (!av_strstart(linept, "RTSP/1.0", NULL)) {
468  av_log(s, AV_LOG_ERROR, "Error parsing protocol or version\n");
470  }
471  return 0;
472 }
473 
475 {
476  RTSPState *rt = s->priv_data;
477  unsigned char rbuf[MAX_URL_SIZE];
478  unsigned char method[10];
479  char uri[500];
480  int ret;
481  int rbuflen = 0;
482  RTSPMessageHeader request = { 0 };
483  enum RTSPMethod methodcode;
484 
485  ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
486  if (ret < 0)
487  return ret;
488  av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
489  ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
490  sizeof(method), &methodcode);
491  if (ret) {
492  av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
493  return ret;
494  }
495 
496  ret = rtsp_read_request(s, &request, method);
497  if (ret)
498  return ret;
499  rt->seq++;
500  if (methodcode == PAUSE) {
501  rt->state = RTSP_STATE_PAUSED;
502  ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
503  // TODO: Missing date header in response
504  } else if (methodcode == OPTIONS) {
506  "Public: ANNOUNCE, PAUSE, SETUP, TEARDOWN, "
507  "RECORD\r\n", request.seq);
508  } else if (methodcode == TEARDOWN) {
509  rt->state = RTSP_STATE_IDLE;
510  ret = rtsp_send_reply(s, RTSP_STATUS_OK, NULL , request.seq);
511  }
512  return ret;
513 }
514 
516 {
517  RTSPState *rt = s->priv_data;
518  RTSPMessageHeader reply1, *reply = &reply1;
519  int i;
520  char cmd[MAX_URL_SIZE];
521 
522  av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state);
523  rt->nb_byes = 0;
524 
526  for (i = 0; i < rt->nb_rtsp_streams; i++) {
527  RTSPStream *rtsp_st = rt->rtsp_streams[i];
528  /* Try to initialize the connection state in a
529  * potential NAT router by sending dummy packets.
530  * RTP/RTCP dummy packets are used for RDT, too.
531  */
532  if (rtsp_st->rtp_handle &&
533  !(rt->server_type == RTSP_SERVER_WMS && i > 1))
535  }
536  }
537  if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
538  if (rt->transport == RTSP_TRANSPORT_RTP) {
539  for (i = 0; i < rt->nb_rtsp_streams; i++) {
540  RTSPStream *rtsp_st = rt->rtsp_streams[i];
541  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
542  if (!rtpctx)
543  continue;
547  rtpctx->base_timestamp = 0;
548  rtpctx->timestamp = 0;
549  rtpctx->unwrapped_timestamp = 0;
550  rtpctx->rtcp_ts_offset = 0;
551  }
552  }
553  if (rt->state == RTSP_STATE_PAUSED) {
554  cmd[0] = 0;
555  } else {
556  snprintf(cmd, sizeof(cmd),
557  "Range: npt=%"PRId64".%03"PRId64"-\r\n",
559  rt->seek_timestamp / (AV_TIME_BASE / 1000) % 1000);
560  }
561  ff_rtsp_send_cmd(s, "PLAY", rt->control_uri, cmd, reply, NULL);
562  if (reply->status_code != RTSP_STATUS_OK) {
563  return ff_rtsp_averror(reply->status_code, -1);
564  }
565  if (rt->transport == RTSP_TRANSPORT_RTP &&
566  reply->range_start != AV_NOPTS_VALUE) {
567  for (i = 0; i < rt->nb_rtsp_streams; i++) {
568  RTSPStream *rtsp_st = rt->rtsp_streams[i];
569  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
570  AVStream *st = NULL;
571  if (!rtpctx || rtsp_st->stream_index < 0)
572  continue;
573 
574  st = s->streams[rtsp_st->stream_index];
575  rtpctx->range_start_offset =
577  st->time_base);
578  }
579  }
580  }
582  return 0;
583 }
584 
585 /* pause the stream */
587 {
588  RTSPState *rt = s->priv_data;
589  RTSPMessageHeader reply1, *reply = &reply1;
590 
591  if (rt->state != RTSP_STATE_STREAMING)
592  return 0;
593  else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) {
594  ff_rtsp_send_cmd(s, "PAUSE", rt->control_uri, NULL, reply, NULL);
595  if (reply->status_code != RTSP_STATUS_OK) {
596  return ff_rtsp_averror(reply->status_code, -1);
597  }
598  }
599  rt->state = RTSP_STATE_PAUSED;
600  return 0;
601 }
602 
604 {
605  RTSPState *rt = s->priv_data;
606  char cmd[MAX_URL_SIZE];
607  unsigned char *content = NULL;
608  int ret;
609 
610  /* describe the stream */
611  snprintf(cmd, sizeof(cmd),
612  "Accept: application/sdp\r\n");
613  if (rt->server_type == RTSP_SERVER_REAL) {
614  /**
615  * The Require: attribute is needed for proper streaming from
616  * Realmedia servers.
617  */
618  av_strlcat(cmd,
619  "Require: com.real.retain-entity-for-setup\r\n",
620  sizeof(cmd));
621  }
622  ff_rtsp_send_cmd(s, "DESCRIBE", rt->control_uri, cmd, reply, &content);
623  if (reply->status_code != RTSP_STATUS_OK) {
624  av_freep(&content);
626  }
627  if (!content)
628  return AVERROR_INVALIDDATA;
629 
630  av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", content);
631  /* now we got the SDP description, we parse it */
632  ret = ff_sdp_parse(s, (const char *)content);
633  av_freep(&content);
634  if (ret < 0)
635  return ret;
636 
637  return 0;
638 }
639 
641 {
642  RTSPState *rt = s->priv_data;
643  char proto[128], host[128], path[512], auth[128];
644  char uri[500];
645  int port;
646  int default_port = RTSP_DEFAULT_PORT;
647  char tcpname[500];
648  const char *lower_proto = "tcp";
649  unsigned char rbuf[MAX_URL_SIZE];
650  unsigned char method[10];
651  int rbuflen = 0;
652  int ret;
653  enum RTSPMethod methodcode;
654 
655  if (!ff_network_init())
656  return AVERROR(EIO);
657 
658  /* extract hostname and port */
659  av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
660  &port, path, sizeof(path), s->url);
661 
662  /* ff_url_join. No authorization by now (NULL) */
663  ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL, host,
664  port, "%s", path);
665 
666  if (!strcmp(proto, "rtsps")) {
667  lower_proto = "tls";
668  default_port = RTSPS_DEFAULT_PORT;
669  }
670 
671  if (port < 0)
672  port = default_port;
673 
674  /* Create TCP connection */
675  ff_url_join(tcpname, sizeof(tcpname), lower_proto, NULL, host, port,
676  "?listen&listen_timeout=%d", rt->initial_timeout * 1000);
677 
678  if (ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
681  av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n");
682  goto fail;
683  }
684  rt->state = RTSP_STATE_IDLE;
685  rt->rtsp_hd_out = rt->rtsp_hd;
686  for (;;) { /* Wait for incoming RTSP messages */
687  ret = read_line(s, rbuf, sizeof(rbuf), &rbuflen);
688  if (ret < 0)
689  goto fail;
690  av_log(s, AV_LOG_TRACE, "Parsing[%d]: %s\n", rbuflen, rbuf);
691  ret = parse_command_line(s, rbuf, rbuflen, uri, sizeof(uri), method,
692  sizeof(method), &methodcode);
693  if (ret) {
694  av_log(s, AV_LOG_ERROR, "RTSP: Unexpected Command\n");
695  goto fail;
696  }
697 
698  if (methodcode == ANNOUNCE) {
699  ret = rtsp_read_announce(s);
700  rt->state = RTSP_STATE_PAUSED;
701  } else if (methodcode == OPTIONS) {
702  ret = rtsp_read_options(s);
703  } else if (methodcode == RECORD) {
704  ret = rtsp_read_record(s);
705  if (!ret)
706  return 0; // We are ready for streaming
707  } else if (methodcode == SETUP)
708  ret = rtsp_read_setup(s, host, uri);
709  if (ret) {
710  ret = AVERROR_INVALIDDATA;
711  goto fail;
712  }
713  }
714 fail:
718  return ret;
719 }
720 
721 static int rtsp_probe(const AVProbeData *p)
722 {
723  if (
724 #if CONFIG_TLS_PROTOCOL
725  av_strstart(p->filename, "rtsps:", NULL) ||
726 #endif
727  av_strstart(p->filename, "satip:", NULL) ||
728  av_strstart(p->filename, "rtsp:", NULL))
729  return AVPROBE_SCORE_MAX;
730  return 0;
731 }
732 
734 {
735  RTSPState *rt = s->priv_data;
736  int ret;
737 
738  if (rt->initial_timeout > 0)
740 
741  if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
742  ret = rtsp_listen(s);
743  if (ret)
744  return ret;
745  } else {
746  ret = ff_rtsp_connect(s);
747  if (ret)
748  return ret;
749 
750  rt->real_setup_cache = !s->nb_streams ? NULL :
751  av_mallocz_array(s->nb_streams, 2 * sizeof(*rt->real_setup_cache));
752  if (!rt->real_setup_cache && s->nb_streams) {
753  ret = AVERROR(ENOMEM);
754  goto fail;
755  }
756  rt->real_setup = rt->real_setup_cache + s->nb_streams;
757 
758  if (rt->initial_pause) {
759  /* do not start immediately */
760  } else {
761  ret = rtsp_read_play(s);
762  if (ret < 0)
763  goto fail;
764  }
765  }
766 
767  return 0;
768 
769 fail:
770  rtsp_read_close(s);
771  return ret;
772 }
773 
775  uint8_t *buf, int buf_size)
776 {
777  RTSPState *rt = s->priv_data;
778  int id, len, i, ret;
779  RTSPStream *rtsp_st;
780 
781  av_log(s, AV_LOG_TRACE, "tcp_read_packet:\n");
782 redo:
783  for (;;) {
784  RTSPMessageHeader reply;
785 
786  ret = ff_rtsp_read_reply(s, &reply, NULL, 1, NULL);
787  if (ret < 0)
788  return ret;
789  if (ret == 1) /* received '$' */
790  break;
791  /* XXX: parse message */
792  if (rt->state != RTSP_STATE_STREAMING)
793  return 0;
794  }
795  ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
796  if (ret != 3)
797  return AVERROR(EIO);
798  id = buf[0];
799  len = AV_RB16(buf + 1);
800  av_log(s, AV_LOG_TRACE, "id=%d len=%d\n", id, len);
801  if (len > buf_size || len < 8)
802  goto redo;
803  /* get the data */
804  ret = ffurl_read_complete(rt->rtsp_hd, buf, len);
805  if (ret != len)
806  return AVERROR(EIO);
807  if (rt->transport == RTSP_TRANSPORT_RDT &&
808  (ret = ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL)) < 0)
809  return ret;
810 
811  /* find the matching stream */
812  for (i = 0; i < rt->nb_rtsp_streams; i++) {
813  rtsp_st = rt->rtsp_streams[i];
814  if (id >= rtsp_st->interleaved_min &&
815  id <= rtsp_st->interleaved_max)
816  goto found;
817  }
818  goto redo;
819 found:
820  *prtsp_st = rtsp_st;
821  return len;
822 }
823 
825 {
826  RTSPState *rt = s->priv_data;
827  char host[1024];
828  int port;
829 
830  av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0,
831  s->url);
832  ff_rtsp_undo_setup(s, 0);
834  rt->real_challenge);
835 }
836 
838 {
839  RTSPState *rt = s->priv_data;
840  int ret;
841  RTSPMessageHeader reply1, *reply = &reply1;
842  char cmd[MAX_URL_SIZE];
843 
844 retry:
845  if (rt->server_type == RTSP_SERVER_REAL) {
846  int i;
847 
848  for (i = 0; i < s->nb_streams; i++)
849  rt->real_setup[i] = s->streams[i]->discard;
850 
851  if (!rt->need_subscription) {
852  if (memcmp (rt->real_setup, rt->real_setup_cache,
853  sizeof(enum AVDiscard) * s->nb_streams)) {
854  snprintf(cmd, sizeof(cmd),
855  "Unsubscribe: %s\r\n",
856  rt->last_subscription);
857  ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
858  cmd, reply, NULL);
859  if (reply->status_code != RTSP_STATUS_OK)
861  rt->need_subscription = 1;
862  }
863  }
864 
865  if (rt->need_subscription) {
866  int r, rule_nr, first = 1;
867 
868  memcpy(rt->real_setup_cache, rt->real_setup,
869  sizeof(enum AVDiscard) * s->nb_streams);
870  rt->last_subscription[0] = 0;
871 
872  snprintf(cmd, sizeof(cmd),
873  "Subscribe: ");
874  for (i = 0; i < rt->nb_rtsp_streams; i++) {
875  rule_nr = 0;
876  for (r = 0; r < s->nb_streams; r++) {
877  if (s->streams[r]->id == i) {
878  if (s->streams[r]->discard != AVDISCARD_ALL) {
879  if (!first)
880  av_strlcat(rt->last_subscription, ",",
881  sizeof(rt->last_subscription));
883  rt->last_subscription,
884  sizeof(rt->last_subscription), i, rule_nr);
885  first = 0;
886  }
887  rule_nr++;
888  }
889  }
890  }
891  av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription);
892  ff_rtsp_send_cmd(s, "SET_PARAMETER", rt->control_uri,
893  cmd, reply, NULL);
894  if (reply->status_code != RTSP_STATUS_OK)
896  rt->need_subscription = 0;
897 
898  if (rt->state == RTSP_STATE_STREAMING)
899  rtsp_read_play (s);
900  }
901  }
902 
903  ret = ff_rtsp_fetch_packet(s, pkt);
904  if (ret < 0) {
905  if (ret == AVERROR(ETIMEDOUT) && !rt->packets) {
908  RTSPMessageHeader reply1, *reply = &reply1;
909  av_log(s, AV_LOG_WARNING, "UDP timeout, retrying with TCP\n");
910  if (rtsp_read_pause(s) != 0)
911  return -1;
912  // TEARDOWN is required on Real-RTSP, but might make
913  // other servers close the connection.
914  if (rt->server_type == RTSP_SERVER_REAL)
915  ff_rtsp_send_cmd(s, "TEARDOWN", rt->control_uri, NULL,
916  reply, NULL);
917  rt->session_id[0] = '\0';
918  if (resetup_tcp(s) == 0) {
919  rt->state = RTSP_STATE_IDLE;
920  rt->need_subscription = 1;
921  if (rtsp_read_play(s) != 0)
922  return -1;
923  goto retry;
924  }
925  }
926  }
927  return ret;
928  }
929  rt->packets++;
930 
931  if (!(rt->rtsp_flags & RTSP_FLAG_LISTEN)) {
932  /* send dummy request to keep TCP connection alive */
933  if ((av_gettime_relative() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2 ||
934  rt->auth_state.stale) {
935  if (rt->server_type == RTSP_SERVER_WMS ||
936  (rt->server_type != RTSP_SERVER_REAL &&
938  ff_rtsp_send_cmd_async(s, "GET_PARAMETER", rt->control_uri, NULL);
939  } else {
940  ff_rtsp_send_cmd_async(s, "OPTIONS", rt->control_uri, NULL);
941  }
942  /* The stale flag should be reset when creating the auth response in
943  * ff_rtsp_send_cmd_async, but reset it here just in case we never
944  * called the auth code (if we didn't have any credentials set). */
945  rt->auth_state.stale = 0;
946  }
947  }
948 
949  return 0;
950 }
951 
952 static int rtsp_read_seek(AVFormatContext *s, int stream_index,
953  int64_t timestamp, int flags)
954 {
955  RTSPState *rt = s->priv_data;
956  int ret;
957 
958  rt->seek_timestamp = av_rescale_q(timestamp,
959  s->streams[stream_index]->time_base,
961  switch(rt->state) {
962  default:
963  case RTSP_STATE_IDLE:
964  break;
966  if ((ret = rtsp_read_pause(s)) != 0)
967  return ret;
969  if ((ret = rtsp_read_play(s)) != 0)
970  return ret;
971  break;
972  case RTSP_STATE_PAUSED:
973  rt->state = RTSP_STATE_IDLE;
974  break;
975  }
976  return 0;
977 }
978 
979 static const AVClass rtsp_demuxer_class = {
980  .class_name = "RTSP demuxer",
981  .item_name = av_default_item_name,
982  .option = ff_rtsp_options,
983  .version = LIBAVUTIL_VERSION_INT,
984 };
985 
987  .name = "rtsp",
988  .long_name = NULL_IF_CONFIG_SMALL("RTSP input"),
989  .priv_data_size = sizeof(RTSPState),
995  .flags = AVFMT_NOFILE,
996  .read_play = rtsp_read_play,
997  .read_pause = rtsp_read_pause,
998  .priv_class = &rtsp_demuxer_class,
999 };
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:96
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:4759
int rtp_port_min
Minimum and maximum local UDP ports.
Definition: rtsp.h:397
#define NULL
Definition: coverity.c:32
Realmedia Data Transport.
Definition: rtsp.h:60
#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:528
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:309
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:405
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1521
static const struct RTSPStatusMessage status_messages[]
char content_type[64]
Content type header.
Definition: rtsp.h:190
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:200
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
const char * filename
Definition: avformat.h:442
static int rtsp_read_header(AVFormatContext *s)
Definition: rtspdec.c:733
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:415
#define RTSP_DEFAULT_PORT
Definition: rtsp.h:74
Windows Media server.
Definition: rtsp.h:217
int64_t range_start_offset
Definition: rtpdec.h:156
int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
Open RTSP transport context.
Definition: rtsp.c:828
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:235
enum AVDiscard * real_setup
current stream setup.
Definition: rtsp.h:305
static int resetup_tcp(AVFormatContext *s)
Definition: rtspdec.c:824
enum AVDiscard * real_setup_cache
stream setup during the last frame read.
Definition: rtsp.h:301
int mode_record
transport set to record data
Definition: rtsp.h:115
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:603
void ff_network_close(void)
Definition: network.c:116
UDP/unicast.
Definition: rtsp.h:39
int seq
sequence number
Definition: rtsp.h:147
initialized and sending/receiving data
Definition: rtsp.h:205
RTSPMethod
Definition: rtspcodes.h:129
char real_challenge[64]
the "RealChallenge1:" field from the server
Definition: rtsp.h:279
static int rtsp_read_pause(AVFormatContext *s)
Definition: rtspdec.c:586
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:774
discard all
Definition: avcodec.h:236
static AVPacket pkt
uint64_t last_rtcp_ntp_time
Definition: rtpdec.h:175
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:91
#define RTSP_FLAG_LISTEN
Wait for incoming connections.
Definition: rtsp.h:429
char session_id[512]
copy of RTSPMessageHeader->session_id, i.e.
Definition: rtsp.h:254
int64_t seek_timestamp
the seek value requested when calling av_seek_frame().
Definition: rtsp.h:248
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:124
This describes the server response to each RTSP command.
Definition: rtsp.h:130
Definition: ftp.c:37
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:145
Format I/O context.
Definition: avformat.h:1243
#define MAX_URL_SIZE
Definition: internal.h:30
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:177
static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: rtspdec.c:837
int get_parameter_supported
Whether the server supports the GET_PARAMETER method.
Definition: rtsp.h:369
Standards-compliant RTP.
Definition: rtsp.h:59
uint8_t
char session_id[512]
the "Session:" field.
Definition: rtsp.h:151
int ff_network_init(void)
Definition: network.c:58
miscellaneous OS support macros and functions.
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:220
void ff_rtp_reset_packet_queue(RTPDemuxContext *s)
Definition: rtpdec.c:747
int id
Format-specific stream ID.
Definition: avformat.h:891
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:402
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:1311
URLContext * rtsp_hd_out
Additional output handle, used when input and output are done separately, eg for HTTP tunneling...
Definition: rtsp.h:337
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:447
char * protocol_whitelist
&#39;,&#39; separated list of allowed protocols.
Definition: avformat.h:1815
enum RTSPStatusCode status_code
response code from server
Definition: rtsp.h:134
#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:210
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:515
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:137
void ff_rtsp_parse_line(AVFormatContext *s, RTSPMessageHeader *reply, const char *buf, RTSPState *rt, const char *method)
void ff_rdt_parse_close(RDTDemuxContext *s)
Definition: rdt.c:78
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:474
Private data for the RTSP demuxer.
Definition: rtsp.h:227
int64_t last_cmd_time
timestamp of the last RTSP command that we sent to the RTSP server.
Definition: rtsp.h:264
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
int timeout
copy of RTSPMessageHeader->timeout, i.e.
Definition: rtsp.h:259
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:115
char * url
input or output URL.
Definition: avformat.h:1339
const char * r
Definition: vf_curves.c:116
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
const AVOption ff_rtsp_options[]
Definition: rtsp.c:80
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:229
int64_t rtcp_ts_offset
Definition: rtpdec.h:179
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
#define fail()
Definition: checkasm.h:133
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:371
struct RTSPStream ** rtsp_streams
streams in this session
Definition: rtsp.h:234
static int rtsp_read_record(AVFormatContext *s)
Definition: rtspdec.c:349
uint32_t timestamp
Definition: rtpdec.h:153
int stream_index
corresponding stream index, if any.
Definition: rtsp.h:452
int seq
RTSP command sequence number.
Definition: rtsp.h:250
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1299
AVDictionary * opts
Definition: movenc.c:50
#define LIBAVFORMAT_IDENT
Definition: version.h:46
char control_uri[MAX_URL_SIZE]
some MS RTSP streams contain a URL in the SDP that we need to use for all subsequent RTSP requests...
Definition: rtsp.h:326
int nb_rtsp_streams
number of items in the &#39;rtsp_streams&#39; variable
Definition: rtsp.h:232
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:254
static int rtsp_probe(const AVProbeData *p)
Definition: rtspdec.c:721
int content_length
length of the data following this header
Definition: rtsp.h:132
char last_subscription[1024]
the last value of the "SET_PARAMETER Subscribe:" RTSP command.
Definition: rtsp.h:310
#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:527
if(ret)
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition: avio.c:438
Stream structure.
Definition: avformat.h:884
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:38
int nb_byes
Definition: rtsp.h:345
enum RTSPLowerTransport lower_transport
the negotiated network layer transport protocol; e.g.
Definition: rtsp.h:271
#define AV_LOG_INFO
Standard information.
Definition: log.h:205
void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
Undo the effect of ff_rtsp_make_setup_request, close the transport_priv and rtp_handle fields...
Definition: rtsp.c:760
int rtp_port_max
Definition: rtsp.h:397
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
int64_t unwrapped_timestamp
Definition: rtpdec.h:155
#define SDP_MAX_SIZE
Definition: rtsp.h:82
enum RTSPTransport transport
the negotiated data/packet transport protocol; e.g.
Definition: rtsp.h:267
#define RTSPS_DEFAULT_PORT
Definition: rtsp.h:75
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:676
#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:387
int client_port_max
Definition: rtsp.h:104
Describe the class of an AVClass context structure.
Definition: log.h:67
AVInputFormat ff_rtsp_demuxer
Definition: rtspdec.c:986
int index
Definition: gxfenc.c:89
static int rtsp_listen(AVFormatContext *s)
Definition: rtspdec.c:640
not initialized
Definition: rtsp.h:204
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:792
#define snprintf
Definition: snprintf.h:34
int buffer_size
Definition: rtsp.h:420
This structure contains the data a format has to probe a file.
Definition: avformat.h:441
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:96
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:276
RTSPStatusCode
RTSP handling.
Definition: rtspcodes.h:31
int64_t range_start
Time range of the streams that the server will stream.
Definition: rtsp.h:141
enum RTSPClientState state
indicator of whether we are currently receiving data from the server.
Definition: rtsp.h:240
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:453
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:979
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:207
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:458
int need_subscription
The following are used for Real stream selection.
Definition: rtsp.h:297
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
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:408
static int rtsp_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: rtspdec.c:952
uint32_t base_timestamp
Definition: rtpdec.h:154
initialized, but not receiving data
Definition: rtsp.h:206
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:40
HTTPAuthState auth_state
authentication state
Definition: rtsp.h:285
int len
void * priv_data
Format private data.
Definition: avformat.h:1271
#define AVERROR_STREAM_NOT_FOUND
Stream not found.
Definition: error.h:65
uint64_t packets
The number of returned packets.
Definition: rtsp.h:358
void ff_rtp_parse_close(RTPDemuxContext *s)
Definition: rtpdec.c:919
AVDiscard
Definition: avcodec.h:227
char * protocol_blacklist
&#39;,&#39; separated list of disallowed protocols.
Definition: avformat.h:1850
Realmedia-style server.
Definition: rtsp.h:216
int lower_transport_mask
A mask with all requested transport methods.
Definition: rtsp.h:353
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
char control_url[MAX_URL_SIZE]
url for this stream (from SDP)
Definition: rtsp.h:458
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:913
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:456
enum AVDiscard discard
Selects which packets can be discarded at will and do not need to be demuxed.
Definition: avformat.h:939
enum AVCodecID id
int interleaved_min
interleave IDs; copies of RTSPTransportField->interleaved_min/max for the selected transport...
Definition: rtsp.h:456
This structure stores compressed data.
Definition: packet.h:340
void ff_rtsp_close_connections(AVFormatContext *s)
Close all connection handles within the RTSP (de)muxer.
int i
Definition: input.c:407
URLContext * rtp_handle
RTP stream handle (if UDP)
Definition: rtsp.h:448
#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:449
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:104
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:190
int initial_pause
Do not begin to play the stream immediately.
Definition: rtsp.h:374