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 /* Timeout values for socket poll, in ms,
55  * and read_packet(), in seconds */
56 #define POLL_TIMEOUT_MS 100
57 #define READ_PACKET_TIMEOUT_S 10
58 #define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / POLL_TIMEOUT_MS
59 #define SDP_MAX_SIZE 16384
60 #define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
61 #define DEFAULT_REORDERING_DELAY 100000
62 
63 #define OFFSET(x) offsetof(RTSPState, x)
64 #define DEC AV_OPT_FLAG_DECODING_PARAM
65 #define ENC AV_OPT_FLAG_ENCODING_PARAM
66 
67 #define RTSP_FLAG_OPTS(name, longname) \
68  { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \
69  { "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" }
70 
71 #define RTSP_MEDIATYPE_OPTS(name, longname) \
72  { 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" }, \
73  { "video", "Video", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_VIDEO}, 0, 0, DEC, "allowed_media_types" }, \
74  { "audio", "Audio", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_AUDIO}, 0, 0, DEC, "allowed_media_types" }, \
75  { "data", "Data", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_DATA}, 0, 0, DEC, "allowed_media_types" }, \
76  { "subtitle", "Subtitle", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_SUBTITLE}, 0, 0, DEC, "allowed_media_types" }
77 
78 #define COMMON_OPTS() \
79  { "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 }, \
80  { "buffer_size", "Underlying protocol send/receive buffer size", OFFSET(buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC|ENC }, \
81  { "pkt_size", "Underlying protocol send packet size", OFFSET(pkt_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, ENC } \
82 
83 
85  { "initial_pause", "do not start playing the stream immediately", OFFSET(initial_pause), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, DEC },
86  FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags),
87  { "rtsp_transport", "set RTSP transport protocols", OFFSET(lower_transport_mask), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC|ENC, "rtsp_transport" }, \
88  { "udp", "UDP", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_UDP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
89  { "tcp", "TCP", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_TCP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
90  { "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, "rtsp_transport" },
91  { "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {.i64 = (1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, "rtsp_transport" },
92  { "https", "HTTPS tunneling", 0, AV_OPT_TYPE_CONST, {.i64 = (1 << RTSP_LOWER_TRANSPORT_HTTPS )}, 0, 0, DEC, "rtsp_transport" },
93  RTSP_FLAG_OPTS("rtsp_flags", "set RTSP flags"),
94  { "listen", "wait for incoming connections", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_LISTEN}, 0, 0, DEC, "rtsp_flags" },
95  { "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" },
96  RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"),
97  { "min_port", "set minimum local UDP port", OFFSET(rtp_port_min), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MIN}, 0, 65535, DEC|ENC },
98  { "max_port", "set maximum local UDP port", OFFSET(rtp_port_max), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MAX}, 0, 65535, DEC|ENC },
99  { "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 },
100 #if FF_API_OLD_RTSP_OPTIONS
101  { "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 },
102  { "stimeout", "set timeout (in microseconds) of socket TCP I/O operations", OFFSET(stimeout), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC },
103 #else
104  { "timeout", "set timeout (in microseconds) of socket TCP I/O operations", OFFSET(stimeout), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC },
105 #endif
106  COMMON_OPTS(),
107  { "user_agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, DEC },
108 #if FF_API_OLD_RTSP_OPTIONS
109  { "user-agent", "override User-Agent header (deprecated, use user_agent)", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = LIBAVFORMAT_IDENT}, 0, 0, DEC },
110 #endif
111  { NULL },
112 };
113 
114 static const AVOption sdp_options[] = {
115  RTSP_FLAG_OPTS("sdp_flags", "SDP flags"),
116  { "custom_io", "use custom I/O", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_CUSTOM_IO}, 0, 0, DEC, "rtsp_flags" },
117  { "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" },
118  RTSP_MEDIATYPE_OPTS("allowed_media_types", "set media types to accept from the server"),
119  COMMON_OPTS(),
120  { NULL },
121 };
122 
123 static const AVOption rtp_options[] = {
124  RTSP_FLAG_OPTS("rtp_flags", "set RTP flags"),
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  return AVERROR_EOF;
1969  else
1971  "Unable to answer to TEARDOWN\n");
1972  } else
1973  return 0;
1974  } else {
1975  RTSPMessageHeader reply;
1976  ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL);
1977  if (ret < 0)
1978  return ret;
1979  /* XXX: parse message */
1980  if (rt->state != RTSP_STATE_STREAMING)
1981  return 0;
1982  }
1983 
1984  return 0;
1985 }
1986 
1987 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
1988  uint8_t *buf, int buf_size, int64_t wait_end)
1989 {
1990  RTSPState *rt = s->priv_data;
1991  RTSPStream *rtsp_st;
1992  int n, i, ret, timeout_cnt = 0;
1993  struct pollfd *p = rt->p;
1994  int *fds = NULL, fdsnum, fdsidx;
1995 
1996  if (!p) {
1997  p = rt->p = av_malloc_array(2 * (rt->nb_rtsp_streams + 1), sizeof(struct pollfd));
1998  if (!p)
1999  return AVERROR(ENOMEM);
2000 
2001  if (rt->rtsp_hd) {
2002  p[rt->max_p].fd = ffurl_get_file_handle(rt->rtsp_hd);
2003  p[rt->max_p++].events = POLLIN;
2004  }
2005  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2006  rtsp_st = rt->rtsp_streams[i];
2007  if (rtsp_st->rtp_handle) {
2008  if (ret = ffurl_get_multi_file_handle(rtsp_st->rtp_handle,
2009  &fds, &fdsnum)) {
2010  av_log(s, AV_LOG_ERROR, "Unable to recover rtp ports\n");
2011  return ret;
2012  }
2013  if (fdsnum != 2) {
2014  av_log(s, AV_LOG_ERROR,
2015  "Number of fds %d not supported\n", fdsnum);
2016  return AVERROR_INVALIDDATA;
2017  }
2018  for (fdsidx = 0; fdsidx < fdsnum; fdsidx++) {
2019  p[rt->max_p].fd = fds[fdsidx];
2020  p[rt->max_p++].events = POLLIN;
2021  }
2022  av_freep(&fds);
2023  }
2024  }
2025  }
2026 
2027  for (;;) {
2029  return AVERROR_EXIT;
2030  if (wait_end && wait_end - av_gettime_relative() < 0)
2031  return AVERROR(EAGAIN);
2032  n = poll(p, rt->max_p, POLL_TIMEOUT_MS);
2033  if (n > 0) {
2034  int j = rt->rtsp_hd ? 1 : 0;
2035  timeout_cnt = 0;
2036  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2037  rtsp_st = rt->rtsp_streams[i];
2038  if (rtsp_st->rtp_handle) {
2039  if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) {
2040  ret = ffurl_read(rtsp_st->rtp_handle, buf, buf_size);
2041  if (ret > 0) {
2042  *prtsp_st = rtsp_st;
2043  return ret;
2044  }
2045  }
2046  j+=2;
2047  }
2048  }
2049 #if CONFIG_RTSP_DEMUXER
2050  if (rt->rtsp_hd && p[0].revents & POLLIN) {
2051  if ((ret = parse_rtsp_message(s)) < 0) {
2052  return ret;
2053  }
2054  }
2055 #endif
2056  } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) {
2057  return AVERROR(ETIMEDOUT);
2058  } else if (n < 0 && errno != EINTR)
2059  return AVERROR(errno);
2060  }
2061 }
2062 
2063 static int pick_stream(AVFormatContext *s, RTSPStream **rtsp_st,
2064  const uint8_t *buf, int len)
2065 {
2066  RTSPState *rt = s->priv_data;
2067  int i;
2068  if (len < 0)
2069  return len;
2070  if (rt->nb_rtsp_streams == 1) {
2071  *rtsp_st = rt->rtsp_streams[0];
2072  return len;
2073  }
2074  if (len >= 8 && rt->transport == RTSP_TRANSPORT_RTP) {
2075  if (RTP_PT_IS_RTCP(rt->recvbuf[1])) {
2076  int no_ssrc = 0;
2077  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2078  RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
2079  if (!rtpctx)
2080  continue;
2081  if (rtpctx->ssrc == AV_RB32(&buf[4])) {
2082  *rtsp_st = rt->rtsp_streams[i];
2083  return len;
2084  }
2085  if (!rtpctx->ssrc)
2086  no_ssrc = 1;
2087  }
2088  if (no_ssrc) {
2090  "Unable to pick stream for packet - SSRC not known for "
2091  "all streams\n");
2092  return AVERROR(EAGAIN);
2093  }
2094  } else {
2095  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2096  if ((buf[1] & 0x7f) == rt->rtsp_streams[i]->sdp_payload_type) {
2097  *rtsp_st = rt->rtsp_streams[i];
2098  return len;
2099  }
2100  }
2101  }
2102  }
2103  av_log(s, AV_LOG_WARNING, "Unable to pick stream for packet\n");
2104  return AVERROR(EAGAIN);
2105 }
2106 
2107 static int read_packet(AVFormatContext *s,
2108  RTSPStream **rtsp_st, RTSPStream *first_queue_st,
2109  int64_t wait_end)
2110 {
2111  RTSPState *rt = s->priv_data;
2112  int len;
2113 
2114  switch(rt->lower_transport) {
2115  default:
2116 #if CONFIG_RTSP_DEMUXER
2118  len = ff_rtsp_tcp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE);
2119  break;
2120 #endif
2123  len = udp_read_packet(s, rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
2124  if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
2125  ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, (*rtsp_st)->rtp_handle, NULL, len);
2126  break;
2128  if (first_queue_st && rt->transport == RTSP_TRANSPORT_RTP &&
2129  wait_end && wait_end < av_gettime_relative())
2130  len = AVERROR(EAGAIN);
2131  else
2132  len = avio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE);
2133  len = pick_stream(s, rtsp_st, rt->recvbuf, len);
2134  if (len > 0 && (*rtsp_st)->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
2135  ff_rtp_check_and_send_back_rr((*rtsp_st)->transport_priv, NULL, s->pb, len);
2136  break;
2137  }
2138 
2139  if (len == 0)
2140  return AVERROR_EOF;
2141 
2142  return len;
2143 }
2144 
2146 {
2147  RTSPState *rt = s->priv_data;
2148  int ret, len;
2149  RTSPStream *rtsp_st, *first_queue_st = NULL;
2150  int64_t wait_end = 0;
2151 
2152  if (rt->nb_byes == rt->nb_rtsp_streams)
2153  return AVERROR_EOF;
2154 
2155  /* get next frames from the same RTP packet */
2156  if (rt->cur_transport_priv) {
2157  if (rt->transport == RTSP_TRANSPORT_RDT) {
2158  ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
2159  } else if (rt->transport == RTSP_TRANSPORT_RTP) {
2160  ret = ff_rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
2161  } else if (CONFIG_RTPDEC && rt->ts) {
2162  ret = avpriv_mpegts_parse_packet(rt->ts, pkt, rt->recvbuf + rt->recvbuf_pos, rt->recvbuf_len - rt->recvbuf_pos);
2163  if (ret >= 0) {
2164  rt->recvbuf_pos += ret;
2165  ret = rt->recvbuf_pos < rt->recvbuf_len;
2166  }
2167  } else
2168  ret = -1;
2169  if (ret == 0) {
2170  rt->cur_transport_priv = NULL;
2171  return 0;
2172  } else if (ret == 1) {
2173  return 0;
2174  } else
2175  rt->cur_transport_priv = NULL;
2176  }
2177 
2178 redo:
2179  if (rt->transport == RTSP_TRANSPORT_RTP) {
2180  int i;
2181  int64_t first_queue_time = 0;
2182  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2183  RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
2184  int64_t queue_time;
2185  if (!rtpctx)
2186  continue;
2187  queue_time = ff_rtp_queued_packet_time(rtpctx);
2188  if (queue_time && (queue_time - first_queue_time < 0 ||
2189  !first_queue_time)) {
2190  first_queue_time = queue_time;
2191  first_queue_st = rt->rtsp_streams[i];
2192  }
2193  }
2194  if (first_queue_time) {
2195  wait_end = first_queue_time + s->max_delay;
2196  } else {
2197  wait_end = 0;
2198  first_queue_st = NULL;
2199  }
2200  }
2201 
2202  /* read next RTP packet */
2203  if (!rt->recvbuf) {
2205  if (!rt->recvbuf)
2206  return AVERROR(ENOMEM);
2207  }
2208 
2209  len = read_packet(s, &rtsp_st, first_queue_st, wait_end);
2210  if (len == AVERROR(EAGAIN) && first_queue_st &&
2211  rt->transport == RTSP_TRANSPORT_RTP) {
2213  "max delay reached. need to consume packet\n");
2214  rtsp_st = first_queue_st;
2215  ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
2216  goto end;
2217  }
2218  if (len < 0)
2219  return len;
2220 
2221  if (rt->transport == RTSP_TRANSPORT_RDT) {
2222  ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
2223  } else if (rt->transport == RTSP_TRANSPORT_RTP) {
2224  ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
2225  if (rtsp_st->feedback) {
2226  AVIOContext *pb = NULL;
2228  pb = s->pb;
2229  ff_rtp_send_rtcp_feedback(rtsp_st->transport_priv, rtsp_st->rtp_handle, pb);
2230  }
2231  if (ret < 0) {
2232  /* Either bad packet, or a RTCP packet. Check if the
2233  * first_rtcp_ntp_time field was initialized. */
2234  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
2235  if (rtpctx->first_rtcp_ntp_time != AV_NOPTS_VALUE) {
2236  /* first_rtcp_ntp_time has been initialized for this stream,
2237  * copy the same value to all other uninitialized streams,
2238  * in order to map their timestamp origin to the same ntp time
2239  * as this one. */
2240  int i;
2241  AVStream *st = NULL;
2242  if (rtsp_st->stream_index >= 0)
2243  st = s->streams[rtsp_st->stream_index];
2244  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2245  RTPDemuxContext *rtpctx2 = rt->rtsp_streams[i]->transport_priv;
2246  AVStream *st2 = NULL;
2247  if (rt->rtsp_streams[i]->stream_index >= 0)
2248  st2 = s->streams[rt->rtsp_streams[i]->stream_index];
2249  if (rtpctx2 && st && st2 &&
2250  rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
2251  rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_time;
2252  rtpctx2->rtcp_ts_offset = av_rescale_q(
2253  rtpctx->rtcp_ts_offset, st->time_base,
2254  st2->time_base);
2255  }
2256  }
2257  // Make real NTP start time available in AVFormatContext
2258  if (s->start_time_realtime == AV_NOPTS_VALUE) {
2259  s->start_time_realtime = av_rescale (rtpctx->first_rtcp_ntp_time - (NTP_OFFSET << 32), 1000000, 1LL << 32);
2260  if (rtpctx->st) {
2261  s->start_time_realtime -=
2262  av_rescale (rtpctx->rtcp_ts_offset,
2263  (uint64_t) rtpctx->st->time_base.num * 1000000,
2264  rtpctx->st->time_base.den);
2265  }
2266  }
2267  }
2268  if (ret == -RTCP_BYE) {
2269  rt->nb_byes++;
2270 
2271  av_log(s, AV_LOG_DEBUG, "Received BYE for stream %d (%d/%d)\n",
2272  rtsp_st->stream_index, rt->nb_byes, rt->nb_rtsp_streams);
2273 
2274  if (rt->nb_byes == rt->nb_rtsp_streams)
2275  return AVERROR_EOF;
2276  }
2277  }
2278  } else if (CONFIG_RTPDEC && rt->ts) {
2279  ret = avpriv_mpegts_parse_packet(rt->ts, pkt, rt->recvbuf, len);
2280  if (ret >= 0) {
2281  if (ret < len) {
2282  rt->recvbuf_len = len;
2283  rt->recvbuf_pos = ret;
2284  rt->cur_transport_priv = rt->ts;
2285  return 1;
2286  } else {
2287  ret = 0;
2288  }
2289  }
2290  } else {
2291  return AVERROR_INVALIDDATA;
2292  }
2293 end:
2294  if (ret < 0)
2295  goto redo;
2296  if (ret == 1)
2297  /* more packets may follow, so we save the RTP context */
2298  rt->cur_transport_priv = rtsp_st->transport_priv;
2299 
2300  return ret;
2301 }
2302 #endif /* CONFIG_RTPDEC */
2303 
2304 #if CONFIG_SDP_DEMUXER
2305 static int sdp_probe(const AVProbeData *p1)
2306 {
2307  const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
2308 
2309  /* we look for a line beginning "c=IN IP" */
2310  while (p < p_end && *p != '\0') {
2311  if (sizeof("c=IN IP") - 1 < p_end - p &&
2312  av_strstart(p, "c=IN IP", NULL))
2313  return AVPROBE_SCORE_EXTENSION;
2314 
2315  while (p < p_end - 1 && *p != '\n') p++;
2316  if (++p >= p_end)
2317  break;
2318  if (*p == '\r')
2319  p++;
2320  }
2321  return 0;
2322 }
2323 
2324 static void append_source_addrs(char *buf, int size, const char *name,
2325  int count, struct RTSPSource **addrs)
2326 {
2327  int i;
2328  if (!count)
2329  return;
2330  av_strlcatf(buf, size, "&%s=%s", name, addrs[0]->addr);
2331  for (i = 1; i < count; i++)
2332  av_strlcatf(buf, size, ",%s", addrs[i]->addr);
2333 }
2334 
2335 static int sdp_read_header(AVFormatContext *s)
2336 {
2337  RTSPState *rt = s->priv_data;
2338  RTSPStream *rtsp_st;
2339  int size, i, err;
2340  char *content;
2341  char url[1024];
2342 
2343  if (!ff_network_init())
2344  return AVERROR(EIO);
2345 
2346  if (s->max_delay < 0) /* Not set by the caller */
2348  if (rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)
2350 
2351  /* read the whole sdp file */
2352  /* XXX: better loading */
2353  content = av_malloc(SDP_MAX_SIZE);
2354  if (!content)
2355  return AVERROR(ENOMEM);
2356  size = avio_read(s->pb, content, SDP_MAX_SIZE - 1);
2357  if (size <= 0) {
2358  av_free(content);
2359  return AVERROR_INVALIDDATA;
2360  }
2361  content[size] ='\0';
2362 
2363  err = ff_sdp_parse(s, content);
2364  av_freep(&content);
2365  if (err) goto fail;
2366 
2367  /* open each RTP stream */
2368  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2369  char namebuf[50];
2370  rtsp_st = rt->rtsp_streams[i];
2371 
2372  if (!(rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)) {
2373  AVDictionary *opts = map_to_opts(rt);
2374 
2375  err = getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip,
2376  sizeof(rtsp_st->sdp_ip),
2377  namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
2378  if (err) {
2379  av_log(s, AV_LOG_ERROR, "getnameinfo: %s\n", gai_strerror(err));
2380  err = AVERROR(EIO);
2381  av_dict_free(&opts);
2382  goto fail;
2383  }
2384  ff_url_join(url, sizeof(url), "rtp", NULL,
2385  namebuf, rtsp_st->sdp_port,
2386  "?localport=%d&ttl=%d&connect=%d&write_to_source=%d",
2387  rtsp_st->sdp_port, rtsp_st->sdp_ttl,
2388  rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0,
2389  rt->rtsp_flags & RTSP_FLAG_RTCP_TO_SOURCE ? 1 : 0);
2390 
2391  append_source_addrs(url, sizeof(url), "sources",
2392  rtsp_st->nb_include_source_addrs,
2393  rtsp_st->include_source_addrs);
2394  append_source_addrs(url, sizeof(url), "block",
2395  rtsp_st->nb_exclude_source_addrs,
2396  rtsp_st->exclude_source_addrs);
2397  err = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ,
2399 
2400  av_dict_free(&opts);
2401 
2402  if (err < 0) {
2403  err = AVERROR_INVALIDDATA;
2404  goto fail;
2405  }
2406  }
2407  if ((err = ff_rtsp_open_transport_ctx(s, rtsp_st)))
2408  goto fail;
2409  }
2410  return 0;
2411 fail:
2413  ff_network_close();
2414  return err;
2415 }
2416 
2417 static int sdp_read_close(AVFormatContext *s)
2418 {
2420  ff_network_close();
2421  return 0;
2422 }
2423 
2424 static const AVClass sdp_demuxer_class = {
2425  .class_name = "SDP demuxer",
2426  .item_name = av_default_item_name,
2427  .option = sdp_options,
2428  .version = LIBAVUTIL_VERSION_INT,
2429 };
2430 
2432  .name = "sdp",
2433  .long_name = NULL_IF_CONFIG_SMALL("SDP"),
2434  .priv_data_size = sizeof(RTSPState),
2435  .read_probe = sdp_probe,
2436  .read_header = sdp_read_header,
2438  .read_close = sdp_read_close,
2439  .priv_class = &sdp_demuxer_class,
2440 };
2441 #endif /* CONFIG_SDP_DEMUXER */
2442 
2443 #if CONFIG_RTP_DEMUXER
2444 static int rtp_probe(const AVProbeData *p)
2445 {
2446  if (av_strstart(p->filename, "rtp:", NULL))
2447  return AVPROBE_SCORE_MAX;
2448  return 0;
2449 }
2450 
2451 static int rtp_read_header(AVFormatContext *s)
2452 {
2453  uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
2454  char host[500], filters_buf[1000];
2455  int ret, port;
2456  URLContext* in = NULL;
2457  int payload_type;
2458  AVCodecParameters *par = NULL;
2459  struct sockaddr_storage addr;
2460  AVIOContext pb;
2461  socklen_t addrlen = sizeof(addr);
2462  RTSPState *rt = s->priv_data;
2463  const char *p;
2464  AVBPrint sdp;
2465 
2466  if (!ff_network_init())
2467  return AVERROR(EIO);
2468 
2469  ret = ffurl_open_whitelist(&in, s->url, AVIO_FLAG_READ,
2471  if (ret)
2472  goto fail;
2473 
2474  while (1) {
2475  ret = ffurl_read(in, recvbuf, sizeof(recvbuf));
2476  if (ret == AVERROR(EAGAIN))
2477  continue;
2478  if (ret < 0)
2479  goto fail;
2480  if (ret < 12) {
2481  av_log(s, AV_LOG_WARNING, "Received too short packet\n");
2482  continue;
2483  }
2484 
2485  if ((recvbuf[0] & 0xc0) != 0x80) {
2486  av_log(s, AV_LOG_WARNING, "Unsupported RTP version packet "
2487  "received\n");
2488  continue;
2489  }
2490 
2491  if (RTP_PT_IS_RTCP(recvbuf[1]))
2492  continue;
2493 
2494  payload_type = recvbuf[1] & 0x7f;
2495  break;
2496  }
2497  getsockname(ffurl_get_file_handle(in), (struct sockaddr*) &addr, &addrlen);
2498  ffurl_closep(&in);
2499 
2500  par = avcodec_parameters_alloc();
2501  if (!par) {
2502  ret = AVERROR(ENOMEM);
2503  goto fail;
2504  }
2505 
2506  if (ff_rtp_get_codec_info(par, payload_type)) {
2507  av_log(s, AV_LOG_ERROR, "Unable to receive RTP payload type %d "
2508  "without an SDP file describing it\n",
2509  payload_type);
2510  goto fail;
2511  }
2512  if (par->codec_type != AVMEDIA_TYPE_DATA) {
2513  av_log(s, AV_LOG_WARNING, "Guessing on RTP content - if not received "
2514  "properly you need an SDP file "
2515  "describing it\n");
2516  }
2517 
2518  av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
2519  NULL, 0, s->url);
2520 
2522  av_bprintf(&sdp, "v=0\r\nc=IN IP%d %s\r\n",
2523  addr.ss_family == AF_INET ? 4 : 6, host);
2524 
2525  p = strchr(s->url, '?');
2526  if (p) {
2527  static const char filters[][2][8] = { { "sources", "incl" },
2528  { "block", "excl" } };
2529  int i;
2530  char *q;
2531  for (i = 0; i < FF_ARRAY_ELEMS(filters); i++) {
2532  if (av_find_info_tag(filters_buf, sizeof(filters_buf), filters[i][0], p)) {
2533  q = filters_buf;
2534  while ((q = strchr(q, ',')) != NULL)
2535  *q = ' ';
2536  av_bprintf(&sdp, "a=source-filter:%s IN IP%d %s %s\r\n",
2537  filters[i][1],
2538  addr.ss_family == AF_INET ? 4 : 6, host,
2539  filters_buf);
2540  }
2541  }
2542  }
2543 
2544  av_bprintf(&sdp, "m=%s %d RTP/AVP %d\r\n",
2545  par->codec_type == AVMEDIA_TYPE_DATA ? "application" :
2546  par->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
2547  port, payload_type);
2548  av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp.str);
2549  if (!av_bprint_is_complete(&sdp))
2550  goto fail_nobuf;
2552 
2553  ffio_init_context(&pb, sdp.str, sdp.len, 0, NULL, NULL, NULL, NULL);
2554  s->pb = &pb;
2555 
2556  /* sdp_read_header initializes this again */
2557  ff_network_close();
2558 
2559  rt->media_type_mask = (1 << (AVMEDIA_TYPE_SUBTITLE+1)) - 1;
2560 
2561  ret = sdp_read_header(s);
2562  s->pb = NULL;
2563  av_bprint_finalize(&sdp, NULL);
2564  return ret;
2565 
2566 fail_nobuf:
2567  ret = AVERROR(ENOMEM);
2568  av_log(s, AV_LOG_ERROR, "rtp_read_header(): not enough buffer space for sdp-headers\n");
2569  av_bprint_finalize(&sdp, NULL);
2570 fail:
2572  ffurl_closep(&in);
2573  ff_network_close();
2574  return ret;
2575 }
2576 
2577 static const AVClass rtp_demuxer_class = {
2578  .class_name = "RTP demuxer",
2579  .item_name = av_default_item_name,
2580  .option = rtp_options,
2581  .version = LIBAVUTIL_VERSION_INT,
2582 };
2583 
2585  .name = "rtp",
2586  .long_name = NULL_IF_CONFIG_SMALL("RTP input"),
2587  .priv_data_size = sizeof(RTSPState),
2588  .read_probe = rtp_probe,
2589  .read_header = rtp_read_header,
2591  .read_close = sdp_read_close,
2592  .flags = AVFMT_NOFILE,
2593  .priv_class = &rtp_demuxer_class,
2594 };
2595 #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:4792
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:518
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:1604
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:1629
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
#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:4938
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
const char * desc
Definition: nvenc.c:87
#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:3320
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:877
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:223
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:1400
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:87
#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:60
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:1351
#define RTP_PT_PRIVATE
Definition: rtp.h:77
#define COMMON_OPTS()
Definition: rtsp.c:78
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:1295
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:90
int id
Format-specific stream ID.
Definition: avformat.h:883
enum AVStreamParseType need_parsing
Definition: avformat.h:1094
#define POLL_TIMEOUT_MS
Definition: rtsp.c:56
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:108
#define DEFAULT_REORDERING_DELAY
Definition: rtsp.c:61
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:4519
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:87
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1419
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:1911
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
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:2062
#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:1591
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:1363
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:1447
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
const AVOption ff_rtsp_options[]
Definition: rtsp.c:84
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:1407
#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:213
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:1953
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:5845
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:940
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:65
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:1370
void ffio_free_dyn_buf(AVIOContext **s)
Free a dynamic buffer.
Definition: aviobuf.c:1444
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:876
#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:37
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:1393
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:67
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:59
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:3341
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:71
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:4448
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
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
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0f/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0/(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(UINT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(UINT64_C(1)<< 63)))#define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};static void cpy1(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, len);}static void cpy2(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 2 *len);}static void cpy4(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 4 *len);}static void cpy8(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);return ctx;}void swri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len){int ch;int off=0;const int os=(out->planar?1:out->ch_count)*out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){int planes=in->planar?in->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){int planes=out->planar?out->ch_count:1;unsigned m=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){int planes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
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:1456
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:64
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:2052
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:114
const OptionDef options[]
Definition: ffmpeg_opt.c:3391
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:4491
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:1379
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:3401
int channels
Audio only.
Definition: codec_par.h:166
int sdp_ttl
IP Time-To-Live (from SDP content)
Definition: rtsp.h:459
#define MAX_TIMEOUTS
Definition: rtsp.c:58
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:1946
int ai_flags
Definition: network.h:138
int64_t duration
Duration of the stream, in AV_TIME_BASE fractional seconds.
Definition: avformat.h:1466
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:650
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:1023
#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:905
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:101
void avpriv_mpegts_parse_close(MpegTSContext *ts)
Definition: mpegts.c:3366
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:332
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:1182
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:123
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:406
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:63
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