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