annotate ffmpeg/libavformat/rtsp.c @ 13:844d341cf643 tip

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