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