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