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