FFmpeg
rtsp.c
Go to the documentation of this file.
1 /*
2  * RTSP/SDP client
3  * Copyright (c) 2002 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config_components.h"
23 
24 #include "libavutil/avassert.h"
25 #include "libavutil/base64.h"
26 #include "libavutil/bprint.h"
27 #include "libavutil/avstring.h"
28 #include "libavutil/intreadwrite.h"
29 #include "libavutil/mathematics.h"
30 #include "libavutil/mem.h"
31 #include "libavutil/parseutils.h"
32 #include "libavutil/random_seed.h"
33 #include "libavutil/dict.h"
34 #include "libavutil/opt.h"
35 #include "libavutil/time.h"
36 #include "libavcodec/codec_desc.h"
37 #include "avformat.h"
38 #include "avio_internal.h"
39 #include "demux.h"
40 
41 #if HAVE_POLL_H
42 #include <poll.h>
43 #endif
44 #include "internal.h"
45 #include "network.h"
46 #include "os_support.h"
47 #include "http.h"
48 #include "rtsp.h"
49 
50 #include "rtpdec.h"
51 #include "rtpproto.h"
52 #include "rdt.h"
53 #include "rtpdec_formats.h"
54 #include "rtpenc_chain.h"
55 #include "url.h"
56 #include "tls.h"
57 #include "rtpenc.h"
58 #include "mpegts.h"
59 #include "version.h"
60 
61 /* Default timeout values for read packet in seconds */
62 #define READ_PACKET_TIMEOUT_S 10
63 #define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
64 #define DEFAULT_REORDERING_DELAY 100000
65 
66 #define OFFSET(x) offsetof(RTSPState, x)
67 #define DEC AV_OPT_FLAG_DECODING_PARAM
68 #define ENC AV_OPT_FLAG_ENCODING_PARAM
69 
70 #define RTSP_FLAG_OPTS(name, longname) \
71  { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC, .unit = "rtsp_flags" }, \
72  { "filter_src", "only receive packets from the negotiated peer IP", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_FILTER_SRC}, 0, 0, DEC, .unit = "rtsp_flags" }
73 
74 #define RTSP_MEDIATYPE_OPTS(name, longname) \
75  { name, longname, OFFSET(media_type_mask), AV_OPT_TYPE_FLAGS, { .i64 = (1 << (AVMEDIA_TYPE_SUBTITLE+1)) - 1 }, INT_MIN, INT_MAX, DEC, .unit = "allowed_media_types" }, \
76  { "video", "Video", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_VIDEO}, 0, 0, DEC, .unit = "allowed_media_types" }, \
77  { "audio", "Audio", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_AUDIO}, 0, 0, DEC, .unit = "allowed_media_types" }, \
78  { "data", "Data", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_DATA}, 0, 0, DEC, .unit = "allowed_media_types" }, \
79  { "subtitle", "Subtitle", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_SUBTITLE}, 0, 0, DEC, .unit = "allowed_media_types" }
80 
81 #define COMMON_OPTS() \
82  { "reorder_queue_size", "set number of packets to buffer for handling of reordered packets", OFFSET(reordering_queue_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC }, \
83  { "buffer_size", "Underlying protocol send/receive buffer size", OFFSET(buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC|ENC }, \
84  { "pkt_size", "Underlying protocol send packet size", OFFSET(pkt_size), AV_OPT_TYPE_INT, { .i64 = 1472 }, -1, INT_MAX, ENC } \
85 
86 
88  { "initial_pause", "do not start playing the stream immediately", OFFSET(initial_pause), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
89  FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags),
90  { "rtsp_transport", "set RTSP transport protocols", OFFSET(lower_transport_mask), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC|ENC, .unit = "rtsp_transport" }, \
91  { "udp", "UDP", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_UDP}, 0, 0, DEC|ENC, .unit = "rtsp_transport" }, \
92  { "tcp", "TCP", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_TCP}, 0, 0, DEC|ENC, .unit = "rtsp_transport" }, \
93  { "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, .unit = "rtsp_transport" },
94  { "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {.i64 = (1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, .unit = "rtsp_transport" },
95  { "https", "HTTPS tunneling", 0, AV_OPT_TYPE_CONST, {.i64 = (1 << RTSP_LOWER_TRANSPORT_HTTPS )}, 0, 0, DEC, .unit = "rtsp_transport" },
96  RTSP_FLAG_OPTS("rtsp_flags", "set RTSP flags"),
97  { "listen", "wait for incoming connections", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_LISTEN}, 0, 0, DEC, .unit = "rtsp_flags" },
98  { "prefer_tcp", "try RTP via TCP first, if available", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_PREFER_TCP}, 0, 0, DEC|ENC, .unit = "rtsp_flags" },
99  { "satip_raw", "export raw MPEG-TS stream instead of demuxing", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_SATIP_RAW}, 0, 0, DEC, .unit = "rtsp_flags" },
100  RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"),
101  { "min_port", "set minimum local UDP port", OFFSET(rtp_port_min), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MIN}, 0, 65535, DEC|ENC },
102  { "max_port", "set maximum local UDP port", OFFSET(rtp_port_max), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MAX}, 0, 65535, DEC|ENC },
103  { "listen_timeout", "set maximum timeout (in seconds) to wait for incoming connections (-1 is infinite, imply flag listen)", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC },
104  { "timeout", "set timeout (in microseconds) of socket I/O operations", OFFSET(stimeout), AV_OPT_TYPE_INT64, {.i64 = 0}, INT_MIN, INT64_MAX, DEC },
105  COMMON_OPTS(),
106  { "user_agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, DEC },
107 
108  // TLS options
109  FF_TLS_CLIENT_OPTIONS(RTSPState, tls_opts),
110  { NULL },
111 };
112 
113 static const AVOption sdp_options[] = {
114  RTSP_FLAG_OPTS("sdp_flags", "SDP flags"),
115  { "custom_io", "use custom I/O", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_CUSTOM_IO}, 0, 0, DEC, .unit = "rtsp_flags" },
116  { "rtcp_to_source", "send RTCP packets to the source address of received packets", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_RTCP_TO_SOURCE}, 0, 0, DEC, .unit = "rtsp_flags" },
117  { "listen_timeout", "set maximum timeout (in seconds) to wait for incoming connections", OFFSET(stimeout), AV_OPT_TYPE_DURATION, {.i64 = READ_PACKET_TIMEOUT_S*1000000}, INT_MIN, INT64_MAX, DEC },
118  { "localaddr", "local address", OFFSET(localaddr),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, \
119  RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"),
120  COMMON_OPTS(),
121  { NULL },
122 };
123 
124 static const AVOption rtp_options[] = {
125  RTSP_FLAG_OPTS("rtp_flags", "set RTP flags"),
126  { "listen_timeout", "set maximum timeout (in seconds) to wait for incoming connections", OFFSET(stimeout), AV_OPT_TYPE_DURATION, {.i64 = READ_PACKET_TIMEOUT_S*1000000}, INT_MIN, INT64_MAX, DEC },
127  { "localaddr", "local address", OFFSET(localaddr),AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, \
128  RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"),
129  COMMON_OPTS(),
130  { NULL },
131 };
132 
133 
135 {
137 
138  av_dict_set_int(&opts, "buffer_size", rt->buffer_size, 0);
139  av_dict_set_int(&opts, "pkt_size", rt->pkt_size, 0);
140  if (rt->localaddr && rt->localaddr[0])
141  av_dict_set(&opts, "localaddr", rt->localaddr, 0);
142 
143  return opts;
144 }
145 
146 #define ERR_RET(c) \
147  do { \
148  int ret = c; \
149  if (ret < 0) \
150  return ret; \
151  } while (0)
152 
153 /**
154  * Add the TLS options of the given RTSPState to the dict
155  */
157 {
158  ERR_RET(av_dict_set_int(dict, "tls_verify", rt->tls_opts.verify, 0));
159  ERR_RET(av_dict_set(dict, "ca_file", rt->tls_opts.ca_file, 0));
160  ERR_RET(av_dict_set(dict, "cert_file", rt->tls_opts.cert_file, 0));
161  ERR_RET(av_dict_set(dict, "key_file", rt->tls_opts.key_file, 0));
162  ERR_RET(av_dict_set(dict, "verifyhost", rt->tls_opts.host, 0));
163 
164  return 0;
165 }
166 
167 #undef ERR_RET
168 
169 static void get_word_until_chars(char *buf, int buf_size,
170  const char *sep, const char **pp)
171 {
172  const char *p;
173  char *q;
174 
175  p = *pp;
176  p += strspn(p, SPACE_CHARS);
177  q = buf;
178  while (!strchr(sep, *p) && *p != '\0') {
179  if ((q - buf) < buf_size - 1)
180  *q++ = *p;
181  p++;
182  }
183  if (buf_size > 0)
184  *q = '\0';
185  *pp = p;
186 }
187 
188 static void get_word_sep(char *buf, int buf_size, const char *sep,
189  const char **pp)
190 {
191  if (**pp == '/') (*pp)++;
192  get_word_until_chars(buf, buf_size, sep, pp);
193 }
194 
195 static void get_word(char *buf, int buf_size, const char **pp)
196 {
197  get_word_until_chars(buf, buf_size, SPACE_CHARS, pp);
198 }
199 
200 /** Parse a string p in the form of Range:npt=xx-xx, and determine the start
201  * and end time.
202  * Used for seeking in the rtp stream.
203  */
204 static void rtsp_parse_range_npt(const char *p, int64_t *start, int64_t *end)
205 {
206  char buf[256];
207 
208  p += strspn(p, SPACE_CHARS);
209  if (!av_stristart(p, "npt=", &p))
210  return;
211 
212  *start = AV_NOPTS_VALUE;
213  *end = AV_NOPTS_VALUE;
214 
215  get_word_sep(buf, sizeof(buf), "-", &p);
216  if (av_parse_time(start, buf, 1) < 0)
217  return;
218  if (*p == '-') {
219  p++;
220  get_word_sep(buf, sizeof(buf), "-", &p);
221  if (av_parse_time(end, buf, 1) < 0)
222  av_log(NULL, AV_LOG_DEBUG, "Failed to parse interval end specification '%s'\n", buf);
223  }
224 }
225 
227  const char *buf, struct sockaddr_storage *sock)
228 {
229  struct addrinfo hints = { 0 }, *ai = NULL;
230  int ret;
231 
232  hints.ai_flags = AI_NUMERICHOST;
233  if ((ret = getaddrinfo(buf, NULL, &hints, &ai))) {
234  av_log(s, AV_LOG_ERROR, "getaddrinfo(%s): %s\n",
235  buf,
236  gai_strerror(ret));
237  return -1;
238  }
239  memcpy(sock, ai->ai_addr, FFMIN(sizeof(*sock), ai->ai_addrlen));
240  freeaddrinfo(ai);
241  return 0;
242 }
243 
244 #if CONFIG_RTPDEC
245 static void init_rtp_handler(const RTPDynamicProtocolHandler *handler,
246  RTSPStream *rtsp_st, AVStream *st)
247 {
248  AVCodecParameters *par = st ? st->codecpar : NULL;
249  if (!handler)
250  return;
251  if (par)
252  par->codec_id = handler->codec_id;
253  rtsp_st->dynamic_handler = handler;
254  if (st)
255  ffstream(st)->need_parsing = handler->need_parsing;
256  if (handler->priv_data_size) {
257  rtsp_st->dynamic_protocol_context = av_mallocz(handler->priv_data_size);
258  if (!rtsp_st->dynamic_protocol_context)
259  rtsp_st->dynamic_handler = NULL;
260  }
261 }
262 
263 static void finalize_rtp_handler_init(AVFormatContext *s, RTSPStream *rtsp_st,
264  AVStream *st)
265 {
266  if (rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->init) {
267  int ret = rtsp_st->dynamic_handler->init(s, st ? st->index : -1,
268  rtsp_st->dynamic_protocol_context);
269  if (ret < 0) {
270  if (rtsp_st->dynamic_protocol_context) {
271  if (rtsp_st->dynamic_handler->close)
272  rtsp_st->dynamic_handler->close(
273  rtsp_st->dynamic_protocol_context);
275  }
276  rtsp_st->dynamic_protocol_context = NULL;
277  rtsp_st->dynamic_handler = NULL;
278  }
279  }
280 }
281 
282 #if CONFIG_RTSP_DEMUXER
283 static int init_satip_stream(AVFormatContext *s)
284 {
285  RTSPState *rt = s->priv_data;
286  RTSPStream *rtsp_st = av_mallocz(sizeof(RTSPStream));
287  if (!rtsp_st)
288  return AVERROR(ENOMEM);
290  &rt->nb_rtsp_streams, rtsp_st);
291 
292  rtsp_st->sdp_payload_type = 33; // MP2T
293  av_strlcpy(rtsp_st->control_url,
294  rt->control_uri, sizeof(rtsp_st->control_url));
295 
296  if (rt->rtsp_flags & RTSP_FLAG_SATIP_RAW) {
298  if (!st)
299  return AVERROR(ENOMEM);
300  st->id = rt->nb_rtsp_streams - 1;
301  rtsp_st->stream_index = st->index;
304  } else {
305  rtsp_st->stream_index = -1;
306  init_rtp_handler(&ff_mpegts_dynamic_handler, rtsp_st, NULL);
307  finalize_rtp_handler_init(s, rtsp_st, NULL);
308  }
309  return 0;
310 }
311 #endif
312 
313 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */
314 static int sdp_parse_rtpmap(AVFormatContext *s,
315  AVStream *st, RTSPStream *rtsp_st,
316  int payload_type, const char *p)
317 {
318  AVCodecParameters *par = st->codecpar;
319  char buf[256];
320  int i;
321  const AVCodecDescriptor *desc;
322  const char *c_name;
323 
324  /* See if we can handle this kind of payload.
325  * The space should normally not be there but some Real streams or
326  * particular servers ("RealServer Version 6.1.3.970", see issue 1658)
327  * have a trailing space. */
328  get_word_sep(buf, sizeof(buf), "/ ", &p);
329  if (payload_type < RTP_PT_PRIVATE) {
330  /* We are in a standard case
331  * (from http://www.iana.org/assignments/rtp-parameters). */
332  par->codec_id = ff_rtp_codec_id(buf, par->codec_type);
333  }
334 
335  if (par->codec_id == AV_CODEC_ID_NONE) {
338  init_rtp_handler(handler, rtsp_st, st);
339  /* If no dynamic handler was found, check with the list of standard
340  * allocated types, if such a stream for some reason happens to
341  * use a private payload type. This isn't handled in rtpdec.c, since
342  * the format name from the rtpmap line never is passed into rtpdec. */
343  if (!rtsp_st->dynamic_handler)
344  par->codec_id = ff_rtp_codec_id(buf, par->codec_type);
345  }
346 
348  if (desc && desc->name)
349  c_name = desc->name;
350  else
351  c_name = "(null)";
352 
353  get_word_sep(buf, sizeof(buf), "/", &p);
354  i = atoi(buf);
355  switch (par->codec_type) {
356  case AVMEDIA_TYPE_AUDIO:
357  av_log(s, AV_LOG_DEBUG, "audio codec set to: %s\n", c_name);
360  if (i > 0) {
361  par->sample_rate = i;
362  avpriv_set_pts_info(st, 32, 1, par->sample_rate);
363  get_word_sep(buf, sizeof(buf), "/", &p);
364  i = atoi(buf);
365  if (i > 0)
367  }
368  av_log(s, AV_LOG_DEBUG, "audio samplerate set to: %i\n",
369  par->sample_rate);
370  av_log(s, AV_LOG_DEBUG, "audio channels set to: %i\n",
371  par->ch_layout.nb_channels);
372  break;
373  case AVMEDIA_TYPE_VIDEO:
374  av_log(s, AV_LOG_DEBUG, "video codec set to: %s\n", c_name);
375  if (i > 0)
376  avpriv_set_pts_info(st, 32, 1, i);
377  break;
378  default:
379  break;
380  }
381  finalize_rtp_handler_init(s, rtsp_st, st);
382  return 0;
383 }
384 
385 /* parse the attribute line from the fmtp a line of an sdp response. This
386  * is broken out as a function because it is used in rtp_h264.c, which is
387  * forthcoming. */
388 int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size,
389  char *value, int value_size)
390 {
391  *p += strspn(*p, SPACE_CHARS);
392  if (**p) {
393  get_word_sep(attr, attr_size, "=", p);
394  if (**p == '=')
395  (*p)++;
396  get_word_sep(value, value_size, ";", p);
397  if (**p == ';')
398  (*p)++;
399  return 1;
400  }
401  return 0;
402 }
403 
404 typedef struct SDPParseState {
405  /* SDP only */
406  struct sockaddr_storage default_ip;
407  int default_ttl;
408  int skip_media; ///< set if an unknown m= line occurs
409  int nb_default_include_source_addrs; /**< Number of source-specific multicast include source IP address (from SDP content) */
410  struct RTSPSource **default_include_source_addrs; /**< Source-specific multicast include source IP address (from SDP content) */
411  int nb_default_exclude_source_addrs; /**< Number of source-specific multicast exclude source IP address (from SDP content) */
412  struct RTSPSource **default_exclude_source_addrs; /**< Source-specific multicast exclude source IP address (from SDP content) */
413  int seen_rtpmap;
414  int seen_fmtp;
415  char delayed_fmtp[2048];
416 } SDPParseState;
417 
418 static void copy_default_source_addrs(struct RTSPSource **addrs, int count,
419  struct RTSPSource ***dest, int *dest_count)
420 {
421  RTSPSource *rtsp_src, *rtsp_src2;
422  int i;
423  for (i = 0; i < count; i++) {
424  rtsp_src = addrs[i];
425  rtsp_src2 = av_memdup(rtsp_src, sizeof(*rtsp_src));
426  if (!rtsp_src2)
427  continue;
428  dynarray_add(dest, dest_count, rtsp_src2);
429  }
430 }
431 
432 static void parse_fmtp(AVFormatContext *s, RTSPState *rt,
433  int payload_type, const char *line)
434 {
435  int i;
436 
437  for (i = 0; i < rt->nb_rtsp_streams; i++) {
438  RTSPStream *rtsp_st = rt->rtsp_streams[i];
439  if (rtsp_st->sdp_payload_type == payload_type &&
440  rtsp_st->dynamic_handler &&
441  rtsp_st->dynamic_handler->parse_sdp_a_line) {
442  rtsp_st->dynamic_handler->parse_sdp_a_line(s, rtsp_st->stream_index,
443  rtsp_st->dynamic_protocol_context, line);
444  }
445  }
446 }
447 
448 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
449  int letter, const char *buf)
450 {
451  RTSPState *rt = s->priv_data;
452  char buf1[64], st_type[64];
453  const char *p;
454  enum AVMediaType codec_type;
455  int payload_type;
456  AVStream *st;
457  RTSPStream *rtsp_st;
458  RTSPSource *rtsp_src;
459  struct sockaddr_storage sdp_ip;
460  int ttl;
461 
462  av_log(s, AV_LOG_TRACE, "sdp: %c='%s'\n", letter, buf);
463 
464  p = buf;
465  if (s1->skip_media && letter != 'm')
466  return;
467  switch (letter) {
468  case 'c':
469  get_word(buf1, sizeof(buf1), &p);
470  if (strcmp(buf1, "IN") != 0)
471  return;
472  get_word(buf1, sizeof(buf1), &p);
473  if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6"))
474  return;
475  get_word_sep(buf1, sizeof(buf1), "/", &p);
476  if (get_sockaddr(s, buf1, &sdp_ip))
477  return;
478  ttl = 16;
479  if (*p == '/') {
480  p++;
481  get_word_sep(buf1, sizeof(buf1), "/", &p);
482  ttl = atoi(buf1);
483  }
484  if (s->nb_streams == 0) {
485  s1->default_ip = sdp_ip;
486  s1->default_ttl = ttl;
487  } else {
488  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
489  rtsp_st->sdp_ip = sdp_ip;
490  rtsp_st->sdp_ttl = ttl;
491  }
492  break;
493  case 's':
494  av_dict_set(&s->metadata, "title", p, 0);
495  break;
496  case 'i':
497  if (s->nb_streams == 0) {
498  av_dict_set(&s->metadata, "comment", p, 0);
499  break;
500  }
501  break;
502  case 'm':
503  /* new stream */
504  s1->skip_media = 0;
505  s1->seen_fmtp = 0;
506  s1->seen_rtpmap = 0;
508  get_word(st_type, sizeof(st_type), &p);
509  if (!strcmp(st_type, "audio")) {
511  } else if (!strcmp(st_type, "video")) {
513  } else if (!strcmp(st_type, "application")) {
515  } else if (!strcmp(st_type, "text")) {
517  }
519  !(rt->media_type_mask & (1 << codec_type)) ||
520  rt->nb_rtsp_streams >= s->max_streams
521  ) {
522  s1->skip_media = 1;
523  return;
524  }
525  rtsp_st = av_mallocz(sizeof(RTSPStream));
526  if (!rtsp_st)
527  return;
528  rtsp_st->stream_index = -1;
529  dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st);
530 
531  rtsp_st->sdp_ip = s1->default_ip;
532  rtsp_st->sdp_ttl = s1->default_ttl;
533 
534  copy_default_source_addrs(s1->default_include_source_addrs,
535  s1->nb_default_include_source_addrs,
536  &rtsp_st->include_source_addrs,
537  &rtsp_st->nb_include_source_addrs);
538  copy_default_source_addrs(s1->default_exclude_source_addrs,
539  s1->nb_default_exclude_source_addrs,
540  &rtsp_st->exclude_source_addrs,
541  &rtsp_st->nb_exclude_source_addrs);
542 
543  get_word(buf1, sizeof(buf1), &p); /* port */
544  rtsp_st->sdp_port = atoi(buf1);
545 
546  get_word(buf1, sizeof(buf1), &p); /* protocol */
547  if (!strcmp(buf1, "udp"))
549  else if (strstr(buf1, "/AVPF") || strstr(buf1, "/SAVPF"))
550  rtsp_st->feedback = 1;
551 
552  /* XXX: handle list of formats */
553  get_word(buf1, sizeof(buf1), &p); /* format list */
554  rtsp_st->sdp_payload_type = atoi(buf1);
555 
556  if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
557  /* no corresponding stream */
558  if (rt->transport == RTSP_TRANSPORT_RAW) {
559  if (CONFIG_RTPDEC && !rt->ts)
561  } else {
565  init_rtp_handler(handler, rtsp_st, NULL);
566  finalize_rtp_handler_init(s, rtsp_st, NULL);
567  }
568  } else if (rt->server_type == RTSP_SERVER_WMS &&
570  /* RTX stream, a stream that carries all the other actual
571  * audio/video streams. Don't expose this to the callers. */
572  } else {
573  st = avformat_new_stream(s, NULL);
574  if (!st)
575  return;
576  st->id = rt->nb_rtsp_streams - 1;
577  rtsp_st->stream_index = st->index;
579  if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
581  /* if standard payload type, we can find the codec right now */
583  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
584  st->codecpar->sample_rate > 0)
585  avpriv_set_pts_info(st, 32, 1, st->codecpar->sample_rate);
586  /* Even static payload types may need a custom depacketizer */
588  rtsp_st->sdp_payload_type, st->codecpar->codec_type);
589  init_rtp_handler(handler, rtsp_st, st);
590  finalize_rtp_handler_init(s, rtsp_st, st);
591  }
592  if (rt->default_lang[0])
593  av_dict_set(&st->metadata, "language", rt->default_lang, 0);
594  }
595  /* put a default control url */
596  av_strlcpy(rtsp_st->control_url, rt->control_uri,
597  sizeof(rtsp_st->control_url));
598  break;
599  case 'a':
600  if (av_strstart(p, "control:", &p)) {
601  if (rt->nb_rtsp_streams == 0) {
602  if (!strncmp(p, "rtsp://", 7))
603  av_strlcpy(rt->control_uri, p,
604  sizeof(rt->control_uri));
605  } else {
606  char proto[32];
607  /* get the control url */
608  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
609 
610  /* XXX: may need to add full url resolution */
611  av_url_split(proto, sizeof(proto), NULL, 0, NULL, 0,
612  NULL, NULL, 0, p);
613  if (proto[0] == '\0') {
614  /* relative control URL */
615  if (rtsp_st->control_url[strlen(rtsp_st->control_url)-1]!='/')
616  av_strlcat(rtsp_st->control_url, "/",
617  sizeof(rtsp_st->control_url));
618  av_strlcat(rtsp_st->control_url, p,
619  sizeof(rtsp_st->control_url));
620  } else
621  av_strlcpy(rtsp_st->control_url, p,
622  sizeof(rtsp_st->control_url));
623  }
624  } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) {
625  /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
626  get_word(buf1, sizeof(buf1), &p);
627  payload_type = atoi(buf1);
628  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
629  if (rtsp_st->stream_index >= 0) {
630  st = s->streams[rtsp_st->stream_index];
631  sdp_parse_rtpmap(s, st, rtsp_st, payload_type, p);
632  }
633  s1->seen_rtpmap = 1;
634  if (s1->seen_fmtp) {
635  parse_fmtp(s, rt, payload_type, s1->delayed_fmtp);
636  }
637  } else if (av_strstart(p, "fmtp:", &p) ||
638  av_strstart(p, "framesize:", &p)) {
639  // let dynamic protocol handlers have a stab at the line.
640  get_word(buf1, sizeof(buf1), &p);
641  payload_type = atoi(buf1);
642  if (s1->seen_rtpmap) {
643  parse_fmtp(s, rt, payload_type, buf);
644  } else {
645  s1->seen_fmtp = 1;
646  av_strlcpy(s1->delayed_fmtp, buf, sizeof(s1->delayed_fmtp));
647  }
648  } else if (av_strstart(p, "framerate:", &p) && s->nb_streams > 0) {
649  // RFC 8866
650  double framerate;
651  if (av_sscanf(p, "%lf%c", &framerate, &(char){0}) == 1) {
652  st = s->streams[s->nb_streams - 1];
653  st->avg_frame_rate = av_d2q(framerate, INT_MAX);
654  }
655  } else if (av_strstart(p, "ssrc:", &p) && s->nb_streams > 0) {
656  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
657  get_word(buf1, sizeof(buf1), &p);
658  rtsp_st->ssrc = strtoll(buf1, NULL, 10);
659  } else if (av_strstart(p, "range:", &p)) {
660  int64_t start, end;
661 
662  // this is so that seeking on a streamed file can work.
663  rtsp_parse_range_npt(p, &start, &end);
664  s->start_time = start;
665  /* AV_NOPTS_VALUE means live broadcast (and can't seek) */
666  if (end != AV_NOPTS_VALUE)
667  s->duration = end - start;
668  } else if (av_strstart(p, "lang:", &p)) {
669  if (s->nb_streams > 0) {
670  get_word(buf1, sizeof(buf1), &p);
671  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
672  if (rtsp_st->stream_index >= 0) {
673  st = s->streams[rtsp_st->stream_index];
674  av_dict_set(&st->metadata, "language", buf1, 0);
675  }
676  } else
677  get_word(rt->default_lang, sizeof(rt->default_lang), &p);
678  } else if (av_strstart(p, "IsRealDataType:integer;",&p)) {
679  if (atoi(p) == 1)
681  } else if (av_strstart(p, "SampleRate:integer;", &p) &&
682  s->nb_streams > 0) {
683  st = s->streams[s->nb_streams - 1];
684  st->codecpar->sample_rate = atoi(p);
685  } else if (av_strstart(p, "crypto:", &p) && s->nb_streams > 0) {
686  // RFC 4568
687  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
688  get_word(buf1, sizeof(buf1), &p); // ignore tag
689  get_word(rtsp_st->crypto_suite, sizeof(rtsp_st->crypto_suite), &p);
690  p += strspn(p, SPACE_CHARS);
691  if (av_strstart(p, "inline:", &p))
692  get_word(rtsp_st->crypto_params, sizeof(rtsp_st->crypto_params), &p);
693  } else if (av_strstart(p, "source-filter:", &p)) {
694  int exclude = 0;
695  get_word(buf1, sizeof(buf1), &p);
696  if (strcmp(buf1, "incl") && strcmp(buf1, "excl"))
697  return;
698  exclude = !strcmp(buf1, "excl");
699 
700  get_word(buf1, sizeof(buf1), &p);
701  if (strcmp(buf1, "IN") != 0)
702  return;
703  get_word(buf1, sizeof(buf1), &p);
704  if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6") && strcmp(buf1, "*"))
705  return;
706  // not checking that the destination address actually matches or is wildcard
707  get_word(buf1, sizeof(buf1), &p);
708 
709  while (*p != '\0') {
710  rtsp_src = av_mallocz(sizeof(*rtsp_src));
711  if (!rtsp_src)
712  return;
713  get_word(rtsp_src->addr, sizeof(rtsp_src->addr), &p);
714  if (exclude) {
715  if (s->nb_streams == 0) {
716  dynarray_add(&s1->default_exclude_source_addrs, &s1->nb_default_exclude_source_addrs, rtsp_src);
717  } else {
718  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
719  dynarray_add(&rtsp_st->exclude_source_addrs, &rtsp_st->nb_exclude_source_addrs, rtsp_src);
720  }
721  } else {
722  if (s->nb_streams == 0) {
723  dynarray_add(&s1->default_include_source_addrs, &s1->nb_default_include_source_addrs, rtsp_src);
724  } else {
725  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
726  dynarray_add(&rtsp_st->include_source_addrs, &rtsp_st->nb_include_source_addrs, rtsp_src);
727  }
728  }
729  }
730  } else {
731  if (rt->server_type == RTSP_SERVER_WMS)
733  if (s->nb_streams > 0) {
734  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
735 
736  if (rt->server_type == RTSP_SERVER_REAL)
738 
739  if (rtsp_st->dynamic_handler &&
742  rtsp_st->stream_index,
743  rtsp_st->dynamic_protocol_context, buf);
744  }
745  }
746  break;
747  }
748 }
749 
750 int ff_sdp_parse(AVFormatContext *s, const char *content)
751 {
752  const char *p;
753  int letter, i;
754  char buf[SDP_MAX_SIZE], *q;
755  SDPParseState sdp_parse_state = { { 0 } }, *s1 = &sdp_parse_state;
756 
757  s->duration = AV_NOPTS_VALUE;
758 
759  p = content;
760  for (;;) {
761  p += strspn(p, SPACE_CHARS);
762  letter = *p;
763  if (letter == '\0')
764  break;
765  p++;
766  if (*p != '=')
767  goto next_line;
768  p++;
769  /* get the content */
770  q = buf;
771  while (*p != '\n' && *p != '\r' && *p != '\0') {
772  if ((q - buf) < sizeof(buf) - 1)
773  *q++ = *p;
774  p++;
775  }
776  *q = '\0';
777  sdp_parse_line(s, s1, letter, buf);
778  next_line:
779  while (*p != '\n' && *p != '\0')
780  p++;
781  if (*p == '\n')
782  p++;
783  }
784 
785  for (i = 0; i < s1->nb_default_include_source_addrs; i++)
786  av_freep(&s1->default_include_source_addrs[i]);
787  av_freep(&s1->default_include_source_addrs);
788  for (i = 0; i < s1->nb_default_exclude_source_addrs; i++)
789  av_freep(&s1->default_exclude_source_addrs[i]);
790  av_freep(&s1->default_exclude_source_addrs);
791 
792  if (s->duration == AV_NOPTS_VALUE)
793  s->ctx_flags |= AVFMTCTX_UNSEEKABLE;
794 
795  return 0;
796 }
797 #endif /* CONFIG_RTPDEC */
798 
799 void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
800 {
801  RTSPState *rt = s->priv_data;
802  int i;
803 
804  rt->stored_msg.expected_seq = -1;
805  for (i = 0; i < rt->nb_rtsp_streams; i++) {
806  RTSPStream *rtsp_st = rt->rtsp_streams[i];
807  if (!rtsp_st)
808  continue;
809  if (rtsp_st->transport_priv) {
810  if (s->oformat) {
811  AVFormatContext *rtpctx = rtsp_st->transport_priv;
812  av_write_trailer(rtpctx);
814  if (CONFIG_RTSP_MUXER && rtpctx->pb && send_packets)
815  ff_rtsp_tcp_write_packet(s, rtsp_st);
816  ffio_free_dyn_buf(&rtpctx->pb);
817  } else {
818  avio_closep(&rtpctx->pb);
819  }
820  avformat_free_context(rtpctx);
821  } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
823  else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP)
825  }
826  rtsp_st->transport_priv = NULL;
827  ffurl_closep(&rtsp_st->rtp_handle);
828  }
829 }
830 
831 /* close and free RTSP streams */
833 {
834  RTSPState *rt = s->priv_data;
835  int i, j;
836  RTSPStream *rtsp_st;
837 
838  ff_rtsp_undo_setup(s, 0);
839  for (i = 0; i < rt->nb_rtsp_streams; i++) {
840  rtsp_st = rt->rtsp_streams[i];
841  if (rtsp_st) {
842  if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context) {
843  if (rtsp_st->dynamic_handler->close)
844  rtsp_st->dynamic_handler->close(
845  rtsp_st->dynamic_protocol_context);
847  }
848  for (j = 0; j < rtsp_st->nb_include_source_addrs; j++)
849  av_freep(&rtsp_st->include_source_addrs[j]);
850  av_freep(&rtsp_st->include_source_addrs);
851  for (j = 0; j < rtsp_st->nb_exclude_source_addrs; j++)
852  av_freep(&rtsp_st->exclude_source_addrs[j]);
853  av_freep(&rtsp_st->exclude_source_addrs);
854 
855  av_freep(&rtsp_st);
856  }
857  }
858  av_freep(&rt->rtsp_streams);
859  if (rt->asf_ctx) {
861  }
862  if (CONFIG_RTPDEC && rt->ts)
864  av_freep(&rt->p);
865  av_freep(&rt->recvbuf);
866 }
867 
869 {
870  RTSPState *rt = s->priv_data;
871  AVStream *st = NULL;
872  int reordering_queue_size = rt->reordering_queue_size;
873  if (reordering_queue_size < 0) {
874  if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP || !s->max_delay)
875  reordering_queue_size = 0;
876  else
877  reordering_queue_size = RTP_REORDER_QUEUE_DEFAULT_SIZE;
878  }
879 
880  /* open the RTP context */
881  if (rtsp_st->stream_index >= 0)
882  st = s->streams[rtsp_st->stream_index];
883  if (!st)
884  s->ctx_flags |= AVFMTCTX_NOHEADER;
885 
886  if (CONFIG_RTSP_MUXER && s->oformat && st) {
888  s, st, rtsp_st->rtp_handle,
889  rt->pkt_size,
890  rtsp_st->stream_index);
891  /* Ownership of rtp_handle is passed to the rtp mux context */
892  rtsp_st->rtp_handle = NULL;
893  if (ret < 0)
894  return ret;
895  st->time_base = ((AVFormatContext*)rtsp_st->transport_priv)->streams[0]->time_base;
896  } else if (rt->transport == RTSP_TRANSPORT_RAW) {
897  return 0; // Don't need to open any parser here
898  } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT && st)
899  rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
900  rtsp_st->dynamic_protocol_context,
901  rtsp_st->dynamic_handler);
902  else if (CONFIG_RTPDEC)
903  rtsp_st->transport_priv = ff_rtp_parse_open(s, st,
904  rtsp_st->sdp_payload_type,
905  reordering_queue_size);
906 
907  if (!rtsp_st->transport_priv) {
908  return AVERROR(ENOMEM);
909  } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP &&
910  s->iformat) {
911  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
912  rtpctx->ssrc = rtsp_st->ssrc;
913  if (rtsp_st->dynamic_handler) {
915  rtsp_st->dynamic_protocol_context,
916  rtsp_st->dynamic_handler);
917  }
918  if (rtsp_st->crypto_suite[0])
920  rtsp_st->crypto_suite,
921  rtsp_st->crypto_params);
922  }
923 
924  return 0;
925 }
926 
927 #if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER
928 static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
929 {
930  const char *q;
931  char *p;
932  int v;
933 
934  q = *pp;
935  q += strspn(q, SPACE_CHARS);
936  v = strtol(q, &p, 10);
937  if (*p == '-') {
938  p++;
939  *min_ptr = v;
940  v = strtol(p, &p, 10);
941  *max_ptr = v;
942  } else {
943  *min_ptr = v;
944  *max_ptr = v;
945  }
946  *pp = p;
947 }
948 
949 /* XXX: only one transport specification is parsed */
950 static void rtsp_parse_transport(AVFormatContext *s,
951  RTSPMessageHeader *reply, const char *p)
952 {
953  char transport_protocol[16];
954  char profile[16];
955  char lower_transport[16];
956  char parameter[16];
957  RTSPTransportField *th;
958  char buf[256];
959 
960  reply->nb_transports = 0;
961 
962  for (;;) {
963  p += strspn(p, SPACE_CHARS);
964  if (*p == '\0')
965  break;
966 
967  th = &reply->transports[reply->nb_transports];
968 
969  get_word_sep(transport_protocol, sizeof(transport_protocol),
970  "/", &p);
971  if (!av_strcasecmp (transport_protocol, "rtp")) {
972  get_word_sep(profile, sizeof(profile), "/;,", &p);
973  lower_transport[0] = '\0';
974  /* rtp/avp/<protocol> */
975  if (*p == '/') {
976  get_word_sep(lower_transport, sizeof(lower_transport),
977  ";,", &p);
978  }
980  } else if (!av_strcasecmp (transport_protocol, "x-pn-tng") ||
981  !av_strcasecmp (transport_protocol, "x-real-rdt")) {
982  /* x-pn-tng/<protocol> */
983  get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p);
984  profile[0] = '\0';
986  } else if (!av_strcasecmp(transport_protocol, "raw")) {
987  get_word_sep(profile, sizeof(profile), "/;,", &p);
988  lower_transport[0] = '\0';
989  /* raw/raw/<protocol> */
990  if (*p == '/') {
991  get_word_sep(lower_transport, sizeof(lower_transport),
992  ";,", &p);
993  }
995  } else {
996  break;
997  }
998  if (!av_strcasecmp(lower_transport, "TCP"))
1000  else
1002 
1003  if (*p == ';')
1004  p++;
1005  /* get each parameter */
1006  while (*p != '\0' && *p != ',') {
1007  get_word_sep(parameter, sizeof(parameter), "=;,", &p);
1008  if (!strcmp(parameter, "port")) {
1009  if (*p == '=') {
1010  p++;
1011  rtsp_parse_range(&th->port_min, &th->port_max, &p);
1012  }
1013  } else if (!strcmp(parameter, "client_port")) {
1014  if (*p == '=') {
1015  p++;
1016  rtsp_parse_range(&th->client_port_min,
1017  &th->client_port_max, &p);
1018  }
1019  } else if (!strcmp(parameter, "server_port")) {
1020  if (*p == '=') {
1021  p++;
1022  rtsp_parse_range(&th->server_port_min,
1023  &th->server_port_max, &p);
1024  }
1025  } else if (!strcmp(parameter, "interleaved")) {
1026  if (*p == '=') {
1027  p++;
1028  rtsp_parse_range(&th->interleaved_min,
1029  &th->interleaved_max, &p);
1030  }
1031  } else if (!strcmp(parameter, "multicast")) {
1034  } else if (!strcmp(parameter, "ttl")) {
1035  if (*p == '=') {
1036  char *end;
1037  p++;
1038  th->ttl = strtol(p, &end, 10);
1039  p = end;
1040  }
1041  } else if (!strcmp(parameter, "destination")) {
1042  if (*p == '=') {
1043  p++;
1044  get_word_sep(buf, sizeof(buf), ";,", &p);
1045  get_sockaddr(s, buf, &th->destination);
1046  }
1047  } else if (!strcmp(parameter, "source")) {
1048  if (*p == '=') {
1049  p++;
1050  get_word_sep(buf, sizeof(buf), ";,", &p);
1051  av_strlcpy(th->source, buf, sizeof(th->source));
1052  }
1053  } else if (!strcmp(parameter, "mode")) {
1054  if (*p == '=') {
1055  p++;
1056  get_word_sep(buf, sizeof(buf), ";, ", &p);
1057  if (!av_strcasecmp(buf, "record") ||
1058  !av_strcasecmp(buf, "receive"))
1059  th->mode_record = 1;
1060  }
1061  }
1062 
1063  while (*p != ';' && *p != '\0' && *p != ',')
1064  p++;
1065  if (*p == ';')
1066  p++;
1067  }
1068  if (*p == ',')
1069  p++;
1070 
1071  reply->nb_transports++;
1072  if (reply->nb_transports >= RTSP_MAX_TRANSPORTS)
1073  break;
1074  }
1075 }
1076 
1077 static void handle_rtp_info(RTSPState *rt, const char *url,
1078  uint32_t seq, uint32_t rtptime)
1079 {
1080  int i;
1081  if (!rtptime || !url[0])
1082  return;
1083  if (rt->transport != RTSP_TRANSPORT_RTP)
1084  return;
1085  for (i = 0; i < rt->nb_rtsp_streams; i++) {
1086  RTSPStream *rtsp_st = rt->rtsp_streams[i];
1087  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
1088  if (!rtpctx)
1089  continue;
1090  if (!strcmp(rtsp_st->control_url, url)) {
1091  rtpctx->base_timestamp = rtptime;
1092  break;
1093  }
1094  }
1095 }
1096 
1097 static void rtsp_parse_rtp_info(RTSPState *rt, const char *p)
1098 {
1099  int read = 0;
1100  char key[20], value[MAX_URL_SIZE], url[MAX_URL_SIZE] = "";
1101  uint32_t seq = 0, rtptime = 0;
1102 
1103  for (;;) {
1104  p += strspn(p, SPACE_CHARS);
1105  if (!*p)
1106  break;
1107  get_word_sep(key, sizeof(key), "=", &p);
1108  if (*p != '=')
1109  break;
1110  p++;
1111  get_word_sep(value, sizeof(value), ";, ", &p);
1112  read++;
1113  if (!strcmp(key, "url"))
1114  av_strlcpy(url, value, sizeof(url));
1115  else if (!strcmp(key, "seq"))
1116  seq = strtoul(value, NULL, 10);
1117  else if (!strcmp(key, "rtptime"))
1118  rtptime = strtoul(value, NULL, 10);
1119  if (*p == ',') {
1120  handle_rtp_info(rt, url, seq, rtptime);
1121  url[0] = '\0';
1122  seq = rtptime = 0;
1123  read = 0;
1124  }
1125  if (*p)
1126  p++;
1127  }
1128  if (read > 0)
1129  handle_rtp_info(rt, url, seq, rtptime);
1130 }
1131 
1133  RTSPMessageHeader *reply, const char *buf,
1134  RTSPState *rt, const char *method)
1135 {
1136  const char *p;
1137 
1138  /* NOTE: we do case independent match for broken servers */
1139  p = buf;
1140  if (av_stristart(p, "Session:", &p)) {
1141  int t;
1142  get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p);
1143  if (av_stristart(p, ";timeout=", &p) &&
1144  (t = strtol(p, NULL, 10)) > 0) {
1145  reply->timeout = t;
1146  }
1147  } else if (av_stristart(p, "Content-Length:", &p)) {
1148  reply->content_length = strtol(p, NULL, 10);
1149  } else if (av_stristart(p, "Transport:", &p)) {
1150  rtsp_parse_transport(s, reply, p);
1151  } else if (av_stristart(p, "CSeq:", &p)) {
1152  reply->seq = strtol(p, NULL, 10);
1153  } else if (av_stristart(p, "Range:", &p)) {
1154  rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end);
1155  } else if (av_stristart(p, "RealChallenge1:", &p)) {
1156  p += strspn(p, SPACE_CHARS);
1157  av_strlcpy(reply->real_challenge, p, sizeof(reply->real_challenge));
1158  } else if (av_stristart(p, "Server:", &p)) {
1159  p += strspn(p, SPACE_CHARS);
1160  av_strlcpy(reply->server, p, sizeof(reply->server));
1161  } else if (av_stristart(p, "Notice:", &p) ||
1162  av_stristart(p, "X-Notice:", &p)) {
1163  reply->notice = strtol(p, NULL, 10);
1164  } else if (av_stristart(p, "Location:", &p)) {
1165  p += strspn(p, SPACE_CHARS);
1166  av_strlcpy(reply->location, p , sizeof(reply->location));
1167  } else if (av_stristart(p, "WWW-Authenticate:", &p) && rt) {
1168  p += strspn(p, SPACE_CHARS);
1169  ff_http_auth_handle_header(&rt->auth_state, "WWW-Authenticate", p);
1170  } else if (av_stristart(p, "Authentication-Info:", &p) && rt) {
1171  p += strspn(p, SPACE_CHARS);
1172  ff_http_auth_handle_header(&rt->auth_state, "Authentication-Info", p);
1173  } else if (av_stristart(p, "Content-Base:", &p) && rt) {
1174  p += strspn(p, SPACE_CHARS);
1175  if (method && !strcmp(method, "DESCRIBE"))
1176  av_strlcpy(rt->control_uri, p , sizeof(rt->control_uri));
1177  } else if (av_stristart(p, "RTP-Info:", &p) && rt) {
1178  p += strspn(p, SPACE_CHARS);
1179  if (method && !strcmp(method, "PLAY"))
1180  rtsp_parse_rtp_info(rt, p);
1181  } else if (av_stristart(p, "Public:", &p) && rt) {
1182  if (strstr(p, "GET_PARAMETER") &&
1183  method && !strcmp(method, "OPTIONS"))
1184  rt->get_parameter_supported = 1;
1185  } else if (av_stristart(p, "x-Accept-Dynamic-Rate:", &p) && rt) {
1186  p += strspn(p, SPACE_CHARS);
1187  rt->accept_dynamic_rate = atoi(p);
1188  } else if (av_stristart(p, "Content-Type:", &p)) {
1189  p += strspn(p, SPACE_CHARS);
1190  av_strlcpy(reply->content_type, p, sizeof(reply->content_type));
1191  } else if (av_stristart(p, "com.ses.streamID:", &p)) {
1192  p += strspn(p, SPACE_CHARS);
1193  av_strlcpy(reply->stream_id, p, sizeof(reply->stream_id));
1194  }
1195 }
1196 
1197 /* skip a RTP/TCP interleaved packet */
1199 {
1200  RTSPState *rt = s->priv_data;
1201  int ret, len, len1;
1202  uint8_t buf[MAX_URL_SIZE];
1203 
1204  rt->pending_packet = 0;
1205  ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
1206  if (ret != 3)
1207  return ret < 0 ? ret : AVERROR(EIO);
1208  len = AV_RB16(buf + 1);
1209 
1210  av_log(s, AV_LOG_TRACE, "skipping RTP packet len=%d\n", len);
1211 
1212  /* skip payload */
1213  while (len > 0) {
1214  len1 = len;
1215  if (len1 > sizeof(buf))
1216  len1 = sizeof(buf);
1217  ret = ffurl_read_complete(rt->rtsp_hd, buf, len1);
1218  if (ret != len1)
1219  return ret < 0 ? ret : AVERROR(EIO);
1220  len -= len1;
1221  }
1222 
1223  return 0;
1224 }
1225 
1226 static int ff_rtsp_read_reply_internal(AVFormatContext *s,
1227  RTSPMessageHeader *reply,
1228  unsigned char **content_ptr,
1229  int return_on_interleaved_data,
1230  const char *method)
1231 {
1232  RTSPState *rt = s->priv_data;
1233  char buf[MAX_URL_SIZE], buf1[MAX_URL_SIZE], *q;
1234  unsigned char ch;
1235  const char *p;
1236  int ret, content_length, line_count, request;
1237  unsigned char *content;
1238 
1239 start:
1240  line_count = 0;
1241  request = 0;
1242  content = NULL;
1243  memset(reply, 0, sizeof(*reply));
1244 
1245  /* parse reply (XXX: use buffers) */
1246  rt->last_reply[0] = '\0';
1247  for (;;) {
1248  q = buf;
1249  for (;;) {
1250  ret = ffurl_read_complete(rt->rtsp_hd, &ch, 1);
1251  if (ret != 1) {
1252  ret = (ret < 0) ? ret : AVERROR(EIO);
1253  av_log(s, AV_LOG_WARNING, "Failed reading RTSP data: %s\n", av_err2str(ret));
1254  return ret;
1255  }
1256  av_log(s, AV_LOG_TRACE, "ret=%d c=%02x [%c]\n", ret, ch, ch);
1257  if (ch == '\n')
1258  break;
1259  if (ch == '$' && q == buf) {
1260  if (return_on_interleaved_data) {
1261  rt->pending_packet = 1;
1262  return 1;
1263  } else {
1265  if (ret < 0)
1266  return ret;
1267  }
1268  } else if (ch != '\r') {
1269  if ((q - buf) < sizeof(buf) - 1)
1270  *q++ = ch;
1271  }
1272  }
1273  *q = '\0';
1274 
1275  av_log(s, AV_LOG_TRACE, "line='%s'\n", buf);
1276 
1277  /* test if last line */
1278  if (buf[0] == '\0')
1279  break;
1280  p = buf;
1281  if (line_count == 0) {
1282  /* get reply code */
1283  get_word(buf1, sizeof(buf1), &p);
1284  if (!strncmp(buf1, "RTSP/", 5)) {
1285  get_word(buf1, sizeof(buf1), &p);
1286  reply->status_code = atoi(buf1);
1287  p += strspn(p, SPACE_CHARS);
1288  av_strlcpy(reply->reason, p, sizeof(reply->reason));
1289  } else {
1290  av_strlcpy(reply->reason, buf1, sizeof(reply->reason)); // method
1291  get_word(buf1, sizeof(buf1), &p); // object
1292  request = 1;
1293  }
1294  } else {
1295  ff_rtsp_parse_line(s, reply, p, rt, method);
1296  av_strlcat(rt->last_reply, p, sizeof(rt->last_reply));
1297  av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply));
1298  }
1299  line_count++;
1300  }
1301 
1302  if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0' && !request)
1303  av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id));
1304 
1305  content_length = reply->content_length;
1306  if (content_length > 0) {
1307  /* leave some room for a trailing '\0' (useful for simple parsing) */
1308  content = av_malloc(content_length + 1);
1309  if (!content)
1310  return AVERROR(ENOMEM);
1311  if ((ret = ffurl_read_complete(rt->rtsp_hd, content, content_length)) != content_length) {
1312  av_freep(&content);
1313  return ret < 0 ? ret : AVERROR(EIO);
1314  }
1315  content[content_length] = '\0';
1316  }
1317  if (content_ptr)
1318  *content_ptr = content;
1319  else
1320  av_freep(&content);
1321 
1322  if (request) {
1323  char buf[MAX_URL_SIZE];
1324  char base64buf[AV_BASE64_SIZE(sizeof(buf))];
1325  const char* ptr = buf;
1326 
1327  if (!strcmp(reply->reason, "OPTIONS") ||
1328  !strcmp(reply->reason, "GET_PARAMETER")) {
1329  snprintf(buf, sizeof(buf), "RTSP/1.0 200 OK\r\n");
1330  if (reply->seq)
1331  av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", reply->seq);
1332  if (reply->session_id[0])
1333  av_strlcatf(buf, sizeof(buf), "Session: %s\r\n",
1334  reply->session_id);
1335  } else {
1336  snprintf(buf, sizeof(buf), "RTSP/1.0 501 Not Implemented\r\n");
1337  }
1338  av_strlcat(buf, "\r\n", sizeof(buf));
1339 
1340  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1341  av_base64_encode(base64buf, sizeof(base64buf), buf, strlen(buf));
1342  ptr = base64buf;
1343  }
1344  ffurl_write(rt->rtsp_hd_out, ptr, strlen(ptr));
1345 
1347  /* Even if the request from the server had data, it is not the data
1348  * that the caller wants or expects. The memory could also be leaked
1349  * if the actual following reply has content data. */
1350  if (content_ptr)
1351  av_freep(content_ptr);
1352  /* If method is set, this is called from ff_rtsp_send_cmd,
1353  * where a reply to exactly this request is awaited. For
1354  * callers from within packet receiving, we just want to
1355  * return to the caller and go back to receiving packets. */
1356  if (method)
1357  goto start;
1358  return 0;
1359  }
1360 
1361  if (rt->seq != reply->seq) {
1362  av_log(s, AV_LOG_WARNING, "CSeq %d expected, %d received.\n",
1363  rt->seq, reply->seq);
1364  }
1365 
1366  /* EOS */
1367  if (reply->notice == 2101 /* End-of-Stream Reached */ ||
1368  reply->notice == 2104 /* Start-of-Stream Reached */ ||
1369  reply->notice == 2306 /* Continuous Feed Terminated */) {
1370  rt->state = RTSP_STATE_IDLE;
1371  } else if (reply->notice >= 4400 && reply->notice < 5500) {
1372  return AVERROR(EIO); /* data or server error */
1373  } else if (reply->notice == 2401 /* Ticket Expired */ ||
1374  (reply->notice >= 5500 && reply->notice < 5600) /* end of term */ )
1375  return AVERROR(EPERM);
1376 
1377  return 0;
1378 }
1379 
1381  unsigned char **content_ptr,
1382  int return_on_interleaved_data, const char *method)
1383 {
1384  int ret;
1385  RTSPState *rt = s->priv_data;
1386 
1387  // If we returned on pending packet last time,
1388  // do not try to read again, as it would corrupt
1389  // the state due to the already consumed '$'.
1390  if (rt->pending_packet) {
1391  if (return_on_interleaved_data)
1392  return 1;
1393 
1395  if (ret < 0)
1396  return ret;
1397  }
1398 
1399  if (rt->stored_msg.expected_seq != -1) {
1401 
1402  ret = ff_rtsp_read_reply_internal(s, &header,
1403  &rt->stored_msg.body, return_on_interleaved_data, NULL);
1404  if (ret != 0)
1405  return ret;
1406 
1407  if (rt->stored_msg.expected_seq == header.seq) {
1408  // Got the expected reply, store it for later
1409  rt->stored_msg.expected_seq = -1;
1410  rt->stored_msg.header = av_calloc(1, sizeof(*rt->stored_msg.header));
1411  if (!rt->stored_msg.header) {
1412  av_freep(&rt->stored_msg.body);
1413  return AVERROR(ENOMEM);
1414  }
1415  memcpy(rt->stored_msg.header, &header, sizeof(header));
1416  } else {
1417  av_log(s, AV_LOG_WARNING, "Unexpected reply with seq %d, expected %d\n",
1418  header.seq, rt->stored_msg.expected_seq);
1419  av_freep(&rt->stored_msg.body);
1420  }
1421 
1422  // Do not return here as we still need to read the reply
1423  // the caller was actually wanting to retrieve.
1424  }
1425 
1426  return ff_rtsp_read_reply_internal(s, reply, content_ptr,
1427  return_on_interleaved_data, method);
1428 }
1429 
1430 /**
1431  * Send a command to the RTSP server without waiting for the reply.
1432  *
1433  * @param s RTSP (de)muxer context
1434  * @param method the method for the request
1435  * @param url the target url for the request
1436  * @param headers extra header lines to include in the request
1437  * @param send_content if non-null, the data to send as request body content
1438  * @param send_content_length the length of the send_content data, or 0 if
1439  * send_content is null
1440  *
1441  * @return zero if success, nonzero otherwise
1442  */
1444  const char *method, const char *url,
1445  const char *headers,
1446  const unsigned char *send_content,
1447  int send_content_length)
1448 {
1449  RTSPState *rt = s->priv_data;
1450  char buf[MAX_URL_SIZE], *out_buf;
1451  char base64buf[AV_BASE64_SIZE(sizeof(buf))];
1452 
1453  if (!rt->rtsp_hd_out)
1454  return AVERROR(ENOTCONN);
1455 
1456  /* Add in RTSP headers */
1457  out_buf = buf;
1458  rt->seq++;
1459  snprintf(buf, sizeof(buf), "%s %s RTSP/1.0\r\n", method, url);
1460  if (headers)
1461  av_strlcat(buf, headers, sizeof(buf));
1462  av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", rt->seq);
1463  av_strlcatf(buf, sizeof(buf), "User-Agent: %s\r\n", rt->user_agent);
1464  if (rt->session_id[0] != '\0' && (!headers ||
1465  !strstr(headers, "\nIf-Match:"))) {
1466  av_strlcatf(buf, sizeof(buf), "Session: %s\r\n", rt->session_id);
1467  }
1468  if (rt->auth[0]) {
1469  char *str = ff_http_auth_create_response(&rt->auth_state,
1470  rt->auth, url, method);
1471  if (str)
1472  av_strlcat(buf, str, sizeof(buf));
1473  av_free(str);
1474  }
1475  if (send_content_length > 0 && send_content)
1476  av_strlcatf(buf, sizeof(buf), "Content-Length: %d\r\n", send_content_length);
1477  av_strlcat(buf, "\r\n", sizeof(buf));
1478 
1479  /* base64 encode rtsp if tunneling */
1480  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1481  av_base64_encode(base64buf, sizeof(base64buf), buf, strlen(buf));
1482  out_buf = base64buf;
1483  }
1484 
1485  av_log(s, AV_LOG_TRACE, "Sending:\n%s--\n", buf);
1486 
1487  ffurl_write(rt->rtsp_hd_out, out_buf, strlen(out_buf));
1488  if (send_content_length > 0 && send_content) {
1489  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1490  avpriv_report_missing_feature(s, "Tunneling of RTSP requests with content data");
1491  return AVERROR_PATCHWELCOME;
1492  }
1493  ffurl_write(rt->rtsp_hd_out, send_content, send_content_length);
1494  }
1496 
1497  return 0;
1498 }
1499 
1501  const char *method, const char *url,
1502  const char *headers,
1503  const unsigned char *send_content,
1504  int send_content_length)
1505 {
1506  RTSPState *rt = s->priv_data;
1507  int ret = ff_rtsp_send_cmd_with_content_async(s, method, url, headers,
1508  send_content, send_content_length);
1509  if (ret < 0)
1510  return ret;
1511 
1512  rt->stored_msg.expected_seq = rt->seq;
1513  av_freep(&rt->stored_msg.header);
1514  av_freep(&rt->stored_msg.body);
1515  return 0;
1516 }
1517 
1518 int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method,
1519  const char *url, const char *headers)
1520 {
1521  return ff_rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
1522 }
1523 
1524 int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url,
1525  const char *headers, RTSPMessageHeader *reply,
1526  unsigned char **content_ptr)
1527 {
1528  return ff_rtsp_send_cmd_with_content(s, method, url, headers, reply,
1529  content_ptr, NULL, 0);
1530 }
1531 
1533  const char *method, const char *url,
1534  const char *header,
1535  RTSPMessageHeader *reply,
1536  unsigned char **content_ptr,
1537  const unsigned char *send_content,
1538  int send_content_length)
1539 {
1540  RTSPState *rt = s->priv_data;
1541  HTTPAuthType cur_auth_type;
1542  int ret, attempts = 0;
1543 
1544 retry:
1545  cur_auth_type = rt->auth_state.auth_type;
1546  if ((ret = ff_rtsp_send_cmd_with_content_async(s, method, url, header,
1547  send_content,
1548  send_content_length)) < 0)
1549  return ret;
1550 
1551  if ((ret = ff_rtsp_read_reply(s, reply, content_ptr, 0, method) ) < 0)
1552  return ret;
1553  attempts++;
1554 
1555  if (reply->status_code == 401 &&
1556  (cur_auth_type == HTTP_AUTH_NONE || rt->auth_state.stale) &&
1557  rt->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2)
1558  goto retry;
1559 
1560  if (reply->status_code > 400){
1561  av_log(s, AV_LOG_ERROR, "method %s failed: %d (%s)\n",
1562  method,
1563  reply->status_code,
1564  reply->reason);
1565  av_log(s, AV_LOG_DEBUG, "%s\n", rt->last_reply);
1566  }
1567 
1568  return 0;
1569 }
1570 
1572  unsigned char **content_ptr)
1573 {
1574  RTSPState *rt = s->priv_data;
1575  if (rt->stored_msg.header == NULL) {
1576  if (rt->stored_msg.expected_seq == -1)
1577  return AVERROR(EINVAL); // Reply to be stored was never requested
1578 
1579  // Reply pending, tell caller to try again later
1580  return AVERROR(EAGAIN);
1581  }
1582 
1583  if (reply)
1584  *reply = rt->stored_msg.header;
1585  else
1586  av_free(rt->stored_msg.header);
1587 
1588  if (content_ptr)
1589  *content_ptr = rt->stored_msg.body;
1590  else
1591  av_free(rt->stored_msg.body);
1592 
1593  rt->stored_msg.header = NULL;
1594  rt->stored_msg.body = NULL;
1595  return 0;
1596 }
1597 
1598 int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
1599  int lower_transport, const char *real_challenge)
1600 {
1601  RTSPState *rt = s->priv_data;
1602  int rtx = 0, j, i, err, interleave = 0, port_off = 0;
1603  RTSPStream *rtsp_st;
1604  RTSPMessageHeader reply1, *reply = &reply1;
1605  char cmd[MAX_URL_SIZE];
1606  const char *trans_pref;
1607 
1608  memset(&reply1, 0, sizeof(reply1));
1609 
1610  if (rt->transport == RTSP_TRANSPORT_RDT)
1611  trans_pref = "x-pn-tng";
1612  else if (rt->transport == RTSP_TRANSPORT_RAW)
1613  trans_pref = "RAW/RAW";
1614  else
1615  trans_pref = "RTP/AVP";
1616 
1617  /* default timeout: 1 minute */
1618  rt->timeout = 60;
1619 
1620  /* Choose a random starting offset within the first half of the
1621  * port range, to allow for a number of ports to try even if the offset
1622  * happens to be at the end of the random range. */
1623  if (rt->rtp_port_max - rt->rtp_port_min >= 4) {
1624  port_off = av_get_random_seed() % ((rt->rtp_port_max - rt->rtp_port_min)/2);
1625  /* even random offset */
1626  port_off -= port_off & 0x01;
1627  }
1628 
1629  for (j = rt->rtp_port_min + port_off, i = 0; i < rt->nb_rtsp_streams; ++i) {
1630  char transport[MAX_URL_SIZE];
1631 
1632  /*
1633  * WMS serves all UDP data over a single connection, the RTX, which
1634  * isn't necessarily the first in the SDP but has to be the first
1635  * to be set up, else the second/third SETUP will fail with a 461.
1636  */
1637  if (lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
1638  rt->server_type == RTSP_SERVER_WMS) {
1639  if (i == 0) {
1640  /* rtx first */
1641  for (rtx = 0; rtx < rt->nb_rtsp_streams; rtx++) {
1642  int len = strlen(rt->rtsp_streams[rtx]->control_url);
1643  if (len >= 4 &&
1644  !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4,
1645  "/rtx"))
1646  break;
1647  }
1648  if (rtx == rt->nb_rtsp_streams)
1649  return -1; /* no RTX found */
1650  rtsp_st = rt->rtsp_streams[rtx];
1651  } else
1652  rtsp_st = rt->rtsp_streams[i > rtx ? i : i - 1];
1653  } else
1654  rtsp_st = rt->rtsp_streams[i];
1655 
1656  /* RTP/UDP */
1657  if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
1658  char buf[256];
1659 
1660  if (rt->server_type == RTSP_SERVER_WMS && i > 1) {
1661  port = reply->transports[0].client_port_min;
1662  goto have_port;
1663  }
1664 
1665  /* first try in specified port range */
1666  while (j + 1 <= rt->rtp_port_max) {
1667  AVDictionary *opts = map_to_opts(rt);
1668 
1669  ff_url_join(buf, sizeof(buf), "rtp", NULL, host, -1,
1670  "?localrtpport=%d", j);
1671  /* we will use two ports per rtp stream (rtp and rtcp) */
1672  j += 2;
1674  &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);
1675 
1676  av_dict_free(&opts);
1677 
1678  if (!err)
1679  goto rtp_opened;
1680  }
1681  av_log(s, AV_LOG_ERROR, "Unable to open an input RTP port\n");
1682  err = AVERROR(EIO);
1683  goto fail;
1684 
1685  rtp_opened:
1686  port = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
1687  have_port:
1688  av_strlcpy(transport, trans_pref, sizeof(transport));
1689  av_strlcat(transport,
1690  rt->server_type == RTSP_SERVER_SATIP ? ";" : "/UDP;",
1691  sizeof(transport));
1692  if (rt->server_type != RTSP_SERVER_REAL)
1693  av_strlcat(transport, "unicast;", sizeof(transport));
1694  av_strlcatf(transport, sizeof(transport),
1695  "client_port=%d", port);
1696  if (rt->transport == RTSP_TRANSPORT_RTP &&
1697  !(rt->server_type == RTSP_SERVER_WMS && i > 0))
1698  av_strlcatf(transport, sizeof(transport), "-%d", port + 1);
1699  }
1700 
1701  /* RTP/TCP */
1702  else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
1703  /* For WMS streams, the application streams are only used for
1704  * UDP. When trying to set it up for TCP streams, the server
1705  * will return an error. Therefore, we skip those streams. */
1706  if (rt->server_type == RTSP_SERVER_WMS &&
1707  (rtsp_st->stream_index < 0 ||
1708  s->streams[rtsp_st->stream_index]->codecpar->codec_type ==
1710  continue;
1711  snprintf(transport, sizeof(transport) - 1,
1712  "%s/TCP;", trans_pref);
1713  if (rt->transport != RTSP_TRANSPORT_RDT)
1714  av_strlcat(transport, "unicast;", sizeof(transport));
1715  av_strlcatf(transport, sizeof(transport),
1716  "interleaved=%d-%d",
1717  interleave, interleave + 1);
1718  interleave += 2;
1719  }
1720 
1721  else if (lower_transport == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) {
1722  snprintf(transport, sizeof(transport) - 1,
1723  "%s/UDP;multicast", trans_pref);
1724  } else {
1725  err = AVERROR(EINVAL);
1726  goto fail; // transport would be uninitialized
1727  }
1728 
1729  if (s->oformat) {
1730  av_strlcat(transport, ";mode=record", sizeof(transport));
1731  } else if (rt->server_type == RTSP_SERVER_REAL ||
1733  av_strlcat(transport, ";mode=play", sizeof(transport));
1734  snprintf(cmd, sizeof(cmd),
1735  "Transport: %s\r\n",
1736  transport);
1737  if (rt->accept_dynamic_rate)
1738  av_strlcat(cmd, "x-Dynamic-Rate: 0\r\n", sizeof(cmd));
1739  if (CONFIG_RTPDEC && i == 0 && rt->server_type == RTSP_SERVER_REAL) {
1740  char real_res[41], real_csum[9];
1741  ff_rdt_calc_response_and_checksum(real_res, real_csum,
1742  real_challenge);
1743  av_strlcatf(cmd, sizeof(cmd),
1744  "If-Match: %s\r\n"
1745  "RealChallenge2: %s, sd=%s\r\n",
1746  rt->session_id, real_res, real_csum);
1747  }
1748  ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL);
1749  if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) {
1750  err = 1;
1751  goto fail;
1752  } else if (reply->status_code != RTSP_STATUS_OK ||
1753  reply->nb_transports != 1) {
1755  goto fail;
1756  }
1757 
1758  if (rt->server_type == RTSP_SERVER_SATIP && reply->stream_id[0]) {
1759  char proto[128], host[128], path[512], auth[128];
1760  int port;
1761  av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
1762  &port, path, sizeof(path), rt->control_uri);
1763  ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL, host,
1764  port, "/stream=%s", reply->stream_id);
1765  }
1766 
1767  /* XXX: same protocol for all streams is required */
1768  if (i > 0) {
1769  if (reply->transports[0].lower_transport != rt->lower_transport ||
1770  reply->transports[0].transport != rt->transport) {
1771  err = AVERROR_INVALIDDATA;
1772  goto fail;
1773  }
1774  } else {
1775  rt->lower_transport = reply->transports[0].lower_transport;
1776  rt->transport = reply->transports[0].transport;
1777  }
1778 
1779  /* Fail if the server responded with another lower transport mode
1780  * than what we requested. */
1781  if (reply->transports[0].lower_transport != lower_transport) {
1782  av_log(s, AV_LOG_ERROR, "Nonmatching transport in server reply\n");
1783  err = AVERROR_INVALIDDATA;
1784  goto fail;
1785  }
1786 
1787  switch(reply->transports[0].lower_transport) {
1789  rtsp_st->interleaved_min = reply->transports[0].interleaved_min;
1790  rtsp_st->interleaved_max = reply->transports[0].interleaved_max;
1791  break;
1792 
1793  case RTSP_LOWER_TRANSPORT_UDP: {
1794  char url[MAX_URL_SIZE], options[30] = "";
1795  const char *peer = host;
1796 
1797  if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
1798  av_strlcpy(options, "?connect=1", sizeof(options));
1799  /* Use source address if specified */
1800  if (reply->transports[0].source[0])
1801  peer = reply->transports[0].source;
1802  ff_url_join(url, sizeof(url), "rtp", NULL, peer,
1803  reply->transports[0].server_port_min, "%s", options);
1804  if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
1805  ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
1806  err = AVERROR_INVALIDDATA;
1807  goto fail;
1808  }
1809  break;
1810  }
1812  char url[MAX_URL_SIZE], namebuf[50], optbuf[20] = "";
1813  struct sockaddr_storage addr;
1814  int port, ttl;
1815  AVDictionary *opts = map_to_opts(rt);
1816 
1817  if (reply->transports[0].destination.ss_family) {
1818  addr = reply->transports[0].destination;
1819  port = reply->transports[0].port_min;
1820  ttl = reply->transports[0].ttl;
1821  } else {
1822  addr = rtsp_st->sdp_ip;
1823  port = rtsp_st->sdp_port;
1824  ttl = rtsp_st->sdp_ttl;
1825  }
1826  if (ttl > 0)
1827  snprintf(optbuf, sizeof(optbuf), "?ttl=%d", ttl);
1828  getnameinfo((struct sockaddr*) &addr, sizeof(addr),
1829  namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
1830  ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
1831  port, "%s", optbuf);
1833  &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);
1834  av_dict_free(&opts);
1835 
1836  if (err < 0) {
1837  err = AVERROR_INVALIDDATA;
1838  goto fail;
1839  }
1840  break;
1841  }
1842  }
1843 
1844  if ((err = ff_rtsp_open_transport_ctx(s, rtsp_st)))
1845  goto fail;
1846  }
1847 
1848  if (rt->nb_rtsp_streams && reply->timeout > 0)
1849  rt->timeout = reply->timeout;
1850 
1851  if (rt->server_type == RTSP_SERVER_REAL)
1852  rt->need_subscription = 1;
1853 
1854  return 0;
1855 
1856 fail:
1857  ff_rtsp_undo_setup(s, 0);
1858  return err;
1859 }
1860 
1862 {
1863  RTSPState *rt = s->priv_data;
1864  if (rt->rtsp_hd_out != rt->rtsp_hd)
1865  ffurl_closep(&rt->rtsp_hd_out);
1866  rt->rtsp_hd_out = NULL;
1867  ffurl_closep(&rt->rtsp_hd);
1868 }
1869 
1871 {
1872  RTSPState *rt = s->priv_data;
1873  char proto[128], host[1024], path[2048];
1874  char tcpname[1024], cmd[MAX_URL_SIZE], auth[128];
1875  const char *lower_rtsp_proto = "tcp";
1876  int port, err, tcp_fd;
1877  RTSPMessageHeader reply1, *reply = &reply1;
1878  int lower_transport_mask = 0;
1879  int default_port = RTSP_DEFAULT_PORT;
1880  int https_tunnel = 0;
1881  char real_challenge[64] = "";
1882  struct sockaddr_storage peer;
1883  socklen_t peer_len = sizeof(peer);
1884 
1885  rt->stored_msg.expected_seq = -1;
1886  if (rt->rtp_port_max < rt->rtp_port_min) {
1887  av_log(s, AV_LOG_ERROR, "Invalid UDP port range, max port %d less "
1888  "than min port %d\n", rt->rtp_port_max,
1889  rt->rtp_port_min);
1890  return AVERROR(EINVAL);
1891  }
1892 
1893  if (!ff_network_init())
1894  return AVERROR(EIO);
1895 
1896  if (s->max_delay < 0) /* Not set by the caller */
1897  s->max_delay = s->iformat ? DEFAULT_REORDERING_DELAY : 0;
1898 
1901  (1 << RTSP_LOWER_TRANSPORT_HTTPS))) {
1902  https_tunnel = !!(rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_HTTPS));
1905  }
1906  /* Only pass through valid flags from here */
1908 
1909 redirect:
1910  memset(&reply1, 0, sizeof(reply1));
1911  /* extract hostname and port */
1912  av_url_split(proto, sizeof(proto), auth, sizeof(auth),
1913  host, sizeof(host), &port, path, sizeof(path), s->url);
1914 
1915  if (!strcmp(proto, "rtsps")) {
1916  lower_rtsp_proto = "tls";
1917  default_port = RTSPS_DEFAULT_PORT;
1919  } else if (!strcmp(proto, "satip")) {
1920  av_strlcpy(proto, "rtsp", sizeof(proto));
1922  }
1923 
1924  if (*auth) {
1925  av_strlcpy(rt->auth, auth, sizeof(rt->auth));
1926  }
1927  if (port < 0)
1928  port = default_port;
1929 
1930  lower_transport_mask = rt->lower_transport_mask;
1931 
1932  if (!lower_transport_mask)
1933  lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
1934 
1935  if (s->oformat) {
1936  /* Only UDP or TCP - UDP multicast isn't supported. */
1937  lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_UDP) |
1938  (1 << RTSP_LOWER_TRANSPORT_TCP);
1939  if (!lower_transport_mask || rt->control_transport == RTSP_MODE_TUNNEL) {
1940  av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, "
1941  "only UDP and TCP are supported for output.\n");
1942  err = AVERROR(EINVAL);
1943  goto fail;
1944  }
1945  }
1946 
1947  /* Construct the URI used in request; this is similar to s->url,
1948  * but with authentication credentials removed and RTSP specific options
1949  * stripped out. */
1950  ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL,
1951  host, port, "%s", path);
1952 
1953  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1954  /* set up initial handshake for tunneling */
1955  char httpname[1024];
1956  char sessioncookie[17];
1957  char headers[1024];
1959 
1960  av_dict_set_int(&options, "timeout", rt->stimeout, 0);
1961  if (https_tunnel) {
1962  int ret = copy_tls_opts_dict(rt, &options);
1963  if (ret < 0) {
1965  err = ret;
1966  goto fail;
1967  }
1968  }
1969 
1970  ff_url_join(httpname, sizeof(httpname), https_tunnel ? "https" : "http", auth, host, port, "%s", path);
1971  snprintf(sessioncookie, sizeof(sessioncookie), "%08x%08x",
1973 
1974  /* GET requests */
1975  if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_FLAG_READ,
1976  &s->interrupt_callback) < 0) {
1978  err = AVERROR(EIO);
1979  goto fail;
1980  }
1981 
1982  /* generate GET headers */
1983  snprintf(headers, sizeof(headers),
1984  "x-sessioncookie: %s\r\n"
1985  "Accept: application/x-rtsp-tunnelled\r\n"
1986  "Pragma: no-cache\r\n"
1987  "Cache-Control: no-cache\r\n",
1988  sessioncookie);
1989  av_opt_set(rt->rtsp_hd->priv_data, "headers", headers, 0);
1990 
1991  if (!rt->rtsp_hd->protocol_whitelist && s->protocol_whitelist) {
1992  rt->rtsp_hd->protocol_whitelist = av_strdup(s->protocol_whitelist);
1993  if (!rt->rtsp_hd->protocol_whitelist) {
1995  err = AVERROR(ENOMEM);
1996  goto fail;
1997  }
1998  }
1999 
2000  /* complete the connection */
2001  if (ffurl_connect(rt->rtsp_hd, &options)) {
2003  err = AVERROR(EIO);
2004  goto fail;
2005  }
2006 
2007  /* POST requests */
2008  if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_FLAG_WRITE,
2009  &s->interrupt_callback) < 0 ) {
2011  err = AVERROR(EIO);
2012  goto fail;
2013  }
2014 
2015  /* generate POST headers */
2016  snprintf(headers, sizeof(headers),
2017  "x-sessioncookie: %s\r\n"
2018  "Content-Type: application/x-rtsp-tunnelled\r\n"
2019  "Pragma: no-cache\r\n"
2020  "Cache-Control: no-cache\r\n"
2021  "Content-Length: 32767\r\n"
2022  "Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n",
2023  sessioncookie);
2024  av_opt_set(rt->rtsp_hd_out->priv_data, "headers", headers, 0);
2025  av_opt_set(rt->rtsp_hd_out->priv_data, "chunked_post", "0", 0);
2026  av_opt_set(rt->rtsp_hd_out->priv_data, "send_expect_100", "0", 0);
2027 
2028  /* Initialize the authentication state for the POST session. The HTTP
2029  * protocol implementation doesn't properly handle multi-pass
2030  * authentication for POST requests, since it would require one of
2031  * the following:
2032  * - implementing Expect: 100-continue, which many HTTP servers
2033  * don't support anyway, even less the RTSP servers that do HTTP
2034  * tunneling
2035  * - sending the whole POST data until getting a 401 reply specifying
2036  * what authentication method to use, then resending all that data
2037  * - waiting for potential 401 replies directly after sending the
2038  * POST header (waiting for some unspecified time)
2039  * Therefore, we copy the full auth state, which works for both basic
2040  * and digest. (For digest, we would have to synchronize the nonce
2041  * count variable between the two sessions, if we'd do more requests
2042  * with the original session, though.)
2043  */
2045 
2046  /* complete the connection */
2047  if (ffurl_connect(rt->rtsp_hd_out, &options)) {
2049  err = AVERROR(EIO);
2050  goto fail;
2051  }
2053  } else {
2054  int ret;
2055  /* open the tcp connection */
2056  AVDictionary *proto_opts = NULL;
2057  if (strcmp("tls", lower_rtsp_proto) == 0) {
2058  ret = copy_tls_opts_dict(rt, &proto_opts);
2059  if (ret < 0) {
2060  av_dict_free(&proto_opts);
2061  err = ret;
2062  goto fail;
2063  }
2064  }
2065 
2066  ff_url_join(tcpname, sizeof(tcpname), lower_rtsp_proto, NULL,
2067  host, port,
2068  "?timeout=%"PRId64, rt->stimeout);
2069  if ((ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
2070  &s->interrupt_callback, &proto_opts, s->protocol_whitelist, s->protocol_blacklist, NULL)) < 0) {
2071  av_dict_free(&proto_opts);
2072  err = ret;
2073  goto fail;
2074  }
2075  av_dict_free(&proto_opts);
2076  rt->rtsp_hd_out = rt->rtsp_hd;
2077  }
2078  rt->seq = 0;
2079 
2080  tcp_fd = ffurl_get_file_handle(rt->rtsp_hd);
2081  if (tcp_fd < 0) {
2082  err = tcp_fd;
2083  goto fail;
2084  }
2085  if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) {
2086  getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host),
2087  NULL, 0, NI_NUMERICHOST);
2088  }
2089 
2090  /* request options supported by the server; this also detects server
2091  * type */
2092  if (rt->server_type != RTSP_SERVER_SATIP)
2094  for (;;) {
2095  cmd[0] = 0;
2096  if (rt->server_type == RTSP_SERVER_REAL)
2097  av_strlcat(cmd,
2098  /*
2099  * The following entries are required for proper
2100  * streaming from a Realmedia server. They are
2101  * interdependent in some way although we currently
2102  * don't quite understand how. Values were copied
2103  * from mplayer SVN r23589.
2104  * ClientChallenge is a 16-byte ID in hex
2105  * CompanyID is a 16-byte ID in base64
2106  */
2107  "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
2108  "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
2109  "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
2110  "GUID: 00000000-0000-0000-0000-000000000000\r\n",
2111  sizeof(cmd));
2112  ff_rtsp_send_cmd(s, "OPTIONS", rt->control_uri, cmd, reply, NULL);
2113  if (reply->status_code != RTSP_STATUS_OK) {
2115  goto fail;
2116  }
2117 
2118  /* detect server type if not standard-compliant RTP */
2119  if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
2121  continue;
2122  } else if (!av_strncasecmp(reply->server, "WMServer/", 9)) {
2124  } else if (rt->server_type == RTSP_SERVER_REAL)
2125  strcpy(real_challenge, reply->real_challenge);
2126  break;
2127  }
2128 
2129 #if CONFIG_RTSP_DEMUXER
2130  if (s->iformat) {
2131  if (rt->server_type == RTSP_SERVER_SATIP)
2132  err = init_satip_stream(s);
2133  else
2134  err = ff_rtsp_setup_input_streams(s, reply);
2135  } else
2136 #endif
2137  if (CONFIG_RTSP_MUXER)
2138  err = ff_rtsp_setup_output_streams(s, host);
2139  else
2140  av_unreachable("Either muxer or demuxer must be enabled");
2141  if (err)
2142  goto fail;
2143 
2144  do {
2145  int lower_transport = ff_log2_tab[lower_transport_mask &
2146  ~(lower_transport_mask - 1)];
2147 
2148  if ((lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP))
2149  && (rt->rtsp_flags & RTSP_FLAG_PREFER_TCP))
2150  lower_transport = RTSP_LOWER_TRANSPORT_TCP;
2151 
2152  err = ff_rtsp_make_setup_request(s, host, port, lower_transport,
2153  rt->server_type == RTSP_SERVER_REAL ?
2154  real_challenge : NULL);
2155  if (err < 0)
2156  goto fail;
2157  lower_transport_mask &= ~(1 << lower_transport);
2158  if (lower_transport_mask == 0 && err == 1) {
2159  err = AVERROR(EPROTONOSUPPORT);
2160  goto fail;
2161  }
2162  } while (err);
2163 
2164  rt->lower_transport_mask = lower_transport_mask;
2165  av_strlcpy(rt->real_challenge, real_challenge, sizeof(rt->real_challenge));
2166  rt->state = RTSP_STATE_IDLE;
2167  rt->seek_timestamp = 0; /* default is to start stream at position zero */
2168  return 0;
2169  fail:
2172  if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) {
2173  char *new_url = av_strdup(reply->location);
2174  if (!new_url) {
2175  err = AVERROR(ENOMEM);
2176  goto fail2;
2177  }
2178  ff_format_set_url(s, new_url);
2179  rt->session_id[0] = '\0';
2180  av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n",
2181  reply->status_code,
2182  s->url);
2183  goto redirect;
2184  }
2185  fail2:
2186  ff_network_close();
2187  return err;
2188 }
2189 #endif /* CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER */
2190 
2191 #if CONFIG_RTPDEC
2192 #if CONFIG_RTSP_DEMUXER
2193 static int parse_rtsp_message(AVFormatContext *s)
2194 {
2195  RTSPState *rt = s->priv_data;
2196  int ret;
2197 
2198  if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
2199  if (rt->state == RTSP_STATE_STREAMING) {
2201  } else
2202  return AVERROR_EOF;
2203  } else {
2204  RTSPMessageHeader reply;
2205  ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL);
2206  if (ret < 0)
2207  return ret;
2208  /* XXX: parse message */
2209  if (rt->state != RTSP_STATE_STREAMING)
2210  return 0;
2211  }
2212 
2213  return 0;
2214 }
2215 #endif
2216 
2217 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
2218  uint8_t *buf, int buf_size, int64_t wait_end)
2219 {
2220  RTSPState *rt = s->priv_data;
2221  RTSPStream *rtsp_st;
2222  int n, i, ret;
2223  struct pollfd *p = rt->p;
2224  int *fds = NULL, fdsnum, fdsidx;
2225  int64_t runs = rt->stimeout / POLLING_TIME / 1000;
2226 
2227  if (!p) {
2228  p = rt->p = av_malloc_array(2 * rt->nb_rtsp_streams + 1, sizeof(*p));
2229  if (!p)
2230  return AVERROR(ENOMEM);
2231 
2232  if (rt->rtsp_hd) {
2233  p[rt->max_p].fd = ffurl_get_file_handle(rt->rtsp_hd);
2234  p[rt->max_p++].events = POLLIN;
2235  }
2236  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2237  rtsp_st = rt->rtsp_streams[i];
2238  if (rtsp_st->rtp_handle) {
2240  &fds, &fdsnum)) {
2241  av_log(s, AV_LOG_ERROR, "Unable to recover rtp ports\n");
2242  return ret;
2243  }
2244  if (fdsnum != 2) {
2246  "Number of fds %d not supported\n", fdsnum);
2247  av_freep(&fds);
2248  return AVERROR_INVALIDDATA;
2249  }
2250  for (fdsidx = 0; fdsidx < fdsnum; fdsidx++) {
2251  p[rt->max_p].fd = fds[fdsidx];
2252  p[rt->max_p++].events = POLLIN;
2253  }
2254  av_freep(&fds);
2255  }
2256  }
2257  }
2258 
2259  for (;;) {
2260  if (ff_check_interrupt(&s->interrupt_callback))
2261  return AVERROR_EXIT;
2262  if (wait_end && wait_end - av_gettime_relative() < 0)
2263  return AVERROR(EAGAIN);
2264  n = poll(p, rt->max_p, POLLING_TIME);
2265  if (n > 0) {
2266  int j = rt->rtsp_hd ? 1 : 0;
2267  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2268  rtsp_st = rt->rtsp_streams[i];
2269  if (rtsp_st->rtp_handle) {
2270  if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) {
2271  ret = ffurl_read(rtsp_st->rtp_handle, buf, buf_size);
2272  if (ret > 0) {
2273  *prtsp_st = rtsp_st;
2274  return ret;
2275  }
2276  }
2277  j+=2;
2278  }
2279  }
2280 #if CONFIG_RTSP_DEMUXER
2281  if (rt->rtsp_hd && p[0].revents & POLLIN) {
2282  if ((ret = parse_rtsp_message(s)) < 0) {
2283  return ret;
2284  }
2285  }
2286 #endif
2287  } else if (n == 0 && rt->stimeout > 0 && --runs <= 0) {
2288  return AVERROR(ETIMEDOUT);
2289  } else if (n < 0 && errno != EINTR)
2290  return AVERROR(errno);
2291  }
2292 }
2293 
2294 static int pick_stream(AVFormatContext *s, RTSPStream **rtsp_st,
2295  const uint8_t *buf, int len)
2296 {
2297  RTSPState *rt = s->priv_data;
2298  int i;
2299  if (len < 0)
2300  return len;
2301  if (rt->nb_rtsp_streams == 1) {
2302  *rtsp_st = rt->rtsp_streams[0];
2303  return len;
2304  }
2305  if (len >= 8 && rt->transport == RTSP_TRANSPORT_RTP) {
2306  if (RTP_PT_IS_RTCP(rt->recvbuf[1])) {
2307  int no_ssrc = 0;
2308  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2309  RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
2310  if (!rtpctx)
2311  continue;
2312  if (rtpctx->ssrc == AV_RB32(&buf[4])) {
2313  *rtsp_st = rt->rtsp_streams[i];
2314  return len;
2315  }
2316  if (!rtpctx->ssrc)
2317  no_ssrc = 1;
2318  }
2319  if (no_ssrc) {
2321  "Unable to pick stream for packet - SSRC not known for "
2322  "all streams\n");
2323  return AVERROR(EAGAIN);
2324  }
2325  } else {
2326  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2327  if ((buf[1] & 0x7f) == rt->rtsp_streams[i]->sdp_payload_type) {
2328  *rtsp_st = rt->rtsp_streams[i];
2329  return len;
2330  }
2331  }
2332  }
2333  }
2334  av_log(s, AV_LOG_WARNING, "Unable to pick stream for packet\n");
2335  return AVERROR(EAGAIN);
2336 }
2337 
2338 static int read_packet(AVFormatContext *s,
2339  RTSPStream **rtsp_st, RTSPStream *first_queue_st,
2340  int64_t wait_end)
2341 {
2342  RTSPState *rt = s->priv_data;
2343  int len;
2344 
2345  switch(rt->lower_transport) {
2346  default:
2347 #if CONFIG_RTSP_DEMUXER
2349  len = ff_rtsp_tcp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE);
2350  break;
2351 #endif
2354  len = udp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
2355  if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
2356  ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, (*rtsp_st)->rtp_handle, NULL, len);
2357  break;
2359  if (first_queue_st && rt->transport == RTSP_TRANSPORT_RTP &&
2360  wait_end && wait_end < av_gettime_relative())
2361  len = AVERROR(EAGAIN);
2362  else
2364  len = pick_stream(s, rtsp_st, rt->recvbuf, len);
2365  if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
2366  ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, NULL, s->pb, len);
2367  break;
2368  }
2369 
2370  if (len == 0)
2371  return AVERROR_EOF;
2372 
2373  return len;
2374 }
2375 
2377 {
2378  RTSPState *rt = s->priv_data;
2379  int ret, len;
2380  RTSPStream *rtsp_st, *first_queue_st = NULL;
2381  int64_t wait_end = 0;
2382 
2383  if (rt->nb_byes == rt->nb_rtsp_streams)
2384  return AVERROR_EOF;
2385 
2386  /* get next frames from the same RTP packet */
2387  if (rt->cur_transport_priv) {
2388  if (rt->transport == RTSP_TRANSPORT_RDT) {
2390  } else if (rt->transport == RTSP_TRANSPORT_RTP) {
2392  } else if (CONFIG_RTPDEC && rt->ts) {
2394  if (ret >= 0) {
2395  rt->recvbuf_pos += ret;
2396  ret = rt->recvbuf_pos < rt->recvbuf_len;
2397  }
2398  } else
2399  ret = -1;
2400  if (ret == 0) {
2401  rt->cur_transport_priv = NULL;
2402  return 0;
2403  } else if (ret == 1) {
2404  return 0;
2405  } else
2406  rt->cur_transport_priv = NULL;
2407  }
2408 
2409 redo:
2410  if (rt->transport == RTSP_TRANSPORT_RTP) {
2411  int i;
2412  int64_t first_queue_time = 0;
2413  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2414  RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
2415  int64_t queue_time;
2416  if (!rtpctx)
2417  continue;
2418  queue_time = ff_rtp_queued_packet_time(rtpctx);
2419  if (queue_time && (queue_time - first_queue_time < 0 ||
2420  !first_queue_time)) {
2421  first_queue_time = queue_time;
2422  first_queue_st = rt->rtsp_streams[i];
2423  }
2424  }
2425  if (first_queue_time) {
2426  wait_end = first_queue_time + s->max_delay;
2427  } else {
2428  wait_end = 0;
2429  first_queue_st = NULL;
2430  }
2431  }
2432 
2433  /* read next RTP packet */
2434  if (!rt->recvbuf) {
2436  if (!rt->recvbuf)
2437  return AVERROR(ENOMEM);
2438  }
2439 
2440  len = read_packet(s, &rtsp_st, first_queue_st, wait_end);
2441  if (len == AVERROR(EAGAIN) && first_queue_st &&
2442  rt->transport == RTSP_TRANSPORT_RTP) {
2444  "max delay reached. need to consume packet\n");
2445  rtsp_st = first_queue_st;
2446  ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
2447  goto end;
2448  }
2449  if (len < 0)
2450  return len;
2451 
2452  if (rt->transport == RTSP_TRANSPORT_RDT) {
2453  ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
2454  } else if (rt->transport == RTSP_TRANSPORT_RTP) {
2455  ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
2456  if (rtsp_st->feedback) {
2457  AVIOContext *pb = NULL;
2459  pb = s->pb;
2460  ff_rtp_send_rtcp_feedback(rtsp_st->transport_priv, rtsp_st->rtp_handle, pb);
2461  }
2462  if (ret < 0) {
2463  /* Either bad packet, or a RTCP packet. Check if the
2464  * first_rtcp_ntp_time field was initialized. */
2465  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
2466  if (rtpctx->first_rtcp_ntp_time != AV_NOPTS_VALUE) {
2467  /* first_rtcp_ntp_time has been initialized for this stream,
2468  * copy the same value to all other uninitialized streams,
2469  * in order to map their timestamp origin to the same ntp time
2470  * as this one. */
2471  int i;
2472  AVStream *st = NULL;
2473  if (rtsp_st->stream_index >= 0)
2474  st = s->streams[rtsp_st->stream_index];
2475  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2476  RTPDemuxContext *rtpctx2 = rt->rtsp_streams[i]->transport_priv;
2477  AVStream *st2 = NULL;
2478  if (rt->rtsp_streams[i]->stream_index >= 0)
2479  st2 = s->streams[rt->rtsp_streams[i]->stream_index];
2480  if (rtpctx2 && st && st2 &&
2481  rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
2482  rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_time;
2483  rtpctx2->rtcp_ts_offset = av_rescale_q(
2484  rtpctx->rtcp_ts_offset, st->time_base,
2485  st2->time_base);
2486  }
2487  }
2488  // Make real NTP start time available in AVFormatContext
2489  if (s->start_time_realtime == AV_NOPTS_VALUE) {
2490  s->start_time_realtime = ff_parse_ntp_time(rtpctx->first_rtcp_ntp_time) - NTP_OFFSET_US;
2491  if (rtpctx->st) {
2492  s->start_time_realtime -=
2493  av_rescale_q (rtpctx->rtcp_ts_offset, rtpctx->st->time_base, AV_TIME_BASE_Q);
2494  }
2495  }
2496  }
2497  if (ret == -RTCP_BYE) {
2498  rt->nb_byes++;
2499 
2500  av_log(s, AV_LOG_DEBUG, "Received BYE for stream %d (%d/%d)\n",
2501  rtsp_st->stream_index, rt->nb_byes, rt->nb_rtsp_streams);
2502 
2503  if (rt->nb_byes == rt->nb_rtsp_streams)
2504  return AVERROR_EOF;
2505  }
2506  }
2507  } else if (CONFIG_RTPDEC && rt->ts) {
2509  if (ret >= 0) {
2510  if (ret < len) {
2511  rt->recvbuf_len = len;
2512  rt->recvbuf_pos = ret;
2513  rt->cur_transport_priv = rt->ts;
2514  return 1;
2515  } else {
2516  ret = 0;
2517  }
2518  }
2519  } else {
2520  return AVERROR_INVALIDDATA;
2521  }
2522 end:
2523  if (ret < 0)
2524  goto redo;
2525  if (ret == 1)
2526  /* more packets may follow, so we save the RTP context */
2527  rt->cur_transport_priv = rtsp_st->transport_priv;
2528 
2529  return ret;
2530 }
2531 #endif /* CONFIG_RTPDEC */
2532 
2533 #if CONFIG_SDP_DEMUXER
2534 static int sdp_probe(const AVProbeData *p1)
2535 {
2536  const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
2537 
2538  /* we look for a line beginning "c=IN IP" */
2539  while (p < p_end && *p != '\0') {
2540  if (sizeof("c=IN IP") - 1 < p_end - p &&
2541  av_strstart(p, "c=IN IP", NULL))
2542  return AVPROBE_SCORE_EXTENSION;
2543 
2544  while (p < p_end - 1 && *p != '\n') p++;
2545  if (++p >= p_end)
2546  break;
2547  if (*p == '\r')
2548  p++;
2549  }
2550  return 0;
2551 }
2552 
2553 static void append_source_addrs(char *buf, int size, const char *name,
2554  int count, struct RTSPSource **addrs)
2555 {
2556  int i;
2557  if (!count)
2558  return;
2559  av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->addr);
2560  for (i = 1; i < count; i++)
2561  av_strlcatf(buf, size, ",%s", addrs[i]->addr);
2562 }
2563 
2564 static int sdp_read_header(AVFormatContext *s)
2565 {
2566  RTSPState *rt = s->priv_data;
2567  RTSPStream *rtsp_st;
2568  int i, err;
2569  char url[MAX_URL_SIZE];
2570  AVBPrint bp;
2571 
2572  if (!ff_network_init())
2573  return AVERROR(EIO);
2574 
2575  if (s->max_delay < 0) /* Not set by the caller */
2576  s->max_delay = DEFAULT_REORDERING_DELAY;
2577  if (rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)
2579 
2580  /* read the whole sdp file */
2582  err = avio_read_to_bprint(s->pb, &bp, INT_MAX);
2583  if (err < 0 ) {
2584  ff_network_close();
2585  av_bprint_finalize(&bp, NULL);
2586  return err;
2587  }
2588  err = ff_sdp_parse(s, bp.str);
2589  av_bprint_finalize(&bp, NULL);
2590  if (err) goto fail;
2591 
2592  /* open each RTP stream */
2593  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2594  char namebuf[50];
2595  rtsp_st = rt->rtsp_streams[i];
2596 
2597  if (!(rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)) {
2598  AVDictionary *opts = map_to_opts(rt);
2599  char buf[MAX_URL_SIZE];
2600  const char *p;
2601 
2602  err = getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip,
2603  sizeof(rtsp_st->sdp_ip),
2604  namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
2605  if (err) {
2606  av_log(s, AV_LOG_ERROR, "getnameinfo: %s\n", gai_strerror(err));
2607  err = AVERROR(EIO);
2608  av_dict_free(&opts);
2609  goto fail;
2610  }
2611  ff_url_join(url, sizeof(url), "rtp", NULL,
2612  namebuf, rtsp_st->sdp_port,
2613  "?localrtpport=%d&ttl=%d&connect=%d&write_to_source=%d",
2614  rtsp_st->sdp_port, rtsp_st->sdp_ttl,
2615  rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
2616  rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
2617 
2618  p = strchr(s->url, '?');
2619  if (p && av_find_info_tag(buf, sizeof(buf), "localaddr", p))
2620  av_strlcatf(url, sizeof(url), "&localaddr=%s", buf);
2621  else if (rt->localaddr && rt->localaddr[0])
2622  av_strlcatf(url, sizeof(url), "&localaddr=%s", rt->localaddr);
2623  append_source_addrs(url, sizeof(url), "sources",
2624  rtsp_st->nb_include_source_addrs,
2625  rtsp_st->include_source_addrs);
2626  append_source_addrs(url, sizeof(url), "block",
2627  rtsp_st->nb_exclude_source_addrs,
2628  rtsp_st->exclude_source_addrs);
2629  err = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ,
2630  &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);
2631 
2632  av_dict_free(&opts);
2633 
2634  if (err < 0) {
2635  err = AVERROR_INVALIDDATA;
2636  goto fail;
2637  }
2638  }
2639  if ((err = ff_rtsp_open_transport_ctx(s, rtsp_st)))
2640  goto fail;
2641  }
2642  return 0;
2643 fail:
2645  ff_network_close();
2646  return err;
2647 }
2648 
2649 static int sdp_read_close(AVFormatContext *s)
2650 {
2652  ff_network_close();
2653  return 0;
2654 }
2655 
2656 static const AVClass sdp_demuxer_class = {
2657  .class_name = "SDP demuxer",
2658  .item_name = av_default_item_name,
2659  .option = sdp_options,
2660  .version = LIBAVUTIL_VERSION_INT,
2661 };
2662 
2663 const FFInputFormat ff_sdp_demuxer = {
2664  .p.name = "sdp",
2665  .p.long_name = NULL_IF_CONFIG_SMALL("SDP"),
2666  .p.priv_class = &sdp_demuxer_class,
2667  .priv_data_size = sizeof(RTSPState),
2668  .read_probe = sdp_probe,
2669  .read_header = sdp_read_header,
2671  .read_close = sdp_read_close,
2672 };
2673 #endif /* CONFIG_SDP_DEMUXER */
2674 
2675 #if CONFIG_RTP_DEMUXER
2676 static int rtp_probe(const AVProbeData *p)
2677 {
2678  if (av_strstart(p->filename, "rtp:", NULL))
2679  return AVPROBE_SCORE_MAX;
2680  return 0;
2681 }
2682 
2683 static int rtp_read_header(AVFormatContext *s)
2684 {
2685  uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
2686  char host[500], filters_buf[1000];
2687  int ret, port;
2688  URLContext* in = NULL;
2689  int payload_type;
2690  AVCodecParameters *par = NULL;
2691  struct sockaddr_storage addr;
2692  FFIOContext pb;
2693  socklen_t addrlen = sizeof(addr);
2694  RTSPState *rt = s->priv_data;
2695  const char *p;
2696  AVBPrint sdp;
2697  AVDictionary *opts = NULL;
2698 
2699  if (!ff_network_init())
2700  return AVERROR(EIO);
2701 
2702  opts = map_to_opts(rt);
2704  &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);
2705  av_dict_free(&opts);
2706  if (ret)
2707  goto fail;
2708 
2709  while (1) {
2710  ret = ffurl_read(in, recvbuf, sizeof(recvbuf));
2711  if (ret == AVERROR(EAGAIN))
2712  continue;
2713  if (ret < 0)
2714  goto fail;
2715  if (ret < 12) {
2716  av_log(s, AV_LOG_WARNING, "Received too short packet\n");
2717  continue;
2718  }
2719 
2720  if ((recvbuf[0] & 0xc0) != 0x80) {
2721  av_log(s, AV_LOG_WARNING, "Unsupported RTP version packet "
2722  "received\n");
2723  continue;
2724  }
2725 
2726  if (RTP_PT_IS_RTCP(recvbuf[1]))
2727  continue;
2728 
2729  payload_type = recvbuf[1] & 0x7f;
2730  break;
2731  }
2732  getsockname(ffurl_get_file_handle(in), (struct sockaddr*) &addr, &addrlen);
2733  ffurl_closep(&in);
2734 
2735  par = avcodec_parameters_alloc();
2736  if (!par) {
2737  ret = AVERROR(ENOMEM);
2738  goto fail;
2739  }
2740 
2741  if (ff_rtp_get_codec_info(par, payload_type)) {
2742  av_log(s, AV_LOG_ERROR, "Unable to receive RTP payload type %d "
2743  "without an SDP file describing it\n",
2744  payload_type);
2746  goto fail;
2747  }
2748  if (par->codec_type != AVMEDIA_TYPE_DATA) {
2749  av_log(s, AV_LOG_WARNING, "Guessing on RTP content - if not received "
2750  "properly you need an SDP file "
2751  "describing it\n");
2752  }
2753 
2754  av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
2755  NULL, 0, s->url);
2756 
2758  av_bprintf(&sdp, "v=0\r\nc=IN IP%d %s\r\n",
2759  addr.ss_family == AF_INET ? 4 : 6, host);
2760 
2761  p = strchr(s->url, '?');
2762  if (p) {
2763  static const char filters[][2][8] = { { "sources", "incl" },
2764  { "block", "excl" } };
2765  int i;
2766  char *q;
2767  for (i = 0; i < FF_ARRAY_ELEMS(filters); i++) {
2768  if (av_find_info_tag(filters_buf, sizeof(filters_buf), filters[i][0], p)) {
2769  q = filters_buf;
2770  while ((q = strchr(q, ',')) != NULL)
2771  *q = ' ';
2772  av_bprintf(&sdp, "a=source-filter:%s IN IP%d %s %s\r\n",
2773  filters[i][1],
2774  addr.ss_family == AF_INET ? 4 : 6, host,
2775  filters_buf);
2776  }
2777  }
2778  }
2779 
2780  av_bprintf(&sdp, "m=%s %d RTP/AVP %d\r\n",
2781  par->codec_type == AVMEDIA_TYPE_DATA ? "application" :
2782  par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
2783  port, payload_type);
2784  av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp.str);
2785  if (!av_bprint_is_complete(&sdp))
2786  goto fail_nobuf;
2788 
2789  ffio_init_read_context(&pb, sdp.str, sdp.len);
2790  s->pb = &pb.pub;
2791 
2792  /* if sdp_read_header() fails then following ff_network_close() cancels out */
2793  /* ff_network_init() at the start of this function. Otherwise it cancels out */
2794  /* ff_network_init() inside sdp_read_header() */
2795  ff_network_close();
2796 
2797  rt->media_type_mask = (1 << (AVMEDIA_TYPE_SUBTITLE+1)) - 1;
2798 
2799  ret = sdp_read_header(s);
2800  s->pb = NULL;
2801  av_bprint_finalize(&sdp, NULL);
2802  return ret;
2803 
2804 fail_nobuf:
2805  ret = AVERROR(ENOMEM);
2806  av_log(s, AV_LOG_ERROR, "rtp_read_header(): not enough buffer space for sdp-headers\n");
2807  av_bprint_finalize(&sdp, NULL);
2808 fail:
2810  ffurl_closep(&in);
2811  ff_network_close();
2812  return ret;
2813 }
2814 
2815 static const AVClass rtp_demuxer_class = {
2816  .class_name = "RTP demuxer",
2817  .item_name = av_default_item_name,
2818  .option = rtp_options,
2819  .version = LIBAVUTIL_VERSION_INT,
2820 };
2821 
2822 const FFInputFormat ff_rtp_demuxer = {
2823  .p.name = "rtp",
2824  .p.long_name = NULL_IF_CONFIG_SMALL("RTP input"),
2825  .p.flags = AVFMT_NOFILE,
2826  .p.priv_class = &rtp_demuxer_class,
2827  .priv_data_size = sizeof(RTSPState),
2828  .read_probe = rtp_probe,
2829  .read_header = rtp_read_header,
2831  .read_close = sdp_read_close,
2832 };
2833 #endif /* CONFIG_RTP_DEMUXER */
ff_rtsp_read_reply
int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply, unsigned char **content_ptr, int return_on_interleaved_data, const char *method)
Read a RTSP message from the server, or prepare to read data packets if we're reading data interleave...
RTSPState::last_cmd_time
int64_t last_cmd_time
timestamp of the last RTSP command that we sent to the RTSP server.
Definition: rtsp.h:263
AVMEDIA_TYPE_SUBTITLE
@ AVMEDIA_TYPE_SUBTITLE
Definition: avutil.h:203
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:216
AV_BPRINT_SIZE_UNLIMITED
#define AV_BPRINT_SIZE_UNLIMITED
ff_rtsp_close_streams
void ff_rtsp_close_streams(AVFormatContext *s)
Close and free all streams within the RTSP (de)muxer.
Definition: rtsp.c:832
RTPDynamicProtocolHandler::init
int(* init)(AVFormatContext *s, int st_index, PayloadContext *priv_data)
Initialize dynamic protocol handler, called after the full rtpmap line is parsed, may be null.
Definition: rtpdec.h:127
name
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
LIBAVFORMAT_IDENT
#define LIBAVFORMAT_IDENT
Definition: version.h:45
RTSPState::expected_seq
int expected_seq
Sequence number of the reply to be stored -1 if we are not waiting to store any message.
Definition: rtsp.h:301
av_bprint_is_complete
static int av_bprint_is_complete(const AVBPrint *buf)
Test if the print buffer is complete (not truncated).
Definition: bprint.h:218
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
opt.h
av_find_info_tag
int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
Attempt to find a specific tag in a URL.
Definition: parseutils.c:756
RTSPStream::transport_priv
void * transport_priv
RTP/RDT parse context if input, RTP AVFormatContext if output.
Definition: rtsp.h:479
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
ff_rtsp_send_cmd_with_content
int ff_rtsp_send_cmd_with_content(AVFormatContext *s, const char *method, const char *url, const char *headers, RTSPMessageHeader *reply, unsigned char **content_ptr, const unsigned char *send_content, int send_content_length)
Send a command to the RTSP server and wait for the reply.
mpegts.h
RTPDynamicProtocolHandler::parse_sdp_a_line
int(* parse_sdp_a_line)(AVFormatContext *s, int st_index, PayloadContext *priv_data, const char *line)
Parse the a= line from the sdp field.
Definition: rtpdec.h:129
RTSPStream::rtp_handle
URLContext * rtp_handle
RTP stream handle (if UDP)
Definition: rtsp.h:478
ff_rtp_codec_id
enum AVCodecID ff_rtp_codec_id(const char *buf, enum AVMediaType codec_type)
Return the codec id for the given encoding name and codec type.
Definition: rtp.c:146
RTSPTransportField::port_max
int port_max
Definition: rtsp.h:99
ff_rtp_send_rtcp_feedback
int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd, AVIOContext *avio)
Definition: rtpdec.c:470
av_bprint_init
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
Definition: bprint.c:69
RTSP_SERVER_RTP
@ RTSP_SERVER_RTP
Standards-compliant RTP-server.
Definition: rtsp.h:214
AVCodecParameters
This struct describes the properties of an encoded stream.
Definition: codec_par.h:47
RTSPMessageHeader::status_code
enum RTSPStatusCode status_code
response code from server
Definition: rtsp.h:133
ff_rtsp_send_cmd
int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url, const char *headers, RTSPMessageHeader *reply, unsigned char **content_ptr)
Send a command to the RTSP server and wait for the reply.
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
RTSPState::control_transport
enum RTSPControlTransport control_transport
RTSP transport mode, such as plain or tunneled.
Definition: rtsp.h:361
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
avpriv_mpegts_parse_packet
int avpriv_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, const uint8_t *buf, int len)
Definition: mpegts.c:3544
AVIO_FLAG_READ_WRITE
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:619
RTSP_MODE_PLAIN
@ RTSP_MODE_PLAIN
Normal RTSP.
Definition: rtsp.h:71
parse_fmtp
static int parse_fmtp(AVFormatContext *s, AVStream *stream, PayloadContext *data, const char *attr, const char *value)
Definition: rtpdec_latm.c:133
rtpdec_formats.h
RTSP_TRANSPORT_RTP
@ RTSP_TRANSPORT_RTP
Standards-compliant RTP.
Definition: rtsp.h:60
ff_rtp_demuxer
const FFInputFormat ff_rtp_demuxer
RTSPTransportField::source
char source[INET6_ADDRSTRLEN+1]
source IP address
Definition: rtsp.h:117
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:263
RTSPMessageHeader::range_end
int64_t range_end
Definition: rtsp.h:140
int64_t
long long int64_t
Definition: coverity.c:34
sdp_options
static const AVOption sdp_options[]
Definition: rtsp.c:113
ffurl_write
static int ffurl_write(URLContext *h, const uint8_t *buf, int size)
Write size bytes from buf to the resource accessed by h.
Definition: url.h:202
RTSPState::get_parameter_supported
int get_parameter_supported
Whether the server supports the GET_PARAMETER method.
Definition: rtsp.h:390
ff_rtsp_averror
static int ff_rtsp_averror(enum RTSPStatusCode status_code, int default_averror)
Definition: rtspcodes.h:144
av_strcasecmp
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:208
RTSP_DEFAULT_AUDIO_SAMPLERATE
#define RTSP_DEFAULT_AUDIO_SAMPLERATE
Definition: rtsp.h:78
RTSPStream::nb_include_source_addrs
int nb_include_source_addrs
Number of source-specific multicast include source IP addresses (from SDP content)
Definition: rtsp.h:494
RTSPTransportField::server_port_min
int server_port_min
UDP unicast server port range; the ports to which we should connect to receive unicast UDP RTP/RTCP d...
Definition: rtsp.h:107
RTSPState::auth
char auth[128]
plaintext authorization line (username:password)
Definition: rtsp.h:281
RTSPStream::interleaved_min
int interleaved_min
interleave IDs; copies of RTSPTransportField->interleaved_min/max for the selected transport.
Definition: rtsp.h:486
ff_rtsp_read_reply_async_stored
int ff_rtsp_read_reply_async_stored(AVFormatContext *s, RTSPMessageHeader **reply, unsigned char **content_ptr)
Retrieve a previously stored RTSP reply message from the server.
rtp_options
static const AVOption rtp_options[]
Definition: rtsp.c:124
RTSPState::recvbuf_pos
int recvbuf_pos
Definition: rtsp.h:352
AVOption
AVOption.
Definition: opt.h:429
RTSP_RTP_PORT_MIN
#define RTSP_RTP_PORT_MIN
Definition: rtsp.h:79
AVStream::avg_frame_rate
AVRational avg_frame_rate
Average framerate.
Definition: avformat.h:833
RTSPTransportField::lower_transport
enum RTSPLowerTransport lower_transport
network layer transport protocol; e.g.
Definition: rtsp.h:123
RTSPState::rtp_port_min
int rtp_port_min
Minimum and maximum local UDP ports.
Definition: rtsp.h:418
AV_OPT_TYPE_DURATION
@ AV_OPT_TYPE_DURATION
Underlying C type is int64_t.
Definition: opt.h:319
RTSP_LOWER_TRANSPORT_CUSTOM
@ RTSP_LOWER_TRANSPORT_CUSTOM
Custom IO - not a public option for lower_transport_mask, but set in the SDP demuxer based on a flag.
Definition: rtsp.h:48
RTSPTransportField::interleaved_min
int interleaved_min
interleave ids, if TCP transport; each TCP/RTSP data packet starts with a '$', stream length and stre...
Definition: rtsp.h:95
RTSPTransportField::interleaved_max
int interleaved_max
Definition: rtsp.h:95
RTSPStream
Describe a single stream, as identified by a single m= line block in the SDP content.
Definition: rtsp.h:477
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:226
ff_parse_ntp_time
uint64_t ff_parse_ntp_time(uint64_t ntp_ts)
Parse the NTP time in micro seconds (since NTP epoch).
Definition: utils.c:284
ff_rtsp_send_cmd_async
int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method, const char *url, const char *headers)
Send a command to the RTSP server without waiting for the reply.
RTSPState::real_challenge
char real_challenge[64]
the "RealChallenge1:" field from the server
Definition: rtsp.h:278
mathematics.h
ff_rdt_calc_response_and_checksum
void ff_rdt_calc_response_and_checksum(char response[41], char chksum[9], const char *challenge)
Calculate the response (RealChallenge2 in the RTSP header) to the challenge (RealChallenge1 in the RT...
Definition: rdt.c:96
AVDictionary
Definition: dict.c:32
ffio_init_read_context
void ffio_init_read_context(FFIOContext *s, const uint8_t *buffer, int buffer_size)
Wrap a buffer in an AVIOContext for reading.
Definition: aviobuf.c:99
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:454
ff_network_close
void ff_network_close(void)
Definition: network.c:113
RTSPState::stored_msg
struct RTSPState::@490 stored_msg
Stored message context This is used to store the last reply marked to be stored with ff_rtsp_send_cmd...
RTSPMessageHeader::nb_transports
int nb_transports
number of items in the 'transports' variable below
Definition: rtsp.h:136
RTSP_SERVER_REAL
@ RTSP_SERVER_REAL
Realmedia-style server.
Definition: rtsp.h:215
ff_http_auth_create_response
char * ff_http_auth_create_response(HTTPAuthState *state, const char *auth, const char *path, const char *method)
Definition: httpauth.c:240
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition: channel_layout.h:329
ff_rtp_check_and_send_back_rr
int ff_rtp_check_and_send_back_rr(RTPDemuxContext *s, URLContext *fd, AVIOContext *avio, int count)
some rtp servers assume client is dead if they don't hear from them...
Definition: rtpdec.c:313
codec_type
enum AVMediaType codec_type
Definition: rtp.c:37
av_strlcatf
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:103
RTSPState::seek_timestamp
int64_t seek_timestamp
the seek value requested when calling av_seek_frame().
Definition: rtsp.h:247
ENC
#define ENC
Definition: rtsp.c:68
os_support.h
FFIOContext
Definition: avio_internal.h:28
sockaddr_storage
Definition: network.h:111
ff_network_init
int ff_network_init(void)
Definition: network.c:55
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...
FF_RTP_FLAG_OPTS
#define FF_RTP_FLAG_OPTS(ctx, fieldname)
Definition: rtpenc.h:74
map_to_opts
static AVDictionary * map_to_opts(RTSPState *rt)
Definition: rtsp.c:134
RTSPState::pkt_size
int pkt_size
Definition: rtsp.h:442
RTSPStream::feedback
int feedback
Enable sending RTCP feedback messages according to RFC 4585.
Definition: rtsp.h:512
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:196
av_memdup
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition: mem.c:304
ff_rtsp_send_cmd_with_content_async_stored
int ff_rtsp_send_cmd_with_content_async_stored(AVFormatContext *s, const char *method, const char *url, const char *headers, const unsigned char *send_content, int send_content_length)
Send a command to the RTSP server, storing the reply on future reads.
RTSPState::asf_ctx
AVFormatContext * asf_ctx
The following are used for RTP/ASF streams.
Definition: rtsp.h:337
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
avformat_close_input
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
Definition: demux.c:377
freeaddrinfo
#define freeaddrinfo
Definition: network.h:218
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:780
RTSP_FLAG_SATIP_RAW
#define RTSP_FLAG_SATIP_RAW
Export SAT>IP stream as raw MPEG-TS.
Definition: rtsp.h:465
ffstream
static av_always_inline FFStream * ffstream(AVStream *st)
Definition: internal.h:362
fail
#define fail()
Definition: checkasm.h:218
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:514
rtpenc_chain.h
ff_rtp_set_remote_url
int ff_rtp_set_remote_url(URLContext *h, const char *uri)
If no filename is given to av_open_input_file because you want to get the local port first,...
Definition: rtpproto.c:110
RTSPState::nb_rtsp_streams
int nb_rtsp_streams
number of items in the 'rtsp_streams' variable
Definition: rtsp.h:231
ffurl_connect
int ffurl_connect(URLContext *uc, AVDictionary **options)
Connect an URLContext that has been allocated by ffurl_alloc.
Definition: avio.c:205
sockaddr_storage::ss_family
uint16_t ss_family
Definition: network.h:116
read_close
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:143
ff_rdt_parse_packet
int ff_rdt_parse_packet(RDTDemuxContext *s, AVPacket *pkt, uint8_t **bufptr, int len)
Parse RDT-style packet data (header + media data).
Definition: rdt.c:339
get_word
static void get_word(char *buf, int buf_size, const char **pp)
Definition: rtsp.c:195
dynarray_add
#define dynarray_add(tab, nb_ptr, elem)
Definition: internal.h:373
OFFSET
#define OFFSET(x)
Definition: rtsp.c:66
RTSPMessageHeader::content_length
int content_length
length of the data following this header
Definition: rtsp.h:131
av_opt_set
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:835
RTSPState::key_file
char * key_file
Definition: rtsp.h:452
RTPDynamicProtocolHandler::close
void(* close)(PayloadContext *protocol_data)
Free any data needed by the rtp parsing for this dynamic data.
Definition: rtpdec.h:134
ff_rtp_parse_set_crypto
void ff_rtp_parse_set_crypto(RTPDemuxContext *s, const char *suite, const char *params)
Definition: rtpdec.c:588
RTSP_TRANSPORT_RDT
@ RTSP_TRANSPORT_RDT
Realmedia Data Transport.
Definition: rtsp.h:61
ff_check_interrupt
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
Definition: avio.c:855
RTSP_STATE_STREAMING
@ RTSP_STATE_STREAMING
initialized and sending/receiving data
Definition: rtsp.h:204
rtsp.h
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:721
RTSPState::lower_transport_mask
int lower_transport_mask
A mask with all requested transport methods.
Definition: rtsp.h:374
RTSP_MODE_TUNNEL
@ RTSP_MODE_TUNNEL
RTSP over HTTP (tunneling)
Definition: rtsp.h:72
SPACE_CHARS
#define SPACE_CHARS
Definition: dnn_backend_tf.c:356
RTSPStream::stream_index
int stream_index
corresponding stream index, if any.
Definition: rtsp.h:482
RTSPTransportField::destination
struct sockaddr_storage destination
destination IP address
Definition: rtsp.h:116
URLContext::priv_data
void * priv_data
Definition: url.h:38
ff_rdt_parse_close
void ff_rdt_parse_close(RDTDemuxContext *s)
Definition: rdt.c:80
avassert.h
RTSP_LOWER_TRANSPORT_HTTPS
@ RTSP_LOWER_TRANSPORT_HTTPS
HTTPS tunneled.
Definition: rtsp.h:47
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:358
AV_LOG_TRACE
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:236
avpriv_mpegts_parse_close
void avpriv_mpegts_parse_close(MpegTSContext *ts)
Definition: mpegts.c:3569
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
RTSP_FLAG_LISTEN
#define RTSP_FLAG_LISTEN
Wait for incoming connections.
Definition: rtsp.h:460
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:42
RTSPState::reordering_queue_size
int reordering_queue_size
Size of RTP packet reordering queue.
Definition: rtsp.h:433
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:363
RTSPState::ts
struct MpegTSContext * ts
The following are used for parsing raw mpegts in udp.
Definition: rtsp.h:351
ff_rtsp_send_cmd_with_content_async
int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, const char *method, const char *url, const char *headers, const unsigned char *send_content, int send_content_length)
Send a command to the RTSP server without waiting for the reply.
AVCodecDescriptor
This struct describes the properties of a single codec described by an AVCodecID.
Definition: codec_desc.h:38
RTSPState::body
unsigned char * body
Last stored reply message body from the RTSP server.
Definition: rtsp.h:305
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
RTSPState::nb_byes
int nb_byes
Definition: rtsp.h:366
AI_NUMERICHOST
#define AI_NUMERICHOST
Definition: network.h:187
avio_read_to_bprint
int avio_read_to_bprint(AVIOContext *h, struct AVBPrint *pb, size_t max_size)
Read contents of h into print buffer, up to max_size bytes, or up to EOF.
Definition: aviobuf.c:1254
RTSPState::p
struct pollfd * p
Polling array for udp.
Definition: rtsp.h:384
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:549
RTSPMessageHeader::location
char location[4096]
the "Location:" field.
Definition: rtsp.h:154
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:347
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:201
RTSPMessageHeader::transports
RTSPTransportField transports[RTSP_MAX_TRANSPORTS]
describes the complete "Transport:" line of the server in response to a SETUP RTSP command by the cli...
Definition: rtsp.h:144
RTSPMessageHeader::stream_id
char stream_id[64]
SAT>IP com.ses.streamID header.
Definition: rtsp.h:194
ff_url_join
int ff_url_join(char *str, int size, const char *proto, const char *authorization, const char *hostname, int port, const char *fmt,...)
Definition: url.c:40
filters
#define filters(fmt, type, inverse, clp, inverset, clip, one, clip_fn, packed)
Definition: af_crystalizer.c:55
RTSPState::cert_file
char * cert_file
Definition: rtsp.h:451
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Underlying C type is int64_t.
Definition: opt.h:263
av_sscanf
int av_sscanf(const char *string, const char *format,...)
Definition: avsscanf.c:961
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:618
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:799
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
ERR_RET
#define ERR_RET(c)
Definition: rtsp.c:146
RTSPState::buffer_size
int buffer_size
Definition: rtsp.h:441
ff_rtsp_open_transport_ctx
int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
Open RTSP transport context.
Definition: rtsp.c:868
RTSPTransportField::ttl
int ttl
time-to-live value (required for multicast); the amount of HOPs that packets will be allowed to make ...
Definition: rtsp.h:111
av_rescale_q
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
ff_rtsp_fetch_packet
int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt)
Receive one packet from the RTSPStreams set up in the AVFormatContext (which should contain a RTSPSta...
RTSPStream::dynamic_handler
const RTPDynamicProtocolHandler * dynamic_handler
The following are used for dynamic protocols (rtpdec_*.c/rdt.c)
Definition: rtsp.h:505
av_stristart
int av_stristart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str independent of case.
Definition: avstring.c:47
RTSPMessageHeader::seq
int seq
sequence number
Definition: rtsp.h:146
key
const char * key
Definition: hwcontext_opencl.c:189
AVMEDIA_TYPE_DATA
@ AVMEDIA_TYPE_DATA
Opaque data information usually continuous.
Definition: avutil.h:202
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
RTSP_FLAG_OPTS
#define RTSP_FLAG_OPTS(name, longname)
Definition: rtsp.c:70
ff_rtp_handler_find_by_id
const RTPDynamicProtocolHandler * ff_rtp_handler_find_by_id(int id, enum AVMediaType codec_type)
Find a registered rtp dynamic protocol handler with a matching codec ID.
Definition: rtpdec.c:168
handler
static void handler(vbi_event *ev, void *user_data)
Definition: libzvbi-teletextdec.c:508
RTP_REORDER_QUEUE_DEFAULT_SIZE
#define RTP_REORDER_QUEUE_DEFAULT_SIZE
Definition: rtpdec.h:39
ff_http_auth_handle_header
void ff_http_auth_handle_header(HTTPAuthState *state, const char *key, const char *value)
Definition: httpauth.c:90
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:314
ff_rtsp_setup_output_streams
int ff_rtsp_setup_output_streams(AVFormatContext *s, const char *addr)
Announce the stream to the server and set up the RTSPStream child objects for each media stream.
Definition: rtspenc.c:47
RTSP_MEDIATYPE_OPTS
#define RTSP_MEDIATYPE_OPTS(name, longname)
Definition: rtsp.c:74
RTSPState::host
char * host
Definition: rtsp.h:453
AVFormatContext
Format I/O context.
Definition: avformat.h:1264
internal.h
opts
static AVDictionary * opts
Definition: movenc.c:51
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:767
RTP_PT_PRIVATE
#define RTP_PT_PRIVATE
Definition: rtp.h:79
RTSPState::session_id
char session_id[512]
copy of RTSPMessageHeader->session_id, i.e.
Definition: rtsp.h:253
framerate
float framerate
Definition: av1_levels.c:29
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
RTSPMessageHeader::reason
char reason[256]
The "reason" is meant to specify better the meaning of the error code returned.
Definition: rtsp.h:184
RTSP_STATUS_OK
@ RTSP_STATUS_OK
Definition: rtspcodes.h:33
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:76
URLContext::protocol_whitelist
const char * protocol_whitelist
Definition: url.h:46
ff_rtsp_next_attr_and_value
int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, char *value, int value_size)
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:783
NULL
#define NULL
Definition: coverity.c:32
RECVBUF_SIZE
#define RECVBUF_SIZE
Definition: rtsp.c:63
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
RTSPState::rtsp_hd
URLContext * rtsp_hd
Definition: rtsp.h:228
avcodec_parameters_free
void avcodec_parameters_free(AVCodecParameters **ppar)
Free an AVCodecParameters instance and everything associated with it and write NULL to the supplied p...
Definition: codec_par.c:67
AVFMTCTX_NOHEADER
#define AVFMTCTX_NOHEADER
signal that no header is present (streams are added dynamically)
Definition: avformat.h:1215
FF_TLS_CLIENT_OPTIONS
#define FF_TLS_CLIENT_OPTIONS(pstruct, options_field)
Definition: tls.h:77
ff_rtp_queued_packet_time
int64_t ff_rtp_queued_packet_time(RTPDemuxContext *s)
Definition: rtpdec.c:807
av_unreachable
#define av_unreachable(msg)
Asserts that are used as compiler optimization hints depending upon ASSERT_LEVEL and NBDEBUG.
Definition: avassert.h:116
AVFMTCTX_UNSEEKABLE
#define AVFMTCTX_UNSEEKABLE
signal that the stream is definitely not seekable, and attempts to call the seek function will fail.
Definition: avformat.h:1217
ff_http_init_auth_state
void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
Initialize the authentication state based on another HTTP URLContext.
Definition: http.c:216
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:242
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1306
RTSPState::default_lang
char default_lang[4]
Definition: rtsp.h:440
RTSPMessageHeader::real_challenge
char real_challenge[64]
the "RealChallenge1:" field from the server
Definition: rtsp.h:157
get_word_sep
static void get_word_sep(char *buf, int buf_size, const char *sep, const char **pp)
Definition: rtsp.c:188
parseutils.h
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
RTSPState::ca_file
char * ca_file
Definition: rtsp.h:449
options
Definition: swscale.c:43
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:824
SDP_MAX_SIZE
#define SDP_MAX_SIZE
Definition: rtsp.h:81
AV_CODEC_ID_MPEG2TS
@ AV_CODEC_ID_MPEG2TS
FAKE codec to indicate a raw MPEG-2 TS stream (only used by libavformat)
Definition: codec_id.h:621
DEC
#define DEC
Definition: rtsp.c:67
RTSP_MAX_TRANSPORTS
#define RTSP_MAX_TRANSPORTS
Definition: rtsp.h:77
av_parse_time
int av_parse_time(int64_t *timeval, const char *timestr, int duration)
Parse timestr and return in *time a corresponding number of microseconds.
Definition: parseutils.c:592
RTPDemuxContext::rtcp_ts_offset
int64_t rtcp_ts_offset
Definition: rtpdec.h:178
time.h
RTSPState::header
RTSPMessageHeader * header
Last stored reply message from the RTSP server.
Definition: rtsp.h:303
RTSPState::state
enum RTSPClientState state
indicator of whether we are currently receiving data from the server.
Definition: rtsp.h:239
RTSPState::recvbuf
uint8_t * recvbuf
Reusable buffer for receiving packets.
Definition: rtsp.h:369
RTSP_FLAG_PREFER_TCP
#define RTSP_FLAG_PREFER_TCP
Try RTP via TCP first if possible.
Definition: rtsp.h:464
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
RTSPStream::sdp_port
int sdp_port
The following are used only in SDP, not RTSP.
Definition: rtsp.h:492
base64.h
AVPROBE_SCORE_EXTENSION
#define AVPROBE_SCORE_EXTENSION
score for file extension
Definition: avformat.h:461
RTSPStream::exclude_source_addrs
struct RTSPSource ** exclude_source_addrs
Source-specific multicast exclude source IP addresses (from SDP content)
Definition: rtsp.h:497
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
rtpdec.h
ff_log2_tab
const uint8_t ff_log2_tab[256]
Definition: log2_tab.c:23
copy_tls_opts_dict
static int copy_tls_opts_dict(RTSPState *rt, AVDictionary **dict)
Add the TLS options of the given RTSPState to the dict.
Definition: rtsp.c:156
get_sockaddr
static int get_sockaddr(AVFormatContext *s, const char *buf, struct sockaddr_storage *sock)
Definition: rtsp.c:226
ff_rtp_parse_close
void ff_rtp_parse_close(RTPDemuxContext *s)
Definition: rtpdec.c:939
av_strncasecmp
int av_strncasecmp(const char *a, const char *b, size_t n)
Locale-independent case-insensitive compare.
Definition: avstring.c:218
interleave
static void interleave(uint8_t *dst, uint8_t *src, int w, int h, int dst_linesize, int src_linesize, enum FilterMode mode, int swap)
Definition: vf_il.c:113
RTP_PT_IS_RTCP
#define RTP_PT_IS_RTCP(x)
Definition: rtp.h:112
RTSPSource
Definition: rtsp.h:467
ff_rtp_parse_open
RTPDemuxContext * ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, int payload_type, int queue_size)
open a new RTP parse context for stream 'st'.
Definition: rtpdec.c:538
NI_NUMERICHOST
#define NI_NUMERICHOST
Definition: network.h:195
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
RTSPStream::dynamic_protocol_context
PayloadContext * dynamic_protocol_context
private data associated with the dynamic protocol
Definition: rtsp.h:508
AVMediaType
AVMediaType
Definition: avutil.h:198
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:94
av_bprint_finalize
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
Definition: bprint.c:235
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:892
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:319
RTSPState::rtsp_flags
int rtsp_flags
Various option flags for the RTSP muxer/demuxer.
Definition: rtsp.h:408
ffurl_get_multi_file_handle
int ffurl_get_multi_file_handle(URLContext *h, int **handles, int *numhandles)
Return the file descriptors associated with this URL.
Definition: avio.c:822
ff_rtsp_options
const AVOption ff_rtsp_options[]
Definition: rtsp.c:87
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:122
ff_rtsp_close_connections
void ff_rtsp_close_connections(AVFormatContext *s)
Close all connection handles within the RTSP (de)muxer.
RTSPState
Private data for the RTSP demuxer.
Definition: rtsp.h:226
RTSPStream::include_source_addrs
struct RTSPSource ** include_source_addrs
Source-specific multicast include source IP addresses (from SDP content)
Definition: rtsp.h:495
RTSPState::lower_transport
enum RTSPLowerTransport lower_transport
the negotiated network layer transport protocol; e.g.
Definition: rtsp.h:270
RTSPMessageHeader::range_start
int64_t range_start
Time range of the streams that the server will stream.
Definition: rtsp.h:140
RTSPState::recvbuf_len
int recvbuf_len
Definition: rtsp.h:353
RTSPState::last_reply
char last_reply[2048]
The last reply of the server to a RTSP command.
Definition: rtsp.h:287
size
int size
Definition: twinvq_data.h:10344
RTSPTransportField::transport
enum RTSPTransport transport
data/packet transport protocol; e.g.
Definition: rtsp.h:120
RTPDemuxContext::first_rtcp_ntp_time
uint64_t first_rtcp_ntp_time
Definition: rtpdec.h:177
RTSPState::rtsp_streams
struct RTSPStream ** rtsp_streams
streams in this session
Definition: rtsp.h:233
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:247
NTP_OFFSET_US
#define NTP_OFFSET_US
Definition: internal.h:419
AV_RB32
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_RB32
Definition: bytestream.h:96
avpriv_report_missing_feature
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
ff_rtsp_skip_packet
int ff_rtsp_skip_packet(AVFormatContext *s)
Skip a RTP/TCP interleaved packet.
RTSPState::seq
int seq
RTSP command sequence number.
Definition: rtsp.h:249
COMMON_OPTS
#define COMMON_OPTS()
Definition: rtsp.c:81
RTSPStream::crypto_params
char crypto_params[100]
Definition: rtsp.h:518
AVFMT_NOFILE
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:468
AVMEDIA_TYPE_UNKNOWN
@ AVMEDIA_TYPE_UNKNOWN
Usually treated as AVMEDIA_TYPE_DATA.
Definition: avutil.h:199
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:70
header
static const uint8_t header[24]
Definition: sdr2.c:68
RTSPState::max_p
int max_p
Definition: rtsp.h:385
RTSPState::auth_state
HTTPAuthState auth_state
authentication state
Definition: rtsp.h:284
ff_rtp_get_codec_info
int ff_rtp_get_codec_info(AVCodecParameters *par, int payload_type)
Initialize a codec context based on the payload type.
Definition: rtp.c:71
ff_rtp_handler_find_by_name
const RTPDynamicProtocolHandler * ff_rtp_handler_find_by_name(const char *name, enum AVMediaType codec_type)
Find a registered rtp dynamic protocol handler with the specified name.
Definition: rtpdec.c:154
line
Definition: graph2dot.c:48
ff_rdt_parse_open
RDTDemuxContext * ff_rdt_parse_open(AVFormatContext *ic, int first_stream_of_set_idx, void *priv_data, const RTPDynamicProtocolHandler *handler)
Allocate and init the RDT parsing context.
Definition: rdt.c:57
READ_PACKET_TIMEOUT_S
#define READ_PACKET_TIMEOUT_S
Definition: rtsp.c:62
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:233
read_header
static int read_header(FFV1Context *f, RangeCoder *c)
Definition: ffv1dec.c:498
av_strstart
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:36
gai_strerror
#define gai_strerror
Definition: network.h:225
RTSPStream::nb_exclude_source_addrs
int nb_exclude_source_addrs
Number of source-specific multicast exclude source IP addresses (from SDP content)
Definition: rtsp.h:496
ff_real_parse_sdp_a_line
void ff_real_parse_sdp_a_line(AVFormatContext *s, int stream_index, const char *line)
Parse a server-related SDP line.
Definition: rdt.c:519
RTSPState::timeout
int timeout
copy of RTSPMessageHeader->timeout, i.e.
Definition: rtsp.h:258
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:221
DEFAULT_REORDERING_DELAY
#define DEFAULT_REORDERING_DELAY
Definition: rtsp.c:64
RTSPTransportField::client_port_max
int client_port_max
Definition: rtsp.h:103
ffurl_alloc
int ffurl_alloc(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb)
Create a URLContext for accessing to the resource indicated by url, but do not initiate the connectio...
Definition: avio.c:350
av_channel_layout_default
void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels)
Get the default channel layout for a given number of channels.
Definition: channel_layout.c:839
getaddrinfo
#define getaddrinfo
Definition: network.h:217
avcodec_parameters_alloc
AVCodecParameters * avcodec_parameters_alloc(void)
Allocate a new AVCodecParameters and set its fields to default values (unknown/invalid/0).
Definition: codec_par.c:57
av_write_trailer
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:1238
RTSP_SERVER_SATIP
@ RTSP_SERVER_SATIP
SAT>IP server.
Definition: rtsp.h:217
bprint.h
HTTP_AUTH_NONE
@ HTTP_AUTH_NONE
No authentication specified.
Definition: httpauth.h:29
AV_BASE64_SIZE
#define AV_BASE64_SIZE(x)
Calculate the output size needed to base64-encode x bytes to a null-terminated string.
Definition: base64.h:66
RTSPState::media_type_mask
int media_type_mask
Mask of all requested media types.
Definition: rtsp.h:413
URLContext
Definition: url.h:35
AV_CODEC_ID_NONE
@ AV_CODEC_ID_NONE
Definition: codec_id.h:50
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
RTSPSource::addr
char addr[128]
Source-specific multicast include source IP address (from SDP content)
Definition: rtsp.h:468
avio_internal.h
getnameinfo
#define getnameinfo
Definition: network.h:219
ff_rtp_parse_packet
int ff_rtp_parse_packet(RTPDemuxContext *s, AVPacket *pkt, uint8_t **bufptr, int len)
Parse an RTP or RTCP packet directly sent as a buffer.
Definition: rtpdec.c:926
RTPDemuxContext::ssrc
uint32_t ssrc
Definition: rtpdec.h:152
RTSPMessageHeader::timeout
int timeout
The "timeout" comes as part of the server response to the "SETUP" command, in the "Session: <xyz>[;ti...
Definition: rtsp.h:174
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
RTSPState::need_subscription
int need_subscription
The following are used for Real stream selection.
Definition: rtsp.h:318
RTCP_BYE
@ RTCP_BYE
Definition: rtp.h:102
rtpproto.h
RTPDemuxContext::st
AVStream * st
Definition: rtpdec.h:150
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
ff_rtsp_tcp_write_packet
int ff_rtsp_tcp_write_packet(AVFormatContext *s, RTSPStream *rtsp_st)
Send buffered packets over TCP.
Definition: rtspenc.c:143
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:361
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:486
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_d2q
AVRational av_d2q(double d, int max)
Convert a double precision floating point number to a rational.
Definition: rational.c:106
RTSPStream::ssrc
uint32_t ssrc
SSRC for this stream, to allow identifying RTCP packets before the first RTP packet.
Definition: rtsp.h:515
url.h
RTSP_LOWER_TRANSPORT_TCP
@ RTSP_LOWER_TRANSPORT_TCP
TCP; interleaved in RTSP.
Definition: rtsp.h:41
demux.h
len
int len
Definition: vorbis_enc_data.h:426
profile
int profile
Definition: mxfenc.c:2297
rtpenc.h
RTSPStream::sdp_ttl
int sdp_ttl
IP Time-To-Live (from SDP content)
Definition: rtsp.h:498
RTSP_FLAG_CUSTOM_IO
#define RTSP_FLAG_CUSTOM_IO
Do all IO via the AVIOContext.
Definition: rtsp.h:461
RTPDemuxContext
Definition: rtpdec.h:148
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
RTSPTransportField::client_port_min
int client_port_min
UDP client ports; these should be the local ports of the UDP RTP (and RTCP) sockets over which we rec...
Definition: rtsp.h:103
version.h
RTSPState::rtp_port_max
int rtp_port_max
Definition: rtsp.h:418
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:589
RTSP_LOWER_TRANSPORT_UDP_MULTICAST
@ RTSP_LOWER_TRANSPORT_UDP_MULTICAST
UDP/multicast.
Definition: rtsp.h:42
ffio_free_dyn_buf
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1438
AVStream::id
int id
Format-specific stream ID.
Definition: avformat.h:756
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:744
RTSPState::cur_transport_priv
void * cur_transport_priv
RTSPStream->transport_priv of the last stream that we read a packet from.
Definition: rtsp.h:313
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:81
av_strlcat
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes,...
Definition: avstring.c:95
RTSPStream::sdp_payload_type
int sdp_payload_type
payload type
Definition: rtsp.h:499
av_malloc
void * av_malloc(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:98
ff_wms_parse_sdp_a_line
int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
Parse a Windows Media Server-specific SDP line.
Definition: rtpdec_asf.c:100
avformat.h
ff_rtp_chain_mux_open
int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s, AVStream *st, URLContext *handle, int packet_size, int idx)
Definition: rtpenc_chain.c:29
av_bprintf
void av_bprintf(AVBPrint *buf, const char *fmt,...)
Definition: bprint.c:122
dict.h
network.h
RTP_MAX_PACKET_LENGTH
#define RTP_MAX_PACKET_LENGTH
Definition: rtpdec.h:37
rtsp_parse_range_npt
static void rtsp_parse_range_npt(const char *p, int64_t *start, int64_t *end)
Parse a string p in the form of Range:npt=xx-xx, and determine the start and end time.
Definition: rtsp.c:204
RTSPStream::sdp_ip
struct sockaddr_storage sdp_ip
IP address (from SDP content)
Definition: rtsp.h:493
HTTPAuthState::stale
int stale
Auth ok, but needs to be resent with a new nonce.
Definition: httpauth.h:71
tls.h
RTSP_DEFAULT_PORT
#define RTSP_DEFAULT_PORT
Definition: rtsp.h:75
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:750
RTSP_LOWER_TRANSPORT_HTTP
@ RTSP_LOWER_TRANSPORT_HTTP
HTTP tunneled - not a proper transport mode as such, only for use via AVOptions.
Definition: rtsp.h:44
RTSPTransportField
This describes a single item in the "Transport:" line of one stream as negotiated by the SETUP RTSP c...
Definition: rtsp.h:90
RTSPState::transport
enum RTSPTransport transport
the negotiated data/packet transport protocol; e.g.
Definition: rtsp.h:266
random_seed.h
MAX_URL_SIZE
#define MAX_URL_SIZE
Definition: internal.h:30
RTPDemuxContext::base_timestamp
uint32_t base_timestamp
Definition: rtpdec.h:155
RTSPStream::control_url
char control_url[MAX_URL_SIZE]
url for this stream (from SDP)
Definition: rtsp.h:488
addrinfo::ai_flags
int ai_flags
Definition: network.h:138
RTSPStream::interleaved_max
int interleaved_max
Definition: rtsp.h:486
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition: opt.h:259
RTSPState::localaddr
char * localaddr
Definition: rtsp.h:443
avformat_free_context
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
Definition: avformat.c:143
RTSP_SERVER_WMS
@ RTSP_SERVER_WMS
Windows Media server.
Definition: rtsp.h:216
avpriv_mpegts_parse_open
MpegTSContext * avpriv_mpegts_parse_open(AVFormatContext *s)
Definition: mpegts.c:3522
RTSPMessageHeader
This describes the server response to each RTSP command.
Definition: rtsp.h:129
av_base64_encode
char * av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size)
Encode data to base64 and null-terminate.
Definition: base64.c:147
RTSP_TRANSPORT_RAW
@ RTSP_TRANSPORT_RAW
Raw data (over UDP)
Definition: rtsp.h:62
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
ff_mpegts_dynamic_handler
const RTPDynamicProtocolHandler ff_mpegts_dynamic_handler
Definition: rtpdec_mpegts.c:92
RTSP_RTP_PORT_MAX
#define RTSP_RTP_PORT_MAX
Definition: rtsp.h:80
RTSPState::stimeout
int64_t stimeout
timeout of socket i/o operations.
Definition: rtsp.h:428
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:177
HTTPAuthType
HTTPAuthType
Authentication types, ordered from weakest to strongest.
Definition: httpauth.h:28
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:617
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:272
desc
const char * desc
Definition: libsvtav1.c:78
RTSP_STATE_IDLE
@ RTSP_STATE_IDLE
not initialized
Definition: rtsp.h:203
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:200
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
mem.h
HTTPAuthState::auth_type
int auth_type
The currently chosen auth type.
Definition: httpauth.h:59
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:394
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:558
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
rdt.h
headers
FFmpeg currently uses a custom build this text attempts to document some of its obscure features and options Makefile the full command issued by make and its output will be shown on the screen DBG Preprocess x86 external assembler files to a dbg asm file in the object which then gets compiled Helps in developing those assembler files DESTDIR Destination directory for the install useful to prepare packages or install FFmpeg in cross environments GEN Set to ‘1’ to generate the missing or mismatched references Makefile builds all the libraries and the executables fate Run the fate test note that you must have installed it fate list List all fate regression test targets fate list failing List the fate tests that failed the last time they were executed fate clear reports Remove the test reports from previous test libraries and programs examples Build all examples located in doc examples checkheaders Check headers dependencies alltools Build all tools in tools directory config Reconfigure the project with the current configuration tools target_dec_< decoder > _fuzzer Build fuzzer to fuzz the specified decoder tools target_bsf_< filter > _fuzzer Build fuzzer to fuzz the specified bitstream filter Useful standard make this is useful to reduce unneeded rebuilding when changing headers
Definition: build_system.txt:64
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
RTSP_LOWER_TRANSPORT_NB
@ RTSP_LOWER_TRANSPORT_NB
Definition: rtsp.h:43
ff_rtp_parse_set_dynamic_protocol
void ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx, const RTPDynamicProtocolHandler *handler)
Definition: rtpdec.c:581
AVPacket
This structure stores compressed data.
Definition: packet.h:565
RTSPState::server_type
enum RTSPServerType server_type
brand of server that we're talking to; e.g.
Definition: rtsp.h:275
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition: opt.h:327
RTSPMessageHeader::content_type
char content_type[64]
Content type header.
Definition: rtsp.h:189
RTSPTransportField::server_port_max
int server_port_max
Definition: rtsp.h:107
avio_closep
int avio_closep(AVIOContext **s)
Close the resource accessed by the AVIOContext *s, free it and set the pointer pointing to it to NULL...
Definition: avio.c:650
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:86
POLLING_TIME
#define POLLING_TIME
Definition: network.h:249
FFInputFormat
Definition: demux.h:66
AV_OPT_TYPE_FLAGS
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
Definition: opt.h:255
RTSPTransportField::mode_record
int mode_record
transport set to record data
Definition: rtsp.h:114
RTSPState::accept_dynamic_rate
int accept_dynamic_rate
Whether the server accepts the x-Dynamic-Rate header.
Definition: rtsp.h:403
av_strlcpy
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:85
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
RTSPMessageHeader::session_id
char session_id[512]
the "Session:" field.
Definition: rtsp.h:150
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
ff_rtsp_make_setup_request
int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, int lower_transport, const char *real_challenge)
Do the SETUP requests for each stream for the chosen lower transport mode.
ff_rtp_enc_name
const char * ff_rtp_enc_name(int payload_type)
Return the encoding name (as defined in http://www.iana.org/assignments/rtp-parameters) for a given p...
Definition: rtp.c:135
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:58
avcodec_descriptor_get
const AVCodecDescriptor * avcodec_descriptor_get(enum AVCodecID id)
Definition: codec_desc.c:3887
RTSPMessageHeader::server
char server[64]
the "Server: field, which can be used to identify some special-case servers that are not 100% standar...
Definition: rtsp.h:166
RTSPStream::crypto_suite
char crypto_suite[40]
Definition: rtsp.h:517
pkt
static AVPacket * pkt
Definition: demux_decode.c:55
get_word_until_chars
static void get_word_until_chars(char *buf, int buf_size, const char *sep, const char **pp)
Definition: rtsp.c:169
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
addrinfo
Definition: network.h:137
RTSPState::verify
int verify
Definition: rtsp.h:450
http.h
codec_desc.h
ff_rtsp_connect
int ff_rtsp_connect(AVFormatContext *s)
Connect to the RTSP server and set up the individual media streams.
RTSPTransportField::port_min
int port_min
UDP multicast port range; the ports to which we should connect to receive multicast UDP data.
Definition: rtsp.h:99
ff_sdp_demuxer
const FFInputFormat ff_sdp_demuxer
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
snprintf
#define snprintf
Definition: snprintf.h:34
RTSPState::pending_packet
int pending_packet
Indicates if a packet is pending to be read (useful for interleaved reads)
Definition: rtsp.h:309
ff_format_set_url
void ff_format_set_url(AVFormatContext *s, char *url)
Set AVFormatContext url field to the provided pointer.
Definition: avformat.c:864
RTSP_FLAG_FILTER_SRC
#define RTSP_FLAG_FILTER_SRC
Filter incoming UDP packets - receive packets only from the right source address and port.
Definition: rtsp.h:457
RTSPMessageHeader::notice
int notice
The "Notice" or "X-Notice" field value.
Definition: rtsp.h:179
avio_read_partial
int avio_read_partial(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:687
ffurl_get_file_handle
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:815
RTSPS_DEFAULT_PORT
#define RTSPS_DEFAULT_PORT
Definition: rtsp.h:76
RTSP_LOWER_TRANSPORT_UDP
@ RTSP_LOWER_TRANSPORT_UDP
UDP/unicast.
Definition: rtsp.h:40
read
static uint32_t BS_FUNC() read(BSCTX *bc, unsigned int n)
Return n bits from the buffer, n has to be in the 0-32 range.
Definition: bitstream_template.h:239
RTPDynamicProtocolHandler
Definition: rtpdec.h:116
RTSPState::tls_opts
struct RTSPState::@491 tls_opts
Options used for TLS based RTSP streams.
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
RTSPState::user_agent
char * user_agent
User-Agent string.
Definition: rtsp.h:438
RTSP_FLAG_RTCP_TO_SOURCE
#define RTSP_FLAG_RTCP_TO_SOURCE
Send RTCP packets to the source address of received packets.
Definition: rtsp.h:462
ffurl_read
static int ffurl_read(URLContext *h, uint8_t *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf.
Definition: url.h:181