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