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