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