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