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