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