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