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