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