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