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