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