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  size_t len = strlen(rtsp_st->control_url);
616  if (len == 0 || rtsp_st->control_url[len - 1] != '/')
617  av_strlcat(rtsp_st->control_url, "/",
618  sizeof(rtsp_st->control_url));
619  av_strlcat(rtsp_st->control_url, p,
620  sizeof(rtsp_st->control_url));
621  } else
622  av_strlcpy(rtsp_st->control_url, p,
623  sizeof(rtsp_st->control_url));
624  }
625  } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) {
626  /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
627  get_word(buf1, sizeof(buf1), &p);
628  payload_type = atoi(buf1);
629  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
630  if (rtsp_st->stream_index >= 0) {
631  st = s->streams[rtsp_st->stream_index];
632  sdp_parse_rtpmap(s, st, rtsp_st, payload_type, p);
633  }
634  s1->seen_rtpmap = 1;
635  if (s1->seen_fmtp) {
636  parse_fmtp(s, rt, payload_type, s1->delayed_fmtp);
637  }
638  } else if (av_strstart(p, "fmtp:", &p) ||
639  av_strstart(p, "framesize:", &p)) {
640  // let dynamic protocol handlers have a stab at the line.
641  get_word(buf1, sizeof(buf1), &p);
642  payload_type = atoi(buf1);
643  if (s1->seen_rtpmap) {
644  parse_fmtp(s, rt, payload_type, buf);
645  } else {
646  s1->seen_fmtp = 1;
647  av_strlcpy(s1->delayed_fmtp, buf, sizeof(s1->delayed_fmtp));
648  }
649  } else if (av_strstart(p, "framerate:", &p) && s->nb_streams > 0) {
650  // RFC 8866
651  double framerate;
652  if (av_sscanf(p, "%lf%c", &framerate, &(char){0}) == 1) {
653  st = s->streams[s->nb_streams - 1];
654  st->avg_frame_rate = av_d2q(framerate, INT_MAX);
655  }
656  } else if (av_strstart(p, "ssrc:", &p) && s->nb_streams > 0) {
657  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
658  get_word(buf1, sizeof(buf1), &p);
659  rtsp_st->ssrc = strtoll(buf1, NULL, 10);
660  } else if (av_strstart(p, "range:", &p)) {
661  int64_t start, end;
662 
663  // this is so that seeking on a streamed file can work.
664  rtsp_parse_range_npt(p, &start, &end);
665  s->start_time = start;
666  /* AV_NOPTS_VALUE means live broadcast (and can't seek) */
667  if (end != AV_NOPTS_VALUE)
668  s->duration = end - start;
669  } else if (av_strstart(p, "lang:", &p)) {
670  if (s->nb_streams > 0) {
671  get_word(buf1, sizeof(buf1), &p);
672  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
673  if (rtsp_st->stream_index >= 0) {
674  st = s->streams[rtsp_st->stream_index];
675  av_dict_set(&st->metadata, "language", buf1, 0);
676  }
677  } else
678  get_word(rt->default_lang, sizeof(rt->default_lang), &p);
679  } else if (av_strstart(p, "IsRealDataType:integer;",&p)) {
680  if (atoi(p) == 1)
682  } else if (av_strstart(p, "SampleRate:integer;", &p) &&
683  s->nb_streams > 0) {
684  st = s->streams[s->nb_streams - 1];
685  st->codecpar->sample_rate = atoi(p);
686  } else if (av_strstart(p, "crypto:", &p) && s->nb_streams > 0) {
687  // RFC 4568
688  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
689  get_word(buf1, sizeof(buf1), &p); // ignore tag
690  get_word(rtsp_st->crypto_suite, sizeof(rtsp_st->crypto_suite), &p);
691  p += strspn(p, SPACE_CHARS);
692  if (av_strstart(p, "inline:", &p))
693  get_word(rtsp_st->crypto_params, sizeof(rtsp_st->crypto_params), &p);
694  } else if (av_strstart(p, "source-filter:", &p)) {
695  int exclude = 0;
696  get_word(buf1, sizeof(buf1), &p);
697  if (strcmp(buf1, "incl") && strcmp(buf1, "excl"))
698  return;
699  exclude = !strcmp(buf1, "excl");
700 
701  get_word(buf1, sizeof(buf1), &p);
702  if (strcmp(buf1, "IN") != 0)
703  return;
704  get_word(buf1, sizeof(buf1), &p);
705  if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6") && strcmp(buf1, "*"))
706  return;
707  // not checking that the destination address actually matches or is wildcard
708  get_word(buf1, sizeof(buf1), &p);
709 
710  while (*p != '\0') {
711  rtsp_src = av_mallocz(sizeof(*rtsp_src));
712  if (!rtsp_src)
713  return;
714  get_word(rtsp_src->addr, sizeof(rtsp_src->addr), &p);
715  if (exclude) {
716  if (s->nb_streams == 0) {
717  dynarray_add(&s1->default_exclude_source_addrs, &s1->nb_default_exclude_source_addrs, rtsp_src);
718  } else {
719  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
720  dynarray_add(&rtsp_st->exclude_source_addrs, &rtsp_st->nb_exclude_source_addrs, rtsp_src);
721  }
722  } else {
723  if (s->nb_streams == 0) {
724  dynarray_add(&s1->default_include_source_addrs, &s1->nb_default_include_source_addrs, rtsp_src);
725  } else {
726  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
727  dynarray_add(&rtsp_st->include_source_addrs, &rtsp_st->nb_include_source_addrs, rtsp_src);
728  }
729  }
730  }
731  } else {
732  if (rt->server_type == RTSP_SERVER_WMS)
734  if (s->nb_streams > 0) {
735  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
736 
737  if (rt->server_type == RTSP_SERVER_REAL)
739 
740  if (rtsp_st->dynamic_handler &&
743  rtsp_st->stream_index,
744  rtsp_st->dynamic_protocol_context, buf);
745  }
746  }
747  break;
748  }
749 }
750 
751 int ff_sdp_parse(AVFormatContext *s, const char *content)
752 {
753  const char *p;
754  int letter, i;
755  char buf[SDP_MAX_SIZE], *q;
756  SDPParseState sdp_parse_state = { { 0 } }, *s1 = &sdp_parse_state;
757 
758  s->duration = AV_NOPTS_VALUE;
759 
760  p = content;
761  for (;;) {
762  p += strspn(p, SPACE_CHARS);
763  letter = *p;
764  if (letter == '\0')
765  break;
766  p++;
767  if (*p != '=')
768  goto next_line;
769  p++;
770  /* get the content */
771  q = buf;
772  while (*p != '\n' && *p != '\r' && *p != '\0') {
773  if ((q - buf) < sizeof(buf) - 1)
774  *q++ = *p;
775  p++;
776  }
777  *q = '\0';
778  sdp_parse_line(s, s1, letter, buf);
779  next_line:
780  while (*p != '\n' && *p != '\0')
781  p++;
782  if (*p == '\n')
783  p++;
784  }
785 
786  for (i = 0; i < s1->nb_default_include_source_addrs; i++)
787  av_freep(&s1->default_include_source_addrs[i]);
788  av_freep(&s1->default_include_source_addrs);
789  for (i = 0; i < s1->nb_default_exclude_source_addrs; i++)
790  av_freep(&s1->default_exclude_source_addrs[i]);
791  av_freep(&s1->default_exclude_source_addrs);
792 
793  if (s->duration == AV_NOPTS_VALUE)
794  s->ctx_flags |= AVFMTCTX_UNSEEKABLE;
795 
796  return 0;
797 }
798 #endif /* CONFIG_RTPDEC */
799 
800 void ff_rtsp_undo_setup(AVFormatContext *s, int send_packets)
801 {
802  RTSPState *rt = s->priv_data;
803  int i;
804 
805  rt->stored_msg.expected_seq = -1;
806  for (i = 0; i < rt->nb_rtsp_streams; i++) {
807  RTSPStream *rtsp_st = rt->rtsp_streams[i];
808  if (!rtsp_st)
809  continue;
810  if (rtsp_st->transport_priv) {
811  if (s->oformat) {
812  AVFormatContext *rtpctx = rtsp_st->transport_priv;
813  av_write_trailer(rtpctx);
815  if (CONFIG_RTSP_MUXER && rtpctx->pb && send_packets)
816  ff_rtsp_tcp_write_packet(s, rtsp_st);
817  ffio_free_dyn_buf(&rtpctx->pb);
818  } else {
819  avio_closep(&rtpctx->pb);
820  }
821  avformat_free_context(rtpctx);
822  } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT)
824  else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP)
826  }
827  rtsp_st->transport_priv = NULL;
828  ffurl_closep(&rtsp_st->rtp_handle);
829  }
830 }
831 
832 /* close and free RTSP streams */
834 {
835  RTSPState *rt = s->priv_data;
836  int i, j;
837  RTSPStream *rtsp_st;
838 
839  ff_rtsp_undo_setup(s, 0);
840  for (i = 0; i < rt->nb_rtsp_streams; i++) {
841  rtsp_st = rt->rtsp_streams[i];
842  if (rtsp_st) {
843  if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context) {
844  if (rtsp_st->dynamic_handler->close)
845  rtsp_st->dynamic_handler->close(
846  rtsp_st->dynamic_protocol_context);
848  }
849  for (j = 0; j < rtsp_st->nb_include_source_addrs; j++)
850  av_freep(&rtsp_st->include_source_addrs[j]);
851  av_freep(&rtsp_st->include_source_addrs);
852  for (j = 0; j < rtsp_st->nb_exclude_source_addrs; j++)
853  av_freep(&rtsp_st->exclude_source_addrs[j]);
854  av_freep(&rtsp_st->exclude_source_addrs);
855 
856  av_freep(&rtsp_st);
857  }
858  }
859  av_freep(&rt->rtsp_streams);
860  if (rt->asf_ctx) {
862  }
863  if (CONFIG_RTPDEC && rt->ts)
865  av_freep(&rt->p);
866  av_freep(&rt->recvbuf);
867 }
868 
870 {
871  RTSPState *rt = s->priv_data;
872  AVStream *st = NULL;
873  int reordering_queue_size = rt->reordering_queue_size;
874  if (reordering_queue_size < 0) {
875  if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP || !s->max_delay)
876  reordering_queue_size = 0;
877  else
878  reordering_queue_size = RTP_REORDER_QUEUE_DEFAULT_SIZE;
879  }
880 
881  /* open the RTP context */
882  if (rtsp_st->stream_index >= 0)
883  st = s->streams[rtsp_st->stream_index];
884  if (!st)
885  s->ctx_flags |= AVFMTCTX_NOHEADER;
886 
887  if (CONFIG_RTSP_MUXER && s->oformat && st) {
889  s, st, rtsp_st->rtp_handle,
890  rt->pkt_size,
891  rtsp_st->stream_index);
892  /* Ownership of rtp_handle is passed to the rtp mux context */
893  rtsp_st->rtp_handle = NULL;
894  if (ret < 0)
895  return ret;
896  st->time_base = ((AVFormatContext*)rtsp_st->transport_priv)->streams[0]->time_base;
897  } else if (rt->transport == RTSP_TRANSPORT_RAW) {
898  return 0; // Don't need to open any parser here
899  } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RDT && st)
900  rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
901  rtsp_st->dynamic_protocol_context,
902  rtsp_st->dynamic_handler);
903  else if (CONFIG_RTPDEC)
904  rtsp_st->transport_priv = ff_rtp_parse_open(s, st,
905  rtsp_st->sdp_payload_type,
906  reordering_queue_size);
907 
908  if (!rtsp_st->transport_priv) {
909  return AVERROR(ENOMEM);
910  } else if (CONFIG_RTPDEC && rt->transport == RTSP_TRANSPORT_RTP &&
911  s->iformat) {
912  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
913  rtpctx->ssrc = rtsp_st->ssrc;
914  if (rtsp_st->dynamic_handler) {
916  rtsp_st->dynamic_protocol_context,
917  rtsp_st->dynamic_handler);
918  }
919  if (rtsp_st->crypto_suite[0])
921  rtsp_st->crypto_suite,
922  rtsp_st->crypto_params);
923  }
924 
925  return 0;
926 }
927 
928 #if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER
929 static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
930 {
931  const char *q;
932  char *p;
933  int v;
934 
935  q = *pp;
936  q += strspn(q, SPACE_CHARS);
937  v = strtol(q, &p, 10);
938  if (*p == '-') {
939  p++;
940  *min_ptr = v;
941  v = strtol(p, &p, 10);
942  *max_ptr = v;
943  } else {
944  *min_ptr = v;
945  *max_ptr = v;
946  }
947  *pp = p;
948 }
949 
950 /* XXX: only one transport specification is parsed */
951 static void rtsp_parse_transport(AVFormatContext *s,
952  RTSPMessageHeader *reply, const char *p)
953 {
954  char transport_protocol[16];
955  char profile[16];
956  char lower_transport[16];
957  char parameter[16];
958  RTSPTransportField *th;
959  char buf[256];
960 
961  reply->nb_transports = 0;
962 
963  for (;;) {
964  p += strspn(p, SPACE_CHARS);
965  if (*p == '\0')
966  break;
967 
968  th = &reply->transports[reply->nb_transports];
969 
970  get_word_sep(transport_protocol, sizeof(transport_protocol),
971  "/", &p);
972  if (!av_strcasecmp (transport_protocol, "rtp")) {
973  get_word_sep(profile, sizeof(profile), "/;,", &p);
974  lower_transport[0] = '\0';
975  /* rtp/avp/<protocol> */
976  if (*p == '/') {
977  get_word_sep(lower_transport, sizeof(lower_transport),
978  ";,", &p);
979  }
981  } else if (!av_strcasecmp (transport_protocol, "x-pn-tng") ||
982  !av_strcasecmp (transport_protocol, "x-real-rdt")) {
983  /* x-pn-tng/<protocol> */
984  get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p);
985  profile[0] = '\0';
987  } else if (!av_strcasecmp(transport_protocol, "raw")) {
988  get_word_sep(profile, sizeof(profile), "/;,", &p);
989  lower_transport[0] = '\0';
990  /* raw/raw/<protocol> */
991  if (*p == '/') {
992  get_word_sep(lower_transport, sizeof(lower_transport),
993  ";,", &p);
994  }
996  } else {
997  break;
998  }
999  if (!av_strcasecmp(lower_transport, "TCP"))
1001  else
1003 
1004  if (*p == ';')
1005  p++;
1006  /* get each parameter */
1007  while (*p != '\0' && *p != ',') {
1008  get_word_sep(parameter, sizeof(parameter), "=;,", &p);
1009  if (!strcmp(parameter, "port")) {
1010  if (*p == '=') {
1011  p++;
1012  rtsp_parse_range(&th->port_min, &th->port_max, &p);
1013  }
1014  } else if (!strcmp(parameter, "client_port")) {
1015  if (*p == '=') {
1016  p++;
1017  rtsp_parse_range(&th->client_port_min,
1018  &th->client_port_max, &p);
1019  }
1020  } else if (!strcmp(parameter, "server_port")) {
1021  if (*p == '=') {
1022  p++;
1023  rtsp_parse_range(&th->server_port_min,
1024  &th->server_port_max, &p);
1025  }
1026  } else if (!strcmp(parameter, "interleaved")) {
1027  if (*p == '=') {
1028  p++;
1029  rtsp_parse_range(&th->interleaved_min,
1030  &th->interleaved_max, &p);
1031  }
1032  } else if (!strcmp(parameter, "multicast")) {
1035  } else if (!strcmp(parameter, "ttl")) {
1036  if (*p == '=') {
1037  char *end;
1038  p++;
1039  th->ttl = strtol(p, &end, 10);
1040  p = end;
1041  }
1042  } else if (!strcmp(parameter, "destination")) {
1043  if (*p == '=') {
1044  p++;
1045  get_word_sep(buf, sizeof(buf), ";,", &p);
1046  get_sockaddr(s, buf, &th->destination);
1047  }
1048  } else if (!strcmp(parameter, "source")) {
1049  if (*p == '=') {
1050  p++;
1051  get_word_sep(buf, sizeof(buf), ";,", &p);
1052  av_strlcpy(th->source, buf, sizeof(th->source));
1053  }
1054  } else if (!strcmp(parameter, "mode")) {
1055  if (*p == '=') {
1056  p++;
1057  get_word_sep(buf, sizeof(buf), ";, ", &p);
1058  if (!av_strcasecmp(buf, "record") ||
1059  !av_strcasecmp(buf, "receive"))
1060  th->mode_record = 1;
1061  }
1062  }
1063 
1064  while (*p != ';' && *p != '\0' && *p != ',')
1065  p++;
1066  if (*p == ';')
1067  p++;
1068  }
1069  if (*p == ',')
1070  p++;
1071 
1072  reply->nb_transports++;
1073  if (reply->nb_transports >= RTSP_MAX_TRANSPORTS)
1074  break;
1075  }
1076 }
1077 
1078 static void handle_rtp_info(RTSPState *rt, const char *url,
1079  uint32_t seq, uint32_t rtptime)
1080 {
1081  int i;
1082  if (!rtptime || !url[0])
1083  return;
1084  if (rt->transport != RTSP_TRANSPORT_RTP)
1085  return;
1086  for (i = 0; i < rt->nb_rtsp_streams; i++) {
1087  RTSPStream *rtsp_st = rt->rtsp_streams[i];
1088  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
1089  if (!rtpctx)
1090  continue;
1091  if (!strcmp(rtsp_st->control_url, url)) {
1092  rtpctx->base_timestamp = rtptime;
1093  break;
1094  }
1095  }
1096 }
1097 
1098 static void rtsp_parse_rtp_info(RTSPState *rt, const char *p)
1099 {
1100  int read = 0;
1101  char key[20], value[MAX_URL_SIZE], url[MAX_URL_SIZE] = "";
1102  uint32_t seq = 0, rtptime = 0;
1103 
1104  for (;;) {
1105  p += strspn(p, SPACE_CHARS);
1106  if (!*p)
1107  break;
1108  get_word_sep(key, sizeof(key), "=", &p);
1109  if (*p != '=')
1110  break;
1111  p++;
1112  get_word_sep(value, sizeof(value), ";, ", &p);
1113  read++;
1114  if (!strcmp(key, "url"))
1115  av_strlcpy(url, value, sizeof(url));
1116  else if (!strcmp(key, "seq"))
1117  seq = strtoul(value, NULL, 10);
1118  else if (!strcmp(key, "rtptime"))
1119  rtptime = strtoul(value, NULL, 10);
1120  if (*p == ',') {
1121  handle_rtp_info(rt, url, seq, rtptime);
1122  url[0] = '\0';
1123  seq = rtptime = 0;
1124  read = 0;
1125  }
1126  if (*p)
1127  p++;
1128  }
1129  if (read > 0)
1130  handle_rtp_info(rt, url, seq, rtptime);
1131 }
1132 
1134  RTSPMessageHeader *reply, const char *buf,
1135  RTSPState *rt, const char *method)
1136 {
1137  const char *p;
1138 
1139  /* NOTE: we do case independent match for broken servers */
1140  p = buf;
1141  if (av_stristart(p, "Session:", &p)) {
1142  int t;
1143  get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p);
1144  if (av_stristart(p, ";timeout=", &p) &&
1145  (t = strtol(p, NULL, 10)) > 0) {
1146  reply->timeout = t;
1147  }
1148  } else if (av_stristart(p, "Content-Length:", &p)) {
1149  reply->content_length = strtol(p, NULL, 10);
1150  } else if (av_stristart(p, "Transport:", &p)) {
1151  rtsp_parse_transport(s, reply, p);
1152  } else if (av_stristart(p, "CSeq:", &p)) {
1153  reply->seq = strtol(p, NULL, 10);
1154  } else if (av_stristart(p, "Range:", &p)) {
1155  rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end);
1156  } else if (av_stristart(p, "RealChallenge1:", &p)) {
1157  p += strspn(p, SPACE_CHARS);
1158  av_strlcpy(reply->real_challenge, p, sizeof(reply->real_challenge));
1159  } else if (av_stristart(p, "Server:", &p)) {
1160  p += strspn(p, SPACE_CHARS);
1161  av_strlcpy(reply->server, p, sizeof(reply->server));
1162  } else if (av_stristart(p, "Notice:", &p) ||
1163  av_stristart(p, "X-Notice:", &p)) {
1164  reply->notice = strtol(p, NULL, 10);
1165  } else if (av_stristart(p, "Location:", &p)) {
1166  p += strspn(p, SPACE_CHARS);
1167  av_strlcpy(reply->location, p , sizeof(reply->location));
1168  } else if (av_stristart(p, "WWW-Authenticate:", &p) && rt) {
1169  p += strspn(p, SPACE_CHARS);
1170  ff_http_auth_handle_header(&rt->auth_state, "WWW-Authenticate", p);
1171  } else if (av_stristart(p, "Authentication-Info:", &p) && rt) {
1172  p += strspn(p, SPACE_CHARS);
1173  ff_http_auth_handle_header(&rt->auth_state, "Authentication-Info", p);
1174  } else if (av_stristart(p, "Content-Base:", &p) && rt) {
1175  p += strspn(p, SPACE_CHARS);
1176  if (method && !strcmp(method, "DESCRIBE"))
1177  av_strlcpy(rt->control_uri, p , sizeof(rt->control_uri));
1178  } else if (av_stristart(p, "RTP-Info:", &p) && rt) {
1179  p += strspn(p, SPACE_CHARS);
1180  if (method && !strcmp(method, "PLAY"))
1181  rtsp_parse_rtp_info(rt, p);
1182  } else if (av_stristart(p, "Public:", &p) && rt) {
1183  if (strstr(p, "GET_PARAMETER") &&
1184  method && !strcmp(method, "OPTIONS"))
1185  rt->get_parameter_supported = 1;
1186  } else if (av_stristart(p, "x-Accept-Dynamic-Rate:", &p) && rt) {
1187  p += strspn(p, SPACE_CHARS);
1188  rt->accept_dynamic_rate = atoi(p);
1189  } else if (av_stristart(p, "Content-Type:", &p)) {
1190  p += strspn(p, SPACE_CHARS);
1191  av_strlcpy(reply->content_type, p, sizeof(reply->content_type));
1192  } else if (av_stristart(p, "com.ses.streamID:", &p)) {
1193  p += strspn(p, SPACE_CHARS);
1194  av_strlcpy(reply->stream_id, p, sizeof(reply->stream_id));
1195  }
1196 }
1197 
1198 /* skip a RTP/TCP interleaved packet */
1200 {
1201  RTSPState *rt = s->priv_data;
1202  int ret, len, len1;
1203  uint8_t buf[MAX_URL_SIZE];
1204 
1205  rt->pending_packet = 0;
1206  ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
1207  if (ret != 3)
1208  return ret < 0 ? ret : AVERROR(EIO);
1209  len = AV_RB16(buf + 1);
1210 
1211  av_log(s, AV_LOG_TRACE, "skipping RTP packet len=%d\n", len);
1212 
1213  /* skip payload */
1214  while (len > 0) {
1215  len1 = len;
1216  if (len1 > sizeof(buf))
1217  len1 = sizeof(buf);
1218  ret = ffurl_read_complete(rt->rtsp_hd, buf, len1);
1219  if (ret != len1)
1220  return ret < 0 ? ret : AVERROR(EIO);
1221  len -= len1;
1222  }
1223 
1224  return 0;
1225 }
1226 
1227 static int ff_rtsp_read_reply_internal(AVFormatContext *s,
1228  RTSPMessageHeader *reply,
1229  unsigned char **content_ptr,
1230  int return_on_interleaved_data,
1231  const char *method)
1232 {
1233  RTSPState *rt = s->priv_data;
1234  char buf[MAX_URL_SIZE], buf1[MAX_URL_SIZE], *q;
1235  unsigned char ch;
1236  const char *p;
1237  int ret, content_length, line_count, request;
1238  unsigned char *content;
1239 
1240 start:
1241  line_count = 0;
1242  request = 0;
1243  content = NULL;
1244  memset(reply, 0, sizeof(*reply));
1245 
1246  /* parse reply (XXX: use buffers) */
1247  rt->last_reply[0] = '\0';
1248  for (;;) {
1249  q = buf;
1250  for (;;) {
1251  ret = ffurl_read_complete(rt->rtsp_hd, &ch, 1);
1252  if (ret != 1) {
1253  ret = (ret < 0) ? ret : AVERROR(EIO);
1254  av_log(s, AV_LOG_WARNING, "Failed reading RTSP data: %s\n", av_err2str(ret));
1255  return ret;
1256  }
1257  av_log(s, AV_LOG_TRACE, "ret=%d c=%02x [%c]\n", ret, ch, ch);
1258  if (ch == '\n')
1259  break;
1260  if (ch == '$' && q == buf) {
1261  if (return_on_interleaved_data) {
1262  rt->pending_packet = 1;
1263  return 1;
1264  } else {
1266  if (ret < 0)
1267  return ret;
1268  }
1269  } else if (ch != '\r') {
1270  if ((q - buf) < sizeof(buf) - 1)
1271  *q++ = ch;
1272  }
1273  }
1274  *q = '\0';
1275 
1276  av_log(s, AV_LOG_TRACE, "line='%s'\n", buf);
1277 
1278  /* test if last line */
1279  if (buf[0] == '\0')
1280  break;
1281  p = buf;
1282  if (line_count == 0) {
1283  /* get reply code */
1284  get_word(buf1, sizeof(buf1), &p);
1285  if (!strncmp(buf1, "RTSP/", 5)) {
1286  get_word(buf1, sizeof(buf1), &p);
1287  reply->status_code = atoi(buf1);
1288  p += strspn(p, SPACE_CHARS);
1289  av_strlcpy(reply->reason, p, sizeof(reply->reason));
1290  } else {
1291  av_strlcpy(reply->reason, buf1, sizeof(reply->reason)); // method
1292  get_word(buf1, sizeof(buf1), &p); // object
1293  request = 1;
1294  }
1295  } else {
1296  ff_rtsp_parse_line(s, reply, p, rt, method);
1297  av_strlcat(rt->last_reply, p, sizeof(rt->last_reply));
1298  av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply));
1299  }
1300  line_count++;
1301  }
1302 
1303  if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0' && !request)
1304  av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id));
1305 
1306  content_length = reply->content_length;
1307  if (content_length > 0) {
1308  /* leave some room for a trailing '\0' (useful for simple parsing) */
1309  content = av_malloc(content_length + 1);
1310  if (!content)
1311  return AVERROR(ENOMEM);
1312  if ((ret = ffurl_read_complete(rt->rtsp_hd, content, content_length)) != content_length) {
1313  av_freep(&content);
1314  return ret < 0 ? ret : AVERROR(EIO);
1315  }
1316  content[content_length] = '\0';
1317  }
1318  if (content_ptr)
1319  *content_ptr = content;
1320  else
1321  av_freep(&content);
1322 
1323  if (request) {
1324  char buf[MAX_URL_SIZE];
1325  char base64buf[AV_BASE64_SIZE(sizeof(buf))];
1326  const char* ptr = buf;
1327 
1328  if (!strcmp(reply->reason, "OPTIONS") ||
1329  !strcmp(reply->reason, "GET_PARAMETER")) {
1330  snprintf(buf, sizeof(buf), "RTSP/1.0 200 OK\r\n");
1331  if (reply->seq)
1332  av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", reply->seq);
1333  if (reply->session_id[0])
1334  av_strlcatf(buf, sizeof(buf), "Session: %s\r\n",
1335  reply->session_id);
1336  } else {
1337  snprintf(buf, sizeof(buf), "RTSP/1.0 501 Not Implemented\r\n");
1338  }
1339  av_strlcat(buf, "\r\n", sizeof(buf));
1340 
1341  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1342  av_base64_encode(base64buf, sizeof(base64buf), buf, strlen(buf));
1343  ptr = base64buf;
1344  }
1345  ffurl_write(rt->rtsp_hd_out, ptr, strlen(ptr));
1346 
1348  /* Even if the request from the server had data, it is not the data
1349  * that the caller wants or expects. The memory could also be leaked
1350  * if the actual following reply has content data. */
1351  if (content_ptr)
1352  av_freep(content_ptr);
1353  /* If method is set, this is called from ff_rtsp_send_cmd,
1354  * where a reply to exactly this request is awaited. For
1355  * callers from within packet receiving, we just want to
1356  * return to the caller and go back to receiving packets. */
1357  if (method)
1358  goto start;
1359  return 0;
1360  }
1361 
1362  if (rt->seq != reply->seq) {
1363  av_log(s, AV_LOG_WARNING, "CSeq %d expected, %d received.\n",
1364  rt->seq, reply->seq);
1365  }
1366 
1367  /* EOS */
1368  if (reply->notice == 2101 /* End-of-Stream Reached */ ||
1369  reply->notice == 2104 /* Start-of-Stream Reached */ ||
1370  reply->notice == 2306 /* Continuous Feed Terminated */) {
1371  rt->state = RTSP_STATE_IDLE;
1372  } else if (reply->notice >= 4400 && reply->notice < 5500) {
1373  return AVERROR(EIO); /* data or server error */
1374  } else if (reply->notice == 2401 /* Ticket Expired */ ||
1375  (reply->notice >= 5500 && reply->notice < 5600) /* end of term */ )
1376  return AVERROR(EPERM);
1377 
1378  return 0;
1379 }
1380 
1382  unsigned char **content_ptr,
1383  int return_on_interleaved_data, const char *method)
1384 {
1385  int ret;
1386  RTSPState *rt = s->priv_data;
1387 
1388  // If we returned on pending packet last time,
1389  // do not try to read again, as it would corrupt
1390  // the state due to the already consumed '$'.
1391  if (rt->pending_packet) {
1392  if (return_on_interleaved_data)
1393  return 1;
1394 
1396  if (ret < 0)
1397  return ret;
1398  }
1399 
1400  if (rt->stored_msg.expected_seq != -1) {
1402 
1403  ret = ff_rtsp_read_reply_internal(s, &header,
1404  &rt->stored_msg.body, return_on_interleaved_data, NULL);
1405  if (ret != 0)
1406  return ret;
1407 
1408  if (rt->stored_msg.expected_seq == header.seq) {
1409  // Got the expected reply, store it for later
1410  rt->stored_msg.expected_seq = -1;
1411  rt->stored_msg.header = av_calloc(1, sizeof(*rt->stored_msg.header));
1412  if (!rt->stored_msg.header) {
1413  av_freep(&rt->stored_msg.body);
1414  return AVERROR(ENOMEM);
1415  }
1416  memcpy(rt->stored_msg.header, &header, sizeof(header));
1417  } else {
1418  av_log(s, AV_LOG_WARNING, "Unexpected reply with seq %d, expected %d\n",
1419  header.seq, rt->stored_msg.expected_seq);
1420  av_freep(&rt->stored_msg.body);
1421  }
1422 
1423  // Do not return here as we still need to read the reply
1424  // the caller was actually wanting to retrieve.
1425  }
1426 
1427  return ff_rtsp_read_reply_internal(s, reply, content_ptr,
1428  return_on_interleaved_data, method);
1429 }
1430 
1431 /**
1432  * Send a command to the RTSP server without waiting for the reply.
1433  *
1434  * @param s RTSP (de)muxer context
1435  * @param method the method for the request
1436  * @param url the target url for the request
1437  * @param headers extra header lines to include in the request
1438  * @param send_content if non-null, the data to send as request body content
1439  * @param send_content_length the length of the send_content data, or 0 if
1440  * send_content is null
1441  *
1442  * @return zero if success, nonzero otherwise
1443  */
1445  const char *method, const char *url,
1446  const char *headers,
1447  const unsigned char *send_content,
1448  int send_content_length)
1449 {
1450  RTSPState *rt = s->priv_data;
1451  char buf[MAX_URL_SIZE], *out_buf;
1452  char base64buf[AV_BASE64_SIZE(sizeof(buf))];
1453 
1454  if (!rt->rtsp_hd_out)
1455  return AVERROR(ENOTCONN);
1456 
1457  /* Add in RTSP headers */
1458  out_buf = buf;
1459  rt->seq++;
1460  snprintf(buf, sizeof(buf), "%s %s RTSP/1.0\r\n", method, url);
1461  if (headers)
1462  av_strlcat(buf, headers, sizeof(buf));
1463  av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", rt->seq);
1464  av_strlcatf(buf, sizeof(buf), "User-Agent: %s\r\n", rt->user_agent);
1465  if (rt->session_id[0] != '\0' && (!headers ||
1466  !strstr(headers, "\nIf-Match:"))) {
1467  av_strlcatf(buf, sizeof(buf), "Session: %s\r\n", rt->session_id);
1468  }
1469  if (rt->auth[0]) {
1470  char *str = ff_http_auth_create_response(&rt->auth_state,
1471  rt->auth, url, method);
1472  if (str)
1473  av_strlcat(buf, str, sizeof(buf));
1474  av_free(str);
1475  }
1476  if (send_content_length > 0 && send_content)
1477  av_strlcatf(buf, sizeof(buf), "Content-Length: %d\r\n", send_content_length);
1478  av_strlcat(buf, "\r\n", sizeof(buf));
1479 
1480  /* base64 encode rtsp if tunneling */
1481  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1482  av_base64_encode(base64buf, sizeof(base64buf), buf, strlen(buf));
1483  out_buf = base64buf;
1484  }
1485 
1486  av_log(s, AV_LOG_TRACE, "Sending:\n%s--\n", buf);
1487 
1488  ffurl_write(rt->rtsp_hd_out, out_buf, strlen(out_buf));
1489  if (send_content_length > 0 && send_content) {
1490  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1491  avpriv_report_missing_feature(s, "Tunneling of RTSP requests with content data");
1492  return AVERROR_PATCHWELCOME;
1493  }
1494  ffurl_write(rt->rtsp_hd_out, send_content, send_content_length);
1495  }
1497 
1498  return 0;
1499 }
1500 
1502  const char *method, const char *url,
1503  const char *headers,
1504  const unsigned char *send_content,
1505  int send_content_length)
1506 {
1507  RTSPState *rt = s->priv_data;
1508  int ret = ff_rtsp_send_cmd_with_content_async(s, method, url, headers,
1509  send_content, send_content_length);
1510  if (ret < 0)
1511  return ret;
1512 
1513  rt->stored_msg.expected_seq = rt->seq;
1514  av_freep(&rt->stored_msg.header);
1515  av_freep(&rt->stored_msg.body);
1516  return 0;
1517 }
1518 
1519 int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method,
1520  const char *url, const char *headers)
1521 {
1522  return ff_rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
1523 }
1524 
1525 int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url,
1526  const char *headers, RTSPMessageHeader *reply,
1527  unsigned char **content_ptr)
1528 {
1529  return ff_rtsp_send_cmd_with_content(s, method, url, headers, reply,
1530  content_ptr, NULL, 0);
1531 }
1532 
1534  const char *method, const char *url,
1535  const char *header,
1536  RTSPMessageHeader *reply,
1537  unsigned char **content_ptr,
1538  const unsigned char *send_content,
1539  int send_content_length)
1540 {
1541  RTSPState *rt = s->priv_data;
1542  HTTPAuthType cur_auth_type;
1543  int ret, attempts = 0;
1544 
1545 retry:
1546  cur_auth_type = rt->auth_state.auth_type;
1547  if ((ret = ff_rtsp_send_cmd_with_content_async(s, method, url, header,
1548  send_content,
1549  send_content_length)) < 0)
1550  return ret;
1551 
1552  if ((ret = ff_rtsp_read_reply(s, reply, content_ptr, 0, method) ) < 0)
1553  return ret;
1554  attempts++;
1555 
1556  if (reply->status_code == 401 &&
1557  (cur_auth_type == HTTP_AUTH_NONE || rt->auth_state.stale) &&
1558  rt->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2)
1559  goto retry;
1560 
1561  if (reply->status_code > 400){
1562  av_log(s, AV_LOG_ERROR, "method %s failed: %d (%s)\n",
1563  method,
1564  reply->status_code,
1565  reply->reason);
1566  av_log(s, AV_LOG_DEBUG, "%s\n", rt->last_reply);
1567  }
1568 
1569  return 0;
1570 }
1571 
1573  unsigned char **content_ptr)
1574 {
1575  RTSPState *rt = s->priv_data;
1576  if (rt->stored_msg.header == NULL) {
1577  if (rt->stored_msg.expected_seq == -1)
1578  return AVERROR(EINVAL); // Reply to be stored was never requested
1579 
1580  // Reply pending, tell caller to try again later
1581  return AVERROR(EAGAIN);
1582  }
1583 
1584  if (reply)
1585  *reply = rt->stored_msg.header;
1586  else
1587  av_free(rt->stored_msg.header);
1588 
1589  if (content_ptr)
1590  *content_ptr = rt->stored_msg.body;
1591  else
1592  av_free(rt->stored_msg.body);
1593 
1594  rt->stored_msg.header = NULL;
1595  rt->stored_msg.body = NULL;
1596  return 0;
1597 }
1598 
1599 int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
1600  int lower_transport, const char *real_challenge)
1601 {
1602  RTSPState *rt = s->priv_data;
1603  int rtx = 0, j, i, err, interleave = 0, port_off = 0;
1604  RTSPStream *rtsp_st;
1605  RTSPMessageHeader reply1, *reply = &reply1;
1606  char cmd[MAX_URL_SIZE];
1607  const char *trans_pref;
1608 
1609  memset(&reply1, 0, sizeof(reply1));
1610 
1611  if (rt->transport == RTSP_TRANSPORT_RDT)
1612  trans_pref = "x-pn-tng";
1613  else if (rt->transport == RTSP_TRANSPORT_RAW)
1614  trans_pref = "RAW/RAW";
1615  else
1616  trans_pref = "RTP/AVP";
1617 
1618  /* default timeout: 1 minute */
1619  rt->timeout = 60;
1620 
1621  /* Choose a random starting offset within the first half of the
1622  * port range, to allow for a number of ports to try even if the offset
1623  * happens to be at the end of the random range. */
1624  if (rt->rtp_port_max - rt->rtp_port_min >= 4) {
1625  port_off = av_get_random_seed() % ((rt->rtp_port_max - rt->rtp_port_min)/2);
1626  /* even random offset */
1627  port_off -= port_off & 0x01;
1628  }
1629 
1630  for (j = rt->rtp_port_min + port_off, i = 0; i < rt->nb_rtsp_streams; ++i) {
1631  char transport[MAX_URL_SIZE];
1632 
1633  /*
1634  * WMS serves all UDP data over a single connection, the RTX, which
1635  * isn't necessarily the first in the SDP but has to be the first
1636  * to be set up, else the second/third SETUP will fail with a 461.
1637  */
1638  if (lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
1639  rt->server_type == RTSP_SERVER_WMS) {
1640  if (i == 0) {
1641  /* rtx first */
1642  for (rtx = 0; rtx < rt->nb_rtsp_streams; rtx++) {
1643  int len = strlen(rt->rtsp_streams[rtx]->control_url);
1644  if (len >= 4 &&
1645  !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4,
1646  "/rtx"))
1647  break;
1648  }
1649  if (rtx == rt->nb_rtsp_streams)
1650  return -1; /* no RTX found */
1651  rtsp_st = rt->rtsp_streams[rtx];
1652  } else
1653  rtsp_st = rt->rtsp_streams[i > rtx ? i : i - 1];
1654  } else
1655  rtsp_st = rt->rtsp_streams[i];
1656 
1657  /* RTP/UDP */
1658  if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
1659  char buf[256];
1660 
1661  if (rt->server_type == RTSP_SERVER_WMS && i > 1) {
1662  port = reply->transports[0].client_port_min;
1663  goto have_port;
1664  }
1665 
1666  /* first try in specified port range */
1667  while (j + 1 <= rt->rtp_port_max) {
1668  AVDictionary *opts = map_to_opts(rt);
1669 
1670  ff_url_join(buf, sizeof(buf), "rtp", NULL, host, -1,
1671  "?localrtpport=%d", j);
1672  /* we will use two ports per rtp stream (rtp and rtcp) */
1673  j += 2;
1675  &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);
1676 
1677  av_dict_free(&opts);
1678 
1679  if (!err)
1680  goto rtp_opened;
1681  }
1682  av_log(s, AV_LOG_ERROR, "Unable to open an input RTP port\n");
1683  err = AVERROR(EIO);
1684  goto fail;
1685 
1686  rtp_opened:
1687  port = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
1688  have_port:
1689  av_strlcpy(transport, trans_pref, sizeof(transport));
1690  av_strlcat(transport,
1691  rt->server_type == RTSP_SERVER_SATIP ? ";" : "/UDP;",
1692  sizeof(transport));
1693  if (rt->server_type != RTSP_SERVER_REAL)
1694  av_strlcat(transport, "unicast;", sizeof(transport));
1695  av_strlcatf(transport, sizeof(transport),
1696  "client_port=%d", port);
1697  if (rt->transport == RTSP_TRANSPORT_RTP &&
1698  !(rt->server_type == RTSP_SERVER_WMS && i > 0))
1699  av_strlcatf(transport, sizeof(transport), "-%d", port + 1);
1700  }
1701 
1702  /* RTP/TCP */
1703  else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
1704  /* For WMS streams, the application streams are only used for
1705  * UDP. When trying to set it up for TCP streams, the server
1706  * will return an error. Therefore, we skip those streams. */
1707  if (rt->server_type == RTSP_SERVER_WMS &&
1708  (rtsp_st->stream_index < 0 ||
1709  s->streams[rtsp_st->stream_index]->codecpar->codec_type ==
1711  continue;
1712  snprintf(transport, sizeof(transport) - 1,
1713  "%s/TCP;", trans_pref);
1714  if (rt->transport != RTSP_TRANSPORT_RDT)
1715  av_strlcat(transport, "unicast;", sizeof(transport));
1716  av_strlcatf(transport, sizeof(transport),
1717  "interleaved=%d-%d",
1718  interleave, interleave + 1);
1719  interleave += 2;
1720  }
1721 
1722  else if (lower_transport == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) {
1723  snprintf(transport, sizeof(transport) - 1,
1724  "%s/UDP;multicast", trans_pref);
1725  } else {
1726  err = AVERROR(EINVAL);
1727  goto fail; // transport would be uninitialized
1728  }
1729 
1730  if (s->oformat) {
1731  av_strlcat(transport, ";mode=record", sizeof(transport));
1732  } else if (rt->server_type == RTSP_SERVER_REAL ||
1734  av_strlcat(transport, ";mode=play", sizeof(transport));
1735  snprintf(cmd, sizeof(cmd),
1736  "Transport: %s\r\n",
1737  transport);
1738  if (rt->accept_dynamic_rate)
1739  av_strlcat(cmd, "x-Dynamic-Rate: 0\r\n", sizeof(cmd));
1740  if (CONFIG_RTPDEC && i == 0 && rt->server_type == RTSP_SERVER_REAL) {
1741  char real_res[41], real_csum[9];
1742  ff_rdt_calc_response_and_checksum(real_res, real_csum,
1743  real_challenge);
1744  av_strlcatf(cmd, sizeof(cmd),
1745  "If-Match: %s\r\n"
1746  "RealChallenge2: %s, sd=%s\r\n",
1747  rt->session_id, real_res, real_csum);
1748  }
1749  ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL);
1750  if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) {
1751  err = 1;
1752  goto fail;
1753  } else if (reply->status_code != RTSP_STATUS_OK ||
1754  reply->nb_transports != 1) {
1756  goto fail;
1757  }
1758 
1759  if (rt->server_type == RTSP_SERVER_SATIP && reply->stream_id[0]) {
1760  char proto[128], host[128], path[512], auth[128];
1761  int port;
1762  av_url_split(proto, sizeof(proto), auth, sizeof(auth), host, sizeof(host),
1763  &port, path, sizeof(path), rt->control_uri);
1764  ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL, host,
1765  port, "/stream=%s", reply->stream_id);
1766  }
1767 
1768  /* XXX: same protocol for all streams is required */
1769  if (i > 0) {
1770  if (reply->transports[0].lower_transport != rt->lower_transport ||
1771  reply->transports[0].transport != rt->transport) {
1772  err = AVERROR_INVALIDDATA;
1773  goto fail;
1774  }
1775  } else {
1776  rt->lower_transport = reply->transports[0].lower_transport;
1777  rt->transport = reply->transports[0].transport;
1778  }
1779 
1780  /* Fail if the server responded with another lower transport mode
1781  * than what we requested. */
1782  if (reply->transports[0].lower_transport != lower_transport) {
1783  av_log(s, AV_LOG_ERROR, "Nonmatching transport in server reply\n");
1784  err = AVERROR_INVALIDDATA;
1785  goto fail;
1786  }
1787 
1788  switch(reply->transports[0].lower_transport) {
1790  rtsp_st->interleaved_min = reply->transports[0].interleaved_min;
1791  rtsp_st->interleaved_max = reply->transports[0].interleaved_max;
1792  break;
1793 
1794  case RTSP_LOWER_TRANSPORT_UDP: {
1795  char url[MAX_URL_SIZE], options[30] = "";
1796  const char *peer = host;
1797 
1798  if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
1799  av_strlcpy(options, "?connect=1", sizeof(options));
1800  /* Use source address if specified */
1801  if (reply->transports[0].source[0])
1802  peer = reply->transports[0].source;
1803  ff_url_join(url, sizeof(url), "rtp", NULL, peer,
1804  reply->transports[0].server_port_min, "%s", options);
1805  if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
1806  ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
1807  err = AVERROR_INVALIDDATA;
1808  goto fail;
1809  }
1810  break;
1811  }
1813  char url[MAX_URL_SIZE], namebuf[50], optbuf[20] = "";
1814  struct sockaddr_storage addr;
1815  int port, ttl;
1816  AVDictionary *opts = map_to_opts(rt);
1817 
1818  if (reply->transports[0].destination.ss_family) {
1819  addr = reply->transports[0].destination;
1820  port = reply->transports[0].port_min;
1821  ttl = reply->transports[0].ttl;
1822  } else {
1823  addr = rtsp_st->sdp_ip;
1824  port = rtsp_st->sdp_port;
1825  ttl = rtsp_st->sdp_ttl;
1826  }
1827  if (ttl > 0)
1828  snprintf(optbuf, sizeof(optbuf), "?ttl=%d", ttl);
1829  getnameinfo((struct sockaddr*) &addr, sizeof(addr),
1830  namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
1831  ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
1832  port, "%s", optbuf);
1834  &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);
1835  av_dict_free(&opts);
1836 
1837  if (err < 0) {
1838  err = AVERROR_INVALIDDATA;
1839  goto fail;
1840  }
1841  break;
1842  }
1843  }
1844 
1845  if ((err = ff_rtsp_open_transport_ctx(s, rtsp_st)))
1846  goto fail;
1847  }
1848 
1849  if (rt->nb_rtsp_streams && reply->timeout > 0)
1850  rt->timeout = reply->timeout;
1851 
1852  if (rt->server_type == RTSP_SERVER_REAL)
1853  rt->need_subscription = 1;
1854 
1855  return 0;
1856 
1857 fail:
1858  ff_rtsp_undo_setup(s, 0);
1859  return err;
1860 }
1861 
1863 {
1864  RTSPState *rt = s->priv_data;
1865  if (rt->rtsp_hd_out != rt->rtsp_hd)
1866  ffurl_closep(&rt->rtsp_hd_out);
1867  rt->rtsp_hd_out = NULL;
1868  ffurl_closep(&rt->rtsp_hd);
1869 }
1870 
1871 static int rtsp_url_same_origin(const char *url1, const char *url2)
1872 {
1873  char proto1[128], proto2[128];
1874  char host1[1024], host2[1024];
1875  int port1, port2;
1876 
1877  av_url_split(proto1, sizeof(proto1), NULL, 0, host1, sizeof(host1),
1878  &port1, NULL, 0, url1);
1879  av_url_split(proto2, sizeof(proto2), NULL, 0, host2, sizeof(host2),
1880  &port2, NULL, 0, url2);
1881 
1882  if (!proto1[0] || !proto2[0] || !host1[0] || !host2[0])
1883  return 0;
1884 
1885  if (port1 < 0)
1886  port1 = !av_strcasecmp(proto1, "rtsps") ? RTSPS_DEFAULT_PORT
1888  if (port2 < 0)
1889  port2 = !av_strcasecmp(proto2, "rtsps") ? RTSPS_DEFAULT_PORT
1891 
1892  return !av_strcasecmp(proto1, proto2) &&
1893  !av_strcasecmp(host1, host2) &&
1894  port1 == port2;
1895 }
1896 
1898 {
1899  RTSPState *rt = s->priv_data;
1900  char proto[128], host[1024], path[2048];
1901  char tcpname[1024], cmd[MAX_URL_SIZE], auth[128];
1902  const char *lower_rtsp_proto = "tcp";
1903  int port, err, tcp_fd;
1904  RTSPMessageHeader reply1, *reply = &reply1;
1905  int lower_transport_mask = 0;
1906  int default_port = RTSP_DEFAULT_PORT;
1907  int https_tunnel = 0;
1908  char real_challenge[64] = "";
1909  struct sockaddr_storage peer;
1910  socklen_t peer_len = sizeof(peer);
1911 
1912  rt->stored_msg.expected_seq = -1;
1913  if (rt->rtp_port_max < rt->rtp_port_min) {
1914  av_log(s, AV_LOG_ERROR, "Invalid UDP port range, max port %d less "
1915  "than min port %d\n", rt->rtp_port_max,
1916  rt->rtp_port_min);
1917  return AVERROR(EINVAL);
1918  }
1919 
1920  if ((err = ff_network_init()) < 0)
1921  return err;
1922 
1923  if (s->max_delay < 0) /* Not set by the caller */
1924  s->max_delay = s->iformat ? DEFAULT_REORDERING_DELAY : 0;
1925 
1928  (1 << RTSP_LOWER_TRANSPORT_HTTPS))) {
1929  https_tunnel = !!(rt->lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_HTTPS));
1932  }
1933  /* Only pass through valid flags from here */
1935 
1936 redirect:
1937  memset(&reply1, 0, sizeof(reply1));
1938  /* extract hostname and port */
1939  av_url_split(proto, sizeof(proto), auth, sizeof(auth),
1940  host, sizeof(host), &port, path, sizeof(path), s->url);
1941 
1942  if (!strcmp(proto, "rtsps")) {
1943  lower_rtsp_proto = "tls";
1944  default_port = RTSPS_DEFAULT_PORT;
1946  } else if (!strcmp(proto, "satip")) {
1947  av_strlcpy(proto, "rtsp", sizeof(proto));
1949  } else if (strcmp(proto, "rtsp"))
1950  return AVERROR_INVALIDDATA;
1951 
1952  if (*auth) {
1953  av_strlcpy(rt->auth, auth, sizeof(rt->auth));
1954  }
1955  if (port < 0)
1956  port = default_port;
1957 
1958  lower_transport_mask = rt->lower_transport_mask;
1959 
1960  if (!lower_transport_mask)
1961  lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
1962 
1963  if (s->oformat) {
1964  /* Only UDP or TCP - UDP multicast isn't supported. */
1965  lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_UDP) |
1966  (1 << RTSP_LOWER_TRANSPORT_TCP);
1967  if (!lower_transport_mask || rt->control_transport == RTSP_MODE_TUNNEL) {
1968  av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, "
1969  "only UDP and TCP are supported for output.\n");
1970  err = AVERROR(EINVAL);
1971  goto fail;
1972  }
1973  }
1974 
1975  /* Construct the URI used in request; this is similar to s->url,
1976  * but with authentication credentials removed and RTSP specific options
1977  * stripped out. */
1978  ff_url_join(rt->control_uri, sizeof(rt->control_uri), proto, NULL,
1979  host, port, "%s", path);
1980 
1981  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1982  /* set up initial handshake for tunneling */
1983  char httpname[1024];
1984  char sessioncookie[17];
1985  char headers[1024];
1987 
1988  av_dict_set_int(&options, "timeout", rt->stimeout, 0);
1989  if (https_tunnel) {
1990  int ret = copy_tls_opts_dict(rt, &options);
1991  if (ret < 0) {
1993  err = ret;
1994  goto fail;
1995  }
1996  }
1997 
1998  ff_url_join(httpname, sizeof(httpname), https_tunnel ? "https" : "http", auth, host, port, "%s", path);
1999  snprintf(sessioncookie, sizeof(sessioncookie), "%08x%08x",
2001 
2002  /* GET requests */
2003  if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_FLAG_READ,
2004  &s->interrupt_callback) < 0) {
2006  err = AVERROR(EIO);
2007  goto fail;
2008  }
2009 
2010  /* generate GET headers */
2011  snprintf(headers, sizeof(headers),
2012  "x-sessioncookie: %s\r\n"
2013  "Accept: application/x-rtsp-tunnelled\r\n"
2014  "Pragma: no-cache\r\n"
2015  "Cache-Control: no-cache\r\n",
2016  sessioncookie);
2017  av_opt_set(rt->rtsp_hd->priv_data, "headers", headers, 0);
2018 
2019  if (!rt->rtsp_hd->protocol_whitelist && s->protocol_whitelist) {
2020  rt->rtsp_hd->protocol_whitelist = av_strdup(s->protocol_whitelist);
2021  if (!rt->rtsp_hd->protocol_whitelist) {
2023  err = AVERROR(ENOMEM);
2024  goto fail;
2025  }
2026  }
2027 
2028  if (!rt->rtsp_hd->protocol_blacklist && s->protocol_blacklist) {
2029  rt->rtsp_hd->protocol_blacklist = av_strdup(s->protocol_blacklist);
2030  if (!rt->rtsp_hd->protocol_blacklist) {
2032  err = AVERROR(ENOMEM);
2033  goto fail;
2034  }
2035  }
2036 
2037  /* complete the connection */
2038  if (ffurl_connect(rt->rtsp_hd, &options)) {
2040  err = AVERROR(EIO);
2041  goto fail;
2042  }
2043 
2044  /* POST requests */
2045  if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_FLAG_WRITE,
2046  &s->interrupt_callback) < 0 ) {
2048  err = AVERROR(EIO);
2049  goto fail;
2050  }
2051 
2052  /* generate POST headers */
2053  snprintf(headers, sizeof(headers),
2054  "x-sessioncookie: %s\r\n"
2055  "Content-Type: application/x-rtsp-tunnelled\r\n"
2056  "Pragma: no-cache\r\n"
2057  "Cache-Control: no-cache\r\n"
2058  "Content-Length: 32767\r\n"
2059  "Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n",
2060  sessioncookie);
2061  av_opt_set(rt->rtsp_hd_out->priv_data, "headers", headers, 0);
2062  av_opt_set(rt->rtsp_hd_out->priv_data, "chunked_post", "0", 0);
2063  av_opt_set(rt->rtsp_hd_out->priv_data, "send_expect_100", "0", 0);
2064 
2065  /* Initialize the authentication state for the POST session. The HTTP
2066  * protocol implementation doesn't properly handle multi-pass
2067  * authentication for POST requests, since it would require one of
2068  * the following:
2069  * - implementing Expect: 100-continue, which many HTTP servers
2070  * don't support anyway, even less the RTSP servers that do HTTP
2071  * tunneling
2072  * - sending the whole POST data until getting a 401 reply specifying
2073  * what authentication method to use, then resending all that data
2074  * - waiting for potential 401 replies directly after sending the
2075  * POST header (waiting for some unspecified time)
2076  * Therefore, we copy the full auth state, which works for both basic
2077  * and digest. (For digest, we would have to synchronize the nonce
2078  * count variable between the two sessions, if we'd do more requests
2079  * with the original session, though.)
2080  */
2082 
2083  /* complete the connection */
2084  if (ffurl_connect(rt->rtsp_hd_out, &options)) {
2086  err = AVERROR(EIO);
2087  goto fail;
2088  }
2090  } else {
2091  int ret;
2092  /* open the tcp connection */
2093  AVDictionary *proto_opts = NULL;
2094  if (strcmp("tls", lower_rtsp_proto) == 0) {
2095  ret = copy_tls_opts_dict(rt, &proto_opts);
2096  if (ret < 0) {
2097  av_dict_free(&proto_opts);
2098  err = ret;
2099  goto fail;
2100  }
2101  }
2102 
2103  ff_url_join(tcpname, sizeof(tcpname), lower_rtsp_proto, NULL,
2104  host, port,
2105  "?timeout=%"PRId64, rt->stimeout);
2106  if ((ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
2107  &s->interrupt_callback, &proto_opts, s->protocol_whitelist, s->protocol_blacklist, NULL)) < 0) {
2108  av_dict_free(&proto_opts);
2109  err = ret;
2110  goto fail;
2111  }
2112  av_dict_free(&proto_opts);
2113  rt->rtsp_hd_out = rt->rtsp_hd;
2114  }
2115  rt->seq = 0;
2116 
2117  tcp_fd = ffurl_get_file_handle(rt->rtsp_hd);
2118  if (tcp_fd < 0) {
2119  err = tcp_fd;
2120  goto fail;
2121  }
2122  if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) {
2123  getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host),
2124  NULL, 0, NI_NUMERICHOST);
2125  }
2126 
2127  /* request options supported by the server; this also detects server
2128  * type */
2129  if (rt->server_type != RTSP_SERVER_SATIP)
2131  for (;;) {
2132  cmd[0] = 0;
2133  if (rt->server_type == RTSP_SERVER_REAL)
2134  av_strlcat(cmd,
2135  /*
2136  * The following entries are required for proper
2137  * streaming from a Realmedia server. They are
2138  * interdependent in some way although we currently
2139  * don't quite understand how. Values were copied
2140  * from mplayer SVN r23589.
2141  * ClientChallenge is a 16-byte ID in hex
2142  * CompanyID is a 16-byte ID in base64
2143  */
2144  "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
2145  "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
2146  "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
2147  "GUID: 00000000-0000-0000-0000-000000000000\r\n",
2148  sizeof(cmd));
2149  ff_rtsp_send_cmd(s, "OPTIONS", rt->control_uri, cmd, reply, NULL);
2150  if (reply->status_code != RTSP_STATUS_OK) {
2152  goto fail;
2153  }
2154 
2155  /* detect server type if not standard-compliant RTP */
2156  if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
2158  continue;
2159  } else if (!av_strncasecmp(reply->server, "WMServer/", 9)) {
2161  } else if (rt->server_type == RTSP_SERVER_REAL)
2162  strcpy(real_challenge, reply->real_challenge);
2163  break;
2164  }
2165 
2166 #if CONFIG_RTSP_DEMUXER
2167  if (s->iformat) {
2168  if (rt->server_type == RTSP_SERVER_SATIP)
2169  err = init_satip_stream(s);
2170  else
2171  err = ff_rtsp_setup_input_streams(s, reply);
2172  } else
2173 #endif
2174  if (CONFIG_RTSP_MUXER)
2175  err = ff_rtsp_setup_output_streams(s, host);
2176  else
2177  av_unreachable("Either muxer or demuxer must be enabled");
2178  if (err)
2179  goto fail;
2180 
2181  do {
2182  int lower_transport = ff_log2_tab[lower_transport_mask &
2183  ~(lower_transport_mask - 1)];
2184 
2185  if ((lower_transport_mask & (1 << RTSP_LOWER_TRANSPORT_TCP))
2186  && (rt->rtsp_flags & RTSP_FLAG_PREFER_TCP))
2187  lower_transport = RTSP_LOWER_TRANSPORT_TCP;
2188 
2189  err = ff_rtsp_make_setup_request(s, host, port, lower_transport,
2190  rt->server_type == RTSP_SERVER_REAL ?
2191  real_challenge : NULL);
2192  if (err < 0)
2193  goto fail;
2194  lower_transport_mask &= ~(1 << lower_transport);
2195  if (lower_transport_mask == 0 && err == 1) {
2196  err = AVERROR(EPROTONOSUPPORT);
2197  goto fail;
2198  }
2199  } while (err);
2200 
2201  rt->lower_transport_mask = lower_transport_mask;
2202  av_strlcpy(rt->real_challenge, real_challenge, sizeof(rt->real_challenge));
2203  rt->state = RTSP_STATE_IDLE;
2204  rt->seek_timestamp = 0; /* default is to start stream at position zero */
2205  return 0;
2206  fail:
2209  if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) {
2210  int ret;
2211 
2212  if (!rtsp_url_same_origin(s->url, reply->location)) {
2213  memset(rt->auth, 0, sizeof(rt->auth));
2214  memset(&rt->auth_state, 0, sizeof(rt->auth_state));
2215  }
2217  if (ret < 0) {
2218  err = ret;
2219  goto fail2;
2220  }
2221  rt->session_id[0] = '\0';
2222  av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n",
2223  reply->status_code,
2224  s->url);
2225  goto redirect;
2226  }
2227  fail2:
2228  ff_network_close();
2229  return err;
2230 }
2231 #endif /* CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER */
2232 
2233 #if CONFIG_RTPDEC
2234 #if CONFIG_RTSP_DEMUXER
2235 static int parse_rtsp_message(AVFormatContext *s)
2236 {
2237  RTSPState *rt = s->priv_data;
2238  int ret;
2239 
2240  if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
2241  if (rt->state == RTSP_STATE_STREAMING) {
2243  } else
2244  return AVERROR_EOF;
2245  } else {
2246  RTSPMessageHeader reply;
2247  ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL);
2248  if (ret < 0)
2249  return ret;
2250  /* XXX: parse message */
2251  if (rt->state != RTSP_STATE_STREAMING)
2252  return 0;
2253  }
2254 
2255  return 0;
2256 }
2257 #endif
2258 
2259 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
2260  uint8_t *buf, int buf_size, int64_t wait_end)
2261 {
2262  RTSPState *rt = s->priv_data;
2263  RTSPStream *rtsp_st;
2264  int n, i, ret;
2265  struct pollfd *p = rt->p;
2266  int *fds = NULL, fdsnum, fdsidx;
2267  int64_t runs = rt->stimeout / POLLING_TIME / 1000;
2268 
2269  if (!p) {
2270  p = rt->p = av_malloc_array(2 * rt->nb_rtsp_streams + 1, sizeof(*p));
2271  if (!p)
2272  return AVERROR(ENOMEM);
2273 
2274  if (rt->rtsp_hd) {
2275  p[rt->max_p].fd = ffurl_get_file_handle(rt->rtsp_hd);
2276  p[rt->max_p++].events = POLLIN;
2277  }
2278  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2279  rtsp_st = rt->rtsp_streams[i];
2280  if (rtsp_st->rtp_handle) {
2282  &fds, &fdsnum)) {
2283  av_log(s, AV_LOG_ERROR, "Unable to recover rtp ports\n");
2284  return ret;
2285  }
2286  if (fdsnum != 2) {
2288  "Number of fds %d not supported\n", fdsnum);
2289  av_freep(&fds);
2290  return AVERROR_INVALIDDATA;
2291  }
2292  for (fdsidx = 0; fdsidx < fdsnum; fdsidx++) {
2293  p[rt->max_p].fd = fds[fdsidx];
2294  p[rt->max_p++].events = POLLIN;
2295  }
2296  av_freep(&fds);
2297  }
2298  }
2299  }
2300 
2301  for (;;) {
2302  if (ff_check_interrupt(&s->interrupt_callback))
2303  return AVERROR_EXIT;
2304  if (wait_end && wait_end - av_gettime_relative() < 0)
2305  return AVERROR(EAGAIN);
2306  n = poll(p, rt->max_p, POLLING_TIME);
2307  if (n > 0) {
2308  int j = rt->rtsp_hd ? 1 : 0;
2309  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2310  rtsp_st = rt->rtsp_streams[i];
2311  if (rtsp_st->rtp_handle) {
2312  if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) {
2313  ret = ffurl_read(rtsp_st->rtp_handle, buf, buf_size);
2314  if (ret > 0) {
2315  *prtsp_st = rtsp_st;
2316  return ret;
2317  }
2318  }
2319  j+=2;
2320  }
2321  }
2322 #if CONFIG_RTSP_DEMUXER
2323  if (rt->rtsp_hd && p[0].revents & POLLIN) {
2324  if ((ret = parse_rtsp_message(s)) < 0) {
2325  return ret;
2326  }
2327  }
2328 #endif
2329  } else if (n == 0 && rt->stimeout > 0 && --runs <= 0) {
2330  return AVERROR(ETIMEDOUT);
2331  } else if (n < 0 && errno != EINTR)
2332  return AVERROR(errno);
2333  }
2334 }
2335 
2336 static int pick_stream(AVFormatContext *s, RTSPStream **rtsp_st,
2337  const uint8_t *buf, int len)
2338 {
2339  RTSPState *rt = s->priv_data;
2340  int i;
2341  if (len < 0)
2342  return len;
2343  if (rt->nb_rtsp_streams == 1) {
2344  *rtsp_st = rt->rtsp_streams[0];
2345  return len;
2346  }
2347  if (len >= 8 && rt->transport == RTSP_TRANSPORT_RTP) {
2348  if (RTP_PT_IS_RTCP(rt->recvbuf[1])) {
2349  int no_ssrc = 0;
2350  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2351  RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
2352  if (!rtpctx)
2353  continue;
2354  if (rtpctx->ssrc == AV_RB32(&buf[4])) {
2355  *rtsp_st = rt->rtsp_streams[i];
2356  return len;
2357  }
2358  if (!rtpctx->ssrc)
2359  no_ssrc = 1;
2360  }
2361  if (no_ssrc) {
2363  "Unable to pick stream for packet - SSRC not known for "
2364  "all streams\n");
2365  return AVERROR(EAGAIN);
2366  }
2367  } else {
2368  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2369  if ((buf[1] & 0x7f) == rt->rtsp_streams[i]->sdp_payload_type) {
2370  *rtsp_st = rt->rtsp_streams[i];
2371  return len;
2372  }
2373  }
2374  }
2375  }
2376  av_log(s, AV_LOG_WARNING, "Unable to pick stream for packet\n");
2377  return AVERROR(EAGAIN);
2378 }
2379 
2380 static int read_packet(AVFormatContext *s,
2381  RTSPStream **rtsp_st, RTSPStream *first_queue_st,
2382  int64_t wait_end)
2383 {
2384  RTSPState *rt = s->priv_data;
2385  int len;
2386 
2387  switch(rt->lower_transport) {
2388  default:
2389 #if CONFIG_RTSP_DEMUXER
2391  len = ff_rtsp_tcp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE);
2392  break;
2393 #endif
2396  len = udp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
2397  if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
2398  ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, (*rtsp_st)->rtp_handle, NULL, len);
2399  break;
2401  if (first_queue_st && rt->transport == RTSP_TRANSPORT_RTP &&
2402  wait_end && wait_end < av_gettime_relative())
2403  len = AVERROR(EAGAIN);
2404  else
2406  len = pick_stream(s, rtsp_st, rt->recvbuf, len);
2407  if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
2408  ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, NULL, s->pb, len);
2409  break;
2410  }
2411 
2412  if (len == 0)
2413  return AVERROR_EOF;
2414 
2415  return len;
2416 }
2417 
2419 {
2420  RTSPState *rt = s->priv_data;
2421  int ret, len;
2422  RTSPStream *rtsp_st, *first_queue_st = NULL;
2423  int64_t wait_end = 0;
2424 
2425  if (rt->nb_byes == rt->nb_rtsp_streams)
2426  return AVERROR_EOF;
2427 
2428  /* get next frames from the same RTP packet */
2429  if (rt->cur_transport_priv) {
2430  if (rt->transport == RTSP_TRANSPORT_RDT) {
2432  } else if (rt->transport == RTSP_TRANSPORT_RTP) {
2434  } else if (CONFIG_RTPDEC && rt->ts) {
2436  if (ret >= 0) {
2437  rt->recvbuf_pos += ret;
2438  ret = rt->recvbuf_pos < rt->recvbuf_len;
2439  }
2440  } else
2441  ret = -1;
2442  if (ret == 0) {
2443  rt->cur_transport_priv = NULL;
2444  return 0;
2445  } else if (ret == 1) {
2446  return 0;
2447  } else
2448  rt->cur_transport_priv = NULL;
2449  }
2450 
2451 redo:
2452  if (rt->transport == RTSP_TRANSPORT_RTP) {
2453  int i;
2454  int64_t first_queue_time = 0;
2455  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2456  RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
2457  int64_t queue_time;
2458  if (!rtpctx)
2459  continue;
2460  queue_time = ff_rtp_queued_packet_time(rtpctx);
2461  if (queue_time && (queue_time - first_queue_time < 0 ||
2462  !first_queue_time)) {
2463  first_queue_time = queue_time;
2464  first_queue_st = rt->rtsp_streams[i];
2465  }
2466  }
2467  if (first_queue_time) {
2468  wait_end = first_queue_time + s->max_delay;
2469  } else {
2470  wait_end = 0;
2471  first_queue_st = NULL;
2472  }
2473  }
2474 
2475  /* read next RTP packet */
2476  if (!rt->recvbuf) {
2478  if (!rt->recvbuf)
2479  return AVERROR(ENOMEM);
2480  }
2481 
2482  len = read_packet(s, &rtsp_st, first_queue_st, wait_end);
2483  if (len == AVERROR(EAGAIN) && first_queue_st &&
2484  rt->transport == RTSP_TRANSPORT_RTP) {
2486  "max delay reached. need to consume packet\n");
2487  rtsp_st = first_queue_st;
2488  ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
2489  goto end;
2490  }
2491  if (len < 0)
2492  return len;
2493 
2494  if (rt->transport == RTSP_TRANSPORT_RDT) {
2495  ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
2496  } else if (rt->transport == RTSP_TRANSPORT_RTP) {
2497  ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
2498  if (rtsp_st->feedback) {
2499  AVIOContext *pb = NULL;
2501  pb = s->pb;
2502  ff_rtp_send_rtcp_feedback(rtsp_st->transport_priv, rtsp_st->rtp_handle, pb);
2503  }
2504  if (ret < 0) {
2505  /* Either bad packet, or a RTCP packet. Check if the
2506  * first_rtcp_ntp_time field was initialized. */
2507  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
2508  if (rtpctx->first_rtcp_ntp_time != AV_NOPTS_VALUE) {
2509  /* first_rtcp_ntp_time has been initialized for this stream,
2510  * copy the same value to all other uninitialized streams,
2511  * in order to map their timestamp origin to the same ntp time
2512  * as this one. */
2513  int i;
2514  AVStream *st = NULL;
2515  if (rtsp_st->stream_index >= 0)
2516  st = s->streams[rtsp_st->stream_index];
2517  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2518  RTPDemuxContext *rtpctx2 = rt->rtsp_streams[i]->transport_priv;
2519  AVStream *st2 = NULL;
2520  if (rt->rtsp_streams[i]->stream_index >= 0)
2521  st2 = s->streams[rt->rtsp_streams[i]->stream_index];
2522  if (rtpctx2 && st && st2 &&
2523  rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
2524  rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_time;
2525  rtpctx2->rtcp_ts_offset = av_rescale_q(
2526  rtpctx->rtcp_ts_offset, st->time_base,
2527  st2->time_base);
2528  }
2529  }
2530  // Make real NTP start time available in AVFormatContext
2531  if (s->start_time_realtime == AV_NOPTS_VALUE) {
2532  s->start_time_realtime = ff_parse_ntp_time(rtpctx->first_rtcp_ntp_time) - NTP_OFFSET_US;
2533  if (rtpctx->st) {
2534  s->start_time_realtime -=
2535  av_rescale_q (rtpctx->rtcp_ts_offset, rtpctx->st->time_base, AV_TIME_BASE_Q);
2536  }
2537  }
2538  }
2539  if (ret == -RTCP_BYE) {
2540  rt->nb_byes++;
2541 
2542  av_log(s, AV_LOG_DEBUG, "Received BYE for stream %d (%d/%d)\n",
2543  rtsp_st->stream_index, rt->nb_byes, rt->nb_rtsp_streams);
2544 
2545  if (rt->nb_byes == rt->nb_rtsp_streams)
2546  return AVERROR_EOF;
2547  }
2548  }
2549  } else if (CONFIG_RTPDEC && rt->ts) {
2551  if (ret >= 0) {
2552  if (ret < len) {
2553  rt->recvbuf_len = len;
2554  rt->recvbuf_pos = ret;
2555  rt->cur_transport_priv = rt->ts;
2556  return 1;
2557  } else {
2558  ret = 0;
2559  }
2560  }
2561  } else {
2562  return AVERROR_INVALIDDATA;
2563  }
2564 end:
2565  if (ret < 0)
2566  goto redo;
2567  if (ret == 1)
2568  /* more packets may follow, so we save the RTP context */
2569  rt->cur_transport_priv = rtsp_st->transport_priv;
2570 
2571  return ret;
2572 }
2573 #endif /* CONFIG_RTPDEC */
2574 
2575 #if CONFIG_SDP_DEMUXER
2576 static int sdp_probe(const AVProbeData *p1)
2577 {
2578  const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
2579 
2580  /* we look for a line beginning "c=IN IP" */
2581  while (p < p_end && *p != '\0') {
2582  if (sizeof("c=IN IP") - 1 < p_end - p &&
2583  av_strstart(p, "c=IN IP", NULL))
2584  return AVPROBE_SCORE_EXTENSION;
2585 
2586  while (p < p_end - 1 && *p != '\n') p++;
2587  if (++p >= p_end)
2588  break;
2589  if (*p == '\r')
2590  p++;
2591  }
2592  return 0;
2593 }
2594 
2595 static void append_source_addrs(char *buf, int size, const char *name,
2596  int count, struct RTSPSource **addrs)
2597 {
2598  int i;
2599  if (!count)
2600  return;
2601  av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->addr);
2602  for (i = 1; i < count; i++)
2603  av_strlcatf(buf, size, ",%s", addrs[i]->addr);
2604 }
2605 
2606 static int sdp_read_header(AVFormatContext *s)
2607 {
2608  RTSPState *rt = s->priv_data;
2609  RTSPStream *rtsp_st;
2610  int i, err;
2611  char url[MAX_URL_SIZE];
2612  AVBPrint bp;
2613 
2614  if ((err = ff_network_init()) < 0)
2615  return err;
2616 
2617  if (s->max_delay < 0) /* Not set by the caller */
2618  s->max_delay = DEFAULT_REORDERING_DELAY;
2619  if (rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)
2621 
2622  /* read the whole sdp file */
2624  err = avio_read_to_bprint(s->pb, &bp, INT_MAX);
2625  if (err < 0 ) {
2626  ff_network_close();
2627  av_bprint_finalize(&bp, NULL);
2628  return err;
2629  }
2630  err = ff_sdp_parse(s, bp.str);
2631  av_bprint_finalize(&bp, NULL);
2632  if (err) goto fail;
2633 
2634  /* open each RTP stream */
2635  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2636  char namebuf[50];
2637  rtsp_st = rt->rtsp_streams[i];
2638 
2639  if (!(rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)) {
2640  AVDictionary *opts = map_to_opts(rt);
2641  char buf[MAX_URL_SIZE];
2642  const char *p;
2643 
2644  err = getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip,
2645  sizeof(rtsp_st->sdp_ip),
2646  namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
2647  if (err) {
2648  av_log(s, AV_LOG_ERROR, "getnameinfo: %s\n", gai_strerror(err));
2649  err = AVERROR(EIO);
2650  av_dict_free(&opts);
2651  goto fail;
2652  }
2653  ff_url_join(url, sizeof(url), "rtp", NULL,
2654  namebuf, rtsp_st->sdp_port,
2655  "?localrtpport=%d&ttl=%d&connect=%d&write_to_source=%d",
2656  rtsp_st->sdp_port, rtsp_st->sdp_ttl,
2657  rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
2658  rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
2659 
2660  p = strchr(s->url, '?');
2661  if (p && av_find_info_tag(buf, sizeof(buf), "localaddr", p))
2662  av_strlcatf(url, sizeof(url), "&localaddr=%s", buf);
2663  else if (rt->localaddr && rt->localaddr[0])
2664  av_strlcatf(url, sizeof(url), "&localaddr=%s", rt->localaddr);
2665  append_source_addrs(url, sizeof(url), "sources",
2666  rtsp_st->nb_include_source_addrs,
2667  rtsp_st->include_source_addrs);
2668  append_source_addrs(url, sizeof(url), "block",
2669  rtsp_st->nb_exclude_source_addrs,
2670  rtsp_st->exclude_source_addrs);
2671  err = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ,
2672  &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);
2673 
2674  av_dict_free(&opts);
2675 
2676  if (err < 0) {
2677  err = AVERROR_INVALIDDATA;
2678  goto fail;
2679  }
2680  }
2681  if ((err = ff_rtsp_open_transport_ctx(s, rtsp_st)))
2682  goto fail;
2683  }
2684  return 0;
2685 fail:
2687  ff_network_close();
2688  return err;
2689 }
2690 
2691 static int sdp_read_close(AVFormatContext *s)
2692 {
2694  ff_network_close();
2695  return 0;
2696 }
2697 
2698 static const AVClass sdp_demuxer_class = {
2699  .class_name = "SDP demuxer",
2700  .item_name = av_default_item_name,
2701  .option = sdp_options,
2702  .version = LIBAVUTIL_VERSION_INT,
2703 };
2704 
2705 const FFInputFormat ff_sdp_demuxer = {
2706  .p.name = "sdp",
2707  .p.long_name = NULL_IF_CONFIG_SMALL("SDP"),
2708  .p.priv_class = &sdp_demuxer_class,
2709  .priv_data_size = sizeof(RTSPState),
2710  .read_probe = sdp_probe,
2711  .read_header = sdp_read_header,
2713  .read_close = sdp_read_close,
2714 };
2715 #endif /* CONFIG_SDP_DEMUXER */
2716 
2717 #if CONFIG_RTP_DEMUXER
2718 static int rtp_probe(const AVProbeData *p)
2719 {
2720  if (av_strstart(p->filename, "rtp:", NULL))
2721  return AVPROBE_SCORE_MAX;
2722  return 0;
2723 }
2724 
2725 static int rtp_read_header(AVFormatContext *s)
2726 {
2727  uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
2728  char host[500], filters_buf[1000];
2729  int ret, port;
2730  URLContext* in = NULL;
2731  int payload_type;
2732  AVCodecParameters *par = NULL;
2733  struct sockaddr_storage addr;
2734  FFIOContext pb;
2735  socklen_t addrlen = sizeof(addr);
2736  RTSPState *rt = s->priv_data;
2737  const char *p;
2738  AVBPrint sdp;
2739  AVDictionary *opts = NULL;
2740 
2741  if ((ret = ff_network_init()) < 0)
2742  return ret;
2743 
2744  opts = map_to_opts(rt);
2746  &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist, NULL);
2747  av_dict_free(&opts);
2748  if (ret)
2749  goto fail;
2750 
2751  while (1) {
2752  ret = ffurl_read(in, recvbuf, sizeof(recvbuf));
2753  if (ret == AVERROR(EAGAIN))
2754  continue;
2755  if (ret < 0)
2756  goto fail;
2757  if (ret < 12) {
2758  av_log(s, AV_LOG_WARNING, "Received too short packet\n");
2759  continue;
2760  }
2761 
2762  if ((recvbuf[0] & 0xc0) != 0x80) {
2763  av_log(s, AV_LOG_WARNING, "Unsupported RTP version packet "
2764  "received\n");
2765  continue;
2766  }
2767 
2768  if (RTP_PT_IS_RTCP(recvbuf[1]))
2769  continue;
2770 
2771  payload_type = recvbuf[1] & 0x7f;
2772  break;
2773  }
2774  getsockname(ffurl_get_file_handle(in), (struct sockaddr*) &addr, &addrlen);
2775  ffurl_closep(&in);
2776 
2777  par = avcodec_parameters_alloc();
2778  if (!par) {
2779  ret = AVERROR(ENOMEM);
2780  goto fail;
2781  }
2782 
2783  if (ff_rtp_get_codec_info(par, payload_type)) {
2784  av_log(s, AV_LOG_ERROR, "Unable to receive RTP payload type %d "
2785  "without an SDP file describing it\n",
2786  payload_type);
2788  goto fail;
2789  }
2790  if (par->codec_type != AVMEDIA_TYPE_DATA) {
2791  av_log(s, AV_LOG_WARNING, "Guessing on RTP content - if not received "
2792  "properly you need an SDP file "
2793  "describing it\n");
2794  }
2795 
2796  av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
2797  NULL, 0, s->url);
2798 
2800  av_bprintf(&sdp, "v=0\r\nc=IN IP%d %s\r\n",
2801  addr.ss_family == AF_INET ? 4 : 6, host);
2802 
2803  p = strchr(s->url, '?');
2804  if (p) {
2805  static const char filters[][2][8] = { { "sources", "incl" },
2806  { "block", "excl" } };
2807  int i;
2808  char *q;
2809  for (i = 0; i < FF_ARRAY_ELEMS(filters); i++) {
2810  if (av_find_info_tag(filters_buf, sizeof(filters_buf), filters[i][0], p)) {
2811  q = filters_buf;
2812  while ((q = strchr(q, ',')) != NULL)
2813  *q = ' ';
2814  av_bprintf(&sdp, "a=source-filter:%s IN IP%d %s %s\r\n",
2815  filters[i][1],
2816  addr.ss_family == AF_INET ? 4 : 6, host,
2817  filters_buf);
2818  }
2819  }
2820  }
2821 
2822  av_bprintf(&sdp, "m=%s %d RTP/AVP %d\r\n",
2823  par->codec_type == AVMEDIA_TYPE_DATA ? "application" :
2824  par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
2825  port, payload_type);
2826  av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp.str);
2827  if (!av_bprint_is_complete(&sdp))
2828  goto fail_nobuf;
2830 
2831  ffio_init_read_context(&pb, sdp.str, sdp.len);
2832  s->pb = &pb.pub;
2833 
2834  /* if sdp_read_header() fails then following ff_network_close() cancels out */
2835  /* ff_network_init() at the start of this function. Otherwise it cancels out */
2836  /* ff_network_init() inside sdp_read_header() */
2837  ff_network_close();
2838 
2839  rt->media_type_mask = (1 << (AVMEDIA_TYPE_SUBTITLE+1)) - 1;
2840 
2841  ret = sdp_read_header(s);
2842  s->pb = NULL;
2843  av_bprint_finalize(&sdp, NULL);
2844  return ret;
2845 
2846 fail_nobuf:
2847  ret = AVERROR(ENOMEM);
2848  av_log(s, AV_LOG_ERROR, "rtp_read_header(): not enough buffer space for sdp-headers\n");
2849  av_bprint_finalize(&sdp, NULL);
2850 fail:
2852  ffurl_closep(&in);
2853  ff_network_close();
2854  return ret;
2855 }
2856 
2857 static const AVClass rtp_demuxer_class = {
2858  .class_name = "RTP demuxer",
2859  .item_name = av_default_item_name,
2860  .option = rtp_options,
2861  .version = LIBAVUTIL_VERSION_INT,
2862 };
2863 
2864 const FFInputFormat ff_rtp_demuxer = {
2865  .p.name = "rtp",
2866  .p.long_name = NULL_IF_CONFIG_SMALL("RTP input"),
2867  .p.flags = AVFMT_NOFILE,
2868  .p.priv_class = &rtp_demuxer_class,
2869  .priv_data_size = sizeof(RTSPState),
2870  .read_probe = rtp_probe,
2871  .read_header = rtp_read_header,
2873  .read_close = sdp_read_close,
2874 };
2875 #endif /* CONFIG_RTP_DEMUXER */
av_strdup
#define av_strdup(s)
Definition: ops_static.c:47
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:57
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:833
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::stored_msg
struct RTSPState::@522 stored_msg
Stored message context This is used to store the last reply marked to be stored with ff_rtsp_send_cmd...
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:53
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:469
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:49
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:3837
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:137
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:204
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:428
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:855
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:318
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 microseconds (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:474
ff_network_close
void ff_network_close(void)
Definition: network.c:121
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
key
const char * key
Definition: ffmpeg_mux_init.c:2971
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:30
sockaddr_storage
Definition: network.h:111
ff_network_init
int ff_network_init(void)
Initialize the network subsystem.
Definition: network.c:63
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:302
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:483
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:834
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:365
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:210
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:376
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:824
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:587
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:922
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:3862
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:461
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
RTSPState::nb_byes
int nb_byes
Definition: rtsp.h:366
AI_NUMERICHOST
#define AI_NUMERICHOST
Definition: network.h:187
ff_format_check_set_url
int ff_format_check_set_url(AVFormatContext *s, const char *url)
Set AVFormatContext url field to a av_strdup of the provided pointer.
Definition: avformat.c:930
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:570
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:473
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:262
av_sscanf
int av_sscanf(const char *string, const char *format,...)
Definition: avsscanf.c:962
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:800
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:231
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 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:59
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:869
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
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:510
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:93
FFStream::need_parsing
enum AVStreamParseType need_parsing
Definition: internal.h:321
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:1333
fail
#define fail
Definition: test.h:478
internal.h
opts
static AVDictionary * opts
Definition: movenc.c:51
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:789
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
RTSPState::tls_opts
struct RTSPState::@523 tls_opts
Options used for TLS based RTSP streams.
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:805
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
AVFMTCTX_NOHEADER
#define AVFMTCTX_NOHEADER
signal that no header is present (streams are added dynamically)
Definition: avformat.h:1284
URLContext::protocol_blacklist
const char * protocol_blacklist
Definition: url.h:47
FF_TLS_CLIENT_OPTIONS
#define FF_TLS_CLIENT_OPTIONS(pstruct, options_field)
Definition: tls.h:90
ff_rtp_queued_packet_time
int64_t ff_rtp_queued_packet_time(RTPDemuxContext *s)
Definition: rtpdec.c:806
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:1286
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:239
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:1375
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:471
RTSPState::ca_file
char * ca_file
Definition: rtsp.h:449
options
Definition: swscale.c:50
AVStream::metadata
AVDictionary * metadata
Definition: avformat.h:846
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:616
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
The channel layout and number of channels.
Definition: codec_par.h:207
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:481
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
The number of audio samples per second.
Definition: codec_par.h:213
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:938
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:537
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:88
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:889
ff_rtsp_options
const AVOption ff_rtsp_options[]
Definition: rtsp.c:87
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
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:422
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
av_malloc
#define av_malloc(s)
Definition: ops_static.c:44
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:488
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:578
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
AVCodecParameters::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
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:360
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:841
getaddrinfo
#define getaddrinfo
Definition: network.h:217
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:48
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:925
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
s
uint8_t s
Definition: llvidencdsp.c:39
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:110
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:2299
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:656
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:778
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:766
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
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:102
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
AVCodecParameters::avcodec_parameters_free
void avcodec_parameters_free(AVCodecParameters **par)
Free an AVCodecParameters instance and everything associated with it and write NULL to the supplied p...
Definition: codec_par.c:67
tls.h
RTSP_DEFAULT_PORT
#define RTSP_DEFAULT_PORT
Definition: rtsp.h:75
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:772
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:258
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:150
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:3815
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
desc
const char * desc
Definition: libsvtav1.c:83
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:625
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
rdt.h
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:57
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:580
AVPacket
This structure stores compressed data.
Definition: packet.h:580
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:326
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:717
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:254
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:3891
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:275
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:298
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
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:882
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
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:183