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 "rdt.h"
46 #include "rtpdec_formats.h"
47 #include "rtpenc_chain.h"
48 #include "url.h"
49 #include "rtpenc.h"
50 #include "mpegts.h"
51 
52 //#define DEBUG
53 
54 /* Timeout values for socket poll, in ms,
55  * and read_packet(), in seconds */
56 #define POLL_TIMEOUT_MS 100
57 #define READ_PACKET_TIMEOUT_S 10
58 #define MAX_TIMEOUTS READ_PACKET_TIMEOUT_S * 1000 / POLL_TIMEOUT_MS
59 #define SDP_MAX_SIZE 16384
60 #define RECVBUF_SIZE 10 * RTP_MAX_PACKET_LENGTH
61 #define DEFAULT_REORDERING_DELAY 100000
62 
63 #define OFFSET(x) offsetof(RTSPState, x)
64 #define DEC AV_OPT_FLAG_DECODING_PARAM
65 #define ENC AV_OPT_FLAG_ENCODING_PARAM
66 
67 #define RTSP_FLAG_OPTS(name, longname) \
68  { name, longname, OFFSET(rtsp_flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtsp_flags" }, \
69  { "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" }, \
70  { "listen", "Wait for incoming connections", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_LISTEN}, 0, 0, DEC, "rtsp_flags" }
71 
72 #define RTSP_MEDIATYPE_OPTS(name, longname) \
73  { name, longname, OFFSET(media_type_mask), AV_OPT_TYPE_FLAGS, { .i64 = (1 << (AVMEDIA_TYPE_DATA+1)) - 1 }, INT_MIN, INT_MAX, DEC, "allowed_media_types" }, \
74  { "video", "Video", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_VIDEO}, 0, 0, DEC, "allowed_media_types" }, \
75  { "audio", "Audio", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_AUDIO}, 0, 0, DEC, "allowed_media_types" }, \
76  { "data", "Data", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << AVMEDIA_TYPE_DATA}, 0, 0, DEC, "allowed_media_types" }
77 
78 #define RTSP_REORDERING_OPTS() \
79  { "reorder_queue_size", "Number of packets to buffer for handling of reordered packets", OFFSET(reordering_queue_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, DEC }
80 
82  { "initial_pause", "Don't start playing the stream immediately", OFFSET(initial_pause), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC },
83  FF_RTP_FLAG_OPTS(RTSPState, rtp_muxer_flags),
84  { "rtsp_transport", "RTSP transport protocols", OFFSET(lower_transport_mask), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, DEC|ENC, "rtsp_transport" }, \
85  { "udp", "UDP", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_UDP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
86  { "tcp", "TCP", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_TCP}, 0, 0, DEC|ENC, "rtsp_transport" }, \
87  { "udp_multicast", "UDP multicast", 0, AV_OPT_TYPE_CONST, {.i64 = 1 << RTSP_LOWER_TRANSPORT_UDP_MULTICAST}, 0, 0, DEC, "rtsp_transport" },
88  { "http", "HTTP tunneling", 0, AV_OPT_TYPE_CONST, {.i64 = (1 << RTSP_LOWER_TRANSPORT_HTTP)}, 0, 0, DEC, "rtsp_transport" },
89  RTSP_FLAG_OPTS("rtsp_flags", "RTSP flags"),
90  RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"),
91  { "min_port", "Minimum local UDP port", OFFSET(rtp_port_min), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MIN}, 0, 65535, DEC|ENC },
92  { "max_port", "Maximum local UDP port", OFFSET(rtp_port_max), AV_OPT_TYPE_INT, {.i64 = RTSP_RTP_PORT_MAX}, 0, 65535, DEC|ENC },
93  { "timeout", "Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies flag listen", OFFSET(initial_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC },
94  { "stimeout", "timeout (in micro seconds) of socket i/o operations.", OFFSET(stimeout), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC },
96  { NULL },
97 };
98 
99 static const AVOption sdp_options[] = {
100  RTSP_FLAG_OPTS("sdp_flags", "SDP flags"),
101  { "custom_io", "Use custom IO", 0, AV_OPT_TYPE_CONST, {.i64 = RTSP_FLAG_CUSTOM_IO}, 0, 0, DEC, "rtsp_flags" },
102  RTSP_MEDIATYPE_OPTS("allowed_media_types", "Media types to accept from the server"),
104  { NULL },
105 };
106 
107 static const AVOption rtp_options[] = {
108  RTSP_FLAG_OPTS("rtp_flags", "RTP flags"),
110  { NULL },
111 };
112 
113 static void get_word_until_chars(char *buf, int buf_size,
114  const char *sep, const char **pp)
115 {
116  const char *p;
117  char *q;
118 
119  p = *pp;
120  p += strspn(p, SPACE_CHARS);
121  q = buf;
122  while (!strchr(sep, *p) && *p != '\0') {
123  if ((q - buf) < buf_size - 1)
124  *q++ = *p;
125  p++;
126  }
127  if (buf_size > 0)
128  *q = '\0';
129  *pp = p;
130 }
131 
132 static void get_word_sep(char *buf, int buf_size, const char *sep,
133  const char **pp)
134 {
135  if (**pp == '/') (*pp)++;
136  get_word_until_chars(buf, buf_size, sep, pp);
137 }
138 
139 static void get_word(char *buf, int buf_size, const char **pp)
140 {
141  get_word_until_chars(buf, buf_size, SPACE_CHARS, pp);
142 }
143 
144 /** Parse a string p in the form of Range:npt=xx-xx, and determine the start
145  * and end time.
146  * Used for seeking in the rtp stream.
147  */
148 static void rtsp_parse_range_npt(const char *p, int64_t *start, int64_t *end)
149 {
150  char buf[256];
151 
152  p += strspn(p, SPACE_CHARS);
153  if (!av_stristart(p, "npt=", &p))
154  return;
155 
156  *start = AV_NOPTS_VALUE;
157  *end = AV_NOPTS_VALUE;
158 
159  get_word_sep(buf, sizeof(buf), "-", &p);
160  av_parse_time(start, buf, 1);
161  if (*p == '-') {
162  p++;
163  get_word_sep(buf, sizeof(buf), "-", &p);
164  av_parse_time(end, buf, 1);
165  }
166 }
167 
168 static int get_sockaddr(const char *buf, struct sockaddr_storage *sock)
169 {
170  struct addrinfo hints = { 0 }, *ai = NULL;
171  hints.ai_flags = AI_NUMERICHOST;
172  if (getaddrinfo(buf, NULL, &hints, &ai))
173  return -1;
174  memcpy(sock, ai->ai_addr, FFMIN(sizeof(*sock), ai->ai_addrlen));
175  freeaddrinfo(ai);
176  return 0;
177 }
178 
179 #if CONFIG_RTPDEC
180 static void init_rtp_handler(RTPDynamicProtocolHandler *handler,
181  RTSPStream *rtsp_st, AVCodecContext *codec)
182 {
183  if (!handler)
184  return;
185  if (codec)
186  codec->codec_id = handler->codec_id;
187  rtsp_st->dynamic_handler = handler;
188  if (handler->alloc) {
189  rtsp_st->dynamic_protocol_context = handler->alloc();
190  if (!rtsp_st->dynamic_protocol_context)
191  rtsp_st->dynamic_handler = NULL;
192  }
193 }
194 
195 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */
196 static int sdp_parse_rtpmap(AVFormatContext *s,
197  AVStream *st, RTSPStream *rtsp_st,
198  int payload_type, const char *p)
199 {
200  AVCodecContext *codec = st->codec;
201  char buf[256];
202  int i;
203  AVCodec *c;
204  const char *c_name;
205 
206  /* See if we can handle this kind of payload.
207  * The space should normally not be there but some Real streams or
208  * particular servers ("RealServer Version 6.1.3.970", see issue 1658)
209  * have a trailing space. */
210  get_word_sep(buf, sizeof(buf), "/ ", &p);
211  if (payload_type < RTP_PT_PRIVATE) {
212  /* We are in a standard case
213  * (from http://www.iana.org/assignments/rtp-parameters). */
214  codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
215  }
216 
217  if (codec->codec_id == AV_CODEC_ID_NONE) {
218  RTPDynamicProtocolHandler *handler =
220  init_rtp_handler(handler, rtsp_st, codec);
221  /* If no dynamic handler was found, check with the list of standard
222  * allocated types, if such a stream for some reason happens to
223  * use a private payload type. This isn't handled in rtpdec.c, since
224  * the format name from the rtpmap line never is passed into rtpdec. */
225  if (!rtsp_st->dynamic_handler)
226  codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type);
227  }
228 
229  c = avcodec_find_decoder(codec->codec_id);
230  if (c && c->name)
231  c_name = c->name;
232  else
233  c_name = "(null)";
234 
235  get_word_sep(buf, sizeof(buf), "/", &p);
236  i = atoi(buf);
237  switch (codec->codec_type) {
238  case AVMEDIA_TYPE_AUDIO:
239  av_log(s, AV_LOG_DEBUG, "audio codec set to: %s\n", c_name);
242  if (i > 0) {
243  codec->sample_rate = i;
244  avpriv_set_pts_info(st, 32, 1, codec->sample_rate);
245  get_word_sep(buf, sizeof(buf), "/", &p);
246  i = atoi(buf);
247  if (i > 0)
248  codec->channels = i;
249  }
250  av_log(s, AV_LOG_DEBUG, "audio samplerate set to: %i\n",
251  codec->sample_rate);
252  av_log(s, AV_LOG_DEBUG, "audio channels set to: %i\n",
253  codec->channels);
254  break;
255  case AVMEDIA_TYPE_VIDEO:
256  av_log(s, AV_LOG_DEBUG, "video codec set to: %s\n", c_name);
257  if (i > 0)
258  avpriv_set_pts_info(st, 32, 1, i);
259  break;
260  default:
261  break;
262  }
263  if (rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->init)
264  rtsp_st->dynamic_handler->init(s, st->index,
265  rtsp_st->dynamic_protocol_context);
266  return 0;
267 }
268 
269 /* parse the attribute line from the fmtp a line of an sdp response. This
270  * is broken out as a function because it is used in rtp_h264.c, which is
271  * forthcoming. */
272 int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size,
273  char *value, int value_size)
274 {
275  *p += strspn(*p, SPACE_CHARS);
276  if (**p) {
277  get_word_sep(attr, attr_size, "=", p);
278  if (**p == '=')
279  (*p)++;
280  get_word_sep(value, value_size, ";", p);
281  if (**p == ';')
282  (*p)++;
283  return 1;
284  }
285  return 0;
286 }
287 
288 typedef struct SDPParseState {
289  /* SDP only */
290  struct sockaddr_storage default_ip;
291  int default_ttl;
292  int skip_media; ///< set if an unknown m= line occurs
293 } SDPParseState;
294 
295 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1,
296  int letter, const char *buf)
297 {
298  RTSPState *rt = s->priv_data;
299  char buf1[64], st_type[64];
300  const char *p;
301  enum AVMediaType codec_type;
302  int payload_type, i;
303  AVStream *st;
304  RTSPStream *rtsp_st;
305  struct sockaddr_storage sdp_ip;
306  int ttl;
307 
308  av_dlog(s, "sdp: %c='%s'\n", letter, buf);
309 
310  p = buf;
311  if (s1->skip_media && letter != 'm')
312  return;
313  switch (letter) {
314  case 'c':
315  get_word(buf1, sizeof(buf1), &p);
316  if (strcmp(buf1, "IN") != 0)
317  return;
318  get_word(buf1, sizeof(buf1), &p);
319  if (strcmp(buf1, "IP4") && strcmp(buf1, "IP6"))
320  return;
321  get_word_sep(buf1, sizeof(buf1), "/", &p);
322  if (get_sockaddr(buf1, &sdp_ip))
323  return;
324  ttl = 16;
325  if (*p == '/') {
326  p++;
327  get_word_sep(buf1, sizeof(buf1), "/", &p);
328  ttl = atoi(buf1);
329  }
330  if (s->nb_streams == 0) {
331  s1->default_ip = sdp_ip;
332  s1->default_ttl = ttl;
333  } else {
334  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
335  rtsp_st->sdp_ip = sdp_ip;
336  rtsp_st->sdp_ttl = ttl;
337  }
338  break;
339  case 's':
340  av_dict_set(&s->metadata, "title", p, 0);
341  break;
342  case 'i':
343  if (s->nb_streams == 0) {
344  av_dict_set(&s->metadata, "comment", p, 0);
345  break;
346  }
347  break;
348  case 'm':
349  /* new stream */
350  s1->skip_media = 0;
351  codec_type = AVMEDIA_TYPE_UNKNOWN;
352  get_word(st_type, sizeof(st_type), &p);
353  if (!strcmp(st_type, "audio")) {
354  codec_type = AVMEDIA_TYPE_AUDIO;
355  } else if (!strcmp(st_type, "video")) {
356  codec_type = AVMEDIA_TYPE_VIDEO;
357  } else if (!strcmp(st_type, "application")) {
358  codec_type = AVMEDIA_TYPE_DATA;
359  }
360  if (codec_type == AVMEDIA_TYPE_UNKNOWN || !(rt->media_type_mask & (1 << codec_type))) {
361  s1->skip_media = 1;
362  return;
363  }
364  rtsp_st = av_mallocz(sizeof(RTSPStream));
365  if (!rtsp_st)
366  return;
367  rtsp_st->stream_index = -1;
368  dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st);
369 
370  rtsp_st->sdp_ip = s1->default_ip;
371  rtsp_st->sdp_ttl = s1->default_ttl;
372 
373  get_word(buf1, sizeof(buf1), &p); /* port */
374  rtsp_st->sdp_port = atoi(buf1);
375 
376  get_word(buf1, sizeof(buf1), &p); /* protocol */
377  if (!strcmp(buf1, "udp"))
379  else if (strstr(buf1, "/AVPF") || strstr(buf1, "/SAVPF"))
380  rtsp_st->feedback = 1;
381 
382  /* XXX: handle list of formats */
383  get_word(buf1, sizeof(buf1), &p); /* format list */
384  rtsp_st->sdp_payload_type = atoi(buf1);
385 
386  if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) {
387  /* no corresponding stream */
388  if (rt->transport == RTSP_TRANSPORT_RAW) {
389  if (!rt->ts && CONFIG_RTPDEC)
390  rt->ts = ff_mpegts_parse_open(s);
391  } else {
392  RTPDynamicProtocolHandler *handler;
393  handler = ff_rtp_handler_find_by_id(
395  init_rtp_handler(handler, rtsp_st, NULL);
396  if (handler && handler->init)
397  handler->init(s, -1, rtsp_st->dynamic_protocol_context);
398  }
399  } else if (rt->server_type == RTSP_SERVER_WMS &&
400  codec_type == AVMEDIA_TYPE_DATA) {
401  /* RTX stream, a stream that carries all the other actual
402  * audio/video streams. Don't expose this to the callers. */
403  } else {
404  st = avformat_new_stream(s, NULL);
405  if (!st)
406  return;
407  st->id = rt->nb_rtsp_streams - 1;
408  rtsp_st->stream_index = st->index;
409  st->codec->codec_type = codec_type;
410  if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) {
411  RTPDynamicProtocolHandler *handler;
412  /* if standard payload type, we can find the codec right now */
414  if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
415  st->codec->sample_rate > 0)
416  avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);
417  /* Even static payload types may need a custom depacketizer */
418  handler = ff_rtp_handler_find_by_id(
419  rtsp_st->sdp_payload_type, st->codec->codec_type);
420  init_rtp_handler(handler, rtsp_st, st->codec);
421  if (handler && handler->init)
422  handler->init(s, st->index,
423  rtsp_st->dynamic_protocol_context);
424  }
425  }
426  /* put a default control url */
427  av_strlcpy(rtsp_st->control_url, rt->control_uri,
428  sizeof(rtsp_st->control_url));
429  break;
430  case 'a':
431  if (av_strstart(p, "control:", &p)) {
432  if (s->nb_streams == 0) {
433  if (!strncmp(p, "rtsp://", 7))
434  av_strlcpy(rt->control_uri, p,
435  sizeof(rt->control_uri));
436  } else {
437  char proto[32];
438  /* get the control url */
439  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
440 
441  /* XXX: may need to add full url resolution */
442  av_url_split(proto, sizeof(proto), NULL, 0, NULL, 0,
443  NULL, NULL, 0, p);
444  if (proto[0] == '\0') {
445  /* relative control URL */
446  if (rtsp_st->control_url[strlen(rtsp_st->control_url)-1]!='/')
447  av_strlcat(rtsp_st->control_url, "/",
448  sizeof(rtsp_st->control_url));
449  av_strlcat(rtsp_st->control_url, p,
450  sizeof(rtsp_st->control_url));
451  } else
452  av_strlcpy(rtsp_st->control_url, p,
453  sizeof(rtsp_st->control_url));
454  }
455  } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) {
456  /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
457  get_word(buf1, sizeof(buf1), &p);
458  payload_type = atoi(buf1);
459  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
460  if (rtsp_st->stream_index >= 0) {
461  st = s->streams[rtsp_st->stream_index];
462  sdp_parse_rtpmap(s, st, rtsp_st, payload_type, p);
463  }
464  } else if (av_strstart(p, "fmtp:", &p) ||
465  av_strstart(p, "framesize:", &p)) {
466  /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */
467  // let dynamic protocol handlers have a stab at the line.
468  get_word(buf1, sizeof(buf1), &p);
469  payload_type = atoi(buf1);
470  for (i = 0; i < rt->nb_rtsp_streams; i++) {
471  rtsp_st = rt->rtsp_streams[i];
472  if (rtsp_st->sdp_payload_type == payload_type &&
473  rtsp_st->dynamic_handler &&
475  rtsp_st->dynamic_handler->parse_sdp_a_line(s, i,
476  rtsp_st->dynamic_protocol_context, buf);
477  }
478  } else if (av_strstart(p, "range:", &p)) {
479  int64_t start, end;
480 
481  // this is so that seeking on a streamed file can work.
482  rtsp_parse_range_npt(p, &start, &end);
483  s->start_time = start;
484  /* AV_NOPTS_VALUE means live broadcast (and can't seek) */
485  s->duration = (end == AV_NOPTS_VALUE) ?
486  AV_NOPTS_VALUE : end - start;
487  } else if (av_strstart(p, "IsRealDataType:integer;",&p)) {
488  if (atoi(p) == 1)
490  } else if (av_strstart(p, "SampleRate:integer;", &p) &&
491  s->nb_streams > 0) {
492  st = s->streams[s->nb_streams - 1];
493  st->codec->sample_rate = atoi(p);
494  } else if (av_strstart(p, "crypto:", &p) && s->nb_streams > 0) {
495  // RFC 4568
496  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
497  get_word(buf1, sizeof(buf1), &p); // ignore tag
498  get_word(rtsp_st->crypto_suite, sizeof(rtsp_st->crypto_suite), &p);
499  p += strspn(p, SPACE_CHARS);
500  if (av_strstart(p, "inline:", &p))
501  get_word(rtsp_st->crypto_params, sizeof(rtsp_st->crypto_params), &p);
502  } else {
503  if (rt->server_type == RTSP_SERVER_WMS)
505  if (s->nb_streams > 0) {
506  rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
507 
508  if (rt->server_type == RTSP_SERVER_REAL)
509  ff_real_parse_sdp_a_line(s, rtsp_st->stream_index, p);
510 
511  if (rtsp_st->dynamic_handler &&
513  rtsp_st->dynamic_handler->parse_sdp_a_line(s,
514  rtsp_st->stream_index,
515  rtsp_st->dynamic_protocol_context, buf);
516  }
517  }
518  break;
519  }
520 }
521 
522 int ff_sdp_parse(AVFormatContext *s, const char *content)
523 {
524  RTSPState *rt = s->priv_data;
525  const char *p;
526  int letter;
527  /* Some SDP lines, particularly for Realmedia or ASF RTSP streams,
528  * contain long SDP lines containing complete ASF Headers (several
529  * kB) or arrays of MDPR (RM stream descriptor) headers plus
530  * "rulebooks" describing their properties. Therefore, the SDP line
531  * buffer is large.
532  *
533  * The Vorbis FMTP line can be up to 16KB - see xiph_parse_sdp_line
534  * in rtpdec_xiph.c. */
535  char buf[16384], *q;
536  SDPParseState sdp_parse_state = { { 0 } }, *s1 = &sdp_parse_state;
537 
538  p = content;
539  for (;;) {
540  p += strspn(p, SPACE_CHARS);
541  letter = *p;
542  if (letter == '\0')
543  break;
544  p++;
545  if (*p != '=')
546  goto next_line;
547  p++;
548  /* get the content */
549  q = buf;
550  while (*p != '\n' && *p != '\r' && *p != '\0') {
551  if ((q - buf) < sizeof(buf) - 1)
552  *q++ = *p;
553  p++;
554  }
555  *q = '\0';
556  sdp_parse_line(s, s1, letter, buf);
557  next_line:
558  while (*p != '\n' && *p != '\0')
559  p++;
560  if (*p == '\n')
561  p++;
562  }
563  rt->p = av_malloc(sizeof(struct pollfd)*2*(rt->nb_rtsp_streams+1));
564  if (!rt->p) return AVERROR(ENOMEM);
565  return 0;
566 }
567 #endif /* CONFIG_RTPDEC */
568 
570 {
571  RTSPState *rt = s->priv_data;
572  int i;
573 
574  for (i = 0; i < rt->nb_rtsp_streams; i++) {
575  RTSPStream *rtsp_st = rt->rtsp_streams[i];
576  if (!rtsp_st)
577  continue;
578  if (rtsp_st->transport_priv) {
579  if (s->oformat) {
580  AVFormatContext *rtpctx = rtsp_st->transport_priv;
581  av_write_trailer(rtpctx);
583  uint8_t *ptr;
584  avio_close_dyn_buf(rtpctx->pb, &ptr);
585  av_free(ptr);
586  } else {
587  avio_close(rtpctx->pb);
588  }
589  avformat_free_context(rtpctx);
590  } else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
592  else if (rt->transport == RTSP_TRANSPORT_RTP && CONFIG_RTPDEC)
594  }
595  rtsp_st->transport_priv = NULL;
596  if (rtsp_st->rtp_handle)
597  ffurl_close(rtsp_st->rtp_handle);
598  rtsp_st->rtp_handle = NULL;
599  }
600 }
601 
602 /* close and free RTSP streams */
604 {
605  RTSPState *rt = s->priv_data;
606  int i;
607  RTSPStream *rtsp_st;
608 
610  for (i = 0; i < rt->nb_rtsp_streams; i++) {
611  rtsp_st = rt->rtsp_streams[i];
612  if (rtsp_st) {
613  if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context)
614  rtsp_st->dynamic_handler->free(
615  rtsp_st->dynamic_protocol_context);
616  av_free(rtsp_st);
617  }
618  }
619  av_free(rt->rtsp_streams);
620  if (rt->asf_ctx) {
622  }
623  if (rt->ts && CONFIG_RTPDEC)
625  av_free(rt->p);
626  av_free(rt->recvbuf);
627 }
628 
630 {
631  RTSPState *rt = s->priv_data;
632  AVStream *st = NULL;
633  int reordering_queue_size = rt->reordering_queue_size;
634  if (reordering_queue_size < 0) {
636  reordering_queue_size = 0;
637  else
638  reordering_queue_size = RTP_REORDER_QUEUE_DEFAULT_SIZE;
639  }
640 
641  /* open the RTP context */
642  if (rtsp_st->stream_index >= 0)
643  st = s->streams[rtsp_st->stream_index];
644  if (!st)
646 
647  if (s->oformat && CONFIG_RTSP_MUXER) {
648  int ret = ff_rtp_chain_mux_open((AVFormatContext **)&rtsp_st->transport_priv, s, st,
649  rtsp_st->rtp_handle,
651  rtsp_st->stream_index);
652  /* Ownership of rtp_handle is passed to the rtp mux context */
653  rtsp_st->rtp_handle = NULL;
654  if (ret < 0)
655  return ret;
656  } else if (rt->transport == RTSP_TRANSPORT_RAW) {
657  return 0; // Don't need to open any parser here
658  } else if (rt->transport == RTSP_TRANSPORT_RDT && CONFIG_RTPDEC)
659  rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index,
660  rtsp_st->dynamic_protocol_context,
661  rtsp_st->dynamic_handler);
662  else if (CONFIG_RTPDEC)
663  rtsp_st->transport_priv = ff_rtp_parse_open(s, st,
664  rtsp_st->sdp_payload_type,
665  reordering_queue_size);
666 
667  if (!rtsp_st->transport_priv) {
668  return AVERROR(ENOMEM);
669  } else if (rt->transport == RTSP_TRANSPORT_RTP && CONFIG_RTPDEC) {
670  if (rtsp_st->dynamic_handler) {
672  rtsp_st->dynamic_protocol_context,
673  rtsp_st->dynamic_handler);
674  }
675  if (rtsp_st->crypto_suite[0])
677  rtsp_st->crypto_suite,
678  rtsp_st->crypto_params);
679  }
680 
681  return 0;
682 }
683 
684 #if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER
685 static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp)
686 {
687  const char *q;
688  char *p;
689  int v;
690 
691  q = *pp;
692  q += strspn(q, SPACE_CHARS);
693  v = strtol(q, &p, 10);
694  if (*p == '-') {
695  p++;
696  *min_ptr = v;
697  v = strtol(p, &p, 10);
698  *max_ptr = v;
699  } else {
700  *min_ptr = v;
701  *max_ptr = v;
702  }
703  *pp = p;
704 }
705 
706 /* XXX: only one transport specification is parsed */
707 static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p)
708 {
709  char transport_protocol[16];
710  char profile[16];
711  char lower_transport[16];
712  char parameter[16];
714  char buf[256];
715 
716  reply->nb_transports = 0;
717 
718  for (;;) {
719  p += strspn(p, SPACE_CHARS);
720  if (*p == '\0')
721  break;
722 
723  th = &reply->transports[reply->nb_transports];
724 
725  get_word_sep(transport_protocol, sizeof(transport_protocol),
726  "/", &p);
727  if (!av_strcasecmp (transport_protocol, "rtp")) {
728  get_word_sep(profile, sizeof(profile), "/;,", &p);
729  lower_transport[0] = '\0';
730  /* rtp/avp/<protocol> */
731  if (*p == '/') {
732  get_word_sep(lower_transport, sizeof(lower_transport),
733  ";,", &p);
734  }
736  } else if (!av_strcasecmp (transport_protocol, "x-pn-tng") ||
737  !av_strcasecmp (transport_protocol, "x-real-rdt")) {
738  /* x-pn-tng/<protocol> */
739  get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p);
740  profile[0] = '\0';
742  } else if (!av_strcasecmp(transport_protocol, "raw")) {
743  get_word_sep(profile, sizeof(profile), "/;,", &p);
744  lower_transport[0] = '\0';
745  /* raw/raw/<protocol> */
746  if (*p == '/') {
747  get_word_sep(lower_transport, sizeof(lower_transport),
748  ";,", &p);
749  }
751  }
752  if (!av_strcasecmp(lower_transport, "TCP"))
754  else
756 
757  if (*p == ';')
758  p++;
759  /* get each parameter */
760  while (*p != '\0' && *p != ',') {
761  get_word_sep(parameter, sizeof(parameter), "=;,", &p);
762  if (!strcmp(parameter, "port")) {
763  if (*p == '=') {
764  p++;
765  rtsp_parse_range(&th->port_min, &th->port_max, &p);
766  }
767  } else if (!strcmp(parameter, "client_port")) {
768  if (*p == '=') {
769  p++;
770  rtsp_parse_range(&th->client_port_min,
771  &th->client_port_max, &p);
772  }
773  } else if (!strcmp(parameter, "server_port")) {
774  if (*p == '=') {
775  p++;
776  rtsp_parse_range(&th->server_port_min,
777  &th->server_port_max, &p);
778  }
779  } else if (!strcmp(parameter, "interleaved")) {
780  if (*p == '=') {
781  p++;
782  rtsp_parse_range(&th->interleaved_min,
783  &th->interleaved_max, &p);
784  }
785  } else if (!strcmp(parameter, "multicast")) {
788  } else if (!strcmp(parameter, "ttl")) {
789  if (*p == '=') {
790  char *end;
791  p++;
792  th->ttl = strtol(p, &end, 10);
793  p = end;
794  }
795  } else if (!strcmp(parameter, "destination")) {
796  if (*p == '=') {
797  p++;
798  get_word_sep(buf, sizeof(buf), ";,", &p);
799  get_sockaddr(buf, &th->destination);
800  }
801  } else if (!strcmp(parameter, "source")) {
802  if (*p == '=') {
803  p++;
804  get_word_sep(buf, sizeof(buf), ";,", &p);
805  av_strlcpy(th->source, buf, sizeof(th->source));
806  }
807  } else if (!strcmp(parameter, "mode")) {
808  if (*p == '=') {
809  p++;
810  get_word_sep(buf, sizeof(buf), ";, ", &p);
811  if (!strcmp(buf, "record") ||
812  !strcmp(buf, "receive"))
813  th->mode_record = 1;
814  }
815  }
816 
817  while (*p != ';' && *p != '\0' && *p != ',')
818  p++;
819  if (*p == ';')
820  p++;
821  }
822  if (*p == ',')
823  p++;
824 
825  reply->nb_transports++;
826  }
827 }
828 
829 static void handle_rtp_info(RTSPState *rt, const char *url,
830  uint32_t seq, uint32_t rtptime)
831 {
832  int i;
833  if (!rtptime || !url[0])
834  return;
835  if (rt->transport != RTSP_TRANSPORT_RTP)
836  return;
837  for (i = 0; i < rt->nb_rtsp_streams; i++) {
838  RTSPStream *rtsp_st = rt->rtsp_streams[i];
839  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
840  if (!rtpctx)
841  continue;
842  if (!strcmp(rtsp_st->control_url, url)) {
843  rtpctx->base_timestamp = rtptime;
844  break;
845  }
846  }
847 }
848 
849 static void rtsp_parse_rtp_info(RTSPState *rt, const char *p)
850 {
851  int read = 0;
852  char key[20], value[1024], url[1024] = "";
853  uint32_t seq = 0, rtptime = 0;
854 
855  for (;;) {
856  p += strspn(p, SPACE_CHARS);
857  if (!*p)
858  break;
859  get_word_sep(key, sizeof(key), "=", &p);
860  if (*p != '=')
861  break;
862  p++;
863  get_word_sep(value, sizeof(value), ";, ", &p);
864  read++;
865  if (!strcmp(key, "url"))
866  av_strlcpy(url, value, sizeof(url));
867  else if (!strcmp(key, "seq"))
868  seq = strtoul(value, NULL, 10);
869  else if (!strcmp(key, "rtptime"))
870  rtptime = strtoul(value, NULL, 10);
871  if (*p == ',') {
872  handle_rtp_info(rt, url, seq, rtptime);
873  url[0] = '\0';
874  seq = rtptime = 0;
875  read = 0;
876  }
877  if (*p)
878  p++;
879  }
880  if (read > 0)
881  handle_rtp_info(rt, url, seq, rtptime);
882 }
883 
884 void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf,
885  RTSPState *rt, const char *method)
886 {
887  const char *p;
888 
889  /* NOTE: we do case independent match for broken servers */
890  p = buf;
891  if (av_stristart(p, "Session:", &p)) {
892  int t;
893  get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p);
894  if (av_stristart(p, ";timeout=", &p) &&
895  (t = strtol(p, NULL, 10)) > 0) {
896  reply->timeout = t;
897  }
898  } else if (av_stristart(p, "Content-Length:", &p)) {
899  reply->content_length = strtol(p, NULL, 10);
900  } else if (av_stristart(p, "Transport:", &p)) {
901  rtsp_parse_transport(reply, p);
902  } else if (av_stristart(p, "CSeq:", &p)) {
903  reply->seq = strtol(p, NULL, 10);
904  } else if (av_stristart(p, "Range:", &p)) {
905  rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end);
906  } else if (av_stristart(p, "RealChallenge1:", &p)) {
907  p += strspn(p, SPACE_CHARS);
908  av_strlcpy(reply->real_challenge, p, sizeof(reply->real_challenge));
909  } else if (av_stristart(p, "Server:", &p)) {
910  p += strspn(p, SPACE_CHARS);
911  av_strlcpy(reply->server, p, sizeof(reply->server));
912  } else if (av_stristart(p, "Notice:", &p) ||
913  av_stristart(p, "X-Notice:", &p)) {
914  reply->notice = strtol(p, NULL, 10);
915  } else if (av_stristart(p, "Location:", &p)) {
916  p += strspn(p, SPACE_CHARS);
917  av_strlcpy(reply->location, p , sizeof(reply->location));
918  } else if (av_stristart(p, "WWW-Authenticate:", &p) && rt) {
919  p += strspn(p, SPACE_CHARS);
920  ff_http_auth_handle_header(&rt->auth_state, "WWW-Authenticate", p);
921  } else if (av_stristart(p, "Authentication-Info:", &p) && rt) {
922  p += strspn(p, SPACE_CHARS);
923  ff_http_auth_handle_header(&rt->auth_state, "Authentication-Info", p);
924  } else if (av_stristart(p, "Content-Base:", &p) && rt) {
925  p += strspn(p, SPACE_CHARS);
926  if (method && !strcmp(method, "DESCRIBE"))
927  av_strlcpy(rt->control_uri, p , sizeof(rt->control_uri));
928  } else if (av_stristart(p, "RTP-Info:", &p) && rt) {
929  p += strspn(p, SPACE_CHARS);
930  if (method && !strcmp(method, "PLAY"))
931  rtsp_parse_rtp_info(rt, p);
932  } else if (av_stristart(p, "Public:", &p) && rt) {
933  if (strstr(p, "GET_PARAMETER") &&
934  method && !strcmp(method, "OPTIONS"))
935  rt->get_parameter_supported = 1;
936  } else if (av_stristart(p, "x-Accept-Dynamic-Rate:", &p) && rt) {
937  p += strspn(p, SPACE_CHARS);
938  rt->accept_dynamic_rate = atoi(p);
939  } else if (av_stristart(p, "Content-Type:", &p)) {
940  p += strspn(p, SPACE_CHARS);
941  av_strlcpy(reply->content_type, p, sizeof(reply->content_type));
942  }
943 }
944 
945 /* skip a RTP/TCP interleaved packet */
947 {
948  RTSPState *rt = s->priv_data;
949  int ret, len, len1;
950  uint8_t buf[1024];
951 
952  ret = ffurl_read_complete(rt->rtsp_hd, buf, 3);
953  if (ret != 3)
954  return;
955  len = AV_RB16(buf + 1);
956 
957  av_dlog(s, "skipping RTP packet len=%d\n", len);
958 
959  /* skip payload */
960  while (len > 0) {
961  len1 = len;
962  if (len1 > sizeof(buf))
963  len1 = sizeof(buf);
964  ret = ffurl_read_complete(rt->rtsp_hd, buf, len1);
965  if (ret != len1)
966  return;
967  len -= len1;
968  }
969 }
970 
972  unsigned char **content_ptr,
973  int return_on_interleaved_data, const char *method)
974 {
975  RTSPState *rt = s->priv_data;
976  char buf[4096], buf1[1024], *q;
977  unsigned char ch;
978  const char *p;
979  int ret, content_length, line_count = 0, request = 0;
980  unsigned char *content = NULL;
981 
982 start:
983  line_count = 0;
984  request = 0;
985  content = NULL;
986  memset(reply, 0, sizeof(*reply));
987 
988  /* parse reply (XXX: use buffers) */
989  rt->last_reply[0] = '\0';
990  for (;;) {
991  q = buf;
992  for (;;) {
993  ret = ffurl_read_complete(rt->rtsp_hd, &ch, 1);
994  av_dlog(s, "ret=%d c=%02x [%c]\n", ret, ch, ch);
995  if (ret != 1)
996  return AVERROR_EOF;
997  if (ch == '\n')
998  break;
999  if (ch == '$') {
1000  /* XXX: only parse it if first char on line ? */
1001  if (return_on_interleaved_data) {
1002  return 1;
1003  } else
1005  } else if (ch != '\r') {
1006  if ((q - buf) < sizeof(buf) - 1)
1007  *q++ = ch;
1008  }
1009  }
1010  *q = '\0';
1011 
1012  av_dlog(s, "line='%s'\n", buf);
1013 
1014  /* test if last line */
1015  if (buf[0] == '\0')
1016  break;
1017  p = buf;
1018  if (line_count == 0) {
1019  /* get reply code */
1020  get_word(buf1, sizeof(buf1), &p);
1021  if (!strncmp(buf1, "RTSP/", 5)) {
1022  get_word(buf1, sizeof(buf1), &p);
1023  reply->status_code = atoi(buf1);
1024  av_strlcpy(reply->reason, p, sizeof(reply->reason));
1025  } else {
1026  av_strlcpy(reply->reason, buf1, sizeof(reply->reason)); // method
1027  get_word(buf1, sizeof(buf1), &p); // object
1028  request = 1;
1029  }
1030  } else {
1031  ff_rtsp_parse_line(reply, p, rt, method);
1032  av_strlcat(rt->last_reply, p, sizeof(rt->last_reply));
1033  av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply));
1034  }
1035  line_count++;
1036  }
1037 
1038  if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0' && !request)
1039  av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id));
1040 
1041  content_length = reply->content_length;
1042  if (content_length > 0) {
1043  /* leave some room for a trailing '\0' (useful for simple parsing) */
1044  content = av_malloc(content_length + 1);
1045  ffurl_read_complete(rt->rtsp_hd, content, content_length);
1046  content[content_length] = '\0';
1047  }
1048  if (content_ptr)
1049  *content_ptr = content;
1050  else
1051  av_free(content);
1052 
1053  if (request) {
1054  char buf[1024];
1055  char base64buf[AV_BASE64_SIZE(sizeof(buf))];
1056  const char* ptr = buf;
1057 
1058  if (!strcmp(reply->reason, "OPTIONS")) {
1059  snprintf(buf, sizeof(buf), "RTSP/1.0 200 OK\r\n");
1060  if (reply->seq)
1061  av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", reply->seq);
1062  if (reply->session_id[0])
1063  av_strlcatf(buf, sizeof(buf), "Session: %s\r\n",
1064  reply->session_id);
1065  } else {
1066  snprintf(buf, sizeof(buf), "RTSP/1.0 501 Not Implemented\r\n");
1067  }
1068  av_strlcat(buf, "\r\n", sizeof(buf));
1069 
1070  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1071  av_base64_encode(base64buf, sizeof(base64buf), buf, strlen(buf));
1072  ptr = base64buf;
1073  }
1074  ffurl_write(rt->rtsp_hd_out, ptr, strlen(ptr));
1075 
1076  rt->last_cmd_time = av_gettime();
1077  /* Even if the request from the server had data, it is not the data
1078  * that the caller wants or expects. The memory could also be leaked
1079  * if the actual following reply has content data. */
1080  if (content_ptr)
1081  av_freep(content_ptr);
1082  /* If method is set, this is called from ff_rtsp_send_cmd,
1083  * where a reply to exactly this request is awaited. For
1084  * callers from within packet receiving, we just want to
1085  * return to the caller and go back to receiving packets. */
1086  if (method)
1087  goto start;
1088  return 0;
1089  }
1090 
1091  if (rt->seq != reply->seq) {
1092  av_log(s, AV_LOG_WARNING, "CSeq %d expected, %d received.\n",
1093  rt->seq, reply->seq);
1094  }
1095 
1096  /* EOS */
1097  if (reply->notice == 2101 /* End-of-Stream Reached */ ||
1098  reply->notice == 2104 /* Start-of-Stream Reached */ ||
1099  reply->notice == 2306 /* Continuous Feed Terminated */) {
1100  rt->state = RTSP_STATE_IDLE;
1101  } else if (reply->notice >= 4400 && reply->notice < 5500) {
1102  return AVERROR(EIO); /* data or server error */
1103  } else if (reply->notice == 2401 /* Ticket Expired */ ||
1104  (reply->notice >= 5500 && reply->notice < 5600) /* end of term */ )
1105  return AVERROR(EPERM);
1106 
1107  return 0;
1108 }
1109 
1110 /**
1111  * Send a command to the RTSP server without waiting for the reply.
1112  *
1113  * @param s RTSP (de)muxer context
1114  * @param method the method for the request
1115  * @param url the target url for the request
1116  * @param headers extra header lines to include in the request
1117  * @param send_content if non-null, the data to send as request body content
1118  * @param send_content_length the length of the send_content data, or 0 if
1119  * send_content is null
1120  *
1121  * @return zero if success, nonzero otherwise
1122  */
1123 static int ff_rtsp_send_cmd_with_content_async(AVFormatContext *s,
1124  const char *method, const char *url,
1125  const char *headers,
1126  const unsigned char *send_content,
1127  int send_content_length)
1128 {
1129  RTSPState *rt = s->priv_data;
1130  char buf[4096], *out_buf;
1131  char base64buf[AV_BASE64_SIZE(sizeof(buf))];
1132 
1133  /* Add in RTSP headers */
1134  out_buf = buf;
1135  rt->seq++;
1136  snprintf(buf, sizeof(buf), "%s %s RTSP/1.0\r\n", method, url);
1137  if (headers)
1138  av_strlcat(buf, headers, sizeof(buf));
1139  av_strlcatf(buf, sizeof(buf), "CSeq: %d\r\n", rt->seq);
1140  if (rt->session_id[0] != '\0' && (!headers ||
1141  !strstr(headers, "\nIf-Match:"))) {
1142  av_strlcatf(buf, sizeof(buf), "Session: %s\r\n", rt->session_id);
1143  }
1144  if (rt->auth[0]) {
1145  char *str = ff_http_auth_create_response(&rt->auth_state,
1146  rt->auth, url, method);
1147  if (str)
1148  av_strlcat(buf, str, sizeof(buf));
1149  av_free(str);
1150  }
1151  if (send_content_length > 0 && send_content)
1152  av_strlcatf(buf, sizeof(buf), "Content-Length: %d\r\n", send_content_length);
1153  av_strlcat(buf, "\r\n", sizeof(buf));
1154 
1155  /* base64 encode rtsp if tunneling */
1156  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1157  av_base64_encode(base64buf, sizeof(base64buf), buf, strlen(buf));
1158  out_buf = base64buf;
1159  }
1160 
1161  av_dlog(s, "Sending:\n%s--\n", buf);
1162 
1163  ffurl_write(rt->rtsp_hd_out, out_buf, strlen(out_buf));
1164  if (send_content_length > 0 && send_content) {
1165  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1166  av_log(s, AV_LOG_ERROR, "tunneling of RTSP requests "
1167  "with content data not supported\n");
1168  return AVERROR_PATCHWELCOME;
1169  }
1170  ffurl_write(rt->rtsp_hd_out, send_content, send_content_length);
1171  }
1172  rt->last_cmd_time = av_gettime();
1173 
1174  return 0;
1175 }
1176 
1177 int ff_rtsp_send_cmd_async(AVFormatContext *s, const char *method,
1178  const char *url, const char *headers)
1179 {
1180  return ff_rtsp_send_cmd_with_content_async(s, method, url, headers, NULL, 0);
1181 }
1182 
1183 int ff_rtsp_send_cmd(AVFormatContext *s, const char *method, const char *url,
1184  const char *headers, RTSPMessageHeader *reply,
1185  unsigned char **content_ptr)
1186 {
1187  return ff_rtsp_send_cmd_with_content(s, method, url, headers, reply,
1188  content_ptr, NULL, 0);
1189 }
1190 
1192  const char *method, const char *url,
1193  const char *header,
1194  RTSPMessageHeader *reply,
1195  unsigned char **content_ptr,
1196  const unsigned char *send_content,
1197  int send_content_length)
1198 {
1199  RTSPState *rt = s->priv_data;
1200  HTTPAuthType cur_auth_type;
1201  int ret, attempts = 0;
1202 
1203 retry:
1204  cur_auth_type = rt->auth_state.auth_type;
1205  if ((ret = ff_rtsp_send_cmd_with_content_async(s, method, url, header,
1206  send_content,
1207  send_content_length)))
1208  return ret;
1209 
1210  if ((ret = ff_rtsp_read_reply(s, reply, content_ptr, 0, method) ) < 0)
1211  return ret;
1212  attempts++;
1213 
1214  if (reply->status_code == 401 &&
1215  (cur_auth_type == HTTP_AUTH_NONE || rt->auth_state.stale) &&
1216  rt->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2)
1217  goto retry;
1218 
1219  if (reply->status_code > 400){
1220  av_log(s, AV_LOG_ERROR, "method %s failed: %d%s\n",
1221  method,
1222  reply->status_code,
1223  reply->reason);
1224  av_log(s, AV_LOG_DEBUG, "%s\n", rt->last_reply);
1225  }
1226 
1227  return 0;
1228 }
1229 
1230 int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port,
1231  int lower_transport, const char *real_challenge)
1232 {
1233  RTSPState *rt = s->priv_data;
1234  int rtx = 0, j, i, err, interleave = 0, port_off;
1235  RTSPStream *rtsp_st;
1236  RTSPMessageHeader reply1, *reply = &reply1;
1237  char cmd[2048];
1238  const char *trans_pref;
1239 
1240  if (rt->transport == RTSP_TRANSPORT_RDT)
1241  trans_pref = "x-pn-tng";
1242  else if (rt->transport == RTSP_TRANSPORT_RAW)
1243  trans_pref = "RAW/RAW";
1244  else
1245  trans_pref = "RTP/AVP";
1246 
1247  /* default timeout: 1 minute */
1248  rt->timeout = 60;
1249 
1250  /* Choose a random starting offset within the first half of the
1251  * port range, to allow for a number of ports to try even if the offset
1252  * happens to be at the end of the random range. */
1253  port_off = av_get_random_seed() % ((rt->rtp_port_max - rt->rtp_port_min)/2);
1254  /* even random offset */
1255  port_off -= port_off & 0x01;
1256 
1257  for (j = rt->rtp_port_min + port_off, i = 0; i < rt->nb_rtsp_streams; ++i) {
1258  char transport[2048];
1259 
1260  /*
1261  * WMS serves all UDP data over a single connection, the RTX, which
1262  * isn't necessarily the first in the SDP but has to be the first
1263  * to be set up, else the second/third SETUP will fail with a 461.
1264  */
1265  if (lower_transport == RTSP_LOWER_TRANSPORT_UDP &&
1266  rt->server_type == RTSP_SERVER_WMS) {
1267  if (i == 0) {
1268  /* rtx first */
1269  for (rtx = 0; rtx < rt->nb_rtsp_streams; rtx++) {
1270  int len = strlen(rt->rtsp_streams[rtx]->control_url);
1271  if (len >= 4 &&
1272  !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4,
1273  "/rtx"))
1274  break;
1275  }
1276  if (rtx == rt->nb_rtsp_streams)
1277  return -1; /* no RTX found */
1278  rtsp_st = rt->rtsp_streams[rtx];
1279  } else
1280  rtsp_st = rt->rtsp_streams[i > rtx ? i : i - 1];
1281  } else
1282  rtsp_st = rt->rtsp_streams[i];
1283 
1284  /* RTP/UDP */
1285  if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) {
1286  char buf[256];
1287 
1288  if (rt->server_type == RTSP_SERVER_WMS && i > 1) {
1289  port = reply->transports[0].client_port_min;
1290  goto have_port;
1291  }
1292 
1293  /* first try in specified port range */
1294  while (j <= rt->rtp_port_max) {
1295  ff_url_join(buf, sizeof(buf), "rtp", NULL, host, -1,
1296  "?localport=%d", j);
1297  /* we will use two ports per rtp stream (rtp and rtcp) */
1298  j += 2;
1299  if (!ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE,
1300  &s->interrupt_callback, NULL))
1301  goto rtp_opened;
1302  }
1303  av_log(s, AV_LOG_ERROR, "Unable to open an input RTP port\n");
1304  err = AVERROR(EIO);
1305  goto fail;
1306 
1307  rtp_opened:
1308  port = ff_rtp_get_local_rtp_port(rtsp_st->rtp_handle);
1309  have_port:
1310  snprintf(transport, sizeof(transport) - 1,
1311  "%s/UDP;", trans_pref);
1312  if (rt->server_type != RTSP_SERVER_REAL)
1313  av_strlcat(transport, "unicast;", sizeof(transport));
1314  av_strlcatf(transport, sizeof(transport),
1315  "client_port=%d", port);
1316  if (rt->transport == RTSP_TRANSPORT_RTP &&
1317  !(rt->server_type == RTSP_SERVER_WMS && i > 0))
1318  av_strlcatf(transport, sizeof(transport), "-%d", port + 1);
1319  }
1320 
1321  /* RTP/TCP */
1322  else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) {
1323  /* For WMS streams, the application streams are only used for
1324  * UDP. When trying to set it up for TCP streams, the server
1325  * will return an error. Therefore, we skip those streams. */
1326  if (rt->server_type == RTSP_SERVER_WMS &&
1327  (rtsp_st->stream_index < 0 ||
1328  s->streams[rtsp_st->stream_index]->codec->codec_type ==
1330  continue;
1331  snprintf(transport, sizeof(transport) - 1,
1332  "%s/TCP;", trans_pref);
1333  if (rt->transport != RTSP_TRANSPORT_RDT)
1334  av_strlcat(transport, "unicast;", sizeof(transport));
1335  av_strlcatf(transport, sizeof(transport),
1336  "interleaved=%d-%d",
1337  interleave, interleave + 1);
1338  interleave += 2;
1339  }
1340 
1341  else if (lower_transport == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) {
1342  snprintf(transport, sizeof(transport) - 1,
1343  "%s/UDP;multicast", trans_pref);
1344  }
1345  if (s->oformat) {
1346  av_strlcat(transport, ";mode=record", sizeof(transport));
1347  } else if (rt->server_type == RTSP_SERVER_REAL ||
1349  av_strlcat(transport, ";mode=play", sizeof(transport));
1350  snprintf(cmd, sizeof(cmd),
1351  "Transport: %s\r\n",
1352  transport);
1353  if (rt->accept_dynamic_rate)
1354  av_strlcat(cmd, "x-Dynamic-Rate: 0\r\n", sizeof(cmd));
1355  if (i == 0 && rt->server_type == RTSP_SERVER_REAL && CONFIG_RTPDEC) {
1356  char real_res[41], real_csum[9];
1357  ff_rdt_calc_response_and_checksum(real_res, real_csum,
1358  real_challenge);
1359  av_strlcatf(cmd, sizeof(cmd),
1360  "If-Match: %s\r\n"
1361  "RealChallenge2: %s, sd=%s\r\n",
1362  rt->session_id, real_res, real_csum);
1363  }
1364  ff_rtsp_send_cmd(s, "SETUP", rtsp_st->control_url, cmd, reply, NULL);
1365  if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) {
1366  err = 1;
1367  goto fail;
1368  } else if (reply->status_code != RTSP_STATUS_OK ||
1369  reply->nb_transports != 1) {
1370  err = AVERROR_INVALIDDATA;
1371  goto fail;
1372  }
1373 
1374  /* XXX: same protocol for all streams is required */
1375  if (i > 0) {
1376  if (reply->transports[0].lower_transport != rt->lower_transport ||
1377  reply->transports[0].transport != rt->transport) {
1378  err = AVERROR_INVALIDDATA;
1379  goto fail;
1380  }
1381  } else {
1382  rt->lower_transport = reply->transports[0].lower_transport;
1383  rt->transport = reply->transports[0].transport;
1384  }
1385 
1386  /* Fail if the server responded with another lower transport mode
1387  * than what we requested. */
1388  if (reply->transports[0].lower_transport != lower_transport) {
1389  av_log(s, AV_LOG_ERROR, "Nonmatching transport in server reply\n");
1390  err = AVERROR_INVALIDDATA;
1391  goto fail;
1392  }
1393 
1394  switch(reply->transports[0].lower_transport) {
1396  rtsp_st->interleaved_min = reply->transports[0].interleaved_min;
1397  rtsp_st->interleaved_max = reply->transports[0].interleaved_max;
1398  break;
1399 
1400  case RTSP_LOWER_TRANSPORT_UDP: {
1401  char url[1024], options[30] = "";
1402 
1403  if (rt->rtsp_flags & RTSP_FLAG_FILTER_SRC)
1404  av_strlcpy(options, "?connect=1", sizeof(options));
1405  /* Use source address if specified */
1406  if (reply->transports[0].source[0]) {
1407  ff_url_join(url, sizeof(url), "rtp", NULL,
1408  reply->transports[0].source,
1409  reply->transports[0].server_port_min, "%s", options);
1410  } else {
1411  ff_url_join(url, sizeof(url), "rtp", NULL, host,
1412  reply->transports[0].server_port_min, "%s", options);
1413  }
1414  if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) &&
1415  ff_rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {
1416  err = AVERROR_INVALIDDATA;
1417  goto fail;
1418  }
1419  /* Try to initialize the connection state in a
1420  * potential NAT router by sending dummy packets.
1421  * RTP/RTCP dummy packets are used for RDT, too.
1422  */
1423  if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat &&
1424  CONFIG_RTPDEC)
1426  break;
1427  }
1429  char url[1024], namebuf[50], optbuf[20] = "";
1430  struct sockaddr_storage addr;
1431  int port, ttl;
1432 
1433  if (reply->transports[0].destination.ss_family) {
1434  addr = reply->transports[0].destination;
1435  port = reply->transports[0].port_min;
1436  ttl = reply->transports[0].ttl;
1437  } else {
1438  addr = rtsp_st->sdp_ip;
1439  port = rtsp_st->sdp_port;
1440  ttl = rtsp_st->sdp_ttl;
1441  }
1442  if (ttl > 0)
1443  snprintf(optbuf, sizeof(optbuf), "?ttl=%d", ttl);
1444  getnameinfo((struct sockaddr*) &addr, sizeof(addr),
1445  namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
1446  ff_url_join(url, sizeof(url), "rtp", NULL, namebuf,
1447  port, "%s", optbuf);
1448  if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
1449  &s->interrupt_callback, NULL) < 0) {
1450  err = AVERROR_INVALIDDATA;
1451  goto fail;
1452  }
1453  break;
1454  }
1455  }
1456 
1457  if ((err = ff_rtsp_open_transport_ctx(s, rtsp_st)))
1458  goto fail;
1459  }
1460 
1461  if (rt->nb_rtsp_streams && reply->timeout > 0)
1462  rt->timeout = reply->timeout;
1463 
1464  if (rt->server_type == RTSP_SERVER_REAL)
1465  rt->need_subscription = 1;
1466 
1467  return 0;
1468 
1469 fail:
1470  ff_rtsp_undo_setup(s);
1471  return err;
1472 }
1473 
1475 {
1476  RTSPState *rt = s->priv_data;
1477  if (rt->rtsp_hd_out != rt->rtsp_hd) ffurl_close(rt->rtsp_hd_out);
1478  ffurl_close(rt->rtsp_hd);
1479  rt->rtsp_hd = rt->rtsp_hd_out = NULL;
1480 }
1481 
1483 {
1484  RTSPState *rt = s->priv_data;
1485  char host[1024], path[1024], tcpname[1024], cmd[2048], auth[128];
1486  int port, err, tcp_fd;
1487  RTSPMessageHeader reply1 = {0}, *reply = &reply1;
1488  int lower_transport_mask = 0;
1489  char real_challenge[64] = "";
1490  struct sockaddr_storage peer;
1491  socklen_t peer_len = sizeof(peer);
1492 
1493  if (rt->rtp_port_max < rt->rtp_port_min) {
1494  av_log(s, AV_LOG_ERROR, "Invalid UDP port range, max port %d less "
1495  "than min port %d\n", rt->rtp_port_max,
1496  rt->rtp_port_min);
1497  return AVERROR(EINVAL);
1498  }
1499 
1500  if (!ff_network_init())
1501  return AVERROR(EIO);
1502 
1503  if (s->max_delay < 0) /* Not set by the caller */
1505 
1510  }
1511  /* Only pass through valid flags from here */
1513 
1514 redirect:
1515  lower_transport_mask = rt->lower_transport_mask;
1516  /* extract hostname and port */
1517  av_url_split(NULL, 0, auth, sizeof(auth),
1518  host, sizeof(host), &port, path, sizeof(path), s->filename);
1519  if (*auth) {
1520  av_strlcpy(rt->auth, auth, sizeof(rt->auth));
1521  }
1522  if (port < 0)
1523  port = RTSP_DEFAULT_PORT;
1524 
1525  if (!lower_transport_mask)
1526  lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1;
1527 
1528  if (s->oformat) {
1529  /* Only UDP or TCP - UDP multicast isn't supported. */
1530  lower_transport_mask &= (1 << RTSP_LOWER_TRANSPORT_UDP) |
1531  (1 << RTSP_LOWER_TRANSPORT_TCP);
1532  if (!lower_transport_mask || rt->control_transport == RTSP_MODE_TUNNEL) {
1533  av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, "
1534  "only UDP and TCP are supported for output.\n");
1535  err = AVERROR(EINVAL);
1536  goto fail;
1537  }
1538  }
1539 
1540  /* Construct the URI used in request; this is similar to s->filename,
1541  * but with authentication credentials removed and RTSP specific options
1542  * stripped out. */
1543  ff_url_join(rt->control_uri, sizeof(rt->control_uri), "rtsp", NULL,
1544  host, port, "%s", path);
1545 
1546  if (rt->control_transport == RTSP_MODE_TUNNEL) {
1547  /* set up initial handshake for tunneling */
1548  char httpname[1024];
1549  char sessioncookie[17];
1550  char headers[1024];
1551 
1552  ff_url_join(httpname, sizeof(httpname), "http", auth, host, port, "%s", path);
1553  snprintf(sessioncookie, sizeof(sessioncookie), "%08x%08x",
1555 
1556  /* GET requests */
1557  if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_FLAG_READ,
1558  &s->interrupt_callback) < 0) {
1559  err = AVERROR(EIO);
1560  goto fail;
1561  }
1562 
1563  /* generate GET headers */
1564  snprintf(headers, sizeof(headers),
1565  "x-sessioncookie: %s\r\n"
1566  "Accept: application/x-rtsp-tunnelled\r\n"
1567  "Pragma: no-cache\r\n"
1568  "Cache-Control: no-cache\r\n",
1569  sessioncookie);
1570  av_opt_set(rt->rtsp_hd->priv_data, "headers", headers, 0);
1571 
1572  /* complete the connection */
1573  if (ffurl_connect(rt->rtsp_hd, NULL)) {
1574  err = AVERROR(EIO);
1575  goto fail;
1576  }
1577 
1578  /* POST requests */
1579  if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_FLAG_WRITE,
1580  &s->interrupt_callback) < 0 ) {
1581  err = AVERROR(EIO);
1582  goto fail;
1583  }
1584 
1585  /* generate POST headers */
1586  snprintf(headers, sizeof(headers),
1587  "x-sessioncookie: %s\r\n"
1588  "Content-Type: application/x-rtsp-tunnelled\r\n"
1589  "Pragma: no-cache\r\n"
1590  "Cache-Control: no-cache\r\n"
1591  "Content-Length: 32767\r\n"
1592  "Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n",
1593  sessioncookie);
1594  av_opt_set(rt->rtsp_hd_out->priv_data, "headers", headers, 0);
1595  av_opt_set(rt->rtsp_hd_out->priv_data, "chunked_post", "0", 0);
1596 
1597  /* Initialize the authentication state for the POST session. The HTTP
1598  * protocol implementation doesn't properly handle multi-pass
1599  * authentication for POST requests, since it would require one of
1600  * the following:
1601  * - implementing Expect: 100-continue, which many HTTP servers
1602  * don't support anyway, even less the RTSP servers that do HTTP
1603  * tunneling
1604  * - sending the whole POST data until getting a 401 reply specifying
1605  * what authentication method to use, then resending all that data
1606  * - waiting for potential 401 replies directly after sending the
1607  * POST header (waiting for some unspecified time)
1608  * Therefore, we copy the full auth state, which works for both basic
1609  * and digest. (For digest, we would have to synchronize the nonce
1610  * count variable between the two sessions, if we'd do more requests
1611  * with the original session, though.)
1612  */
1614 
1615  /* complete the connection */
1616  if (ffurl_connect(rt->rtsp_hd_out, NULL)) {
1617  err = AVERROR(EIO);
1618  goto fail;
1619  }
1620  } else {
1621  /* open the tcp connection */
1622  ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port,
1623  "?timeout=%d", rt->stimeout);
1624  if (ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE,
1625  &s->interrupt_callback, NULL) < 0) {
1626  err = AVERROR(EIO);
1627  goto fail;
1628  }
1629  rt->rtsp_hd_out = rt->rtsp_hd;
1630  }
1631  rt->seq = 0;
1632 
1633  tcp_fd = ffurl_get_file_handle(rt->rtsp_hd);
1634  if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) {
1635  getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host),
1636  NULL, 0, NI_NUMERICHOST);
1637  }
1638 
1639  /* request options supported by the server; this also detects server
1640  * type */
1641  for (rt->server_type = RTSP_SERVER_RTP;;) {
1642  cmd[0] = 0;
1643  if (rt->server_type == RTSP_SERVER_REAL)
1644  av_strlcat(cmd,
1645  /*
1646  * The following entries are required for proper
1647  * streaming from a Realmedia server. They are
1648  * interdependent in some way although we currently
1649  * don't quite understand how. Values were copied
1650  * from mplayer SVN r23589.
1651  * ClientChallenge is a 16-byte ID in hex
1652  * CompanyID is a 16-byte ID in base64
1653  */
1654  "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n"
1655  "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n"
1656  "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n"
1657  "GUID: 00000000-0000-0000-0000-000000000000\r\n",
1658  sizeof(cmd));
1659  ff_rtsp_send_cmd(s, "OPTIONS", rt->control_uri, cmd, reply, NULL);
1660  if (reply->status_code != RTSP_STATUS_OK) {
1661  err = AVERROR_INVALIDDATA;
1662  goto fail;
1663  }
1664 
1665  /* detect server type if not standard-compliant RTP */
1666  if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
1668  continue;
1669  } else if (!av_strncasecmp(reply->server, "WMServer/", 9)) {
1671  } else if (rt->server_type == RTSP_SERVER_REAL)
1672  strcpy(real_challenge, reply->real_challenge);
1673  break;
1674  }
1675 
1676  if (s->iformat && CONFIG_RTSP_DEMUXER)
1677  err = ff_rtsp_setup_input_streams(s, reply);
1678  else if (CONFIG_RTSP_MUXER)
1679  err = ff_rtsp_setup_output_streams(s, host);
1680  if (err)
1681  goto fail;
1682 
1683  do {
1684  int lower_transport = ff_log2_tab[lower_transport_mask &
1685  ~(lower_transport_mask - 1)];
1686 
1687  err = ff_rtsp_make_setup_request(s, host, port, lower_transport,
1688  rt->server_type == RTSP_SERVER_REAL ?
1689  real_challenge : NULL);
1690  if (err < 0)
1691  goto fail;
1692  lower_transport_mask &= ~(1 << lower_transport);
1693  if (lower_transport_mask == 0 && err == 1) {
1694  err = AVERROR(EPROTONOSUPPORT);
1695  goto fail;
1696  }
1697  } while (err);
1698 
1699  rt->lower_transport_mask = lower_transport_mask;
1700  av_strlcpy(rt->real_challenge, real_challenge, sizeof(rt->real_challenge));
1701  rt->state = RTSP_STATE_IDLE;
1702  rt->seek_timestamp = 0; /* default is to start stream at position zero */
1703  return 0;
1704  fail:
1707  if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) {
1708  av_strlcpy(s->filename, reply->location, sizeof(s->filename));
1709  av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n",
1710  reply->status_code,
1711  s->filename);
1712  goto redirect;
1713  }
1714  ff_network_close();
1715  return err;
1716 }
1717 #endif /* CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER */
1718 
1719 #if CONFIG_RTPDEC
1720 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st,
1721  uint8_t *buf, int buf_size, int64_t wait_end)
1722 {
1723  RTSPState *rt = s->priv_data;
1724  RTSPStream *rtsp_st;
1725  int n, i, ret, tcp_fd, timeout_cnt = 0;
1726  int max_p = 0;
1727  struct pollfd *p = rt->p;
1728  int *fds = NULL, fdsnum, fdsidx;
1729 
1730  for (;;) {
1732  return AVERROR_EXIT;
1733  if (wait_end && wait_end - av_gettime() < 0)
1734  return AVERROR(EAGAIN);
1735  max_p = 0;
1736  if (rt->rtsp_hd) {
1737  tcp_fd = ffurl_get_file_handle(rt->rtsp_hd);
1738  p[max_p].fd = tcp_fd;
1739  p[max_p++].events = POLLIN;
1740  } else {
1741  tcp_fd = -1;
1742  }
1743  for (i = 0; i < rt->nb_rtsp_streams; i++) {
1744  rtsp_st = rt->rtsp_streams[i];
1745  if (rtsp_st->rtp_handle) {
1746  if (ret = ffurl_get_multi_file_handle(rtsp_st->rtp_handle,
1747  &fds, &fdsnum)) {
1748  av_log(s, AV_LOG_ERROR, "Unable to recover rtp ports\n");
1749  return ret;
1750  }
1751  if (fdsnum != 2) {
1752  av_log(s, AV_LOG_ERROR,
1753  "Number of fds %d not supported\n", fdsnum);
1754  return AVERROR_INVALIDDATA;
1755  }
1756  for (fdsidx = 0; fdsidx < fdsnum; fdsidx++) {
1757  p[max_p].fd = fds[fdsidx];
1758  p[max_p++].events = POLLIN;
1759  }
1760  av_free(fds);
1761  }
1762  }
1763  n = poll(p, max_p, POLL_TIMEOUT_MS);
1764  if (n > 0) {
1765  int j = 1 - (tcp_fd == -1);
1766  timeout_cnt = 0;
1767  for (i = 0; i < rt->nb_rtsp_streams; i++) {
1768  rtsp_st = rt->rtsp_streams[i];
1769  if (rtsp_st->rtp_handle) {
1770  if (p[j].revents & POLLIN || p[j+1].revents & POLLIN) {
1771  ret = ffurl_read(rtsp_st->rtp_handle, buf, buf_size);
1772  if (ret > 0) {
1773  *prtsp_st = rtsp_st;
1774  return ret;
1775  }
1776  }
1777  j+=2;
1778  }
1779  }
1780 #if CONFIG_RTSP_DEMUXER
1781  if (tcp_fd != -1 && p[0].revents & POLLIN) {
1782  if (rt->rtsp_flags & RTSP_FLAG_LISTEN) {
1783  if (rt->state == RTSP_STATE_STREAMING) {
1785  return AVERROR_EOF;
1786  else
1788  "Unable to answer to TEARDOWN\n");
1789  } else
1790  return 0;
1791  } else {
1792  RTSPMessageHeader reply;
1793  ret = ff_rtsp_read_reply(s, &reply, NULL, 0, NULL);
1794  if (ret < 0)
1795  return ret;
1796  /* XXX: parse message */
1797  if (rt->state != RTSP_STATE_STREAMING)
1798  return 0;
1799  }
1800  }
1801 #endif
1802  } else if (n == 0 && ++timeout_cnt >= MAX_TIMEOUTS) {
1803  return AVERROR(ETIMEDOUT);
1804  } else if (n < 0 && errno != EINTR)
1805  return AVERROR(errno);
1806  }
1807 }
1808 
1809 static int pick_stream(AVFormatContext *s, RTSPStream **rtsp_st,
1810  const uint8_t *buf, int len)
1811 {
1812  RTSPState *rt = s->priv_data;
1813  int i;
1814  if (len < 0)
1815  return len;
1816  if (rt->nb_rtsp_streams == 1) {
1817  *rtsp_st = rt->rtsp_streams[0];
1818  return len;
1819  }
1820  if (len >= 8 && rt->transport == RTSP_TRANSPORT_RTP) {
1821  if (RTP_PT_IS_RTCP(rt->recvbuf[1])) {
1822  int no_ssrc = 0;
1823  for (i = 0; i < rt->nb_rtsp_streams; i++) {
1824  RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
1825  if (!rtpctx)
1826  continue;
1827  if (rtpctx->ssrc == AV_RB32(&buf[4])) {
1828  *rtsp_st = rt->rtsp_streams[i];
1829  return len;
1830  }
1831  if (!rtpctx->ssrc)
1832  no_ssrc = 1;
1833  }
1834  if (no_ssrc) {
1836  "Unable to pick stream for packet - SSRC not known for "
1837  "all streams\n");
1838  return AVERROR(EAGAIN);
1839  }
1840  } else {
1841  for (i = 0; i < rt->nb_rtsp_streams; i++) {
1842  if ((buf[1] & 0x7f) == rt->rtsp_streams[i]->sdp_payload_type) {
1843  *rtsp_st = rt->rtsp_streams[i];
1844  return len;
1845  }
1846  }
1847  }
1848  }
1849  av_log(s, AV_LOG_WARNING, "Unable to pick stream for packet\n");
1850  return AVERROR(EAGAIN);
1851 }
1852 
1854 {
1855  RTSPState *rt = s->priv_data;
1856  int ret, len;
1857  RTSPStream *rtsp_st, *first_queue_st = NULL;
1858  int64_t wait_end = 0;
1859 
1860  if (rt->nb_byes == rt->nb_rtsp_streams)
1861  return AVERROR_EOF;
1862 
1863  /* get next frames from the same RTP packet */
1864  if (rt->cur_transport_priv) {
1865  if (rt->transport == RTSP_TRANSPORT_RDT) {
1866  ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
1867  } else if (rt->transport == RTSP_TRANSPORT_RTP) {
1868  ret = ff_rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0);
1869  } else if (rt->ts && CONFIG_RTPDEC) {
1870  ret = ff_mpegts_parse_packet(rt->ts, pkt, rt->recvbuf + rt->recvbuf_pos, rt->recvbuf_len - rt->recvbuf_pos);
1871  if (ret >= 0) {
1872  rt->recvbuf_pos += ret;
1873  ret = rt->recvbuf_pos < rt->recvbuf_len;
1874  }
1875  } else
1876  ret = -1;
1877  if (ret == 0) {
1878  rt->cur_transport_priv = NULL;
1879  return 0;
1880  } else if (ret == 1) {
1881  return 0;
1882  } else
1883  rt->cur_transport_priv = NULL;
1884  }
1885 
1886 redo:
1887  if (rt->transport == RTSP_TRANSPORT_RTP) {
1888  int i;
1889  int64_t first_queue_time = 0;
1890  for (i = 0; i < rt->nb_rtsp_streams; i++) {
1891  RTPDemuxContext *rtpctx = rt->rtsp_streams[i]->transport_priv;
1892  int64_t queue_time;
1893  if (!rtpctx)
1894  continue;
1895  queue_time = ff_rtp_queued_packet_time(rtpctx);
1896  if (queue_time && (queue_time - first_queue_time < 0 ||
1897  !first_queue_time)) {
1898  first_queue_time = queue_time;
1899  first_queue_st = rt->rtsp_streams[i];
1900  }
1901  }
1902  if (first_queue_time) {
1903  wait_end = first_queue_time + s->max_delay;
1904  } else {
1905  wait_end = 0;
1906  first_queue_st = NULL;
1907  }
1908  }
1909 
1910  /* read next RTP packet */
1911  if (!rt->recvbuf) {
1913  if (!rt->recvbuf)
1914  return AVERROR(ENOMEM);
1915  }
1916 
1917  switch(rt->lower_transport) {
1918  default:
1919 #if CONFIG_RTSP_DEMUXER
1921  len = ff_rtsp_tcp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE);
1922  break;
1923 #endif
1926  len = udp_read_packet(s, &rtsp_st, rt->recvbuf, RECVBUF_SIZE, wait_end);
1927  if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
1928  ff_rtp_check_and_send_back_rr(rtsp_st->transport_priv, rtsp_st->rtp_handle, NULL, len);
1929  break;
1931  if (first_queue_st && rt->transport == RTSP_TRANSPORT_RTP &&
1932  wait_end && wait_end < av_gettime())
1933  len = AVERROR(EAGAIN);
1934  else
1935  len = ffio_read_partial(s->pb, rt->recvbuf, RECVBUF_SIZE);
1936  len = pick_stream(s, &rtsp_st, rt->recvbuf, len);
1937  if (len > 0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP)
1939  break;
1940  }
1941  if (len == AVERROR(EAGAIN) && first_queue_st &&
1942  rt->transport == RTSP_TRANSPORT_RTP) {
1943  rtsp_st = first_queue_st;
1944  ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, NULL, 0);
1945  goto end;
1946  }
1947  if (len < 0)
1948  return len;
1949  if (len == 0)
1950  return AVERROR_EOF;
1951  if (rt->transport == RTSP_TRANSPORT_RDT) {
1952  ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
1953  } else if (rt->transport == RTSP_TRANSPORT_RTP) {
1954  ret = ff_rtp_parse_packet(rtsp_st->transport_priv, pkt, &rt->recvbuf, len);
1955  if (rtsp_st->feedback) {
1956  AVIOContext *pb = NULL;
1958  pb = s->pb;
1959  ff_rtp_send_rtcp_feedback(rtsp_st->transport_priv, rtsp_st->rtp_handle, pb);
1960  }
1961  if (ret < 0) {
1962  /* Either bad packet, or a RTCP packet. Check if the
1963  * first_rtcp_ntp_time field was initialized. */
1964  RTPDemuxContext *rtpctx = rtsp_st->transport_priv;
1965  if (rtpctx->first_rtcp_ntp_time != AV_NOPTS_VALUE) {
1966  /* first_rtcp_ntp_time has been initialized for this stream,
1967  * copy the same value to all other uninitialized streams,
1968  * in order to map their timestamp origin to the same ntp time
1969  * as this one. */
1970  int i;
1971  AVStream *st = NULL;
1972  if (rtsp_st->stream_index >= 0)
1973  st = s->streams[rtsp_st->stream_index];
1974  for (i = 0; i < rt->nb_rtsp_streams; i++) {
1975  RTPDemuxContext *rtpctx2 = rt->rtsp_streams[i]->transport_priv;
1976  AVStream *st2 = NULL;
1977  if (rt->rtsp_streams[i]->stream_index >= 0)
1978  st2 = s->streams[rt->rtsp_streams[i]->stream_index];
1979  if (rtpctx2 && st && st2 &&
1980  rtpctx2->first_rtcp_ntp_time == AV_NOPTS_VALUE) {
1981  rtpctx2->first_rtcp_ntp_time = rtpctx->first_rtcp_ntp_time;
1982  rtpctx2->rtcp_ts_offset = av_rescale_q(
1983  rtpctx->rtcp_ts_offset, st->time_base,
1984  st2->time_base);
1985  }
1986  }
1987  }
1988  if (ret == -RTCP_BYE) {
1989  rt->nb_byes++;
1990 
1991  av_log(s, AV_LOG_DEBUG, "Received BYE for stream %d (%d/%d)\n",
1992  rtsp_st->stream_index, rt->nb_byes, rt->nb_rtsp_streams);
1993 
1994  if (rt->nb_byes == rt->nb_rtsp_streams)
1995  return AVERROR_EOF;
1996  }
1997  }
1998  } else if (rt->ts && CONFIG_RTPDEC) {
1999  ret = ff_mpegts_parse_packet(rt->ts, pkt, rt->recvbuf, len);
2000  if (ret >= 0) {
2001  if (ret < len) {
2002  rt->recvbuf_len = len;
2003  rt->recvbuf_pos = ret;
2004  rt->cur_transport_priv = rt->ts;
2005  return 1;
2006  } else {
2007  ret = 0;
2008  }
2009  }
2010  } else {
2011  return AVERROR_INVALIDDATA;
2012  }
2013 end:
2014  if (ret < 0)
2015  goto redo;
2016  if (ret == 1)
2017  /* more packets may follow, so we save the RTP context */
2018  rt->cur_transport_priv = rtsp_st->transport_priv;
2019 
2020  return ret;
2021 }
2022 #endif /* CONFIG_RTPDEC */
2023 
2024 #if CONFIG_SDP_DEMUXER
2025 static int sdp_probe(AVProbeData *p1)
2026 {
2027  const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;
2028 
2029  /* we look for a line beginning "c=IN IP" */
2030  while (p < p_end && *p != '\0') {
2031  if (p + sizeof("c=IN IP") - 1 < p_end &&
2032  av_strstart(p, "c=IN IP", NULL))
2033  return AVPROBE_SCORE_MAX / 2;
2034 
2035  while (p < p_end - 1 && *p != '\n') p++;
2036  if (++p >= p_end)
2037  break;
2038  if (*p == '\r')
2039  p++;
2040  }
2041  return 0;
2042 }
2043 
2044 static int sdp_read_header(AVFormatContext *s)
2045 {
2046  RTSPState *rt = s->priv_data;
2047  RTSPStream *rtsp_st;
2048  int size, i, err;
2049  char *content;
2050  char url[1024];
2051 
2052  if (!ff_network_init())
2053  return AVERROR(EIO);
2054 
2055  if (s->max_delay < 0) /* Not set by the caller */
2057  if (rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)
2059 
2060  /* read the whole sdp file */
2061  /* XXX: better loading */
2062  content = av_malloc(SDP_MAX_SIZE);
2063  size = avio_read(s->pb, content, SDP_MAX_SIZE - 1);
2064  if (size <= 0) {
2065  av_free(content);
2066  return AVERROR_INVALIDDATA;
2067  }
2068  content[size] ='\0';
2069 
2070  err = ff_sdp_parse(s, content);
2071  av_free(content);
2072  if (err) goto fail;
2073 
2074  /* open each RTP stream */
2075  for (i = 0; i < rt->nb_rtsp_streams; i++) {
2076  char namebuf[50];
2077  rtsp_st = rt->rtsp_streams[i];
2078 
2079  if (!(rt->rtsp_flags & RTSP_FLAG_CUSTOM_IO)) {
2080  getnameinfo((struct sockaddr*) &rtsp_st->sdp_ip, sizeof(rtsp_st->sdp_ip),
2081  namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST);
2082  ff_url_join(url, sizeof(url), "rtp", NULL,
2083  namebuf, rtsp_st->sdp_port,
2084  "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port,
2085  rtsp_st->sdp_ttl,
2086  rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0);
2087  if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE,
2088  &s->interrupt_callback, NULL) < 0) {
2089  err = AVERROR_INVALIDDATA;
2090  goto fail;
2091  }
2092  }
2093  if ((err = ff_rtsp_open_transport_ctx(s, rtsp_st)))
2094  goto fail;
2095  }
2096  return 0;
2097 fail:
2099  ff_network_close();
2100  return err;
2101 }
2102 
2103 static int sdp_read_close(AVFormatContext *s)
2104 {
2106  ff_network_close();
2107  return 0;
2108 }
2109 
2110 static const AVClass sdp_demuxer_class = {
2111  .class_name = "SDP demuxer",
2112  .item_name = av_default_item_name,
2113  .option = sdp_options,
2114  .version = LIBAVUTIL_VERSION_INT,
2115 };
2116 
2117 AVInputFormat ff_sdp_demuxer = {
2118  .name = "sdp",
2119  .long_name = NULL_IF_CONFIG_SMALL("SDP"),
2120  .priv_data_size = sizeof(RTSPState),
2121  .read_probe = sdp_probe,
2122  .read_header = sdp_read_header,
2124  .read_close = sdp_read_close,
2125  .priv_class = &sdp_demuxer_class,
2126 };
2127 #endif /* CONFIG_SDP_DEMUXER */
2128 
2129 #if CONFIG_RTP_DEMUXER
2130 static int rtp_probe(AVProbeData *p)
2131 {
2132  if (av_strstart(p->filename, "rtp:", NULL))
2133  return AVPROBE_SCORE_MAX;
2134  return 0;
2135 }
2136 
2137 static int rtp_read_header(AVFormatContext *s)
2138 {
2139  uint8_t recvbuf[RTP_MAX_PACKET_LENGTH];
2140  char host[500], sdp[500];
2141  int ret, port;
2142  URLContext* in = NULL;
2143  int payload_type;
2144  AVCodecContext codec = { 0 };
2145  struct sockaddr_storage addr;
2146  AVIOContext pb;
2147  socklen_t addrlen = sizeof(addr);
2148  RTSPState *rt = s->priv_data;
2149 
2150  if (!ff_network_init())
2151  return AVERROR(EIO);
2152 
2153  ret = ffurl_open(&in, s->filename, AVIO_FLAG_READ,
2154  &s->interrupt_callback, NULL);
2155  if (ret)
2156  goto fail;
2157 
2158  while (1) {
2159  ret = ffurl_read(in, recvbuf, sizeof(recvbuf));
2160  if (ret == AVERROR(EAGAIN))
2161  continue;
2162  if (ret < 0)
2163  goto fail;
2164  if (ret < 12) {
2165  av_log(s, AV_LOG_WARNING, "Received too short packet\n");
2166  continue;
2167  }
2168 
2169  if ((recvbuf[0] & 0xc0) != 0x80) {
2170  av_log(s, AV_LOG_WARNING, "Unsupported RTP version packet "
2171  "received\n");
2172  continue;
2173  }
2174 
2175  if (RTP_PT_IS_RTCP(recvbuf[1]))
2176  continue;
2177 
2178  payload_type = recvbuf[1] & 0x7f;
2179  break;
2180  }
2181  getsockname(ffurl_get_file_handle(in), (struct sockaddr*) &addr, &addrlen);
2182  ffurl_close(in);
2183  in = NULL;
2184 
2185  if (ff_rtp_get_codec_info(&codec, payload_type)) {
2186  av_log(s, AV_LOG_ERROR, "Unable to receive RTP payload type %d "
2187  "without an SDP file describing it\n",
2188  payload_type);
2189  goto fail;
2190  }
2191  if (codec.codec_type != AVMEDIA_TYPE_DATA) {
2192  av_log(s, AV_LOG_WARNING, "Guessing on RTP content - if not received "
2193  "properly you need an SDP file "
2194  "describing it\n");
2195  }
2196 
2197  av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port,
2198  NULL, 0, s->filename);
2199 
2200  snprintf(sdp, sizeof(sdp),
2201  "v=0\r\nc=IN IP%d %s\r\nm=%s %d RTP/AVP %d\r\n",
2202  addr.ss_family == AF_INET ? 4 : 6, host,
2203  codec.codec_type == AVMEDIA_TYPE_DATA ? "application" :
2204  codec.codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio",
2205  port, payload_type);
2206  av_log(s, AV_LOG_VERBOSE, "SDP:\n%s\n", sdp);
2207 
2208  ffio_init_context(&pb, sdp, strlen(sdp), 0, NULL, NULL, NULL, NULL);
2209  s->pb = &pb;
2210 
2211  /* sdp_read_header initializes this again */
2212  ff_network_close();
2213 
2214  rt->media_type_mask = (1 << (AVMEDIA_TYPE_DATA+1)) - 1;
2215 
2216  ret = sdp_read_header(s);
2217  s->pb = NULL;
2218  return ret;
2219 
2220 fail:
2221  if (in)
2222  ffurl_close(in);
2223  ff_network_close();
2224  return ret;
2225 }
2226 
2227 static const AVClass rtp_demuxer_class = {
2228  .class_name = "RTP demuxer",
2229  .item_name = av_default_item_name,
2230  .option = rtp_options,
2231  .version = LIBAVUTIL_VERSION_INT,
2232 };
2233 
2234 AVInputFormat ff_rtp_demuxer = {
2235  .name = "rtp",
2236  .long_name = NULL_IF_CONFIG_SMALL("RTP input"),
2237  .priv_data_size = sizeof(RTSPState),
2238  .read_probe = rtp_probe,
2239  .read_header = rtp_read_header,
2241  .read_close = sdp_read_close,
2242  .flags = AVFMT_NOFILE,
2243  .priv_class = &rtp_demuxer_class,
2244 };
2245 #endif /* CONFIG_RTP_DEMUXER */
char auth[128]
plaintext authorization line (username:password)
Definition: rtsp.h:272
int interleaved_min
interleave ids, if TCP transport; each TCP/RTSP data packet starts with a &#39;$&#39;, stream length and stre...
Definition: rtsp.h:92
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.
char crypto_suite[40]
Definition: rtsp.h:451
Definition: start.py:1
void ff_rtsp_skip_packet(AVFormatContext *s)
Skip a RTP/TCP interleaved packet.
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
int rtp_port_min
Minimum and maximum local UDP ports.
Definition: rtsp.h:386
int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p)
Parse a Windows Media Server-specific SDP line.
Definition: rtpdec_asf.c:96
void ff_rtp_parse_set_crypto(RTPDemuxContext *s, const char *suite, const char *params)
Definition: rtpdec.c:527
float v
const char * s
Definition: avisynth_c.h:668
Bytestream IO Context.
Definition: avio.h:68
Realmedia Data Transport.
Definition: rtsp.h:58
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define RTP_MAX_PACKET_LENGTH
Definition: rtpdec.h:36
void ff_rtsp_undo_setup(AVFormatContext *s)
Undo the effect of ff_rtsp_make_setup_request, close the transport_priv and rtp_handle fields...
Definition: rtsp.c:569
void ff_rtp_send_punch_packets(URLContext *rtp_handle)
Send a dummy packet on both port pairs to set up the connection state in potential NAT routers...
Definition: rtpdec.c:352
AVIOInterruptCB interrupt_callback
Custom interrupt callbacks for the I/O layer.
Definition: avformat.h:1125
int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer)
Return the written size and a pointer to the buffer.
Definition: aviobuf.c:988
AVOption.
Definition: opt.h:251
char source[INET6_ADDRSTRLEN+1]
source IP address
Definition: rtsp.h:114
av_default_item_name
HTTPAuthType
Authentication types, ordered from weakest to strongest.
Definition: httpauth.h:28
char content_type[64]
Content type header.
Definition: rtsp.h:186
const char * filename
Definition: avformat.h:335
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:148
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:316
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.
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:530
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:317
#define RTSP_DEFAULT_PORT
Definition: rtsp.h:72
#define CONFIG_RTPDEC
Definition: config.h:420
Windows Media server.
Definition: rtsp.h:208
struct pollfd * p
Polling array for udp.
Definition: rtsp.h:353
int ff_rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st)
Open RTSP transport context.
Definition: rtsp.c:629
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
int ffurl_connect(URLContext *uc, AVDictionary **options)
Connect an URLContext that has been allocated by ffurl_alloc.
Definition: avio.c:190
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
int index
stream index in AVFormatContext
Definition: avformat.h:644
#define AVIO_FLAG_READ
read-only
Definition: avio.h:332
char location[4096]
the "Location:" field.
Definition: rtsp.h:151
About Git write you should know how to use GIT properly Luckily Git comes with excellent documentation git help man git shows you the available git< command > help man git< command > shows information about the subcommand< command > The most comprehensive manual is the website Git Reference visit they are quite exhaustive You do not need a special username or password All you need is to provide a ssh public key to the Git server admin What follows now is a basic introduction to Git and some FFmpeg specific guidelines Read it at least if you are granted commit privileges to the FFmpeg project you are expected to be familiar with these rules I if not You can get git from etc no matter how small Every one of them has been saved from looking like a fool by this many times It s very easy for stray debug output or cosmetic modifications to slip in
Definition: git-howto.txt:5
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:333
int mode_record
transport set to record data
Definition: rtsp.h:111
enum AVMediaType codec_type
Definition: rtp.c:36
int av_strncasecmp(const char *a, const char *b, size_t n)
Locale-independent case-insensitive compare.
Definition: avstring.c:222
void ff_network_close(void)
Definition: network.c:173
UDP/unicast.
Definition: rtsp.h:38
int seq
sequence number
Definition: rtsp.h:143
initialized and sending/receiving data
Definition: rtsp.h:196
char real_challenge[64]
the "RealChallenge1:" field from the server
Definition: rtsp.h:269
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
static av_always_inline void interleave(IDWTELEM *dst, IDWTELEM *src0, IDWTELEM *src1, int w2, int add, int shift)
Definition: dirac_dwt.c:51
#define RTSP_RTP_PORT_MAX
Definition: rtsp.h:78
#define freeaddrinfo
Definition: network.h:195
int ctx_flags
Format-specific flags, see AVFMTCTX_xx.
Definition: avformat.h:980
#define RTSP_FLAG_LISTEN
Wait for incoming connections.
Definition: rtsp.h:409
char session_id[512]
copy of RTSPMessageHeader->session_id, i.e.
Definition: rtsp.h:244
int64_t seek_timestamp
the seek value requested when calling av_seek_frame().
Definition: rtsp.h:238
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:131
#define AI_NUMERICHOST
Definition: network.h:164
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.
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 DESTDIR Destination directory for the install useful to prepare packages or install FFmpeg in cross environments Makefile builds all the libraries and the executables fate Run the fate test note you must have installed it fate list Will list all fate regression test targets install Install headers
Definition: build_system.txt:1
enum RTSPLowerTransport lower_transport
network layer transport protocol; e.g.
Definition: rtsp.h:120
int ff_url_join(char *str, int size, const char *proto, const char *authorization, const char *hostname, int port, const char *fmt,...) av_printf_format(7
Assemble a URL string from components.
This describes the server response to each RTSP command.
Definition: rtsp.h:126
RTPDemuxContext * ff_rtp_parse_open(AVFormatContext *s1, AVStream *st, int payload_type, int queue_size)
open a new RTP parse context for stream &#39;st&#39;.
Definition: rtpdec.c:488
#define RECVBUF_SIZE
Definition: rtsp.c:60
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
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:141
Format I/O context.
Definition: avformat.h:944
#define RTP_PT_PRIVATE
Definition: rtp.h:76
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:142
int ff_rtsp_connect(AVFormatContext *s)
Connect to the RTSP server and set up the individual media streams.
Standards-compliant RTP-server.
Definition: rtsp.h:206
int reordering_queue_size
Size of RTP packet reordering queue.
Definition: rtsp.h:401
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:55
int recvbuf_len
Definition: rtsp.h:322
Public dictionary API.
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:44
int get_parameter_supported
Whether the server supports the GET_PARAMETER method.
Definition: rtsp.h:358
#define CONFIG_RTSP_DEMUXER
Definition: config.h:966
Standards-compliant RTP.
Definition: rtsp.h:57
uint8_t
char session_id[512]
the "Session:" field.
Definition: rtsp.h:147
Opaque data information usually continuous.
Definition: avutil.h:145
int ttl
time-to-live value (required for multicast); the amount of HOPs that packets will be allowed to make ...
Definition: rtsp.h:108
int ff_network_init(void)
Definition: network.c:126
#define AVFMTCTX_NOHEADER
signal that no header is present (streams are added dynamically)
Definition: avformat.h:914
AVOptions.
miscellaneous OS support macros and functions.
int feedback
Enable sending RTCP feedback messages according to RFC 4585.
Definition: rtsp.h:449
#define AV_RB32
uint16_t ss_family
Definition: network.h:105
static AVPacket pkt
Definition: demuxing.c:56
int id
Format-specific stream ID.
Definition: avformat.h:650
end end
#define POLL_TIMEOUT_MS
Definition: rtsp.c:56
#define DEFAULT_REORDERING_DELAY
Definition: rtsp.c:61
void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf, RTSPState *rt, const char *method)
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, char *value, int value_size)
AVStream ** streams
Definition: avformat.h:992
int accept_dynamic_rate
Whether the server accepts the x-Dynamic-Rate header.
Definition: rtsp.h:371
URLContext * rtsp_hd_out
Additional output handle, used when input and output are done separately, eg for HTTP tunneling...
Definition: rtsp.h:327
Describe a single stream, as identified by a single m= line block in the SDP content.
Definition: rtsp.h:418
Custom IO - not a public option for lower_transport_mask, but set in the SDP demuxer based on a flag...
Definition: rtsp.h:45
#define CONFIG_RTSP_MUXER
Definition: config.h:1452
enum RTSPStatusCode status_code
response code from server
Definition: rtsp.h:130
#define AVERROR_EOF
End of file.
Definition: error.h:55
void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
Initialize the authentication state based on another HTTP URLContext.
Definition: http.c:102
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
const uint8_t ff_log2_tab[256]
int ff_rtsp_parse_streaming_commands(AVFormatContext *s)
Parse RTSP commands (OPTIONS, PAUSE and TEARDOWN) during streaming in listen mode.
Definition: rtspdec.c:451
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.
Normal RTSP.
Definition: rtsp.h:68
const OptionDef options[]
Definition: ffserver.c:4697
int nb_transports
number of items in the &#39;transports&#39; variable below
Definition: rtsp.h:133
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:478
int ff_rtp_get_local_rtp_port(URLContext *h)
Return the local rtp port used by the RTP connection.
Definition: rtpproto.c:292
struct AVOutputFormat * oformat
Definition: avformat.h:958
int notice
The "Notice" or "X-Notice" field value.
Definition: rtsp.h:176
#define RTSP_DEFAULT_AUDIO_SAMPLERATE
Definition: rtsp.h:76
void ff_rdt_parse_close(RDTDemuxContext *s)
Definition: rdt.c:78
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:130
int ff_sdp_parse(AVFormatContext *s, const char *content)
Parse an SDP description of streams by populating an RTSPState struct within the AVFormatContext; als...
Private data for the RTSP demuxer.
Definition: rtsp.h:217
int64_t last_cmd_time
timestamp of the last RTSP command that we sent to the RTSP server.
Definition: rtsp.h:254
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:211
AVDictionary * metadata
Definition: avformat.h:1092
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
int ffurl_get_multi_file_handle(URLContext *h, int **handles, int *numhandles)
Return the file descriptors associated with this URL.
Definition: avio.c:406
int timeout
copy of RTSPMessageHeader->timeout, i.e.
Definition: rtsp.h:249
#define AV_RB16
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
int avio_close(AVIOContext *s)
Close the resource accessed by the AVIOContext s and free it.
Definition: aviobuf.c:821
const AVOption ff_rtsp_options[]
Definition: rtsp.c:81
char reason[256]
The "reason" is meant to specify better the meaning of the error code returned.
Definition: rtsp.h:181
URLContext * rtsp_hd
Definition: rtsp.h:219
simple assert() macros that are a bit more flexible than ISO C assert().
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
enum RTSPControlTransport control_transport
RTSP transport mode, such as plain or tunneled.
Definition: rtsp.h:330
int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:526
char * av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size)
Encode data to base64 and null-terminate.
int64_t rtcp_ts_offset
Definition: rtpdec.h:184
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:82
RTPDynamicProtocolHandler * ff_rtp_handler_find_by_id(int id, enum AVMediaType codec_type)
Definition: rtpdec.c:110
struct RTSPStream ** rtsp_streams
streams in this session
Definition: rtsp.h:224
int size
char server[64]
the "Server: field, which can be used to identify some special-case servers that are not 100% standar...
Definition: rtsp.h:163
int ff_rtp_get_codec_info(AVCodecContext *codec, int payload_type)
Initialize a codec context based on the payload type.
Definition: rtp.c:70
int stream_index
corresponding stream index, if any.
Definition: rtsp.h:423
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
MpegTSContext * ff_mpegts_parse_open(AVFormatContext *s)
Definition: mpegts.c:2241
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:337
int seq
RTSP command sequence number.
Definition: rtsp.h:240
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:336
uint8_t * recvbuf
Reusable buffer for receiving packets.
Definition: rtsp.h:338
unsigned int nb_streams
A list of all streams in the file.
Definition: avformat.h:991
#define AV_LOG_VERBOSE
Definition: log.h:157
#define RTSP_FLAG_CUSTOM_IO
Do all IO via the AVIOContext.
Definition: rtsp.h:410
#define NI_NUMERICHOST
Definition: network.h:172
#define th
Definition: regdef.h:75
AVFormatContext * asf_ctx
The following are used for RTP/ASF streams.
Definition: rtsp.h:306
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:128
int recvbuf_pos
Definition: rtsp.h:321
#define dynarray_add(tab, nb_ptr, elem)
char filename[1024]
input or output filename
Definition: avformat.h:994
int nb_rtsp_streams
number of items in the &#39;rtsp_streams&#39; variable
Definition: rtsp.h:222
int64_t first_rtcp_ntp_time
Definition: rtpdec.h:182
#define AV_BASE64_SIZE(x)
Calculate the output size needed to base64-encode x bytes to a null-terminated string.
Definition: base64.h:61
#define FFMIN(a, b)
Definition: common.h:58
void * cur_transport_priv
RTSPStream->transport_priv of the last stream that we read a packet from.
Definition: rtsp.h:282
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition: avstring.c:212
static int read_probe(AVProbeData *pd)
int content_length
length of the data following this header
Definition: rtsp.h:128
ret
Definition: avfilter.c:821
int timeout
The "timeout" comes as part of the server response to the "SETUP" command, in the "Session: <xyz>[;ti...
Definition: rtsp.h:171
#define RTSP_TCP_MAX_PACKET_SIZE
Definition: rtsp.h:74
t
Definition: genspecsines3.m:6
HTTP tunneled - not a proper transport mode as such, only for use via AVOptions.
Definition: rtsp.h:42
This describes a single item in the "Transport:" line of one stream as negotiated by the SETUP RTSP c...
Definition: rtsp.h:87
RTSP over HTTP (tunneling)
Definition: rtsp.h:69
static void get_word_until_chars(char *buf, int buf_size, const char *sep, const char **pp)
Definition: rtsp.c:113
static void get_word(char *buf, int buf_size, const char **pp)
Definition: rtsp.c:139
char crypto_params[100]
Definition: rtsp.h:452
Usually treated as AVMEDIA_TYPE_DATA.
Definition: avutil.h:142
int ffurl_get_file_handle(URLContext *h)
Return the file descriptor associated with this URL.
Definition: avio.c:399
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
#define ENC
Definition: rtsp.c:65
int sdp_port
The following are used only in SDP, not RTSP.
Definition: rtsp.h:433
int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, const uint8_t *buf, int len)
Definition: mpegts.c:2260
Raw data (over UDP)
Definition: rtsp.h:59
LIBAVUTIL_VERSION_INT
Definition: eval.c:55
struct MpegTSContext * ts
The following are used for parsing raw mpegts in udp.
Definition: rtsp.h:320
int stale
Auth ok, but needs to be resent with a new nonce.
Definition: httpauth.h:71
int sdp_payload_type
payload type
Definition: rtsp.h:436
void ff_rtp_parse_set_dynamic_protocol(RTPDemuxContext *s, PayloadContext *ctx, RTPDynamicProtocolHandler *handler)
Definition: rtpdec.c:520
static int get_sockaddr(const char *buf, struct sockaddr_storage *sock)
Definition: rtsp.c:168
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:517
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
int ff_rtp_send_rtcp_feedback(RTPDemuxContext *s, URLContext *fd, AVIOContext *avio)
Definition: rtpdec.c:420
Stream structure.
Definition: avformat.h:643
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
int nb_byes
Definition: rtsp.h:335
enum RTSPLowerTransport lower_transport
the negotiated network layer transport protocol; e.g.
Definition: rtsp.h:261
NULL
Definition: eval.c:55
struct sockaddr_storage sdp_ip
IP address (from SDP content)
Definition: rtsp.h:434
enum AVMediaType codec_type
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrup a blocking function associated with cb.
Definition: avio.c:428
enum AVCodecID codec_id
int rtp_port_max
Definition: rtsp.h:386
Definition: rtp.h:99
int sample_rate
samples per second
AVIOContext * pb
I/O context.
Definition: avformat.h:977
int media_type_mask
Mask of all requested media types.
Definition: rtsp.h:381
int server_port_max
Definition: rtsp.h:104
#define FF_RTP_FLAG_OPTS(ctx, fieldname)
Definition: rtpenc.h:74
main external API structure.
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
#define RTSP_FLAG_OPTS(name, longname)
Definition: rtsp.c:67
RDTDemuxContext * ff_rdt_parse_open(AVFormatContext *ic, int first_stream_of_set_idx, void *priv_data, RTPDynamicProtocolHandler *handler)
Allocate and init the RDT parsing context.
Definition: rdt.c:55
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
#define RTSP_FLAG_FILTER_SRC
Filter incoming UDP packets - receive packets only from the right source address and port...
Definition: rtsp.h:404
enum AVCodecID codec_id
Definition: rtpdec.h:122
enum RTSPTransport transport
the negotiated data/packet transport protocol; e.g.
Definition: rtsp.h:257
void * buf
Definition: avisynth_c.h:594
Definition: url.h:41
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:130
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
static int read_packet(AVFormatContext *ctx, AVPacket *pkt)
Definition: libcdio.c:114
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:334
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:62
int rtsp_flags
Various option flags for the RTSP muxer/demuxer.
Definition: rtsp.h:376
double value
Definition: eval.c:82
int client_port_max
Definition: rtsp.h:100
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
Describe the class of an AVClass context structure.
Definition: log.h:50
#define SDP_MAX_SIZE
Definition: rtsp.c:59
void ff_real_parse_sdp_a_line(AVFormatContext *s, int stream_index, const char *line)
Parse a server-related SDP line.
Definition: rdt.c:510
synthesis window for stochastic i
#define SPACE_CHARS
void * priv_data
Definition: url.h:44
struct RTSPState RTSPState
Private data for the RTSP demuxer.
PayloadContext * dynamic_protocol_context
private data associated with the dynamic protocol
Definition: rtsp.h:445
char last_reply[2048]
The last reply of the server to a RTSP command.
Definition: rtsp.h:278
PayloadContext *(* alloc)(void)
Allocate any data needed by the rtp parsing for this dynamic data.
Definition: rtpdec.h:133
not initialized
Definition: rtsp.h:195
int64_t range_end
Definition: rtsp.h:137
enum RTSPTransport transport
data/packet transport protocol; e.g.
Definition: rtsp.h:117
char real_challenge[64]
the "RealChallenge1:" field from the server
Definition: rtsp.h:154
AVMediaType
Definition: avutil.h:141
size_t av_strlcatf(char *dst, size_t size, const char *fmt,...)
Definition: avstring.c:100
#define RTSP_MEDIATYPE_OPTS(name, longname)
Definition: rtsp.c:72
int64_t ff_rtp_queued_packet_time(RTPDemuxContext *s)
Definition: rtpdec.c:699
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:713
void ff_rtsp_close_streams(AVFormatContext *s)
Close and free all streams within the RTSP (de)muxer.
Definition: rtsp.c:603
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&#39;t hear from them...
Definition: rtpdec.c:249
#define s1
Definition: regdef.h:38
#define snprintf
Definition: snprintf.h:34
void avformat_free_context(AVFormatContext *s)
Free an AVFormatContext and all its streams.
This structure contains the data a format has to probe a file.
Definition: avformat.h:334
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
#define RTSP_DEFAULT_NB_AUDIO_CHANNELS
Definition: rtsp.h:75
misc parsing utilities
char * ff_http_auth_create_response(HTTPAuthState *state, const char *auth, const char *path, const char *method)
Definition: httpauth.c:242
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:92
int interleaved_max
Definition: rtsp.h:92
#define RTP_PT_IS_RTCP(x)
Definition: rtp.h:109
enum RTSPServerType server_type
brand of server that we&#39;re talking to; e.g.
Definition: rtsp.h:266
static int flags
Definition: cpu.c:23
int ffurl_close(URLContext *h)
Definition: avio.c:359
int64_t range_start
Time range of the streams that the server will stream.
Definition: rtsp.h:137
int64_t start_time
Decoding: position of the first frame of the component, in AV_TIME_BASE fractional seconds...
Definition: avformat.h:1001
enum RTSPClientState state
indicator of whether we are currently receiving data from the server.
Definition: rtsp.h:230
#define DEC
Definition: rtsp.c:64
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...
#define AVPROBE_SCORE_MAX
maximum score, half of that is used for file-extension-based detection
Definition: avformat.h:340
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:33
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.
#define getaddrinfo
Definition: network.h:194
Main libavformat public API header.
static const AVOption sdp_options[]
Definition: rtsp.c:99
void ff_mpegts_parse_close(MpegTSContext *ts)
Definition: mpegts.c:2285
int ff_rtp_chain_mux_open(AVFormatContext **out, AVFormatContext *s, AVStream *st, URLContext *handle, int packet_size, int idx)
Definition: rtpenc_chain.c:29
uint32_t ssrc
Definition: rtpdec.h:155
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:345
RTPDynamicProtocolHandler * ff_rtp_handler_find_by_name(const char *name, enum AVMediaType codec_type)
Definition: rtpdec.c:98
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:71
int ffurl_open(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options)
Create an URLContext for accessing to the resource indicated by url, and open it. ...
Definition: avio.c:247
static double c[64]
int need_subscription
The following are used for Real stream selection.
Definition: rtsp.h:287
RTPDynamicProtocolHandler * dynamic_handler
The following are used for dynamic protocols (rtpdec_*.c/rdt.c)
Definition: rtsp.h:442
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:310
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
first frame pointer p_end
Definition: stft_peak.m:15
#define RTSP_REORDERING_OPTS()
Definition: rtsp.c:78
void(* free)(PayloadContext *protocol_data)
Free any data needed by the rtp parsing for this dynamic data.
Definition: rtpdec.h:135
struct AVInputFormat * iformat
Can only be iformat or oformat, not both at the same time.
Definition: avformat.h:957
void avformat_close_input(AVFormatContext **s)
Close an opened input AVFormatContext.
void ff_http_auth_handle_header(HTTPAuthState *state, const char *key, const char *value)
Definition: httpauth.c:90
uint32_t base_timestamp
Definition: rtpdec.h:158
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&#39;re reading data interleave...
int stimeout
timeout of socket i/o operations.
Definition: rtsp.h:396
#define getnameinfo
Definition: network.h:196
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.
static void get_word_sep(char *buf, int buf_size, const char *sep, const char **pp)
Definition: rtsp.c:132
TCP; interleaved in RTSP.
Definition: rtsp.h:39
HTTPAuthState auth_state
authentication state
Definition: rtsp.h:275
int len
#define RTSP_RTP_PORT_MIN
Definition: rtsp.h:77
int channels
number of audio channels
char control_url[1024]
url for this stream (from SDP)
Definition: rtsp.h:429
void * priv_data
Format private data.
Definition: avformat.h:964
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:567
void ff_rtp_parse_close(RTPDemuxContext *s)
Definition: rtpdec.c:822
int sdp_ttl
IP Time-To-Live (from SDP content)
Definition: rtsp.h:435
#define MAX_TIMEOUTS
Definition: rtsp.c:58
int av_write_trailer(AVFormatContext *s)
Write the stream trailer to an output media file and free the file private data.
Definition: mux.c:769
int ai_flags
Definition: network.h:115
int64_t duration
Decoding: duration of the stream, in AV_TIME_BASE fractional seconds.
Definition: avformat.h:1009
HTTPAuthType auth_type
The currently chosen auth type.
Definition: httpauth.h:59
#define AV_LOG_INFO
Definition: log.h:156
Realmedia-style server.
Definition: rtsp.h:207
int lower_transport_mask
A mask with all requested transport methods.
Definition: rtsp.h:343
void INT64 start
Definition: avisynth_c.h:594
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:461
unbuffered private I/O API
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
Definition: random_seed.c:105
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avformat.h:679
int interleaved_max
Definition: rtsp.h:427
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:58
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:809
struct sockaddr_storage destination
destination IP address
Definition: rtsp.h:113
#define RTP_REORDER_QUEUE_DEFAULT_SIZE
Definition: rtpdec.h:38
int interleaved_min
interleave IDs; copies of RTSPTransportField->interleaved_min/max for the selected transport...
Definition: rtsp.h:427
This structure stores compressed data.
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:104
void ff_rtsp_close_connections(AVFormatContext *s)
Close all connection handles within the RTSP (de)muxer.
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition: opt.c:252
static const AVOption rtp_options[]
Definition: rtsp.c:107
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:303
URLContext * rtp_handle
RTP stream handle (if UDP)
Definition: rtsp.h:419
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:190
#define OFFSET(x)
Definition: rtsp.c:63
int port_min
UDP multicast port range; the ports to which we should connect to receive multicast UDP data...
Definition: rtsp.h:96
void * transport_priv
RTP/RDT parse context if input, RTP AVFormatContext if output.
Definition: rtsp.h:420
No authentication specified.
Definition: httpauth.h:29
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:100