Mercurial > libavformat.hg
annotate rtsp.c @ 5843:777a89fdb1c0 libavformat
RTSP: Synchronize the start time of the chained RTP muxers
This makes sure that the streams get correctly synchronized when viewed,
previously the streams were out of sync by as much time as it took
between the initialization of the individual muxers.
author | mstorsjo |
---|---|
date | Mon, 15 Mar 2010 14:20:07 +0000 |
parents | d605f589f0be |
children | ca238015a806 |
rev | line source |
---|---|
0 | 1 /* |
2 * RTSP/SDP client | |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4206
diff
changeset
|
3 * Copyright (c) 2002 Fabrice Bellard |
0 | 4 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1169
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
887
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
3286 | 21 |
5220
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
22 #include "libavutil/base64.h" |
3286 | 23 #include "libavutil/avstring.h" |
4201
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
4187
diff
changeset
|
24 #include "libavutil/intreadwrite.h" |
0 | 25 #include "avformat.h" |
26 | |
1808
572ce77d7333
Fix compilation on Mac OS X, patch by Marc Hoffman, mmh pleasantst com.
diego
parents:
1754
diff
changeset
|
27 #include <sys/time.h> |
4206 | 28 #if HAVE_SYS_SELECT_H |
3936
6154f62ef652
include sys/select.h instead of unistd.h to get select,
bcoudurier
parents:
3924
diff
changeset
|
29 #include <sys/select.h> |
3941
53c5b89b8dff
only include sys/select.h if present, fix mingw compilation
bcoudurier
parents:
3936
diff
changeset
|
30 #endif |
3714 | 31 #include <strings.h> |
5837
d605f589f0be
move ff_url_split() and ff_url_join() declarations to internal.h
aurel
parents:
5820
diff
changeset
|
32 #include "internal.h" |
1754 | 33 #include "network.h" |
5802
2d82e25df58c
Include os_support.h which has a fallback declaration of socklen_t
mstorsjo
parents:
5800
diff
changeset
|
34 #include "os_support.h" |
2681
6037eb4919fb
Remove the inclusion of rtsp.h and rtp.h from avformat.h, and
lucabe
parents:
2408
diff
changeset
|
35 #include "rtsp.h" |
0 | 36 |
4388 | 37 #include "rtpdec.h" |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
38 #include "rdt.h" |
5726
04b39763b51b
Rename RTP depacketizer files from rtp_* to rtpdec_*
mstorsjo
parents:
5700
diff
changeset
|
39 #include "rtpdec_asf.h" |
04b39763b51b
Rename RTP depacketizer files from rtp_* to rtpdec_*
mstorsjo
parents:
5700
diff
changeset
|
40 #include "rtpdec_vorbis.h" |
1419 | 41 |
0 | 42 //#define DEBUG |
172 | 43 //#define DEBUG_RTP_TCP |
0 | 44 |
2884 | 45 #if LIBAVFORMAT_VERSION_INT < (53 << 16) |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
46 int rtsp_default_protocols = (1 << RTSP_LOWER_TRANSPORT_UDP); |
2884 | 47 #endif |
0 | 48 |
4773
1c9751d3065c
Merge functional code from get_word() and get_word_sep() into a single
rbultje
parents:
4772
diff
changeset
|
49 #define SPACE_CHARS " \t\r\n" |
4789
c18ea19a9771
strchr(string, '\0') returns non-NULL, and is thus not suited for use in
rbultje
parents:
4779
diff
changeset
|
50 /* we use memchr() instead of strchr() here because strchr() will return |
c18ea19a9771
strchr(string, '\0') returns non-NULL, and is thus not suited for use in
rbultje
parents:
4779
diff
changeset
|
51 * the terminating '\0' of SPACE_CHARS instead of NULL if c is '\0'. */ |
c18ea19a9771
strchr(string, '\0') returns non-NULL, and is thus not suited for use in
rbultje
parents:
4779
diff
changeset
|
52 #define redir_isspace(c) memchr(SPACE_CHARS, c, 4) |
0 | 53 static void skip_spaces(const char **pp) |
54 { | |
55 const char *p; | |
56 p = *pp; | |
57 while (redir_isspace(*p)) | |
58 p++; | |
59 *pp = p; | |
60 } | |
61 | |
4773
1c9751d3065c
Merge functional code from get_word() and get_word_sep() into a single
rbultje
parents:
4772
diff
changeset
|
62 static void get_word_until_chars(char *buf, int buf_size, |
1c9751d3065c
Merge functional code from get_word() and get_word_sep() into a single
rbultje
parents:
4772
diff
changeset
|
63 const char *sep, const char **pp) |
0 | 64 { |
65 const char *p; | |
66 char *q; | |
67 | |
68 p = *pp; | |
69 skip_spaces(&p); | |
70 q = buf; | |
71 while (!strchr(sep, *p) && *p != '\0') { | |
72 if ((q - buf) < buf_size - 1) | |
73 *q++ = *p; | |
74 p++; | |
75 } | |
76 if (buf_size > 0) | |
77 *q = '\0'; | |
78 *pp = p; | |
79 } | |
80 | |
4773
1c9751d3065c
Merge functional code from get_word() and get_word_sep() into a single
rbultje
parents:
4772
diff
changeset
|
81 static void get_word_sep(char *buf, int buf_size, const char *sep, |
1c9751d3065c
Merge functional code from get_word() and get_word_sep() into a single
rbultje
parents:
4772
diff
changeset
|
82 const char **pp) |
1c9751d3065c
Merge functional code from get_word() and get_word_sep() into a single
rbultje
parents:
4772
diff
changeset
|
83 { |
1c9751d3065c
Merge functional code from get_word() and get_word_sep() into a single
rbultje
parents:
4772
diff
changeset
|
84 if (**pp == '/') (*pp)++; |
1c9751d3065c
Merge functional code from get_word() and get_word_sep() into a single
rbultje
parents:
4772
diff
changeset
|
85 get_word_until_chars(buf, buf_size, sep, pp); |
1c9751d3065c
Merge functional code from get_word() and get_word_sep() into a single
rbultje
parents:
4772
diff
changeset
|
86 } |
1c9751d3065c
Merge functional code from get_word() and get_word_sep() into a single
rbultje
parents:
4772
diff
changeset
|
87 |
0 | 88 static void get_word(char *buf, int buf_size, const char **pp) |
89 { | |
4773
1c9751d3065c
Merge functional code from get_word() and get_word_sep() into a single
rbultje
parents:
4772
diff
changeset
|
90 get_word_until_chars(buf, buf_size, SPACE_CHARS, pp); |
0 | 91 } |
92 | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
93 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other params>] */ |
5503
4ec7bcff8719
Add correct log context to av_log() calls in parse_rtpmap().
rbultje
parents:
5502
diff
changeset
|
94 static int sdp_parse_rtpmap(AVFormatContext *s, |
4ec7bcff8719
Add correct log context to av_log() calls in parse_rtpmap().
rbultje
parents:
5502
diff
changeset
|
95 AVCodecContext *codec, RTSPStream *rtsp_st, |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
96 int payload_type, const char *p) |
0 | 97 { |
98 char buf[256]; | |
774 | 99 int i; |
100 AVCodec *c; | |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
1003
diff
changeset
|
101 const char *c_name; |
0 | 102 |
774 | 103 /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and |
5529
0a67dbb939a0
Fix issue1658 (trailing space in rtpmap descriptor).
rbultje
parents:
5503
diff
changeset
|
104 * see if we can handle this kind of payload. |
0a67dbb939a0
Fix issue1658 (trailing space in rtpmap descriptor).
rbultje
parents:
5503
diff
changeset
|
105 * The space should normally not be there but some Real streams or |
0a67dbb939a0
Fix issue1658 (trailing space in rtpmap descriptor).
rbultje
parents:
5503
diff
changeset
|
106 * particular servers ("RealServer Version 6.1.3.970", see issue 1658) |
0a67dbb939a0
Fix issue1658 (trailing space in rtpmap descriptor).
rbultje
parents:
5503
diff
changeset
|
107 * have a trailing space. */ |
0a67dbb939a0
Fix issue1658 (trailing space in rtpmap descriptor).
rbultje
parents:
5503
diff
changeset
|
108 get_word_sep(buf, sizeof(buf), "/ ", &p); |
774 | 109 if (payload_type >= RTP_PT_PRIVATE) { |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
110 RTPDynamicProtocolHandler *handler; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
111 for (handler = RTPFirstDynamicPayloadHandler; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
112 handler; handler = handler->next) { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
113 if (!strcasecmp(buf, handler->enc_name) && |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
114 codec->codec_type == handler->codec_type) { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
115 codec->codec_id = handler->codec_id; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
116 rtsp_st->dynamic_handler = handler; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
117 if (handler->open) |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
118 rtsp_st->dynamic_protocol_context = handler->open(); |
774 | 119 break; |
120 } | |
1419 | 121 } |
774 | 122 } else { |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
123 /* We are in a standard case |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
124 * (from http://www.iana.org/assignments/rtp-parameters). */ |
774 | 125 /* search into AVRtpPayloadTypes[] */ |
2759
b252e318023a
Remove the "AVRtpPayloadTypes[i].pt == i" assumption from RTP and RTSP
lucabe
parents:
2711
diff
changeset
|
126 codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type); |
774 | 127 } |
128 | |
129 c = avcodec_find_decoder(codec->codec_id); | |
130 if (c && c->name) | |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
1003
diff
changeset
|
131 c_name = c->name; |
774 | 132 else |
5644
95e016b6158c
Don't forget to set known audio parameters (samplerate, etc.) if the codec is
rbultje
parents:
5589
diff
changeset
|
133 c_name = "(null)"; |
774 | 134 |
5645 | 135 get_word_sep(buf, sizeof(buf), "/", &p); |
136 i = atoi(buf); | |
137 switch (codec->codec_type) { | |
138 case CODEC_TYPE_AUDIO: | |
139 av_log(s, AV_LOG_DEBUG, "audio codec set to: %s\n", c_name); | |
140 codec->sample_rate = RTSP_DEFAULT_AUDIO_SAMPLERATE; | |
141 codec->channels = RTSP_DEFAULT_NB_AUDIO_CHANNELS; | |
142 if (i > 0) { | |
143 codec->sample_rate = i; | |
144 get_word_sep(buf, sizeof(buf), "/", &p); | |
145 i = atoi(buf); | |
146 if (i > 0) | |
147 codec->channels = i; | |
148 // TODO: there is a bug here; if it is a mono stream, and | |
149 // less than 22000Hz, faad upconverts to stereo and twice | |
150 // the frequency. No problem, but the sample rate is being | |
151 // set here by the sdp line. Patch on its way. (rdm) | |
774 | 152 } |
5645 | 153 av_log(s, AV_LOG_DEBUG, "audio samplerate set to: %i\n", |
154 codec->sample_rate); | |
155 av_log(s, AV_LOG_DEBUG, "audio channels set to: %i\n", | |
156 codec->channels); | |
157 break; | |
158 case CODEC_TYPE_VIDEO: | |
159 av_log(s, AV_LOG_DEBUG, "video codec set to: %s\n", c_name); | |
160 break; | |
161 default: | |
162 break; | |
163 } | |
164 return 0; | |
0 | 165 } |
166 | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
167 /* return the length and optionally the data */ |
0 | 168 static int hex_to_data(uint8_t *data, const char *p) |
169 { | |
170 int c, len, v; | |
171 | |
172 len = 0; | |
173 v = 1; | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
174 for (;;) { |
0 | 175 skip_spaces(&p); |
4776
894e353aaeca
Fix silly bug in hex_to_data() where it compares a string pointer for whether
rbultje
parents:
4775
diff
changeset
|
176 if (*p == '\0') |
0 | 177 break; |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
178 c = toupper((unsigned char) *p++); |
0 | 179 if (c >= '0' && c <= '9') |
180 c = c - '0'; | |
181 else if (c >= 'A' && c <= 'F') | |
182 c = c - 'A' + 10; | |
183 else | |
184 break; | |
185 v = (v << 4) | c; | |
186 if (v & 0x100) { | |
187 if (data) | |
188 data[len] = v; | |
189 len++; | |
190 v = 1; | |
191 } | |
192 } | |
193 return len; | |
194 } | |
195 | |
4875
13a2a1a475d5
Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
4874
diff
changeset
|
196 static void sdp_parse_fmtp_config(AVCodecContext * codec, void *ctx, |
13a2a1a475d5
Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
4874
diff
changeset
|
197 char *attr, char *value) |
774 | 198 { |
199 switch (codec->codec_id) { | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
200 case CODEC_ID_MPEG4: |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
201 case CODEC_ID_AAC: |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
202 if (!strcmp(attr, "config")) { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
203 /* decode the hexa encoded parameter */ |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
204 int len = hex_to_data(NULL, value); |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
205 if (codec->extradata) |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
206 av_free(codec->extradata); |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
207 codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE); |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
208 if (!codec->extradata) |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
209 return; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
210 codec->extradata_size = len; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
211 hex_to_data(codec->extradata, value); |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
212 } |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
213 break; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
214 case CODEC_ID_VORBIS: |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
215 ff_vorbis_parse_fmtp_config(codec, ctx, attr, value); |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
216 break; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
217 default: |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
218 break; |
774 | 219 } |
220 return; | |
221 } | |
222 | |
4088 | 223 typedef struct { |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
1003
diff
changeset
|
224 const char *str; |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
225 uint16_t type; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
226 uint32_t offset; |
4088 | 227 } AttrNameMap; |
774 | 228 |
229 /* All known fmtp parmeters and the corresping RTPAttrTypeEnum */ | |
230 #define ATTR_NAME_TYPE_INT 0 | |
231 #define ATTR_NAME_TYPE_STR 1 | |
4088 | 232 static const AttrNameMap attr_names[]= |
774 | 233 { |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
234 { "SizeLength", ATTR_NAME_TYPE_INT, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
235 offsetof(RTPPayloadData, sizelength) }, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
236 { "IndexLength", ATTR_NAME_TYPE_INT, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
237 offsetof(RTPPayloadData, indexlength) }, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
238 { "IndexDeltaLength", ATTR_NAME_TYPE_INT, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
239 offsetof(RTPPayloadData, indexdeltalength) }, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
240 { "profile-level-id", ATTR_NAME_TYPE_INT, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
241 offsetof(RTPPayloadData, profile_level_id) }, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
242 { "StreamType", ATTR_NAME_TYPE_INT, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
243 offsetof(RTPPayloadData, streamtype) }, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
244 { "mode", ATTR_NAME_TYPE_STR, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
245 offsetof(RTPPayloadData, mode) }, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
246 { NULL, -1, -1 }, |
774 | 247 }; |
248 | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
249 /* parse the attribute line from the fmtp a line of an sdp resonse. This |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
250 * is broken out as a function because it is used in rtp_h264.c, which is |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
251 * forthcoming. */ |
5697 | 252 int ff_rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, |
5700 | 253 char *value, int value_size) |
1431
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
254 { |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
255 skip_spaces(p); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
256 if (**p) { |
1431
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
257 get_word_sep(attr, attr_size, "=", p); |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
258 if (**p == '=') |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
259 (*p)++; |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
260 get_word_sep(value, value_size, ";", p); |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
261 if (**p == ';') |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
262 (*p)++; |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
263 return 1; |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
264 } |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
265 return 0; |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
266 } |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
267 |
774 | 268 /* parse a SDP line and save stream attributes */ |
269 static void sdp_parse_fmtp(AVStream *st, const char *p) | |
0 | 270 { |
271 char attr[256]; | |
4874
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
272 /* Vorbis setup headers can be up to 12KB and are sent base64 |
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
273 * encoded, giving a 12KB * (4/3) = 16KB FMTP line. */ |
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
274 char value[16384]; |
774 | 275 int i; |
276 RTSPStream *rtsp_st = st->priv_data; | |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
774
diff
changeset
|
277 AVCodecContext *codec = st->codec; |
4101
af2c0aef892b
Rename rtp_payload_data_t to avoid clashes with the POSIX namespace
lucabe
parents:
4088
diff
changeset
|
278 RTPPayloadData *rtp_payload_data = &rtsp_st->rtp_payload_data; |
0 | 279 |
280 /* loop on each attribute */ | |
5697 | 281 while (ff_rtsp_next_attr_and_value(&p, attr, sizeof(attr), |
5700 | 282 value, sizeof(value))) { |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
283 /* grab the codec extra_data from the config parameter of the fmtp |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
284 * line */ |
4875
13a2a1a475d5
Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
4874
diff
changeset
|
285 sdp_parse_fmtp_config(codec, rtsp_st->dynamic_protocol_context, |
13a2a1a475d5
Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
4874
diff
changeset
|
286 attr, value); |
774 | 287 /* Looking for a known attribute */ |
288 for (i = 0; attr_names[i].str; ++i) { | |
289 if (!strcasecmp(attr, attr_names[i].str)) { | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
290 if (attr_names[i].type == ATTR_NAME_TYPE_INT) { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
291 *(int *)((char *)rtp_payload_data + |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
292 attr_names[i].offset) = atoi(value); |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
293 } else if (attr_names[i].type == ATTR_NAME_TYPE_STR) |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
294 *(char **)((char *)rtp_payload_data + |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
295 attr_names[i].offset) = av_strdup(value); |
887 | 296 } |
0 | 297 } |
298 } | |
299 } | |
300 | |
5485 | 301 /** Parse a string p in the form of Range:npt=xx-xx, and determine the start |
1453
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
302 * and end time. |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
303 * Used for seeking in the rtp stream. |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
304 */ |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
305 static void rtsp_parse_range_npt(const char *p, int64_t *start, int64_t *end) |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
306 { |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
307 char buf[256]; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
308 |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
309 skip_spaces(&p); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
310 if (!av_stristart(p, "npt=", &p)) |
1453
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
311 return; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
312 |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
313 *start = AV_NOPTS_VALUE; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
314 *end = AV_NOPTS_VALUE; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
315 |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
316 get_word_sep(buf, sizeof(buf), "-", &p); |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
317 *start = parse_date(buf, 1); |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
318 if (*p == '-') { |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
319 p++; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
320 get_word_sep(buf, sizeof(buf), "-", &p); |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
321 *end = parse_date(buf, 1); |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
322 } |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
323 // av_log(NULL, AV_LOG_DEBUG, "Range Start: %lld\n", *start); |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
324 // av_log(NULL, AV_LOG_DEBUG, "Range End: %lld\n", *end); |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
325 } |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
326 |
0 | 327 typedef struct SDPParseState { |
328 /* SDP only */ | |
329 struct in_addr default_ip; | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
330 int default_ttl; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
331 int skip_media; ///< set if an unknown m= line occurs |
0 | 332 } SDPParseState; |
333 | |
334 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, | |
335 int letter, const char *buf) | |
336 { | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
337 RTSPState *rt = s->priv_data; |
0 | 338 char buf1[64], st_type[64]; |
339 const char *p; | |
3967 | 340 enum CodecType codec_type; |
341 int payload_type, i; | |
0 | 342 AVStream *st; |
343 RTSPStream *rtsp_st; | |
344 struct in_addr sdp_ip; | |
345 int ttl; | |
346 | |
4990 | 347 dprintf(s, "sdp: %c='%s'\n", letter, buf); |
0 | 348 |
349 p = buf; | |
4281
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
350 if (s1->skip_media && letter != 'm') |
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
351 return; |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
352 switch (letter) { |
0 | 353 case 'c': |
354 get_word(buf1, sizeof(buf1), &p); | |
355 if (strcmp(buf1, "IN") != 0) | |
356 return; | |
357 get_word(buf1, sizeof(buf1), &p); | |
358 if (strcmp(buf1, "IP4") != 0) | |
359 return; | |
360 get_word_sep(buf1, sizeof(buf1), "/", &p); | |
5766
a292ef47e2f9
Localize the #define _SVID_SOURCE needed for inet_aton() to os_support.c
conrad
parents:
5756
diff
changeset
|
361 if (ff_inet_aton(buf1, &sdp_ip) == 0) |
0 | 362 return; |
363 ttl = 16; | |
364 if (*p == '/') { | |
365 p++; | |
366 get_word_sep(buf1, sizeof(buf1), "/", &p); | |
367 ttl = atoi(buf1); | |
368 } | |
369 if (s->nb_streams == 0) { | |
370 s1->default_ip = sdp_ip; | |
371 s1->default_ttl = ttl; | |
372 } else { | |
373 st = s->streams[s->nb_streams - 1]; | |
374 rtsp_st = st->priv_data; | |
375 rtsp_st->sdp_ip = sdp_ip; | |
376 rtsp_st->sdp_ttl = ttl; | |
377 } | |
378 break; | |
379 case 's': | |
4361 | 380 av_metadata_set(&s->metadata, "title", p); |
0 | 381 break; |
382 case 'i': | |
383 if (s->nb_streams == 0) { | |
4361 | 384 av_metadata_set(&s->metadata, "comment", p); |
0 | 385 break; |
386 } | |
387 break; | |
388 case 'm': | |
389 /* new stream */ | |
4281
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
390 s1->skip_media = 0; |
0 | 391 get_word(st_type, sizeof(st_type), &p); |
392 if (!strcmp(st_type, "audio")) { | |
393 codec_type = CODEC_TYPE_AUDIO; | |
394 } else if (!strcmp(st_type, "video")) { | |
395 codec_type = CODEC_TYPE_VIDEO; | |
4637
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
396 } else if (!strcmp(st_type, "application")) { |
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
397 codec_type = CODEC_TYPE_DATA; |
0 | 398 } else { |
4281
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
399 s1->skip_media = 1; |
0 | 400 return; |
401 } | |
402 rtsp_st = av_mallocz(sizeof(RTSPStream)); | |
403 if (!rtsp_st) | |
404 return; | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
405 rtsp_st->stream_index = -1; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
406 dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st); |
0 | 407 |
408 rtsp_st->sdp_ip = s1->default_ip; | |
409 rtsp_st->sdp_ttl = s1->default_ttl; | |
410 | |
411 get_word(buf1, sizeof(buf1), &p); /* port */ | |
412 rtsp_st->sdp_port = atoi(buf1); | |
413 | |
414 get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */ | |
885 | 415 |
0 | 416 /* XXX: handle list of formats */ |
417 get_word(buf1, sizeof(buf1), &p); /* format list */ | |
418 rtsp_st->sdp_payload_type = atoi(buf1); | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
419 |
2759
b252e318023a
Remove the "AVRtpPayloadTypes[i].pt == i" assumption from RTP and RTSP
lucabe
parents:
2711
diff
changeset
|
420 if (!strcmp(ff_rtp_enc_name(rtsp_st->sdp_payload_type), "MP2T")) { |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
421 /* no corresponding stream */ |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
422 } else { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
423 st = av_new_stream(s, 0); |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
424 if (!st) |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
425 return; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
426 st->priv_data = rtsp_st; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
427 rtsp_st->stream_index = st->index; |
820
feca73904e67
changing AVCodecContext codec -> *codec in AVStream so additions to AVCodecContext dont randomize AVStream and break binary compatibility
michael
parents:
774
diff
changeset
|
428 st->codec->codec_type = codec_type; |
774 | 429 if (rtsp_st->sdp_payload_type < RTP_PT_PRIVATE) { |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
430 /* if standard payload type, we can find the codec right now */ |
4519
f4b9967e0131
Remame rtp_get_codec_info() to ff_rtp_get_codec_info(), as it is not
lucabe
parents:
4514
diff
changeset
|
431 ff_rtp_get_codec_info(st->codec, rtsp_st->sdp_payload_type); |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
432 } |
0 | 433 } |
434 /* put a default control url */ | |
5574
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
435 av_strlcpy(rtsp_st->control_url, rt->control_uri, |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
436 sizeof(rtsp_st->control_url)); |
0 | 437 break; |
438 case 'a': | |
5574
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
439 if (av_strstart(p, "control:", &p)) { |
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
440 if (s->nb_streams == 0) { |
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
441 if (!strncmp(p, "rtsp://", 7)) |
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
442 av_strlcpy(rt->control_uri, p, |
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
443 sizeof(rt->control_uri)); |
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
444 } else { |
0 | 445 char proto[32]; |
446 /* get the control url */ | |
447 st = s->streams[s->nb_streams - 1]; | |
448 rtsp_st = st->priv_data; | |
885 | 449 |
0 | 450 /* XXX: may need to add full url resolution */ |
5775 | 451 ff_url_split(proto, sizeof(proto), NULL, 0, NULL, 0, |
5776 | 452 NULL, NULL, 0, p); |
0 | 453 if (proto[0] == '\0') { |
454 /* relative control URL */ | |
5574
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
455 if (rtsp_st->control_url[strlen(rtsp_st->control_url)-1]!='/') |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
456 av_strlcat(rtsp_st->control_url, "/", |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
457 sizeof(rtsp_st->control_url)); |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
458 av_strlcat(rtsp_st->control_url, p, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
459 sizeof(rtsp_st->control_url)); |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
460 } else |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
461 av_strlcpy(rtsp_st->control_url, p, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
462 sizeof(rtsp_st->control_url)); |
5574
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
463 } |
4185
023976c45ae1
Apply rtpmap: SDP lines to the last m= line only, since they generally just
rbultje
parents:
4182
diff
changeset
|
464 } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) { |
0 | 465 /* NOTE: rtpmap is only supported AFTER the 'm=' tag */ |
885 | 466 get_word(buf1, sizeof(buf1), &p); |
0 | 467 payload_type = atoi(buf1); |
4185
023976c45ae1
Apply rtpmap: SDP lines to the last m= line only, since they generally just
rbultje
parents:
4182
diff
changeset
|
468 st = s->streams[s->nb_streams - 1]; |
4186 | 469 rtsp_st = st->priv_data; |
5503
4ec7bcff8719
Add correct log context to av_log() calls in parse_rtpmap().
rbultje
parents:
5502
diff
changeset
|
470 sdp_parse_rtpmap(s, st->codec, rtsp_st, payload_type, p); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
471 } else if (av_strstart(p, "fmtp:", &p)) { |
0 | 472 /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */ |
885 | 473 get_word(buf1, sizeof(buf1), &p); |
0 | 474 payload_type = atoi(buf1); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
475 for (i = 0; i < s->nb_streams; i++) { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
476 st = s->streams[i]; |
0 | 477 rtsp_st = st->priv_data; |
478 if (rtsp_st->sdp_payload_type == payload_type) { | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
479 if (!(rtsp_st->dynamic_handler && |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
480 rtsp_st->dynamic_handler->parse_sdp_a_line && |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
481 rtsp_st->dynamic_handler->parse_sdp_a_line(s, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
482 i, rtsp_st->dynamic_protocol_context, buf))) |
1424
1c39ce5c6a5d
indentation fix, patch by Ryan Martell % rdm4 A martellventures P com %
gpoirier
parents:
1419
diff
changeset
|
483 sdp_parse_fmtp(st, p); |
0 | 484 } |
485 } | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
486 } else if (av_strstart(p, "framesize:", &p)) { |
1431
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
487 // let dynamic protocol handlers have a stab at the line. |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
488 get_word(buf1, sizeof(buf1), &p); |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
489 payload_type = atoi(buf1); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
490 for (i = 0; i < s->nb_streams; i++) { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
491 st = s->streams[i]; |
1431
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
492 rtsp_st = st->priv_data; |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
493 if (rtsp_st->sdp_payload_type == payload_type && |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
494 rtsp_st->dynamic_handler && |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
495 rtsp_st->dynamic_handler->parse_sdp_a_line) |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
496 rtsp_st->dynamic_handler->parse_sdp_a_line(s, i, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
497 rtsp_st->dynamic_protocol_context, buf); |
1431
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
498 } |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
499 } else if (av_strstart(p, "range:", &p)) { |
1453
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
500 int64_t start, end; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
501 |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
502 // this is so that seeking on a streamed file can work. |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
503 rtsp_parse_range_npt(p, &start, &end); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
504 s->start_time = start; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
505 /* AV_NOPTS_VALUE means live broadcast (and can't seek) */ |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
506 s->duration = (end == AV_NOPTS_VALUE) ? |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
507 AV_NOPTS_VALUE : end - start; |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
508 } else if (av_strstart(p, "IsRealDataType:integer;",&p)) { |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
509 if (atoi(p) == 1) |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
510 rt->transport = RTSP_TRANSPORT_RDT; |
4744
51899c07a4f1
Add RTP/ASF header parsing, which is part of the SDP of these streams. See
rbultje
parents:
4667
diff
changeset
|
511 } else { |
51899c07a4f1
Add RTP/ASF header parsing, which is part of the SDP of these streams. See
rbultje
parents:
4667
diff
changeset
|
512 if (rt->server_type == RTSP_SERVER_WMS) |
51899c07a4f1
Add RTP/ASF header parsing, which is part of the SDP of these streams. See
rbultje
parents:
4667
diff
changeset
|
513 ff_wms_parse_sdp_a_line(s, p); |
51899c07a4f1
Add RTP/ASF header parsing, which is part of the SDP of these streams. See
rbultje
parents:
4667
diff
changeset
|
514 if (s->nb_streams > 0) { |
4745 | 515 if (rt->server_type == RTSP_SERVER_REAL) |
516 ff_real_parse_sdp_a_line(s, s->nb_streams - 1, p); | |
4163
8d6512cbd657
Parse the ASMRuleBook SDP line to dynamically create one new AVStream for
rbultje
parents:
4109
diff
changeset
|
517 |
4745 | 518 rtsp_st = s->streams[s->nb_streams - 1]->priv_data; |
519 if (rtsp_st->dynamic_handler && | |
520 rtsp_st->dynamic_handler->parse_sdp_a_line) | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
521 rtsp_st->dynamic_handler->parse_sdp_a_line(s, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
522 s->nb_streams - 1, |
4745 | 523 rtsp_st->dynamic_protocol_context, buf); |
4744
51899c07a4f1
Add RTP/ASF header parsing, which is part of the SDP of these streams. See
rbultje
parents:
4667
diff
changeset
|
524 } |
0 | 525 } |
526 break; | |
527 } | |
528 } | |
529 | |
64 | 530 static int sdp_parse(AVFormatContext *s, const char *content) |
0 | 531 { |
532 const char *p; | |
533 int letter; | |
4187 | 534 /* Some SDP lines, particularly for Realmedia or ASF RTSP streams, |
535 * contain long SDP lines containing complete ASF Headers (several | |
536 * kB) or arrays of MDPR (RM stream descriptor) headers plus | |
537 * "rulebooks" describing their properties. Therefore, the SDP line | |
4874
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
538 * buffer is large. |
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
539 * |
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
540 * The Vorbis FMTP line can be up to 16KB - see sdp_parse_fmtp. */ |
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
541 char buf[16384], *q; |
0 | 542 SDPParseState sdp_parse_state, *s1 = &sdp_parse_state; |
885 | 543 |
0 | 544 memset(s1, 0, sizeof(SDPParseState)); |
545 p = content; | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
546 for (;;) { |
0 | 547 skip_spaces(&p); |
548 letter = *p; | |
549 if (letter == '\0') | |
550 break; | |
551 p++; | |
552 if (*p != '=') | |
553 goto next_line; | |
554 p++; | |
555 /* get the content */ | |
556 q = buf; | |
172 | 557 while (*p != '\n' && *p != '\r' && *p != '\0') { |
0 | 558 if ((q - buf) < sizeof(buf) - 1) |
559 *q++ = *p; | |
560 p++; | |
561 } | |
562 *q = '\0'; | |
563 sdp_parse_line(s, s1, letter, buf); | |
564 next_line: | |
565 while (*p != '\n' && *p != '\0') | |
566 p++; | |
567 if (*p == '\n') | |
568 p++; | |
569 } | |
570 return 0; | |
571 } | |
572 | |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
573 /* close and free RTSP streams */ |
5697 | 574 void ff_rtsp_close_streams(AVFormatContext *s) |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
575 { |
5677
545f70d48943
Make rtsp_close_streams() take a AVFormatContext instead of a RTSPState
rbultje
parents:
5670
diff
changeset
|
576 RTSPState *rt = s->priv_data; |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
577 int i; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
578 RTSPStream *rtsp_st; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
579 |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
580 for (i = 0; i < rt->nb_rtsp_streams; i++) { |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
581 rtsp_st = rt->rtsp_streams[i]; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
582 if (rtsp_st) { |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
583 if (rtsp_st->transport_priv) { |
5688
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
584 if (s->oformat) { |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
585 AVFormatContext *rtpctx = rtsp_st->transport_priv; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
586 av_write_trailer(rtpctx); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
587 url_fclose(rtpctx->pb); |
5694
70bd52594e2b
Free metadata in chained RTP muxers in the RTSP muxer
mstorsjo
parents:
5693
diff
changeset
|
588 av_metadata_free(&rtpctx->streams[0]->metadata); |
70bd52594e2b
Free metadata in chained RTP muxers in the RTSP muxer
mstorsjo
parents:
5693
diff
changeset
|
589 av_metadata_free(&rtpctx->metadata); |
5688
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
590 av_free(rtpctx->streams[0]); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
591 av_free(rtpctx); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
592 } else if (rt->transport == RTSP_TRANSPORT_RDT) |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
593 ff_rdt_parse_close(rtsp_st->transport_priv); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
594 else |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
595 rtp_parse_close(rtsp_st->transport_priv); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
596 } |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
597 if (rtsp_st->rtp_handle) |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
598 url_close(rtsp_st->rtp_handle); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
599 if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context) |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
600 rtsp_st->dynamic_handler->close( |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
601 rtsp_st->dynamic_protocol_context); |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
602 } |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
603 } |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
604 av_free(rt->rtsp_streams); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
605 if (rt->asf_ctx) { |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
606 av_close_input_stream (rt->asf_ctx); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
607 rt->asf_ctx = NULL; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
608 } |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
609 av_freep(&rt->auth_b64); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
610 } |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
611 |
5820
b56e31849e0f
Cosmetics, break a long line, fix brace placement
mstorsjo
parents:
5819
diff
changeset
|
612 static void *rtsp_rtp_mux_open(AVFormatContext *s, AVStream *st, |
b56e31849e0f
Cosmetics, break a long line, fix brace placement
mstorsjo
parents:
5819
diff
changeset
|
613 URLContext *handle) |
b56e31849e0f
Cosmetics, break a long line, fix brace placement
mstorsjo
parents:
5819
diff
changeset
|
614 { |
5843
777a89fdb1c0
RTSP: Synchronize the start time of the chained RTP muxers
mstorsjo
parents:
5837
diff
changeset
|
615 RTSPState *rt = s->priv_data; |
5688
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
616 AVFormatContext *rtpctx; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
617 int ret; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
618 AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
619 |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
620 if (!rtp_format) |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
621 return NULL; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
622 |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
623 /* Allocate an AVFormatContext for each output stream */ |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
624 rtpctx = avformat_alloc_context(); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
625 if (!rtpctx) |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
626 return NULL; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
627 |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
628 rtpctx->oformat = rtp_format; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
629 if (!av_new_stream(rtpctx, 0)) { |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
630 av_free(rtpctx); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
631 return NULL; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
632 } |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
633 /* Copy the max delay setting; the rtp muxer reads this. */ |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
634 rtpctx->max_delay = s->max_delay; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
635 /* Copy other stream parameters. */ |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
636 rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
637 |
5843
777a89fdb1c0
RTSP: Synchronize the start time of the chained RTP muxers
mstorsjo
parents:
5837
diff
changeset
|
638 /* Set the synchronized start time. */ |
777a89fdb1c0
RTSP: Synchronize the start time of the chained RTP muxers
mstorsjo
parents:
5837
diff
changeset
|
639 rtpctx->start_time_realtime = rt->start_time; |
777a89fdb1c0
RTSP: Synchronize the start time of the chained RTP muxers
mstorsjo
parents:
5837
diff
changeset
|
640 |
5688
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
641 /* Remove the local codec, link to the original codec |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
642 * context instead, to give the rtp muxer access to |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
643 * codec parameters. */ |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
644 av_free(rtpctx->streams[0]->codec); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
645 rtpctx->streams[0]->codec = st->codec; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
646 |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
647 url_fdopen(&rtpctx->pb, handle); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
648 ret = av_write_header(rtpctx); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
649 |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
650 if (ret) { |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
651 url_fclose(rtpctx->pb); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
652 av_free(rtpctx->streams[0]); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
653 av_free(rtpctx); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
654 return NULL; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
655 } |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
656 |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
657 /* Copy the RTP AVStream timebase back to the original AVStream */ |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
658 st->time_base = rtpctx->streams[0]->time_base; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
659 return rtpctx; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
660 } |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
661 |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
662 static int rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
663 { |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
664 RTSPState *rt = s->priv_data; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
665 AVStream *st = NULL; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
666 |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
667 /* open the RTP context */ |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
668 if (rtsp_st->stream_index >= 0) |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
669 st = s->streams[rtsp_st->stream_index]; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
670 if (!st) |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
671 s->ctx_flags |= AVFMTCTX_NOHEADER; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
672 |
5688
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
673 if (s->oformat) { |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
674 rtsp_st->transport_priv = rtsp_rtp_mux_open(s, st, rtsp_st->rtp_handle); |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
675 /* Ownage of rtp_handle is passed to the rtp mux context */ |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
676 rtsp_st->rtp_handle = NULL; |
7024b420e1a8
Create AVFormatContext objects as private transport for output RTSP sessions
mstorsjo
parents:
5681
diff
changeset
|
677 } else if (rt->transport == RTSP_TRANSPORT_RDT) |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
678 rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index, |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
679 rtsp_st->dynamic_protocol_context, |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
680 rtsp_st->dynamic_handler); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
681 else |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
682 rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle, |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
683 rtsp_st->sdp_payload_type, |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
684 &rtsp_st->rtp_payload_data); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
685 |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
686 if (!rtsp_st->transport_priv) { |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
687 return AVERROR(ENOMEM); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
688 } else if (rt->transport != RTSP_TRANSPORT_RDT) { |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
689 if (rtsp_st->dynamic_handler) { |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
690 rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv, |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
691 rtsp_st->dynamic_protocol_context, |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
692 rtsp_st->dynamic_handler); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
693 } |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
694 } |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
695 |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
696 return 0; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
697 } |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
698 |
5695 | 699 #if CONFIG_RTSP_DEMUXER || CONFIG_RTSP_MUXER |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
700 static int rtsp_probe(AVProbeData *p) |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
701 { |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
702 if (av_strstart(p->filename, "rtsp:", NULL)) |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
703 return AVPROBE_SCORE_MAX; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
704 return 0; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
705 } |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
706 |
0 | 707 static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp) |
708 { | |
709 const char *p; | |
710 int v; | |
711 | |
712 p = *pp; | |
713 skip_spaces(&p); | |
714 v = strtol(p, (char **)&p, 10); | |
715 if (*p == '-') { | |
716 p++; | |
717 *min_ptr = v; | |
718 v = strtol(p, (char **)&p, 10); | |
719 *max_ptr = v; | |
720 } else { | |
721 *min_ptr = v; | |
722 *max_ptr = v; | |
723 } | |
724 *pp = p; | |
725 } | |
726 | |
727 /* XXX: only one transport specification is parsed */ | |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
728 static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p) |
0 | 729 { |
730 char transport_protocol[16]; | |
731 char profile[16]; | |
732 char lower_transport[16]; | |
733 char parameter[16]; | |
734 RTSPTransportField *th; | |
735 char buf[256]; | |
885 | 736 |
0 | 737 reply->nb_transports = 0; |
885 | 738 |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
739 for (;;) { |
0 | 740 skip_spaces(&p); |
741 if (*p == '\0') | |
742 break; | |
743 | |
744 th = &reply->transports[reply->nb_transports]; | |
745 | |
885 | 746 get_word_sep(transport_protocol, sizeof(transport_protocol), |
0 | 747 "/", &p); |
2865
51aa1054528c
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 2 x-pn-tng support
lu_zero
parents:
2864
diff
changeset
|
748 if (!strcasecmp (transport_protocol, "rtp")) { |
2866
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
749 get_word_sep(profile, sizeof(profile), "/;,", &p); |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
750 lower_transport[0] = '\0'; |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
751 /* rtp/avp/<protocol> */ |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
752 if (*p == '/') { |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
753 get_word_sep(lower_transport, sizeof(lower_transport), |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
754 ";,", &p); |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
755 } |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
756 th->transport = RTSP_TRANSPORT_RTP; |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
757 } else if (!strcasecmp (transport_protocol, "x-pn-tng") || |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
758 !strcasecmp (transport_protocol, "x-real-rdt")) { |
2866
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
759 /* x-pn-tng/<protocol> */ |
2865
51aa1054528c
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 2 x-pn-tng support
lu_zero
parents:
2864
diff
changeset
|
760 get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p); |
51aa1054528c
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 2 x-pn-tng support
lu_zero
parents:
2864
diff
changeset
|
761 profile[0] = '\0'; |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
762 th->transport = RTSP_TRANSPORT_RDT; |
0 | 763 } |
172 | 764 if (!strcasecmp(lower_transport, "TCP")) |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
765 th->lower_transport = RTSP_LOWER_TRANSPORT_TCP; |
0 | 766 else |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
767 th->lower_transport = RTSP_LOWER_TRANSPORT_UDP; |
885 | 768 |
0 | 769 if (*p == ';') |
770 p++; | |
771 /* get each parameter */ | |
772 while (*p != '\0' && *p != ',') { | |
773 get_word_sep(parameter, sizeof(parameter), "=;,", &p); | |
774 if (!strcmp(parameter, "port")) { | |
775 if (*p == '=') { | |
776 p++; | |
777 rtsp_parse_range(&th->port_min, &th->port_max, &p); | |
778 } | |
779 } else if (!strcmp(parameter, "client_port")) { | |
780 if (*p == '=') { | |
781 p++; | |
885 | 782 rtsp_parse_range(&th->client_port_min, |
0 | 783 &th->client_port_max, &p); |
784 } | |
785 } else if (!strcmp(parameter, "server_port")) { | |
786 if (*p == '=') { | |
787 p++; | |
885 | 788 rtsp_parse_range(&th->server_port_min, |
0 | 789 &th->server_port_max, &p); |
790 } | |
791 } else if (!strcmp(parameter, "interleaved")) { | |
792 if (*p == '=') { | |
793 p++; | |
885 | 794 rtsp_parse_range(&th->interleaved_min, |
0 | 795 &th->interleaved_max, &p); |
796 } | |
797 } else if (!strcmp(parameter, "multicast")) { | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
798 if (th->lower_transport == RTSP_LOWER_TRANSPORT_UDP) |
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
799 th->lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST; |
0 | 800 } else if (!strcmp(parameter, "ttl")) { |
801 if (*p == '=') { | |
802 p++; | |
803 th->ttl = strtol(p, (char **)&p, 10); | |
804 } | |
805 } else if (!strcmp(parameter, "destination")) { | |
806 struct in_addr ipaddr; | |
807 | |
808 if (*p == '=') { | |
809 p++; | |
810 get_word_sep(buf, sizeof(buf), ";,", &p); | |
5766
a292ef47e2f9
Localize the #define _SVID_SOURCE needed for inet_aton() to os_support.c
conrad
parents:
5756
diff
changeset
|
811 if (ff_inet_aton(buf, &ipaddr)) |
0 | 812 th->destination = ntohl(ipaddr.s_addr); |
813 } | |
814 } | |
815 while (*p != ';' && *p != '\0' && *p != ',') | |
816 p++; | |
817 if (*p == ';') | |
818 p++; | |
819 } | |
820 if (*p == ',') | |
821 p++; | |
822 | |
823 reply->nb_transports++; | |
824 } | |
825 } | |
826 | |
5697 | 827 void ff_rtsp_parse_line(RTSPMessageHeader *reply, const char *buf) |
0 | 828 { |
829 const char *p; | |
830 | |
831 /* NOTE: we do case independent match for broken servers */ | |
832 p = buf; | |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
833 if (av_stristart(p, "Session:", &p)) { |
4877
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
834 int t; |
0 | 835 get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p); |
4877
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
836 if (av_stristart(p, ";timeout=", &p) && |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
837 (t = strtol(p, NULL, 10)) > 0) { |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
838 reply->timeout = t; |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
839 } |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
840 } else if (av_stristart(p, "Content-Length:", &p)) { |
0 | 841 reply->content_length = strtol(p, NULL, 10); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
842 } else if (av_stristart(p, "Transport:", &p)) { |
0 | 843 rtsp_parse_transport(reply, p); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
844 } else if (av_stristart(p, "CSeq:", &p)) { |
0 | 845 reply->seq = strtol(p, NULL, 10); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
846 } else if (av_stristart(p, "Range:", &p)) { |
1453
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
847 rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end); |
3855 | 848 } else if (av_stristart(p, "RealChallenge1:", &p)) { |
849 skip_spaces(&p); | |
850 av_strlcpy(reply->real_challenge, p, sizeof(reply->real_challenge)); | |
4169
619845a9bab3
Use the "server" RTSP field to detect whether the server that we're talking
rbultje
parents:
4168
diff
changeset
|
851 } else if (av_stristart(p, "Server:", &p)) { |
619845a9bab3
Use the "server" RTSP field to detect whether the server that we're talking
rbultje
parents:
4168
diff
changeset
|
852 skip_spaces(&p); |
619845a9bab3
Use the "server" RTSP field to detect whether the server that we're talking
rbultje
parents:
4168
diff
changeset
|
853 av_strlcpy(reply->server, p, sizeof(reply->server)); |
5112
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
854 } else if (av_stristart(p, "Notice:", &p) || |
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
855 av_stristart(p, "X-Notice:", &p)) { |
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
856 reply->notice = strtol(p, NULL, 10); |
5333 | 857 } else if (av_stristart(p, "Location:", &p)) { |
858 skip_spaces(&p); | |
859 av_strlcpy(reply->location, p , sizeof(reply->location)); | |
0 | 860 } |
861 } | |
862 | |
179 | 863 /* skip a RTP/TCP interleaved packet */ |
864 static void rtsp_skip_packet(AVFormatContext *s) | |
865 { | |
866 RTSPState *rt = s->priv_data; | |
867 int ret, len, len1; | |
868 uint8_t buf[1024]; | |
869 | |
5004
84a7b7a2f252
Move function for reading whole specified amount of data from RTSP
kostya
parents:
4990
diff
changeset
|
870 ret = url_read_complete(rt->rtsp_hd, buf, 3); |
179 | 871 if (ret != 3) |
872 return; | |
2222 | 873 len = AV_RB16(buf + 1); |
4990 | 874 |
875 dprintf(s, "skipping RTP packet len=%d\n", len); | |
876 | |
179 | 877 /* skip payload */ |
878 while (len > 0) { | |
879 len1 = len; | |
880 if (len1 > sizeof(buf)) | |
881 len1 = sizeof(buf); | |
5004
84a7b7a2f252
Move function for reading whole specified amount of data from RTSP
kostya
parents:
4990
diff
changeset
|
882 ret = url_read_complete(rt->rtsp_hd, buf, len1); |
179 | 883 if (ret != len1) |
884 return; | |
885 len -= len1; | |
886 } | |
887 } | |
0 | 888 |
5697 | 889 int ff_rtsp_read_reply(AVFormatContext *s, RTSPMessageHeader *reply, |
5700 | 890 unsigned char **content_ptr, |
891 int return_on_interleaved_data) | |
0 | 892 { |
893 RTSPState *rt = s->priv_data; | |
894 char buf[4096], buf1[1024], *q; | |
895 unsigned char ch; | |
896 const char *p; | |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
897 int ret, content_length, line_count = 0; |
0 | 898 unsigned char *content = NULL; |
899 | |
4549 | 900 memset(reply, 0, sizeof(*reply)); |
0 | 901 |
902 /* parse reply (XXX: use buffers) */ | |
903 rt->last_reply[0] = '\0'; | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
904 for (;;) { |
0 | 905 q = buf; |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
906 for (;;) { |
5004
84a7b7a2f252
Move function for reading whole specified amount of data from RTSP
kostya
parents:
4990
diff
changeset
|
907 ret = url_read_complete(rt->rtsp_hd, &ch, 1); |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
908 #ifdef DEBUG_RTP_TCP |
4990 | 909 dprintf(s, "ret=%d c=%02x [%c]\n", ret, ch, ch); |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
910 #endif |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
911 if (ret != 1) |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
912 return -1; |
0 | 913 if (ch == '\n') |
914 break; | |
179 | 915 if (ch == '$') { |
916 /* XXX: only parse it if first char on line ? */ | |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
917 if (return_on_interleaved_data) { |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
918 return 1; |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
919 } else |
179 | 920 rtsp_skip_packet(s); |
921 } else if (ch != '\r') { | |
0 | 922 if ((q - buf) < sizeof(buf) - 1) |
923 *q++ = ch; | |
924 } | |
925 } | |
926 *q = '\0'; | |
4990 | 927 |
928 dprintf(s, "line='%s'\n", buf); | |
929 | |
0 | 930 /* test if last line */ |
931 if (buf[0] == '\0') | |
932 break; | |
933 p = buf; | |
934 if (line_count == 0) { | |
935 /* get reply code */ | |
936 get_word(buf1, sizeof(buf1), &p); | |
937 get_word(buf1, sizeof(buf1), &p); | |
938 reply->status_code = atoi(buf1); | |
939 } else { | |
5697 | 940 ff_rtsp_parse_line(reply, p); |
2189 | 941 av_strlcat(rt->last_reply, p, sizeof(rt->last_reply)); |
942 av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply)); | |
0 | 943 } |
944 line_count++; | |
945 } | |
885 | 946 |
0 | 947 if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0') |
2189 | 948 av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id)); |
885 | 949 |
0 | 950 content_length = reply->content_length; |
951 if (content_length > 0) { | |
952 /* leave some room for a trailing '\0' (useful for simple parsing) */ | |
953 content = av_malloc(content_length + 1); | |
5004
84a7b7a2f252
Move function for reading whole specified amount of data from RTSP
kostya
parents:
4990
diff
changeset
|
954 (void)url_read_complete(rt->rtsp_hd, content, content_length); |
0 | 955 content[content_length] = '\0'; |
956 } | |
957 if (content_ptr) | |
958 *content_ptr = content; | |
2263 | 959 else |
960 av_free(content); | |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
961 |
5112
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
962 /* EOS */ |
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
963 if (reply->notice == 2101 /* End-of-Stream Reached */ || |
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
964 reply->notice == 2104 /* Start-of-Stream Reached */ || |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
965 reply->notice == 2306 /* Continuous Feed Terminated */) { |
5112
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
966 rt->state = RTSP_STATE_IDLE; |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
967 } else if (reply->notice >= 4400 && reply->notice < 5500) { |
5112
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
968 return AVERROR(EIO); /* data or server error */ |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
969 } else if (reply->notice == 2401 /* Ticket Expired */ || |
5112
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
970 (reply->notice >= 5500 && reply->notice < 5600) /* end of term */ ) |
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
971 return AVERROR(EPERM); |
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
972 |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
973 return 0; |
0 | 974 } |
975 | |
5697 | 976 void ff_rtsp_send_cmd_with_content_async(AVFormatContext *s, |
5700 | 977 const char *cmd, |
978 const unsigned char *send_content, | |
979 int send_content_length) | |
4644
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
980 { |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
981 RTSPState *rt = s->priv_data; |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
982 char buf[4096], buf1[1024]; |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
983 |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
984 rt->seq++; |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
985 av_strlcpy(buf, cmd, sizeof(buf)); |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
986 snprintf(buf1, sizeof(buf1), "CSeq: %d\r\n", rt->seq); |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
987 av_strlcat(buf, buf1, sizeof(buf)); |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
988 if (rt->session_id[0] != '\0' && !strstr(cmd, "\nIf-Match:")) { |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
989 snprintf(buf1, sizeof(buf1), "Session: %s\r\n", rt->session_id); |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
990 av_strlcat(buf, buf1, sizeof(buf)); |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
991 } |
5220
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
992 if (rt->auth_b64) |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
993 av_strlcatf(buf, sizeof(buf), |
5221 | 994 "Authorization: Basic %s\r\n", |
995 rt->auth_b64); | |
5667
9b2e63adc0fa
Add functions to send RTSP commands with content attached to them. This will
rbultje
parents:
5665
diff
changeset
|
996 if (send_content_length > 0 && send_content) |
9b2e63adc0fa
Add functions to send RTSP commands with content attached to them. This will
rbultje
parents:
5665
diff
changeset
|
997 av_strlcatf(buf, sizeof(buf), "Content-Length: %d\r\n", send_content_length); |
4644
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
998 av_strlcat(buf, "\r\n", sizeof(buf)); |
4990 | 999 |
1000 dprintf(s, "Sending:\n%s--\n", buf); | |
1001 | |
4644
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
1002 url_write(rt->rtsp_hd, buf, strlen(buf)); |
5667
9b2e63adc0fa
Add functions to send RTSP commands with content attached to them. This will
rbultje
parents:
5665
diff
changeset
|
1003 if (send_content_length > 0 && send_content) |
9b2e63adc0fa
Add functions to send RTSP commands with content attached to them. This will
rbultje
parents:
5665
diff
changeset
|
1004 url_write(rt->rtsp_hd, send_content, send_content_length); |
4877
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1005 rt->last_cmd_time = av_gettime(); |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1006 } |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1007 |
5697 | 1008 void ff_rtsp_send_cmd_async(AVFormatContext *s, const char *cmd) |
5667
9b2e63adc0fa
Add functions to send RTSP commands with content attached to them. This will
rbultje
parents:
5665
diff
changeset
|
1009 { |
5697 | 1010 ff_rtsp_send_cmd_with_content_async(s, cmd, NULL, 0); |
5667
9b2e63adc0fa
Add functions to send RTSP commands with content attached to them. This will
rbultje
parents:
5665
diff
changeset
|
1011 } |
9b2e63adc0fa
Add functions to send RTSP commands with content attached to them. This will
rbultje
parents:
5665
diff
changeset
|
1012 |
5697 | 1013 void ff_rtsp_send_cmd(AVFormatContext *s, |
5700 | 1014 const char *cmd, RTSPMessageHeader *reply, |
1015 unsigned char **content_ptr) | |
4877
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1016 { |
5697 | 1017 ff_rtsp_send_cmd_async(s, cmd); |
4644
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
1018 |
5697 | 1019 ff_rtsp_read_reply(s, reply, content_ptr, 0); |
4644
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
1020 } |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
1021 |
5697 | 1022 void ff_rtsp_send_cmd_with_content(AVFormatContext *s, |
5693 | 1023 const char *cmd, |
1024 RTSPMessageHeader *reply, | |
1025 unsigned char **content_ptr, | |
1026 const unsigned char *send_content, | |
1027 int send_content_length) | |
5667
9b2e63adc0fa
Add functions to send RTSP commands with content attached to them. This will
rbultje
parents:
5665
diff
changeset
|
1028 { |
5697 | 1029 ff_rtsp_send_cmd_with_content_async(s, cmd, send_content, send_content_length); |
5667
9b2e63adc0fa
Add functions to send RTSP commands with content attached to them. This will
rbultje
parents:
5665
diff
changeset
|
1030 |
5697 | 1031 ff_rtsp_read_reply(s, reply, content_ptr, 0); |
5667
9b2e63adc0fa
Add functions to send RTSP commands with content attached to them. This will
rbultje
parents:
5665
diff
changeset
|
1032 } |
9b2e63adc0fa
Add functions to send RTSP commands with content attached to them. This will
rbultje
parents:
5665
diff
changeset
|
1033 |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1034 /** |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1035 * @returns 0 on success, <0 on error, 1 if protocol is unavailable. |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1036 */ |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1037 static int make_setup_request(AVFormatContext *s, const char *host, int port, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1038 int lower_transport, const char *real_challenge) |
0 | 1039 { |
1040 RTSPState *rt = s->priv_data; | |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1041 int rtx, j, i, err, interleave = 0; |
0 | 1042 RTSPStream *rtsp_st; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1043 RTSPMessageHeader reply1, *reply = &reply1; |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1044 char cmd[2048]; |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1045 const char *trans_pref; |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1046 |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
1047 if (rt->transport == RTSP_TRANSPORT_RDT) |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1048 trans_pref = "x-pn-tng"; |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1049 else |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1050 trans_pref = "RTP/AVP"; |
885 | 1051 |
4877
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1052 /* default timeout: 1 minute */ |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1053 rt->timeout = 60; |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1054 |
0 | 1055 /* for each stream, make the setup request */ |
1056 /* XXX: we assume the same server is used for the control of each | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1057 * RTSP stream */ |
774 | 1058 |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1059 for (j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) { |
0 | 1060 char transport[2048]; |
1061 | |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1062 /** |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1063 * WMS serves all UDP data over a single connection, the RTX, which |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1064 * isn't necessarily the first in the SDP but has to be the first |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1065 * to be set up, else the second/third SETUP will fail with a 461. |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1066 */ |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1067 if (lower_transport == RTSP_LOWER_TRANSPORT_UDP && |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1068 rt->server_type == RTSP_SERVER_WMS) { |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1069 if (i == 0) { |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1070 /* rtx first */ |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1071 for (rtx = 0; rtx < rt->nb_rtsp_streams; rtx++) { |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1072 int len = strlen(rt->rtsp_streams[rtx]->control_url); |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1073 if (len >= 4 && |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1074 !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1075 "/rtx")) |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1076 break; |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1077 } |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1078 if (rtx == rt->nb_rtsp_streams) |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1079 return -1; /* no RTX found */ |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1080 rtsp_st = rt->rtsp_streams[rtx]; |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1081 } else |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1082 rtsp_st = rt->rtsp_streams[i > rtx ? i : i - 1]; |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1083 } else |
4639 | 1084 rtsp_st = rt->rtsp_streams[i]; |
0 | 1085 |
1086 /* RTP/UDP */ | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1087 if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) { |
0 | 1088 char buf[256]; |
1089 | |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1090 if (rt->server_type == RTSP_SERVER_WMS && i > 1) { |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1091 port = reply->transports[0].client_port_min; |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1092 goto have_port; |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1093 } |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1094 |
0 | 1095 /* first try in specified port range */ |
774 | 1096 if (RTSP_RTP_PORT_MIN != 0) { |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1097 while (j <= RTSP_RTP_PORT_MAX) { |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1098 ff_url_join(buf, sizeof(buf), "rtp", NULL, host, -1, |
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1099 "?localport=%d", j); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1100 /* we will use two ports per rtp stream (rtp and rtcp) */ |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1101 j += 2; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1102 if (url_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0) |
0 | 1103 goto rtp_opened; |
1104 } | |
1105 } | |
1106 | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1107 #if 0 |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1108 /* then try on any port */ |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1109 if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1110 err = AVERROR_INVALIDDATA; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1111 goto fail; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1112 } |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1113 #endif |
0 | 1114 |
1115 rtp_opened: | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1116 port = rtp_get_local_port(rtsp_st->rtp_handle); |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1117 have_port: |
3877
3e0c7ad2a675
Remove unused code that used to handle protocol concatenation, i.e. trying
rbultje
parents:
3876
diff
changeset
|
1118 snprintf(transport, sizeof(transport) - 1, |
3958
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
1119 "%s/UDP;", trans_pref); |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
1120 if (rt->server_type != RTSP_SERVER_REAL) |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
1121 av_strlcat(transport, "unicast;", sizeof(transport)); |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
1122 av_strlcatf(transport, sizeof(transport), |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
1123 "client_port=%d", port); |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1124 if (rt->transport == RTSP_TRANSPORT_RTP && |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1125 !(rt->server_type == RTSP_SERVER_WMS && i > 0)) |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1126 av_strlcatf(transport, sizeof(transport), "-%d", port + 1); |
0 | 1127 } |
1128 | |
1129 /* RTP/TCP */ | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1130 else if (lower_transport == RTSP_LOWER_TRANSPORT_TCP) { |
4637
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
1131 /** For WMS streams, the application streams are only used for |
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
1132 * UDP. When trying to set it up for TCP streams, the server |
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
1133 * will return an error. Therefore, we skip those streams. */ |
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
1134 if (rt->server_type == RTSP_SERVER_WMS && |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1135 s->streams[rtsp_st->stream_index]->codec->codec_type == |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1136 CODEC_TYPE_DATA) |
4637
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
1137 continue; |
3877
3e0c7ad2a675
Remove unused code that used to handle protocol concatenation, i.e. trying
rbultje
parents:
3876
diff
changeset
|
1138 snprintf(transport, sizeof(transport) - 1, |
4332
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
1139 "%s/TCP;", trans_pref); |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
1140 if (rt->server_type == RTSP_SERVER_WMS) |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
1141 av_strlcat(transport, "unicast;", sizeof(transport)); |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
1142 av_strlcatf(transport, sizeof(transport), |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
1143 "interleaved=%d-%d", |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
1144 interleave, interleave + 1); |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
1145 interleave += 2; |
0 | 1146 } |
1147 | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1148 else if (lower_transport == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) { |
3877
3e0c7ad2a675
Remove unused code that used to handle protocol concatenation, i.e. trying
rbultje
parents:
3876
diff
changeset
|
1149 snprintf(transport, sizeof(transport) - 1, |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1150 "%s/UDP;multicast", trans_pref); |
0 | 1151 } |
5678
76cb8ea11c47
Use mode=receive instead of mode=play if in RTSP muxer (instead of demuxer)
rbultje
parents:
5677
diff
changeset
|
1152 if (s->oformat) { |
76cb8ea11c47
Use mode=receive instead of mode=play if in RTSP muxer (instead of demuxer)
rbultje
parents:
5677
diff
changeset
|
1153 av_strlcat(transport, ";mode=receive", sizeof(transport)); |
76cb8ea11c47
Use mode=receive instead of mode=play if in RTSP muxer (instead of demuxer)
rbultje
parents:
5677
diff
changeset
|
1154 } else if (rt->server_type == RTSP_SERVER_REAL || |
5691 | 1155 rt->server_type == RTSP_SERVER_WMS) |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1156 av_strlcat(transport, ";mode=play", sizeof(transport)); |
885 | 1157 snprintf(cmd, sizeof(cmd), |
172 | 1158 "SETUP %s RTSP/1.0\r\n" |
1159 "Transport: %s\r\n", | |
0 | 1160 rtsp_st->control_url, transport); |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1161 if (i == 0 && rt->server_type == RTSP_SERVER_REAL) { |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1162 char real_res[41], real_csum[9]; |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1163 ff_rdt_calc_response_and_checksum(real_res, real_csum, |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1164 real_challenge); |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1165 av_strlcatf(cmd, sizeof(cmd), |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1166 "If-Match: %s\r\n" |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1167 "RealChallenge2: %s, sd=%s\r\n", |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1168 rt->session_id, real_res, real_csum); |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1169 } |
5697 | 1170 ff_rtsp_send_cmd(s, cmd, reply, NULL); |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1171 if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) { |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1172 err = 1; |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1173 goto fail; |
3151 | 1174 } else if (reply->status_code != RTSP_STATUS_OK || |
1175 reply->nb_transports != 1) { | |
0 | 1176 err = AVERROR_INVALIDDATA; |
1177 goto fail; | |
1178 } | |
1179 | |
1180 /* XXX: same protocol for all streams is required */ | |
1181 if (i > 0) { | |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
1182 if (reply->transports[0].lower_transport != rt->lower_transport || |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
1183 reply->transports[0].transport != rt->transport) { |
0 | 1184 err = AVERROR_INVALIDDATA; |
1185 goto fail; | |
1186 } | |
1187 } else { | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1188 rt->lower_transport = reply->transports[0].lower_transport; |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
1189 rt->transport = reply->transports[0].transport; |
0 | 1190 } |
1191 | |
1192 /* close RTP connection if not choosen */ | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1193 if (reply->transports[0].lower_transport != RTSP_LOWER_TRANSPORT_UDP && |
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1194 (lower_transport == RTSP_LOWER_TRANSPORT_UDP)) { |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1195 url_close(rtsp_st->rtp_handle); |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1196 rtsp_st->rtp_handle = NULL; |
0 | 1197 } |
1198 | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1199 switch(reply->transports[0].lower_transport) { |
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1200 case RTSP_LOWER_TRANSPORT_TCP: |
0 | 1201 rtsp_st->interleaved_min = reply->transports[0].interleaved_min; |
1202 rtsp_st->interleaved_max = reply->transports[0].interleaved_max; | |
1203 break; | |
885 | 1204 |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1205 case RTSP_LOWER_TRANSPORT_UDP: { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1206 char url[1024]; |
885 | 1207 |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1208 /* XXX: also use address if specified */ |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1209 ff_url_join(url, sizeof(url), "rtp", NULL, host, |
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1210 reply->transports[0].server_port_min, NULL); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1211 if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1212 rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1213 err = AVERROR_INVALIDDATA; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1214 goto fail; |
0 | 1215 } |
5665
93b0d64bf0c9
When using RTP-over-UDP, send dummy packets during stream setup, similar to
rbultje
parents:
5645
diff
changeset
|
1216 /* Try to initialize the connection state in a |
93b0d64bf0c9
When using RTP-over-UDP, send dummy packets during stream setup, similar to
rbultje
parents:
5645
diff
changeset
|
1217 * potential NAT router by sending dummy packets. |
93b0d64bf0c9
When using RTP-over-UDP, send dummy packets during stream setup, similar to
rbultje
parents:
5645
diff
changeset
|
1218 * RTP/RTCP dummy packets are used for RDT, too. |
93b0d64bf0c9
When using RTP-over-UDP, send dummy packets during stream setup, similar to
rbultje
parents:
5645
diff
changeset
|
1219 */ |
5679
4e5c3a9c1f6c
Only send out NAT-punching RTP/RTCP packets when we're in demuxer mode, i.e.
rbultje
parents:
5678
diff
changeset
|
1220 if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && s->iformat) |
5665
93b0d64bf0c9
When using RTP-over-UDP, send dummy packets during stream setup, similar to
rbultje
parents:
5645
diff
changeset
|
1221 rtp_send_punch_packets(rtsp_st->rtp_handle); |
0 | 1222 break; |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1223 } |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1224 case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1225 char url[1024]; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1226 struct in_addr in; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1227 int port, ttl; |
0 | 1228 |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1229 if (reply->transports[0].destination) { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1230 in.s_addr = htonl(reply->transports[0].destination); |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1231 port = reply->transports[0].port_min; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1232 ttl = reply->transports[0].ttl; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1233 } else { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1234 in = rtsp_st->sdp_ip; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1235 port = rtsp_st->sdp_port; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1236 ttl = rtsp_st->sdp_ttl; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1237 } |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1238 ff_url_join(url, sizeof(url), "rtp", NULL, inet_ntoa(in), |
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1239 port, "?ttl=%d", ttl); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1240 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1241 err = AVERROR_INVALIDDATA; |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1242 goto fail; |
0 | 1243 } |
1244 break; | |
1245 } | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1246 } |
774 | 1247 |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
1248 if ((err = rtsp_open_transport_ctx(s, rtsp_st))) |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1249 goto fail; |
0 | 1250 } |
1251 | |
4877
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1252 if (reply->timeout > 0) |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1253 rt->timeout = reply->timeout; |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1254 |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1255 if (rt->server_type == RTSP_SERVER_REAL) |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1256 rt->need_subscription = 1; |
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1257 |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1258 return 0; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1259 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1260 fail: |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1261 for (i = 0; i < rt->nb_rtsp_streams; i++) { |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1262 if (rt->rtsp_streams[i]->rtp_handle) { |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1263 url_close(rt->rtsp_streams[i]->rtp_handle); |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1264 rt->rtsp_streams[i]->rtp_handle = NULL; |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1265 } |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1266 } |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1267 return err; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1268 } |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1269 |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1270 static int rtsp_read_play(AVFormatContext *s) |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1271 { |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1272 RTSPState *rt = s->priv_data; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1273 RTSPMessageHeader reply1, *reply = &reply1; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1274 char cmd[1024]; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1275 |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1276 av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1277 |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1278 if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1279 if (rt->state == RTSP_STATE_PAUSED) { |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1280 snprintf(cmd, sizeof(cmd), |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1281 "PLAY %s RTSP/1.0\r\n", |
5574
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
1282 rt->control_uri); |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1283 } else { |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1284 snprintf(cmd, sizeof(cmd), |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1285 "PLAY %s RTSP/1.0\r\n" |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1286 "Range: npt=%0.3f-\r\n", |
5574
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
1287 rt->control_uri, |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1288 (double)rt->seek_timestamp / AV_TIME_BASE); |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1289 } |
5697 | 1290 ff_rtsp_send_cmd(s, cmd, reply, NULL); |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1291 if (reply->status_code != RTSP_STATUS_OK) { |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1292 return -1; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1293 } |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1294 } |
5670
7fa188f69c22
Rename RTSP_STATE_PLAYING to _STREAMING, since that better covers the
rbultje
parents:
5667
diff
changeset
|
1295 rt->state = RTSP_STATE_STREAMING; |
5365
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1296 return 0; |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1297 } |
4097dc22e612
Move some some functions around, so that splitting the SDP code out of
lucabe
parents:
5334
diff
changeset
|
1298 |
5680
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1299 static int rtsp_setup_input_streams(AVFormatContext *s) |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1300 { |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1301 RTSPState *rt = s->priv_data; |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1302 RTSPMessageHeader reply1, *reply = &reply1; |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1303 char cmd[1024]; |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1304 unsigned char *content = NULL; |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1305 int ret; |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1306 |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1307 /* describe the stream */ |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1308 snprintf(cmd, sizeof(cmd), |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1309 "DESCRIBE %s RTSP/1.0\r\n" |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1310 "Accept: application/sdp\r\n", |
5800
4410bccf6a8a
Use rt->control_uri consequently instead of s->filename in all RTSP commands
mstorsjo
parents:
5798
diff
changeset
|
1311 rt->control_uri); |
5680
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1312 if (rt->server_type == RTSP_SERVER_REAL) { |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1313 /** |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1314 * The Require: attribute is needed for proper streaming from |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1315 * Realmedia servers. |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1316 */ |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1317 av_strlcat(cmd, |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1318 "Require: com.real.retain-entity-for-setup\r\n", |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1319 sizeof(cmd)); |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1320 } |
5697 | 1321 ff_rtsp_send_cmd(s, cmd, reply, &content); |
5680
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1322 if (!content) |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1323 return AVERROR_INVALIDDATA; |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1324 if (reply->status_code != RTSP_STATUS_OK) { |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1325 av_freep(&content); |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1326 return AVERROR_INVALIDDATA; |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1327 } |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1328 |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1329 /* now we got the SDP description, we parse it */ |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1330 ret = sdp_parse(s, (const char *)content); |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1331 av_freep(&content); |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1332 if (ret < 0) |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1333 return AVERROR_INVALIDDATA; |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1334 |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1335 return 0; |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1336 } |
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1337 |
5819
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1338 static int rtsp_setup_output_streams(AVFormatContext *s, const char *addr) |
5689
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1339 { |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1340 RTSPState *rt = s->priv_data; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1341 RTSPMessageHeader reply1, *reply = &reply1; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1342 char cmd[1024]; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1343 int i; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1344 char *sdp; |
5819
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1345 AVFormatContext sdp_ctx, *ctx_array[1]; |
5689
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1346 |
5843
777a89fdb1c0
RTSP: Synchronize the start time of the chained RTP muxers
mstorsjo
parents:
5837
diff
changeset
|
1347 rt->start_time = av_gettime(); |
777a89fdb1c0
RTSP: Synchronize the start time of the chained RTP muxers
mstorsjo
parents:
5837
diff
changeset
|
1348 |
5689
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1349 /* Announce the stream */ |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1350 snprintf(cmd, sizeof(cmd), |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1351 "ANNOUNCE %s RTSP/1.0\r\n" |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1352 "Content-Type: application/sdp\r\n", |
5800
4410bccf6a8a
Use rt->control_uri consequently instead of s->filename in all RTSP commands
mstorsjo
parents:
5798
diff
changeset
|
1353 rt->control_uri); |
5689
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1354 sdp = av_mallocz(8192); |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1355 if (sdp == NULL) |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1356 return AVERROR(ENOMEM); |
5819
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1357 /* We create the SDP based on the RTSP AVFormatContext where we |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1358 * aren't allowed to change the filename field. (We create the SDP |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1359 * based on the RTSP context since the contexts for the RTP streams |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1360 * don't exist yet.) In order to specify a custom URL with the actual |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1361 * peer IP instead of the originally specified hostname, we create |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1362 * a temporary copy of the AVFormatContext, where the custom URL is set. |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1363 * |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1364 * FIXME: Create the SDP without copying the AVFormatContext. |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1365 * This either requires setting up the RTP stream AVFormatContexts |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1366 * already here (complicating things immensely) or getting a more |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1367 * flexible SDP creation interface. |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1368 */ |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1369 sdp_ctx = *s; |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1370 ff_url_join(sdp_ctx.filename, sizeof(sdp_ctx.filename), |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1371 "rtsp", NULL, addr, -1, NULL); |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1372 ctx_array[0] = &sdp_ctx; |
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1373 if (avf_sdp_create(ctx_array, 1, sdp, 8192)) { |
5689
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1374 av_free(sdp); |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1375 return AVERROR_INVALIDDATA; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1376 } |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1377 av_log(s, AV_LOG_INFO, "SDP:\n%s\n", sdp); |
5697 | 1378 ff_rtsp_send_cmd_with_content(s, cmd, reply, NULL, sdp, strlen(sdp)); |
5689
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1379 av_free(sdp); |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1380 if (reply->status_code != RTSP_STATUS_OK) |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1381 return AVERROR_INVALIDDATA; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1382 |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1383 /* Set up the RTSPStreams for each AVStream */ |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1384 for (i = 0; i < s->nb_streams; i++) { |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1385 RTSPStream *rtsp_st; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1386 AVStream *st = s->streams[i]; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1387 |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1388 rtsp_st = av_mallocz(sizeof(RTSPStream)); |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1389 if (!rtsp_st) |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1390 return AVERROR(ENOMEM); |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1391 dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st); |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1392 |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1393 st->priv_data = rtsp_st; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1394 rtsp_st->stream_index = i; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1395 |
5800
4410bccf6a8a
Use rt->control_uri consequently instead of s->filename in all RTSP commands
mstorsjo
parents:
5798
diff
changeset
|
1396 av_strlcpy(rtsp_st->control_url, rt->control_uri, sizeof(rtsp_st->control_url)); |
5689
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1397 /* Note, this must match the relative uri set in the sdp content */ |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1398 av_strlcatf(rtsp_st->control_url, sizeof(rtsp_st->control_url), |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1399 "/streamid=%d", i); |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1400 } |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1401 |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1402 return 0; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1403 } |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1404 |
5697 | 1405 int ff_rtsp_connect(AVFormatContext *s) |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1406 { |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1407 RTSPState *rt = s->priv_data; |
5331 | 1408 char host[1024], path[1024], tcpname[1024], cmd[2048], auth[128]; |
1409 char *option_list, *option, *filename; | |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1410 URLContext *rtsp_hd; |
5798
2af44abfbfe8
RTSP: Resolve and use the actual IP address of the peer we're connected to,
mstorsjo
parents:
5776
diff
changeset
|
1411 int port, err, tcp_fd; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1412 RTSPMessageHeader reply1, *reply = &reply1; |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1413 int lower_transport_mask = 0; |
3856 | 1414 char real_challenge[64]; |
5798
2af44abfbfe8
RTSP: Resolve and use the actual IP address of the peer we're connected to,
mstorsjo
parents:
5776
diff
changeset
|
1415 struct sockaddr_storage peer; |
2af44abfbfe8
RTSP: Resolve and use the actual IP address of the peer we're connected to,
mstorsjo
parents:
5776
diff
changeset
|
1416 socklen_t peer_len = sizeof(peer); |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1417 |
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1418 if (!ff_network_init()) |
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1419 return AVERROR(EIO); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1420 redirect: |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1421 /* extract hostname and port */ |
5775 | 1422 ff_url_split(NULL, 0, auth, sizeof(auth), |
5776 | 1423 host, sizeof(host), &port, path, sizeof(path), s->filename); |
5220
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1424 if (*auth) { |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1425 int auth_len = strlen(auth), b64_len = ((auth_len + 2) / 3) * 4 + 1; |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1426 |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1427 if (!(rt->auth_b64 = av_malloc(b64_len))) |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1428 return AVERROR(ENOMEM); |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1429 if (!av_base64_encode(rt->auth_b64, b64_len, auth, auth_len)) { |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1430 err = AVERROR(EINVAL); |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1431 goto fail; |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1432 } |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1433 } |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1434 if (port < 0) |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1435 port = RTSP_DEFAULT_PORT; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1436 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1437 /* search for options */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1438 option_list = strchr(path, '?'); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1439 if (option_list) { |
5331 | 1440 filename = strchr(s->filename, '?'); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1441 while (option_list) { |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1442 /* move the option pointer */ |
5331 | 1443 option = ++option_list; |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1444 option_list = strchr(option_list, '&'); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1445 if (option_list) |
5331 | 1446 *option_list = 0; |
1447 | |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1448 /* handle the options */ |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1449 if (!strcmp(option, "udp")) { |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1450 lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_UDP); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1451 } else if (!strcmp(option, "multicast")) { |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1452 lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_UDP_MULTICAST); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1453 } else if (!strcmp(option, "tcp")) { |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1454 lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_TCP); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1455 } else { |
5331 | 1456 strcpy(++filename, option); |
1457 filename += strlen(option); | |
1458 if (option_list) *filename = '&'; | |
1459 } | |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1460 } |
5331 | 1461 *filename = 0; |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1462 } |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1463 |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1464 if (!lower_transport_mask) |
4514
2a84d46427d1
Rename RTSP_*_LAST to RTSP_*_NB in line with PIX_FMT_* in lavc. See "[PATCH]
rbultje
parents:
4388
diff
changeset
|
1465 lower_transport_mask = (1 << RTSP_LOWER_TRANSPORT_NB) - 1; |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1466 |
5689
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1467 if (s->oformat) { |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1468 /* Only UDP output is supported at the moment. */ |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1469 lower_transport_mask &= 1 << RTSP_LOWER_TRANSPORT_UDP; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1470 if (!lower_transport_mask) { |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1471 av_log(s, AV_LOG_ERROR, "Unsupported lower transport method, " |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1472 "only UDP is supported for output.\n"); |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1473 err = AVERROR(EINVAL); |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1474 goto fail; |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1475 } |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1476 } |
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1477 |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1478 /* open the tcp connexion */ |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1479 ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL); |
5220
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1480 if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0) { |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1481 err = AVERROR(EIO); |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1482 goto fail; |
cad276e8f96e
RTSP basic authentication, patch originally by Philip Coombes
rbultje
parents:
5112
diff
changeset
|
1483 } |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1484 rt->rtsp_hd = rtsp_hd; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1485 rt->seq = 0; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1486 |
5798
2af44abfbfe8
RTSP: Resolve and use the actual IP address of the peer we're connected to,
mstorsjo
parents:
5776
diff
changeset
|
1487 tcp_fd = url_get_file_handle(rtsp_hd); |
2af44abfbfe8
RTSP: Resolve and use the actual IP address of the peer we're connected to,
mstorsjo
parents:
5776
diff
changeset
|
1488 if (!getpeername(tcp_fd, (struct sockaddr*) &peer, &peer_len)) { |
2af44abfbfe8
RTSP: Resolve and use the actual IP address of the peer we're connected to,
mstorsjo
parents:
5776
diff
changeset
|
1489 getnameinfo((struct sockaddr*) &peer, peer_len, host, sizeof(host), |
2af44abfbfe8
RTSP: Resolve and use the actual IP address of the peer we're connected to,
mstorsjo
parents:
5776
diff
changeset
|
1490 NULL, 0, NI_NUMERICHOST); |
2af44abfbfe8
RTSP: Resolve and use the actual IP address of the peer we're connected to,
mstorsjo
parents:
5776
diff
changeset
|
1491 } |
2af44abfbfe8
RTSP: Resolve and use the actual IP address of the peer we're connected to,
mstorsjo
parents:
5776
diff
changeset
|
1492 |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1493 /* request options supported by the server; this also detects server |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1494 * type */ |
5574
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
1495 av_strlcpy(rt->control_uri, s->filename, |
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
1496 sizeof(rt->control_uri)); |
3856 | 1497 for (rt->server_type = RTSP_SERVER_RTP;;) { |
1498 snprintf(cmd, sizeof(cmd), | |
5800
4410bccf6a8a
Use rt->control_uri consequently instead of s->filename in all RTSP commands
mstorsjo
parents:
5798
diff
changeset
|
1499 "OPTIONS %s RTSP/1.0\r\n", rt->control_uri); |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1500 if (rt->server_type == RTSP_SERVER_REAL) |
3856 | 1501 av_strlcat(cmd, |
1502 /** | |
1503 * The following entries are required for proper | |
1504 * streaming from a Realmedia server. They are | |
1505 * interdependent in some way although we currently | |
1506 * don't quite understand how. Values were copied | |
1507 * from mplayer SVN r23589. | |
1508 * @param CompanyID is a 16-byte ID in base64 | |
1509 * @param ClientChallenge is a 16-byte ID in hex | |
1510 */ | |
1511 "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n" | |
1512 "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n" | |
1513 "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n" | |
1514 "GUID: 00000000-0000-0000-0000-000000000000\r\n", | |
1515 sizeof(cmd)); | |
5697 | 1516 ff_rtsp_send_cmd(s, cmd, reply, NULL); |
3856 | 1517 if (reply->status_code != RTSP_STATUS_OK) { |
1518 err = AVERROR_INVALIDDATA; | |
1519 goto fail; | |
1520 } | |
1521 | |
1522 /* detect server type if not standard-compliant RTP */ | |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1523 if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) { |
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1524 rt->server_type = RTSP_SERVER_REAL; |
3856 | 1525 continue; |
4169
619845a9bab3
Use the "server" RTSP field to detect whether the server that we're talking
rbultje
parents:
4168
diff
changeset
|
1526 } else if (!strncasecmp(reply->server, "WMServer/", 9)) { |
619845a9bab3
Use the "server" RTSP field to detect whether the server that we're talking
rbultje
parents:
4168
diff
changeset
|
1527 rt->server_type = RTSP_SERVER_WMS; |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1528 } else if (rt->server_type == RTSP_SERVER_REAL) |
3856 | 1529 strcpy(real_challenge, reply->real_challenge); |
1530 break; | |
1531 } | |
1532 | |
5689
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1533 if (s->iformat) |
5691 | 1534 err = rtsp_setup_input_streams(s); |
5689
04c5f50dab62
Add a function rtsp_setup_output_streams for announcing the SDP
mstorsjo
parents:
5688
diff
changeset
|
1535 else |
5819
53c5a5d40ee7
RTSP muxer: Create the SDP with the numerical IP of the peer
mstorsjo
parents:
5802
diff
changeset
|
1536 err = rtsp_setup_output_streams(s, host); |
5680
129679c03536
Split out input-specific parts of rtsp_read_header() into its own, new,
rbultje
parents:
5679
diff
changeset
|
1537 if (err) |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1538 goto fail; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1539 |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1540 do { |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1541 int lower_transport = ff_log2_tab[lower_transport_mask & |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1542 ~(lower_transport_mask - 1)]; |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1543 |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1544 err = make_setup_request(s, host, port, lower_transport, |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1545 rt->server_type == RTSP_SERVER_REAL ? |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1546 real_challenge : NULL); |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1547 if (err < 0) |
3151 | 1548 goto fail; |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1549 lower_transport_mask &= ~(1 << lower_transport); |
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1550 if (lower_transport_mask == 0 && err == 1) { |
3202
98e633b72d38
use FF_NETERROR to make winsock happy, patch from prossATxvidDoTorg
lu_zero
parents:
3151
diff
changeset
|
1551 err = AVERROR(FF_NETERROR(EPROTONOSUPPORT)); |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1552 goto fail; |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1553 } |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1554 } while (err); |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1555 |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1556 rt->state = RTSP_STATE_IDLE; |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1557 rt->seek_timestamp = 0; /* default is to start stream at position zero */ |
0 | 1558 return 0; |
1559 fail: | |
5697 | 1560 ff_rtsp_close_streams(s); |
0 | 1561 url_close(rt->rtsp_hd); |
5690 | 1562 if (reply->status_code >=300 && reply->status_code < 400 && s->iformat) { |
5333 | 1563 av_strlcpy(s->filename, reply->location, sizeof(s->filename)); |
1564 av_log(s, AV_LOG_INFO, "Status %d: Redirecting to %s\n", | |
1565 reply->status_code, | |
1566 s->filename); | |
1567 goto redirect; | |
1568 } | |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1569 ff_network_close(); |
0 | 1570 return err; |
1571 } | |
5695 | 1572 #endif |
0 | 1573 |
5695 | 1574 #if CONFIG_RTSP_DEMUXER |
5681
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1575 static int rtsp_read_header(AVFormatContext *s, |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1576 AVFormatParameters *ap) |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1577 { |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1578 RTSPState *rt = s->priv_data; |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1579 int ret; |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1580 |
5697 | 1581 ret = ff_rtsp_connect(s); |
5681
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1582 if (ret) |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1583 return ret; |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1584 |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1585 if (ap->initial_pause) { |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1586 /* do not start immediately */ |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1587 } else { |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1588 if (rtsp_read_play(s) < 0) { |
5697 | 1589 ff_rtsp_close_streams(s); |
5681
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1590 url_close(rt->rtsp_hd); |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1591 return AVERROR_INVALIDDATA; |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1592 } |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1593 } |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1594 |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1595 return 0; |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1596 } |
7539c21106ef
Split rtsp_read_header() into two functions, so that the main part (now also
rbultje
parents:
5680
diff
changeset
|
1597 |
5493 | 1598 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, |
1599 uint8_t *buf, int buf_size) | |
1600 { | |
1601 RTSPState *rt = s->priv_data; | |
1602 RTSPStream *rtsp_st; | |
1603 fd_set rfds; | |
1604 int fd, fd_max, n, i, ret, tcp_fd; | |
1605 struct timeval tv; | |
1606 | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1607 for (;;) { |
5493 | 1608 if (url_interrupt_cb()) |
1609 return AVERROR(EINTR); | |
1610 FD_ZERO(&rfds); | |
1611 if (rt->rtsp_hd) { | |
1612 tcp_fd = fd_max = url_get_file_handle(rt->rtsp_hd); | |
1613 FD_SET(tcp_fd, &rfds); | |
1614 } else { | |
1615 fd_max = 0; | |
1616 tcp_fd = -1; | |
1617 } | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1618 for (i = 0; i < rt->nb_rtsp_streams; i++) { |
5493 | 1619 rtsp_st = rt->rtsp_streams[i]; |
1620 if (rtsp_st->rtp_handle) { | |
1621 /* currently, we cannot probe RTCP handle because of | |
1622 * blocking restrictions */ | |
1623 fd = url_get_file_handle(rtsp_st->rtp_handle); | |
1624 if (fd > fd_max) | |
1625 fd_max = fd; | |
1626 FD_SET(fd, &rfds); | |
1627 } | |
1628 } | |
1629 tv.tv_sec = 0; | |
1630 tv.tv_usec = 100 * 1000; | |
1631 n = select(fd_max + 1, &rfds, NULL, NULL, &tv); | |
1632 if (n > 0) { | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1633 for (i = 0; i < rt->nb_rtsp_streams; i++) { |
5493 | 1634 rtsp_st = rt->rtsp_streams[i]; |
1635 if (rtsp_st->rtp_handle) { | |
1636 fd = url_get_file_handle(rtsp_st->rtp_handle); | |
1637 if (FD_ISSET(fd, &rfds)) { | |
1638 ret = url_read(rtsp_st->rtp_handle, buf, buf_size); | |
1639 if (ret > 0) { | |
1640 *prtsp_st = rtsp_st; | |
1641 return ret; | |
1642 } | |
1643 } | |
1644 } | |
1645 } | |
1646 #if CONFIG_RTSP_DEMUXER | |
5589
dca2836e09b8
Don't use tcp_fd if we're not using TCP-based connections (e.g. when
rbultje
parents:
5574
diff
changeset
|
1647 if (tcp_fd != -1 && FD_ISSET(tcp_fd, &rfds)) { |
5493 | 1648 RTSPMessageHeader reply; |
1649 | |
5697 | 1650 ff_rtsp_read_reply(s, &reply, NULL, 0); |
5493 | 1651 /* XXX: parse message */ |
5670
7fa188f69c22
Rename RTSP_STATE_PLAYING to _STREAMING, since that better covers the
rbultje
parents:
5667
diff
changeset
|
1652 if (rt->state != RTSP_STATE_STREAMING) |
5493 | 1653 return 0; |
1654 } | |
1655 #endif | |
1656 } | |
1657 } | |
1658 } | |
1659 | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1660 static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1661 uint8_t *buf, int buf_size) |
0 | 1662 { |
1663 RTSPState *rt = s->priv_data; | |
172 | 1664 int id, len, i, ret; |
0 | 1665 RTSPStream *rtsp_st; |
1666 | |
172 | 1667 #ifdef DEBUG_RTP_TCP |
4990 | 1668 dprintf(s, "tcp_read_packet:\n"); |
172 | 1669 #endif |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1670 redo: |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1671 for (;;) { |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1672 RTSPMessageHeader reply; |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1673 |
5697 | 1674 ret = ff_rtsp_read_reply(s, &reply, NULL, 1); |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1675 if (ret == -1) |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1676 return -1; |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1677 if (ret == 1) /* received '$' */ |
0 | 1678 break; |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1679 /* XXX: parse message */ |
5670
7fa188f69c22
Rename RTSP_STATE_PLAYING to _STREAMING, since that better covers the
rbultje
parents:
5667
diff
changeset
|
1680 if (rt->state != RTSP_STATE_STREAMING) |
5112
85e0a9761818
Implement support for EOS as used by WMS and other RTSP servers that do not
rbultje
parents:
5013
diff
changeset
|
1681 return 0; |
0 | 1682 } |
5004
84a7b7a2f252
Move function for reading whole specified amount of data from RTSP
kostya
parents:
4990
diff
changeset
|
1683 ret = url_read_complete(rt->rtsp_hd, buf, 3); |
172 | 1684 if (ret != 3) |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1685 return -1; |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1686 id = buf[0]; |
2222 | 1687 len = AV_RB16(buf + 1); |
172 | 1688 #ifdef DEBUG_RTP_TCP |
4990 | 1689 dprintf(s, "id=%d len=%d\n", id, len); |
172 | 1690 #endif |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1691 if (len > buf_size || len < 12) |
0 | 1692 goto redo; |
1693 /* get the data */ | |
5004
84a7b7a2f252
Move function for reading whole specified amount of data from RTSP
kostya
parents:
4990
diff
changeset
|
1694 ret = url_read_complete(rt->rtsp_hd, buf, len); |
172 | 1695 if (ret != len) |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1696 return -1; |
3962
72efef66f566
This patch refactors RDT packet header parsing so that it can be used in
rbultje
parents:
3961
diff
changeset
|
1697 if (rt->transport == RTSP_TRANSPORT_RDT && |
4029
9a0a46d465ae
Add is_keyframe param to ff_rdt_parse_header(). See ML discussion in
rbultje
parents:
4026
diff
changeset
|
1698 ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0) |
3962
72efef66f566
This patch refactors RDT packet header parsing so that it can be used in
rbultje
parents:
3961
diff
changeset
|
1699 return -1; |
885 | 1700 |
0 | 1701 /* find the matching stream */ |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1702 for (i = 0; i < rt->nb_rtsp_streams; i++) { |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1703 rtsp_st = rt->rtsp_streams[i]; |
885 | 1704 if (id >= rtsp_st->interleaved_min && |
1705 id <= rtsp_st->interleaved_max) | |
0 | 1706 goto found; |
1707 } | |
1708 goto redo; | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1709 found: |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1710 *prtsp_st = rtsp_st; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1711 return len; |
0 | 1712 } |
1713 | |
5493 | 1714 static int rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) |
1715 { | |
1716 RTSPState *rt = s->priv_data; | |
1717 int ret, len; | |
1718 uint8_t buf[10 * RTP_MAX_PACKET_LENGTH]; | |
1719 RTSPStream *rtsp_st; | |
1720 | |
1721 /* get next frames from the same RTP packet */ | |
1722 if (rt->cur_transport_priv) { | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1723 if (rt->transport == RTSP_TRANSPORT_RDT) { |
5493 | 1724 ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1725 } else |
5493 | 1726 ret = rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0); |
1727 if (ret == 0) { | |
1728 rt->cur_transport_priv = NULL; | |
1729 return 0; | |
1730 } else if (ret == 1) { | |
1731 return 0; | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1732 } else |
5493 | 1733 rt->cur_transport_priv = NULL; |
1734 } | |
1735 | |
1736 /* read next RTP packet */ | |
1737 redo: | |
1738 switch(rt->lower_transport) { | |
1739 default: | |
1740 #if CONFIG_RTSP_DEMUXER | |
1741 case RTSP_LOWER_TRANSPORT_TCP: | |
1742 len = tcp_read_packet(s, &rtsp_st, buf, sizeof(buf)); | |
1743 break; | |
1744 #endif | |
1745 case RTSP_LOWER_TRANSPORT_UDP: | |
1746 case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: | |
1747 len = udp_read_packet(s, &rtsp_st, buf, sizeof(buf)); | |
1748 if (len >=0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP) | |
1749 rtp_check_and_send_back_rr(rtsp_st->transport_priv, len); | |
1750 break; | |
1751 } | |
1752 if (len < 0) | |
1753 return len; | |
1754 if (len == 0) | |
1755 return AVERROR_EOF; | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1756 if (rt->transport == RTSP_TRANSPORT_RDT) { |
5493 | 1757 ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, buf, len); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1758 } else |
5493 | 1759 ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, buf, len); |
1760 if (ret < 0) | |
1761 goto redo; | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1762 if (ret == 1) |
5493 | 1763 /* more packets may follow, so we save the RTP context */ |
1764 rt->cur_transport_priv = rtsp_st->transport_priv; | |
1765 | |
1766 return ret; | |
1767 } | |
1768 | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1769 static int rtsp_read_packet(AVFormatContext *s, AVPacket *pkt) |
0 | 1770 { |
1771 RTSPState *rt = s->priv_data; | |
5366
a04be95927ac
Split the sdp_read_packet() function out of rtsp_read_packet().
lucabe
parents:
5365
diff
changeset
|
1772 int ret; |
4877
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1773 RTSPMessageHeader reply1, *reply = &reply1; |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1774 char cmd[1024]; |
0 | 1775 |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1776 if (rt->server_type == RTSP_SERVER_REAL) { |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1777 int i; |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1778 enum AVDiscard cache[MAX_STREAMS]; |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1779 |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1780 for (i = 0; i < s->nb_streams; i++) |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1781 cache[i] = s->streams[i]->discard; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1782 |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1783 if (!rt->need_subscription) { |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1784 if (memcmp (cache, rt->real_setup_cache, |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1785 sizeof(enum AVDiscard) * s->nb_streams)) { |
5569
346dce85a801
Pretty embarassing bug; we shouldn't use av_strlcatf() on an uninitialized
rbultje
parents:
5529
diff
changeset
|
1786 snprintf(cmd, sizeof(cmd), |
5570 | 1787 "SET_PARAMETER %s RTSP/1.0\r\n" |
1788 "Unsubscribe: %s\r\n", | |
5574
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
1789 rt->control_uri, rt->last_subscription); |
5697 | 1790 ff_rtsp_send_cmd(s, cmd, reply, NULL); |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1791 if (reply->status_code != RTSP_STATUS_OK) |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1792 return AVERROR_INVALIDDATA; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1793 rt->need_subscription = 1; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1794 } |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1795 } |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1796 |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1797 if (rt->need_subscription) { |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1798 int r, rule_nr, first = 1; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1799 |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1800 memcpy(rt->real_setup_cache, cache, |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1801 sizeof(enum AVDiscard) * s->nb_streams); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1802 rt->last_subscription[0] = 0; |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1803 |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1804 snprintf(cmd, sizeof(cmd), |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1805 "SET_PARAMETER %s RTSP/1.0\r\n" |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1806 "Subscribe: ", |
5574
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
1807 rt->control_uri); |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1808 for (i = 0; i < rt->nb_rtsp_streams; i++) { |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1809 rule_nr = 0; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1810 for (r = 0; r < s->nb_streams; r++) { |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1811 if (s->streams[r]->priv_data == rt->rtsp_streams[i]) { |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1812 if (s->streams[r]->discard != AVDISCARD_ALL) { |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1813 if (!first) |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1814 av_strlcat(rt->last_subscription, ",", |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1815 sizeof(rt->last_subscription)); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1816 ff_rdt_subscribe_rule( |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1817 rt->last_subscription, |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1818 sizeof(rt->last_subscription), i, rule_nr); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1819 first = 0; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1820 } |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1821 rule_nr++; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1822 } |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1823 } |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1824 } |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1825 av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription); |
5697 | 1826 ff_rtsp_send_cmd(s, cmd, reply, NULL); |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1827 if (reply->status_code != RTSP_STATUS_OK) |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1828 return AVERROR_INVALIDDATA; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1829 rt->need_subscription = 0; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1830 |
5670
7fa188f69c22
Rename RTSP_STATE_PLAYING to _STREAMING, since that better covers the
rbultje
parents:
5667
diff
changeset
|
1831 if (rt->state == RTSP_STATE_STREAMING) |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1832 rtsp_read_play (s); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1833 } |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1834 } |
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1835 |
5480 | 1836 ret = rtsp_fetch_packet(s, pkt); |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1837 if (ret < 0) |
5366
a04be95927ac
Split the sdp_read_packet() function out of rtsp_read_packet().
lucabe
parents:
5365
diff
changeset
|
1838 return ret; |
4877
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1839 |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1840 /* send dummy request to keep TCP connection alive */ |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1841 if ((rt->server_type == RTSP_SERVER_WMS || |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1842 rt->server_type == RTSP_SERVER_REAL) && |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1843 (av_gettime() - rt->last_cmd_time) / 1000000 >= rt->timeout / 2) { |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1844 if (rt->server_type == RTSP_SERVER_WMS) { |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1845 snprintf(cmd, sizeof(cmd) - 1, |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1846 "GET_PARAMETER %s RTSP/1.0\r\n", |
5574
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
1847 rt->control_uri); |
5697 | 1848 ff_rtsp_send_cmd_async(s, cmd); |
4877
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1849 } else { |
5697 | 1850 ff_rtsp_send_cmd_async(s, "OPTIONS * RTSP/1.0\r\n"); |
4877
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1851 } |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1852 } |
940946a4569b
Send dummy requests over the TCP connection (WMS wants GET_PARAMETER,
rbultje
parents:
4875
diff
changeset
|
1853 |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1854 return 0; |
0 | 1855 } |
1856 | |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1857 /* pause the stream */ |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1858 static int rtsp_read_pause(AVFormatContext *s) |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1859 { |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1860 RTSPState *rt = s->priv_data; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1861 RTSPMessageHeader reply1, *reply = &reply1; |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1862 char cmd[1024]; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1863 |
179 | 1864 rt = s->priv_data; |
885 | 1865 |
5670
7fa188f69c22
Rename RTSP_STATE_PLAYING to _STREAMING, since that better covers the
rbultje
parents:
5667
diff
changeset
|
1866 if (rt->state != RTSP_STATE_STREAMING) |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1867 return 0; |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1868 else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { |
3904 | 1869 snprintf(cmd, sizeof(cmd), |
1870 "PAUSE %s RTSP/1.0\r\n", | |
5574
016f3d4fe56d
Use the control URI from the SDP (if present) rather than the input filename,
rbultje
parents:
5572
diff
changeset
|
1871 rt->control_uri); |
5697 | 1872 ff_rtsp_send_cmd(s, cmd, reply, NULL); |
3904 | 1873 if (reply->status_code != RTSP_STATUS_OK) { |
1874 return -1; | |
1875 } | |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1876 } |
3861
a0098594ab90
Remove useless "else" case in if X { A; return }; else { B }. See discussion
rbultje
parents:
3860
diff
changeset
|
1877 rt->state = RTSP_STATE_PAUSED; |
a0098594ab90
Remove useless "else" case in if X { A; return }; else { B }. See discussion
rbultje
parents:
3860
diff
changeset
|
1878 return 0; |
179 | 1879 } |
1880 | |
885 | 1881 static int rtsp_read_seek(AVFormatContext *s, int stream_index, |
558 | 1882 int64_t timestamp, int flags) |
179 | 1883 { |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1884 RTSPState *rt = s->priv_data; |
885 | 1885 |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1886 rt->seek_timestamp = av_rescale_q(timestamp, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1887 s->streams[stream_index]->time_base, |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1888 AV_TIME_BASE_Q); |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1889 switch(rt->state) { |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1890 default: |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1891 case RTSP_STATE_IDLE: |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1892 break; |
5670
7fa188f69c22
Rename RTSP_STATE_PLAYING to _STREAMING, since that better covers the
rbultje
parents:
5667
diff
changeset
|
1893 case RTSP_STATE_STREAMING: |
5013 | 1894 if (rtsp_read_pause(s) != 0) |
1895 return -1; | |
1896 rt->state = RTSP_STATE_SEEKING; | |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1897 if (rtsp_read_play(s) != 0) |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1898 return -1; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1899 break; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1900 case RTSP_STATE_PAUSED: |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1901 rt->state = RTSP_STATE_IDLE; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1902 break; |
179 | 1903 } |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1904 return 0; |
179 | 1905 } |
1906 | |
0 | 1907 static int rtsp_read_close(AVFormatContext *s) |
1908 { | |
1909 RTSPState *rt = s->priv_data; | |
1910 char cmd[1024]; | |
1911 | |
172 | 1912 #if 0 |
0 | 1913 /* NOTE: it is valid to flush the buffer here */ |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1914 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) { |
0 | 1915 url_fclose(&rt->rtsp_gb); |
1916 } | |
172 | 1917 #endif |
885 | 1918 snprintf(cmd, sizeof(cmd), |
172 | 1919 "TEARDOWN %s RTSP/1.0\r\n", |
5800
4410bccf6a8a
Use rt->control_uri consequently instead of s->filename in all RTSP commands
mstorsjo
parents:
5798
diff
changeset
|
1920 rt->control_uri); |
5697 | 1921 ff_rtsp_send_cmd_async(s, cmd); |
0 | 1922 |
5697 | 1923 ff_rtsp_close_streams(s); |
0 | 1924 url_close(rt->rtsp_hd); |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1925 ff_network_close(); |
0 | 1926 return 0; |
1927 } | |
1928 | |
1167 | 1929 AVInputFormat rtsp_demuxer = { |
0 | 1930 "rtsp", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3286
diff
changeset
|
1931 NULL_IF_CONFIG_SMALL("RTSP input format"), |
0 | 1932 sizeof(RTSPState), |
1933 rtsp_probe, | |
1934 rtsp_read_header, | |
1935 rtsp_read_packet, | |
1936 rtsp_read_close, | |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1937 rtsp_read_seek, |
0 | 1938 .flags = AVFMT_NOFILE, |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1939 .read_play = rtsp_read_play, |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1940 .read_pause = rtsp_read_pause, |
0 | 1941 }; |
2054 | 1942 #endif |
0 | 1943 |
1944 static int sdp_probe(AVProbeData *p1) | |
1945 { | |
706
fc254f396f15
buffer overflow in sdp_probe() fix by (Gildas Bazin )gbazin altern org)
michael
parents:
587
diff
changeset
|
1946 const char *p = p1->buf, *p_end = p1->buf + p1->buf_size; |
0 | 1947 |
1948 /* we look for a line beginning "c=IN IP4" */ | |
706
fc254f396f15
buffer overflow in sdp_probe() fix by (Gildas Bazin )gbazin altern org)
michael
parents:
587
diff
changeset
|
1949 while (p < p_end && *p != '\0') { |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1950 if (p + sizeof("c=IN IP4") - 1 < p_end && |
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1951 av_strstart(p, "c=IN IP4", NULL)) |
0 | 1952 return AVPROBE_SCORE_MAX / 2; |
706
fc254f396f15
buffer overflow in sdp_probe() fix by (Gildas Bazin )gbazin altern org)
michael
parents:
587
diff
changeset
|
1953 |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1954 while (p < p_end - 1 && *p != '\n') p++; |
706
fc254f396f15
buffer overflow in sdp_probe() fix by (Gildas Bazin )gbazin altern org)
michael
parents:
587
diff
changeset
|
1955 if (++p >= p_end) |
0 | 1956 break; |
1957 if (*p == '\r') | |
1958 p++; | |
1959 } | |
1960 return 0; | |
1961 } | |
1962 | |
1963 #define SDP_MAX_SIZE 8192 | |
1964 | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1965 static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap) |
0 | 1966 { |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1967 RTSPState *rt = s->priv_data; |
0 | 1968 RTSPStream *rtsp_st; |
1969 int size, i, err; | |
1970 char *content; | |
1971 char url[1024]; | |
1972 | |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1973 if (!ff_network_init()) |
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1974 return AVERROR(EIO); |
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1975 |
0 | 1976 /* read the whole sdp file */ |
1977 /* XXX: better loading */ | |
1978 content = av_malloc(SDP_MAX_SIZE); | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2759
diff
changeset
|
1979 size = get_buffer(s->pb, content, SDP_MAX_SIZE - 1); |
0 | 1980 if (size <= 0) { |
1981 av_free(content); | |
1982 return AVERROR_INVALIDDATA; | |
1983 } | |
1984 content[size] ='\0'; | |
1985 | |
1986 sdp_parse(s, content); | |
1987 av_free(content); | |
1988 | |
1989 /* open each RTP stream */ | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
1990 for (i = 0; i < rt->nb_rtsp_streams; i++) { |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1991 rtsp_st = rt->rtsp_streams[i]; |
885 | 1992 |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1993 ff_url_join(url, sizeof(url), "rtp", NULL, |
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1994 inet_ntoa(rtsp_st->sdp_ip), rtsp_st->sdp_port, |
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1995 "?localport=%d&ttl=%d", rtsp_st->sdp_port, |
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
1996 rtsp_st->sdp_ttl); |
1425
00d9393a126f
make ffmpeg able to send back a RTCP receiver report.
gpoirier
parents:
1424
diff
changeset
|
1997 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { |
0 | 1998 err = AVERROR_INVALIDDATA; |
1999 goto fail; | |
2000 } | |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
2001 if ((err = rtsp_open_transport_ctx(s, rtsp_st))) |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
2002 goto fail; |
0 | 2003 } |
2004 return 0; | |
5502
da007db2fe9c
Re-indent to more closely follow general coding standards used in other
rbultje
parents:
5493
diff
changeset
|
2005 fail: |
5697 | 2006 ff_rtsp_close_streams(s); |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
2007 ff_network_close(); |
0 | 2008 return err; |
2009 } | |
2010 | |
2011 static int sdp_read_close(AVFormatContext *s) | |
2012 { | |
5697 | 2013 ff_rtsp_close_streams(s); |
5756
7c7fe75728dd
Use ff_url_join for assembling URLs, instead of snprintf
mstorsjo
parents:
5726
diff
changeset
|
2014 ff_network_close(); |
0 | 2015 return 0; |
2016 } | |
2017 | |
1169 | 2018 AVInputFormat sdp_demuxer = { |
0 | 2019 "sdp", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3286
diff
changeset
|
2020 NULL_IF_CONFIG_SMALL("SDP"), |
0 | 2021 sizeof(RTSPState), |
2022 sdp_probe, | |
2023 sdp_read_header, | |
5480 | 2024 rtsp_fetch_packet, |
0 | 2025 sdp_read_close, |
2026 }; |