Mercurial > libavformat.hg
annotate rtsp.c @ 4638:801468f16243 libavformat
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
RTSP-MS UDP" thread on mailinglist.
Basically, UDP setup needs to be done in a particular order (first rtx
on two UDP ports (one for RTP, one for RTCP), then the other streams over
one, single port for all of them together). Not doing this correctly results
in a "461" error (invalid transport) during setup.
author | rbultje |
---|---|
date | Tue, 03 Mar 2009 16:52:35 +0000 |
parents | eaf90db8cc42 |
children | 70321467b4f9 |
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 |
3722
68749aaea50f
ensure we get explicit definition of various _XOPEN_SOURCE functions we use
aurel
parents:
3714
diff
changeset
|
22 /* needed by inet_aton() */ |
68749aaea50f
ensure we get explicit definition of various _XOPEN_SOURCE functions we use
aurel
parents:
3714
diff
changeset
|
23 #define _SVID_SOURCE |
68749aaea50f
ensure we get explicit definition of various _XOPEN_SOURCE functions we use
aurel
parents:
3714
diff
changeset
|
24 |
3286 | 25 #include "libavutil/avstring.h" |
4201
7d2f3f1b68d8
Fix build: Add intreadwrite.h and bswap.h #includes where necessary.
diego
parents:
4187
diff
changeset
|
26 #include "libavutil/intreadwrite.h" |
0 | 27 #include "avformat.h" |
28 | |
1808
572ce77d7333
Fix compilation on Mac OS X, patch by Marc Hoffman, mmh pleasantst com.
diego
parents:
1754
diff
changeset
|
29 #include <sys/time.h> |
4206 | 30 #if HAVE_SYS_SELECT_H |
3936
6154f62ef652
include sys/select.h instead of unistd.h to get select,
bcoudurier
parents:
3924
diff
changeset
|
31 #include <sys/select.h> |
3941
53c5b89b8dff
only include sys/select.h if present, fix mingw compilation
bcoudurier
parents:
3936
diff
changeset
|
32 #endif |
3714 | 33 #include <strings.h> |
1754 | 34 #include "network.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" |
1419 | 39 |
0 | 40 //#define DEBUG |
172 | 41 //#define DEBUG_RTP_TCP |
0 | 42 |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
43 static int rtsp_read_play(AVFormatContext *s); |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
44 |
0 | 45 /* XXX: currently, the only way to change the protocols consists in |
46 changing this variable */ | |
47 | |
2884 | 48 #if LIBAVFORMAT_VERSION_INT < (53 << 16) |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
49 int rtsp_default_protocols = (1 << RTSP_LOWER_TRANSPORT_UDP); |
2884 | 50 #endif |
0 | 51 |
52 static int rtsp_probe(AVProbeData *p) | |
53 { | |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
54 if (av_strstart(p->filename, "rtsp:", NULL)) |
0 | 55 return AVPROBE_SCORE_MAX; |
56 return 0; | |
57 } | |
58 | |
59 static int redir_isspace(int c) | |
60 { | |
3278 | 61 return c == ' ' || c == '\t' || c == '\n' || c == '\r'; |
0 | 62 } |
63 | |
64 static void skip_spaces(const char **pp) | |
65 { | |
66 const char *p; | |
67 p = *pp; | |
68 while (redir_isspace(*p)) | |
69 p++; | |
70 *pp = p; | |
71 } | |
72 | |
885 | 73 static void get_word_sep(char *buf, int buf_size, const char *sep, |
0 | 74 const char **pp) |
75 { | |
76 const char *p; | |
77 char *q; | |
78 | |
79 p = *pp; | |
774 | 80 if (*p == '/') |
81 p++; | |
0 | 82 skip_spaces(&p); |
83 q = buf; | |
84 while (!strchr(sep, *p) && *p != '\0') { | |
85 if ((q - buf) < buf_size - 1) | |
86 *q++ = *p; | |
87 p++; | |
88 } | |
89 if (buf_size > 0) | |
90 *q = '\0'; | |
91 *pp = p; | |
92 } | |
93 | |
94 static void get_word(char *buf, int buf_size, const char **pp) | |
95 { | |
96 const char *p; | |
97 char *q; | |
98 | |
99 p = *pp; | |
100 skip_spaces(&p); | |
101 q = buf; | |
102 while (!redir_isspace(*p) && *p != '\0') { | |
103 if ((q - buf) < buf_size - 1) | |
104 *q++ = *p; | |
105 p++; | |
106 } | |
107 if (buf_size > 0) | |
108 *q = '\0'; | |
109 *pp = p; | |
110 } | |
111 | |
112 /* parse the rtpmap description: <codec_name>/<clock_rate>[/<other | |
113 params>] */ | |
1419 | 114 static int sdp_parse_rtpmap(AVCodecContext *codec, RTSPStream *rtsp_st, int payload_type, const char *p) |
0 | 115 { |
116 char buf[256]; | |
774 | 117 int i; |
118 AVCodec *c; | |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
1003
diff
changeset
|
119 const char *c_name; |
0 | 120 |
774 | 121 /* Loop into AVRtpDynamicPayloadTypes[] and AVRtpPayloadTypes[] and |
122 see if we can handle this kind of payload */ | |
0 | 123 get_word_sep(buf, sizeof(buf), "/", &p); |
774 | 124 if (payload_type >= RTP_PT_PRIVATE) { |
1419 | 125 RTPDynamicProtocolHandler *handler= RTPFirstDynamicPayloadHandler; |
126 while(handler) { | |
127 if (!strcmp(buf, handler->enc_name) && (codec->codec_type == handler->codec_type)) { | |
128 codec->codec_id = handler->codec_id; | |
129 rtsp_st->dynamic_handler= handler; | |
130 if(handler->open) { | |
131 rtsp_st->dynamic_protocol_context= handler->open(); | |
132 } | |
774 | 133 break; |
134 } | |
1419 | 135 handler= handler->next; |
136 } | |
774 | 137 } else { |
138 /* We are in a standard case ( from http://www.iana.org/assignments/rtp-parameters) */ | |
139 /* search into AVRtpPayloadTypes[] */ | |
2759
b252e318023a
Remove the "AVRtpPayloadTypes[i].pt == i" assumption from RTP and RTSP
lucabe
parents:
2711
diff
changeset
|
140 codec->codec_id = ff_rtp_codec_id(buf, codec->codec_type); |
774 | 141 } |
142 | |
143 c = avcodec_find_decoder(codec->codec_id); | |
144 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
|
145 c_name = c->name; |
774 | 146 else |
147 c_name = (char *)NULL; | |
148 | |
149 if (c_name) { | |
150 get_word_sep(buf, sizeof(buf), "/", &p); | |
151 i = atoi(buf); | |
152 switch (codec->codec_type) { | |
153 case CODEC_TYPE_AUDIO: | |
154 av_log(codec, AV_LOG_DEBUG, " audio codec set to : %s\n", c_name); | |
155 codec->sample_rate = RTSP_DEFAULT_AUDIO_SAMPLERATE; | |
156 codec->channels = RTSP_DEFAULT_NB_AUDIO_CHANNELS; | |
157 if (i > 0) { | |
158 codec->sample_rate = i; | |
159 get_word_sep(buf, sizeof(buf), "/", &p); | |
160 i = atoi(buf); | |
161 if (i > 0) | |
162 codec->channels = i; | |
1431
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
163 // TODO: there is a bug here; if it is a mono stream, and less than 22000Hz, faad upconverts to stereo and twice the |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
164 // frequency. No problem, but the sample rate is being set here by the sdp line. Upcoming patch forthcoming. (rdm) |
774 | 165 } |
166 av_log(codec, AV_LOG_DEBUG, " audio samplerate set to : %i\n", codec->sample_rate); | |
167 av_log(codec, AV_LOG_DEBUG, " audio channels set to : %i\n", codec->channels); | |
168 break; | |
169 case CODEC_TYPE_VIDEO: | |
170 av_log(codec, AV_LOG_DEBUG, " video codec set to : %s\n", c_name); | |
171 break; | |
172 default: | |
173 break; | |
174 } | |
0 | 175 return 0; |
176 } | |
774 | 177 |
178 return -1; | |
0 | 179 } |
180 | |
181 /* return the length and optionnaly the data */ | |
182 static int hex_to_data(uint8_t *data, const char *p) | |
183 { | |
184 int c, len, v; | |
185 | |
186 len = 0; | |
187 v = 1; | |
188 for(;;) { | |
189 skip_spaces(&p); | |
190 if (p == '\0') | |
191 break; | |
192 c = toupper((unsigned char)*p++); | |
193 if (c >= '0' && c <= '9') | |
194 c = c - '0'; | |
195 else if (c >= 'A' && c <= 'F') | |
196 c = c - 'A' + 10; | |
197 else | |
198 break; | |
199 v = (v << 4) | c; | |
200 if (v & 0x100) { | |
201 if (data) | |
202 data[len] = v; | |
203 len++; | |
204 v = 1; | |
205 } | |
206 } | |
207 return len; | |
208 } | |
209 | |
774 | 210 static void sdp_parse_fmtp_config(AVCodecContext *codec, char *attr, char *value) |
211 { | |
212 switch (codec->codec_id) { | |
213 case CODEC_ID_MPEG4: | |
1472
49d5a5ca2987
get rid of CODEC_ID_MPEG4AAC after next version bump, and change it to CODEC_ID_AAC where used
bcoudurier
parents:
1453
diff
changeset
|
214 case CODEC_ID_AAC: |
774 | 215 if (!strcmp(attr, "config")) { |
216 /* decode the hexa encoded parameter */ | |
217 int len = hex_to_data(NULL, value); | |
218 codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE); | |
219 if (!codec->extradata) | |
220 return; | |
221 codec->extradata_size = len; | |
222 hex_to_data(codec->extradata, value); | |
223 } | |
224 break; | |
225 default: | |
226 break; | |
227 } | |
228 return; | |
229 } | |
230 | |
4088 | 231 typedef struct { |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
1003
diff
changeset
|
232 const char *str; |
774 | 233 uint16_t type; |
234 uint32_t offset; | |
4088 | 235 } AttrNameMap; |
774 | 236 |
237 /* All known fmtp parmeters and the corresping RTPAttrTypeEnum */ | |
238 #define ATTR_NAME_TYPE_INT 0 | |
239 #define ATTR_NAME_TYPE_STR 1 | |
4088 | 240 static const AttrNameMap attr_names[]= |
774 | 241 { |
4101
af2c0aef892b
Rename rtp_payload_data_t to avoid clashes with the POSIX namespace
lucabe
parents:
4088
diff
changeset
|
242 {"SizeLength", ATTR_NAME_TYPE_INT, offsetof(RTPPayloadData, sizelength)}, |
af2c0aef892b
Rename rtp_payload_data_t to avoid clashes with the POSIX namespace
lucabe
parents:
4088
diff
changeset
|
243 {"IndexLength", ATTR_NAME_TYPE_INT, offsetof(RTPPayloadData, indexlength)}, |
af2c0aef892b
Rename rtp_payload_data_t to avoid clashes with the POSIX namespace
lucabe
parents:
4088
diff
changeset
|
244 {"IndexDeltaLength", ATTR_NAME_TYPE_INT, offsetof(RTPPayloadData, indexdeltalength)}, |
af2c0aef892b
Rename rtp_payload_data_t to avoid clashes with the POSIX namespace
lucabe
parents:
4088
diff
changeset
|
245 {"profile-level-id", ATTR_NAME_TYPE_INT, offsetof(RTPPayloadData, profile_level_id)}, |
af2c0aef892b
Rename rtp_payload_data_t to avoid clashes with the POSIX namespace
lucabe
parents:
4088
diff
changeset
|
246 {"StreamType", ATTR_NAME_TYPE_INT, offsetof(RTPPayloadData, streamtype)}, |
af2c0aef892b
Rename rtp_payload_data_t to avoid clashes with the POSIX namespace
lucabe
parents:
4088
diff
changeset
|
247 {"mode", ATTR_NAME_TYPE_STR, offsetof(RTPPayloadData, mode)}, |
774 | 248 {NULL, -1, -1}, |
249 }; | |
250 | |
1431
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
251 /** parse the attribute line from the fmtp a line of an sdp resonse. This is broken out as a function |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
252 * because it is used in rtp_h264.c, which is forthcoming. |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
253 */ |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
254 int rtsp_next_attr_and_value(const char **p, char *attr, int attr_size, char *value, int value_size) |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
255 { |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
256 skip_spaces(p); |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
257 if(**p) |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
258 { |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
259 get_word_sep(attr, attr_size, "=", p); |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
260 if (**p == '=') |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
261 (*p)++; |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
262 get_word_sep(value, value_size, ";", p); |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
263 if (**p == ';') |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
264 (*p)++; |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
265 return 1; |
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 return 0; |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
268 } |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
269 |
774 | 270 /* parse a SDP line and save stream attributes */ |
271 static void sdp_parse_fmtp(AVStream *st, const char *p) | |
0 | 272 { |
273 char attr[256]; | |
274 char value[4096]; | |
774 | 275 int i; |
276 | |
277 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
|
278 AVCodecContext *codec = st->codec; |
4101
af2c0aef892b
Rename rtp_payload_data_t to avoid clashes with the POSIX namespace
lucabe
parents:
4088
diff
changeset
|
279 RTPPayloadData *rtp_payload_data = &rtsp_st->rtp_payload_data; |
0 | 280 |
281 /* loop on each attribute */ | |
1514
958decd51c1f
remove duplicate code, patch by Ryan Martell rdm4 A martellventures P com
gpoirier
parents:
1472
diff
changeset
|
282 while(rtsp_next_attr_and_value(&p, attr, sizeof(attr), value, sizeof(value))) |
958decd51c1f
remove duplicate code, patch by Ryan Martell rdm4 A martellventures P com
gpoirier
parents:
1472
diff
changeset
|
283 { |
887 | 284 /* grab the codec extra_data from the config parameter of the fmtp line */ |
774 | 285 sdp_parse_fmtp_config(codec, attr, value); |
286 /* Looking for a known attribute */ | |
287 for (i = 0; attr_names[i].str; ++i) { | |
288 if (!strcasecmp(attr, attr_names[i].str)) { | |
289 if (attr_names[i].type == ATTR_NAME_TYPE_INT) | |
290 *(int *)((char *)rtp_payload_data + attr_names[i].offset) = atoi(value); | |
291 else if (attr_names[i].type == ATTR_NAME_TYPE_STR) | |
292 *(char **)((char *)rtp_payload_data + attr_names[i].offset) = av_strdup(value); | |
887 | 293 } |
0 | 294 } |
295 } | |
296 } | |
297 | |
1453
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
298 /** Parse a string \p in the form of Range:npt=xx-xx, and determine the start |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
299 * and end time. |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
300 * 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
|
301 */ |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
302 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
|
303 { |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
304 char buf[256]; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
305 |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
306 skip_spaces(&p); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
307 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
|
308 return; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
309 |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
310 *start = AV_NOPTS_VALUE; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
311 *end = AV_NOPTS_VALUE; |
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 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
|
314 *start = parse_date(buf, 1); |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
315 if (*p == '-') { |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
316 p++; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
317 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
|
318 *end = parse_date(buf, 1); |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
319 } |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
320 // 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
|
321 // 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
|
322 } |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
323 |
0 | 324 typedef struct SDPParseState { |
325 /* SDP only */ | |
326 struct in_addr default_ip; | |
327 int default_ttl; | |
4281
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
328 int skip_media; ///< set if an unknown m= line occurs |
0 | 329 } SDPParseState; |
330 | |
331 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, | |
332 int letter, const char *buf) | |
333 { | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
334 RTSPState *rt = s->priv_data; |
0 | 335 char buf1[64], st_type[64]; |
336 const char *p; | |
3967 | 337 enum CodecType codec_type; |
338 int payload_type, i; | |
0 | 339 AVStream *st; |
340 RTSPStream *rtsp_st; | |
341 struct in_addr sdp_ip; | |
342 int ttl; | |
343 | |
344 #ifdef DEBUG | |
345 printf("sdp: %c='%s'\n", letter, buf); | |
346 #endif | |
347 | |
348 p = buf; | |
4281
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
349 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
|
350 return; |
0 | 351 switch(letter) { |
352 case 'c': | |
353 get_word(buf1, sizeof(buf1), &p); | |
354 if (strcmp(buf1, "IN") != 0) | |
355 return; | |
356 get_word(buf1, sizeof(buf1), &p); | |
357 if (strcmp(buf1, "IP4") != 0) | |
358 return; | |
359 get_word_sep(buf1, sizeof(buf1), "/", &p); | |
360 if (inet_aton(buf1, &sdp_ip) == 0) | |
361 return; | |
362 ttl = 16; | |
363 if (*p == '/') { | |
364 p++; | |
365 get_word_sep(buf1, sizeof(buf1), "/", &p); | |
366 ttl = atoi(buf1); | |
367 } | |
368 if (s->nb_streams == 0) { | |
369 s1->default_ip = sdp_ip; | |
370 s1->default_ttl = ttl; | |
371 } else { | |
372 st = s->streams[s->nb_streams - 1]; | |
373 rtsp_st = st->priv_data; | |
374 rtsp_st->sdp_ip = sdp_ip; | |
375 rtsp_st->sdp_ttl = ttl; | |
376 } | |
377 break; | |
378 case 's': | |
4361 | 379 av_metadata_set(&s->metadata, "title", p); |
0 | 380 break; |
381 case 'i': | |
382 if (s->nb_streams == 0) { | |
4361 | 383 av_metadata_set(&s->metadata, "comment", p); |
0 | 384 break; |
385 } | |
386 break; | |
387 case 'm': | |
388 /* new stream */ | |
4281
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
389 s1->skip_media = 0; |
0 | 390 get_word(st_type, sizeof(st_type), &p); |
391 if (!strcmp(st_type, "audio")) { | |
392 codec_type = CODEC_TYPE_AUDIO; | |
393 } else if (!strcmp(st_type, "video")) { | |
394 codec_type = CODEC_TYPE_VIDEO; | |
4637
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
395 } else if (!strcmp(st_type, "application")) { |
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
396 codec_type = CODEC_TYPE_DATA; |
0 | 397 } else { |
4281
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
398 s1->skip_media = 1; |
0 | 399 return; |
400 } | |
401 rtsp_st = av_mallocz(sizeof(RTSPStream)); | |
402 if (!rtsp_st) | |
403 return; | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
404 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
|
405 dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st); |
0 | 406 |
407 rtsp_st->sdp_ip = s1->default_ip; | |
408 rtsp_st->sdp_ttl = s1->default_ttl; | |
409 | |
410 get_word(buf1, sizeof(buf1), &p); /* port */ | |
411 rtsp_st->sdp_port = atoi(buf1); | |
412 | |
413 get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */ | |
885 | 414 |
0 | 415 /* XXX: handle list of formats */ |
416 get_word(buf1, sizeof(buf1), &p); /* format list */ | |
417 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
|
418 |
2759
b252e318023a
Remove the "AVRtpPayloadTypes[i].pt == i" assumption from RTP and RTSP
lucabe
parents:
2711
diff
changeset
|
419 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
|
420 /* 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
|
421 } else { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
422 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
|
423 if (!st) |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
424 return; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
425 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
|
426 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
|
427 st->codec->codec_type = codec_type; |
774 | 428 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
|
429 /* 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
|
430 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
|
431 } |
0 | 432 } |
433 /* put a default control url */ | |
2189 | 434 av_strlcpy(rtsp_st->control_url, s->filename, sizeof(rtsp_st->control_url)); |
0 | 435 break; |
436 case 'a': | |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
437 if (av_strstart(p, "control:", &p) && s->nb_streams > 0) { |
0 | 438 char proto[32]; |
439 /* get the control url */ | |
440 st = s->streams[s->nb_streams - 1]; | |
441 rtsp_st = st->priv_data; | |
885 | 442 |
0 | 443 /* XXX: may need to add full url resolution */ |
511
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
391
diff
changeset
|
444 url_split(proto, sizeof(proto), NULL, 0, NULL, 0, NULL, NULL, 0, p); |
0 | 445 if (proto[0] == '\0') { |
446 /* relative control URL */ | |
2189 | 447 av_strlcat(rtsp_st->control_url, "/", sizeof(rtsp_st->control_url)); |
448 av_strlcat(rtsp_st->control_url, p, sizeof(rtsp_st->control_url)); | |
0 | 449 } else { |
2189 | 450 av_strlcpy(rtsp_st->control_url, p, sizeof(rtsp_st->control_url)); |
0 | 451 } |
4185
023976c45ae1
Apply rtpmap: SDP lines to the last m= line only, since they generally just
rbultje
parents:
4182
diff
changeset
|
452 } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) { |
0 | 453 /* NOTE: rtpmap is only supported AFTER the 'm=' tag */ |
885 | 454 get_word(buf1, sizeof(buf1), &p); |
0 | 455 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
|
456 st = s->streams[s->nb_streams - 1]; |
4186 | 457 rtsp_st = st->priv_data; |
458 sdp_parse_rtpmap(st->codec, rtsp_st, payload_type, p); | |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
459 } else if (av_strstart(p, "fmtp:", &p)) { |
0 | 460 /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */ |
885 | 461 get_word(buf1, sizeof(buf1), &p); |
0 | 462 payload_type = atoi(buf1); |
463 for(i = 0; i < s->nb_streams;i++) { | |
464 st = s->streams[i]; | |
465 rtsp_st = st->priv_data; | |
466 if (rtsp_st->sdp_payload_type == payload_type) { | |
1419 | 467 if(rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->parse_sdp_a_line) { |
4067
8adccfc01be3
Change function prototype of the sdp_parse_a_line in DynamicProtocolHandler.
rbultje
parents:
4050
diff
changeset
|
468 if(!rtsp_st->dynamic_handler->parse_sdp_a_line(s, i, rtsp_st->dynamic_protocol_context, buf)) { |
1419 | 469 sdp_parse_fmtp(st, p); |
470 } | |
471 } else { | |
1424
1c39ce5c6a5d
indentation fix, patch by Ryan Martell % rdm4 A martellventures P com %
gpoirier
parents:
1419
diff
changeset
|
472 sdp_parse_fmtp(st, p); |
1419 | 473 } |
0 | 474 } |
475 } | |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
476 } else if(av_strstart(p, "framesize:", &p)) { |
1431
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
477 // 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
|
478 get_word(buf1, sizeof(buf1), &p); |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
479 payload_type = atoi(buf1); |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
480 for(i = 0; i < s->nb_streams;i++) { |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
481 st = s->streams[i]; |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
482 rtsp_st = st->priv_data; |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
483 if (rtsp_st->sdp_payload_type == payload_type) { |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
484 if(rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->parse_sdp_a_line) { |
4067
8adccfc01be3
Change function prototype of the sdp_parse_a_line in DynamicProtocolHandler.
rbultje
parents:
4050
diff
changeset
|
485 rtsp_st->dynamic_handler->parse_sdp_a_line(s, i, rtsp_st->dynamic_protocol_context, buf); |
1431
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
486 } |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
487 } |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
488 } |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
489 } 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
|
490 int64_t start, end; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
491 |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
492 // 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
|
493 rtsp_parse_range_npt(p, &start, &end); |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
494 s->start_time= start; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
495 s->duration= (end==AV_NOPTS_VALUE)?AV_NOPTS_VALUE:end-start; // AV_NOPTS_VALUE means live broadcast (and can't seek) |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
496 } else if (av_strstart(p, "IsRealDataType:integer;",&p)) { |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
497 if (atoi(p) == 1) |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
498 rt->transport = RTSP_TRANSPORT_RDT; |
3784
d370d80ad1df
Use RTPDynamicProtocol parse_sdp_a_line() handlers in case of unknown SDP
rbultje
parents:
3722
diff
changeset
|
499 } else if (s->nb_streams > 0) { |
4163
8d6512cbd657
Parse the ASMRuleBook SDP line to dynamically create one new AVStream for
rbultje
parents:
4109
diff
changeset
|
500 if (rt->server_type == RTSP_SERVER_REAL) |
8d6512cbd657
Parse the ASMRuleBook SDP line to dynamically create one new AVStream for
rbultje
parents:
4109
diff
changeset
|
501 ff_real_parse_sdp_a_line(s, s->nb_streams - 1, p); |
8d6512cbd657
Parse the ASMRuleBook SDP line to dynamically create one new AVStream for
rbultje
parents:
4109
diff
changeset
|
502 |
3784
d370d80ad1df
Use RTPDynamicProtocol parse_sdp_a_line() handlers in case of unknown SDP
rbultje
parents:
3722
diff
changeset
|
503 rtsp_st = s->streams[s->nb_streams - 1]->priv_data; |
d370d80ad1df
Use RTPDynamicProtocol parse_sdp_a_line() handlers in case of unknown SDP
rbultje
parents:
3722
diff
changeset
|
504 if (rtsp_st->dynamic_handler && |
d370d80ad1df
Use RTPDynamicProtocol parse_sdp_a_line() handlers in case of unknown SDP
rbultje
parents:
3722
diff
changeset
|
505 rtsp_st->dynamic_handler->parse_sdp_a_line) |
4067
8adccfc01be3
Change function prototype of the sdp_parse_a_line in DynamicProtocolHandler.
rbultje
parents:
4050
diff
changeset
|
506 rtsp_st->dynamic_handler->parse_sdp_a_line(s, s->nb_streams - 1, |
3784
d370d80ad1df
Use RTPDynamicProtocol parse_sdp_a_line() handlers in case of unknown SDP
rbultje
parents:
3722
diff
changeset
|
507 rtsp_st->dynamic_protocol_context, buf); |
0 | 508 } |
509 break; | |
510 } | |
511 } | |
512 | |
64 | 513 static int sdp_parse(AVFormatContext *s, const char *content) |
0 | 514 { |
515 const char *p; | |
516 int letter; | |
4187 | 517 /* Some SDP lines, particularly for Realmedia or ASF RTSP streams, |
518 * contain long SDP lines containing complete ASF Headers (several | |
519 * kB) or arrays of MDPR (RM stream descriptor) headers plus | |
520 * "rulebooks" describing their properties. Therefore, the SDP line | |
521 * buffer is large. */ | |
4108
132640f78cb2
Increase SDP line buffer size because ASF headers in RTSP-MS are very big. See ML discussion
rbultje
parents:
4101
diff
changeset
|
522 char buf[8192], *q; |
0 | 523 SDPParseState sdp_parse_state, *s1 = &sdp_parse_state; |
885 | 524 |
0 | 525 memset(s1, 0, sizeof(SDPParseState)); |
526 p = content; | |
527 for(;;) { | |
528 skip_spaces(&p); | |
529 letter = *p; | |
530 if (letter == '\0') | |
531 break; | |
532 p++; | |
533 if (*p != '=') | |
534 goto next_line; | |
535 p++; | |
536 /* get the content */ | |
537 q = buf; | |
172 | 538 while (*p != '\n' && *p != '\r' && *p != '\0') { |
0 | 539 if ((q - buf) < sizeof(buf) - 1) |
540 *q++ = *p; | |
541 p++; | |
542 } | |
543 *q = '\0'; | |
544 sdp_parse_line(s, s1, letter, buf); | |
545 next_line: | |
546 while (*p != '\n' && *p != '\0') | |
547 p++; | |
548 if (*p == '\n') | |
549 p++; | |
550 } | |
551 return 0; | |
552 } | |
553 | |
554 static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp) | |
555 { | |
556 const char *p; | |
557 int v; | |
558 | |
559 p = *pp; | |
560 skip_spaces(&p); | |
561 v = strtol(p, (char **)&p, 10); | |
562 if (*p == '-') { | |
563 p++; | |
564 *min_ptr = v; | |
565 v = strtol(p, (char **)&p, 10); | |
566 *max_ptr = v; | |
567 } else { | |
568 *min_ptr = v; | |
569 *max_ptr = v; | |
570 } | |
571 *pp = p; | |
572 } | |
573 | |
574 /* XXX: only one transport specification is parsed */ | |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
575 static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p) |
0 | 576 { |
577 char transport_protocol[16]; | |
578 char profile[16]; | |
579 char lower_transport[16]; | |
580 char parameter[16]; | |
581 RTSPTransportField *th; | |
582 char buf[256]; | |
885 | 583 |
0 | 584 reply->nb_transports = 0; |
885 | 585 |
0 | 586 for(;;) { |
587 skip_spaces(&p); | |
588 if (*p == '\0') | |
589 break; | |
590 | |
591 th = &reply->transports[reply->nb_transports]; | |
592 | |
885 | 593 get_word_sep(transport_protocol, sizeof(transport_protocol), |
0 | 594 "/", &p); |
595 if (*p == '/') | |
596 p++; | |
2865
51aa1054528c
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 2 x-pn-tng support
lu_zero
parents:
2864
diff
changeset
|
597 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
|
598 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
|
599 lower_transport[0] = '\0'; |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
600 /* rtp/avp/<protocol> */ |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
601 if (*p == '/') { |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
602 p++; |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
603 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
|
604 ";,", &p); |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
605 } |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
606 th->transport = RTSP_TRANSPORT_RTP; |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
607 } else if (!strcasecmp (transport_protocol, "x-pn-tng") || |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
608 !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
|
609 /* 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
|
610 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
|
611 profile[0] = '\0'; |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
612 th->transport = RTSP_TRANSPORT_RDT; |
0 | 613 } |
172 | 614 if (!strcasecmp(lower_transport, "TCP")) |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
615 th->lower_transport = RTSP_LOWER_TRANSPORT_TCP; |
0 | 616 else |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
617 th->lower_transport = RTSP_LOWER_TRANSPORT_UDP; |
885 | 618 |
0 | 619 if (*p == ';') |
620 p++; | |
621 /* get each parameter */ | |
622 while (*p != '\0' && *p != ',') { | |
623 get_word_sep(parameter, sizeof(parameter), "=;,", &p); | |
624 if (!strcmp(parameter, "port")) { | |
625 if (*p == '=') { | |
626 p++; | |
627 rtsp_parse_range(&th->port_min, &th->port_max, &p); | |
628 } | |
629 } else if (!strcmp(parameter, "client_port")) { | |
630 if (*p == '=') { | |
631 p++; | |
885 | 632 rtsp_parse_range(&th->client_port_min, |
0 | 633 &th->client_port_max, &p); |
634 } | |
635 } else if (!strcmp(parameter, "server_port")) { | |
636 if (*p == '=') { | |
637 p++; | |
885 | 638 rtsp_parse_range(&th->server_port_min, |
0 | 639 &th->server_port_max, &p); |
640 } | |
641 } else if (!strcmp(parameter, "interleaved")) { | |
642 if (*p == '=') { | |
643 p++; | |
885 | 644 rtsp_parse_range(&th->interleaved_min, |
0 | 645 &th->interleaved_max, &p); |
646 } | |
647 } else if (!strcmp(parameter, "multicast")) { | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
648 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
|
649 th->lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST; |
0 | 650 } else if (!strcmp(parameter, "ttl")) { |
651 if (*p == '=') { | |
652 p++; | |
653 th->ttl = strtol(p, (char **)&p, 10); | |
654 } | |
655 } else if (!strcmp(parameter, "destination")) { | |
656 struct in_addr ipaddr; | |
657 | |
658 if (*p == '=') { | |
659 p++; | |
660 get_word_sep(buf, sizeof(buf), ";,", &p); | |
885 | 661 if (inet_aton(buf, &ipaddr)) |
0 | 662 th->destination = ntohl(ipaddr.s_addr); |
663 } | |
664 } | |
665 while (*p != ';' && *p != '\0' && *p != ',') | |
666 p++; | |
667 if (*p == ';') | |
668 p++; | |
669 } | |
670 if (*p == ',') | |
671 p++; | |
672 | |
673 reply->nb_transports++; | |
674 } | |
675 } | |
676 | |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
677 void rtsp_parse_line(RTSPMessageHeader *reply, const char *buf) |
0 | 678 { |
679 const char *p; | |
680 | |
681 /* NOTE: we do case independent match for broken servers */ | |
682 p = buf; | |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
683 if (av_stristart(p, "Session:", &p)) { |
0 | 684 get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
685 } else if (av_stristart(p, "Content-Length:", &p)) { |
0 | 686 reply->content_length = strtol(p, NULL, 10); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
687 } else if (av_stristart(p, "Transport:", &p)) { |
0 | 688 rtsp_parse_transport(reply, p); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
689 } else if (av_stristart(p, "CSeq:", &p)) { |
0 | 690 reply->seq = strtol(p, NULL, 10); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
691 } 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
|
692 rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end); |
3855 | 693 } else if (av_stristart(p, "RealChallenge1:", &p)) { |
694 skip_spaces(&p); | |
695 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
|
696 } 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
|
697 skip_spaces(&p); |
619845a9bab3
Use the "server" RTSP field to detect whether the server that we're talking
rbultje
parents:
4168
diff
changeset
|
698 av_strlcpy(reply->server, p, sizeof(reply->server)); |
0 | 699 } |
700 } | |
701 | |
391
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
702 static int url_readbuf(URLContext *h, unsigned char *buf, int size) |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
703 { |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
704 int ret, len; |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
705 |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
706 len = 0; |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
707 while (len < size) { |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
708 ret = url_read(h, buf+len, size-len); |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
709 if (ret < 1) |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
710 return ret; |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
711 len += ret; |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
712 } |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
713 return len; |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
714 } |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
715 |
179 | 716 /* skip a RTP/TCP interleaved packet */ |
717 static void rtsp_skip_packet(AVFormatContext *s) | |
718 { | |
719 RTSPState *rt = s->priv_data; | |
720 int ret, len, len1; | |
721 uint8_t buf[1024]; | |
722 | |
391
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
723 ret = url_readbuf(rt->rtsp_hd, buf, 3); |
179 | 724 if (ret != 3) |
725 return; | |
2222 | 726 len = AV_RB16(buf + 1); |
179 | 727 #ifdef DEBUG |
728 printf("skipping RTP packet len=%d\n", len); | |
729 #endif | |
730 /* skip payload */ | |
731 while (len > 0) { | |
732 len1 = len; | |
733 if (len1 > sizeof(buf)) | |
734 len1 = sizeof(buf); | |
391
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
735 ret = url_readbuf(rt->rtsp_hd, buf, len1); |
179 | 736 if (ret != len1) |
737 return; | |
738 len -= len1; | |
739 } | |
740 } | |
0 | 741 |
885 | 742 static void rtsp_send_cmd(AVFormatContext *s, |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
743 const char *cmd, RTSPMessageHeader *reply, |
0 | 744 unsigned char **content_ptr) |
745 { | |
746 RTSPState *rt = s->priv_data; | |
747 char buf[4096], buf1[1024], *q; | |
748 unsigned char ch; | |
749 const char *p; | |
750 int content_length, line_count; | |
751 unsigned char *content = NULL; | |
752 | |
4549 | 753 memset(reply, 0, sizeof(*reply)); |
0 | 754 |
755 rt->seq++; | |
2189 | 756 av_strlcpy(buf, cmd, sizeof(buf)); |
172 | 757 snprintf(buf1, sizeof(buf1), "CSeq: %d\r\n", rt->seq); |
2189 | 758 av_strlcat(buf, buf1, sizeof(buf)); |
0 | 759 if (rt->session_id[0] != '\0' && !strstr(cmd, "\nIf-Match:")) { |
172 | 760 snprintf(buf1, sizeof(buf1), "Session: %s\r\n", rt->session_id); |
2189 | 761 av_strlcat(buf, buf1, sizeof(buf)); |
0 | 762 } |
2189 | 763 av_strlcat(buf, "\r\n", sizeof(buf)); |
0 | 764 #ifdef DEBUG |
765 printf("Sending:\n%s--\n", buf); | |
766 #endif | |
767 url_write(rt->rtsp_hd, buf, strlen(buf)); | |
768 | |
769 /* parse reply (XXX: use buffers) */ | |
770 line_count = 0; | |
771 rt->last_reply[0] = '\0'; | |
772 for(;;) { | |
773 q = buf; | |
774 for(;;) { | |
391
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
775 if (url_readbuf(rt->rtsp_hd, &ch, 1) != 1) |
0 | 776 break; |
777 if (ch == '\n') | |
778 break; | |
179 | 779 if (ch == '$') { |
780 /* XXX: only parse it if first char on line ? */ | |
781 rtsp_skip_packet(s); | |
782 } else if (ch != '\r') { | |
0 | 783 if ((q - buf) < sizeof(buf) - 1) |
784 *q++ = ch; | |
785 } | |
786 } | |
787 *q = '\0'; | |
788 #ifdef DEBUG | |
789 printf("line='%s'\n", buf); | |
790 #endif | |
791 /* test if last line */ | |
792 if (buf[0] == '\0') | |
793 break; | |
794 p = buf; | |
795 if (line_count == 0) { | |
796 /* get reply code */ | |
797 get_word(buf1, sizeof(buf1), &p); | |
798 get_word(buf1, sizeof(buf1), &p); | |
799 reply->status_code = atoi(buf1); | |
800 } else { | |
801 rtsp_parse_line(reply, p); | |
2189 | 802 av_strlcat(rt->last_reply, p, sizeof(rt->last_reply)); |
803 av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply)); | |
0 | 804 } |
805 line_count++; | |
806 } | |
885 | 807 |
0 | 808 if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0') |
2189 | 809 av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id)); |
885 | 810 |
0 | 811 content_length = reply->content_length; |
812 if (content_length > 0) { | |
813 /* leave some room for a trailing '\0' (useful for simple parsing) */ | |
814 content = av_malloc(content_length + 1); | |
391
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
815 (void)url_readbuf(rt->rtsp_hd, content, content_length); |
0 | 816 content[content_length] = '\0'; |
817 } | |
818 if (content_ptr) | |
819 *content_ptr = content; | |
2263 | 820 else |
821 av_free(content); | |
0 | 822 } |
823 | |
824 | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
825 /* close and free RTSP streams */ |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
826 static void rtsp_close_streams(RTSPState *rt) |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
827 { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
828 int i; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
829 RTSPStream *rtsp_st; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
830 |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
831 for(i=0;i<rt->nb_rtsp_streams;i++) { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
832 rtsp_st = rt->rtsp_streams[i]; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
833 if (rtsp_st) { |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
834 if (rtsp_st->transport_priv) { |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
835 if (rt->transport == RTSP_TRANSPORT_RDT) |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
836 ff_rdt_parse_close(rtsp_st->transport_priv); |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
837 else |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
838 rtp_parse_close(rtsp_st->transport_priv); |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
839 } |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
840 if (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
|
841 url_close(rtsp_st->rtp_handle); |
1419 | 842 if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context) |
843 rtsp_st->dynamic_handler->close(rtsp_st->dynamic_protocol_context); | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
844 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
845 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
846 av_free(rt->rtsp_streams); |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
847 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
848 |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
849 static int |
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
850 rtsp_open_transport_ctx(AVFormatContext *s, RTSPStream *rtsp_st) |
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
851 { |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
852 RTSPState *rt = s->priv_data; |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
853 AVStream *st = NULL; |
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
854 |
3920
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
855 /* open the RTP context */ |
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
856 if (rtsp_st->stream_index >= 0) |
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
857 st = s->streams[rtsp_st->stream_index]; |
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
858 if (!st) |
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
859 s->ctx_flags |= AVFMTCTX_NOHEADER; |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
860 |
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
861 if (rt->transport == RTSP_TRANSPORT_RDT) |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
862 rtsp_st->transport_priv = ff_rdt_parse_open(s, st->index, |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
863 rtsp_st->dynamic_protocol_context, |
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
864 rtsp_st->dynamic_handler); |
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
865 else |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
866 rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle, |
3980 | 867 rtsp_st->sdp_payload_type, |
868 &rtsp_st->rtp_payload_data); | |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
869 |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
870 if (!rtsp_st->transport_priv) { |
3920
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
871 return AVERROR(ENOMEM); |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
872 } else if (rt->transport != RTSP_TRANSPORT_RDT) { |
3920
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
873 if(rtsp_st->dynamic_handler) { |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
874 rtp_parse_set_dynamic_protocol(rtsp_st->transport_priv, |
3977
1f1c4535f421
Remove access into RTPDemuxContext in rtsp.c, which allows making it opaque
rbultje
parents:
3975
diff
changeset
|
875 rtsp_st->dynamic_protocol_context, |
1f1c4535f421
Remove access into RTPDemuxContext in rtsp.c, which allows making it opaque
rbultje
parents:
3975
diff
changeset
|
876 rtsp_st->dynamic_handler); |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
877 } |
3920
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
878 } |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
879 |
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
880 return 0; |
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
881 } |
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
882 |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
883 /** |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
884 * @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
|
885 */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
886 static int |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
887 make_setup_request (AVFormatContext *s, const char *host, int port, |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
888 int lower_transport, const char *real_challenge) |
0 | 889 { |
890 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
|
891 int rtx, j, i, err, interleave = 0; |
0 | 892 RTSPStream *rtsp_st; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
893 RTSPMessageHeader reply1, *reply = &reply1; |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
894 char cmd[2048]; |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
895 const char *trans_pref; |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
896 |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
897 if (rt->transport == RTSP_TRANSPORT_RDT) |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
898 trans_pref = "x-pn-tng"; |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
899 else |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
900 trans_pref = "RTP/AVP"; |
885 | 901 |
0 | 902 /* for each stream, make the setup request */ |
903 /* XXX: we assume the same server is used for the control of each | |
904 RTSP stream */ | |
774 | 905 |
906 for(j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) { | |
0 | 907 char transport[2048]; |
908 | |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
909 /** |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
910 * 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
|
911 * 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
|
912 * 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
|
913 */ |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
914 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
|
915 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
|
916 if (i == 0) { |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
917 /* rtx first */ |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
918 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
|
919 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
|
920 if (len >= 4 && |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
921 !strcmp(rt->rtsp_streams[rtx]->control_url + len - 4, "/rtx")) |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
922 break; |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
923 } |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
924 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
|
925 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
|
926 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
|
927 } else |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
928 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
|
929 } else |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
930 rtsp_st = rt->rtsp_streams[i]; |
0 | 931 |
932 /* RTP/UDP */ | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
933 if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) { |
0 | 934 char buf[256]; |
935 | |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
936 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
|
937 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
|
938 goto have_port; |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
939 } |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
940 |
0 | 941 /* first try in specified port range */ |
774 | 942 if (RTSP_RTP_PORT_MIN != 0) { |
943 while(j <= RTSP_RTP_PORT_MAX) { | |
2711
0ff7c5289e68
Specify the server address when opening an rtp:// URL in rtsp.c, so
lucabe
parents:
2684
diff
changeset
|
944 snprintf(buf, sizeof(buf), "rtp://%s?localport=%d", host, j); |
2684
3dd4b622f4e3
If local port n is not available, try n + 2 instead of continuing to bind
lucabe
parents:
2681
diff
changeset
|
945 j += 2; /* we will use two port by rtp stream (rtp and rtcp) */ |
1425
00d9393a126f
make ffmpeg able to send back a RTCP receiver report.
gpoirier
parents:
1424
diff
changeset
|
946 if (url_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0) { |
0 | 947 goto rtp_opened; |
774 | 948 } |
0 | 949 } |
950 } | |
951 | |
774 | 952 /* then try on any port |
953 ** if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) { | |
954 ** err = AVERROR_INVALIDDATA; | |
955 ** goto fail; | |
956 ** } | |
957 */ | |
0 | 958 |
959 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
|
960 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
|
961 have_port: |
3877
3e0c7ad2a675
Remove unused code that used to handle protocol concatenation, i.e. trying
rbultje
parents:
3876
diff
changeset
|
962 snprintf(transport, sizeof(transport) - 1, |
3958
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
963 "%s/UDP;", trans_pref); |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
964 if (rt->server_type != RTSP_SERVER_REAL) |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
965 av_strlcat(transport, "unicast;", sizeof(transport)); |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
966 av_strlcatf(transport, sizeof(transport), |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
967 "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
|
968 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
|
969 !(rt->server_type == RTSP_SERVER_WMS && i > 0)) |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
970 av_strlcatf(transport, sizeof(transport), "-%d", port + 1); |
0 | 971 } |
972 | |
973 /* RTP/TCP */ | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
974 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
|
975 /** 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
|
976 * 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
|
977 * 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
|
978 if (rt->server_type == RTSP_SERVER_WMS && |
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
979 s->streams[rtsp_st->stream_index]->codec->codec_type == CODEC_TYPE_DATA) |
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
980 continue; |
3877
3e0c7ad2a675
Remove unused code that used to handle protocol concatenation, i.e. trying
rbultje
parents:
3876
diff
changeset
|
981 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
|
982 "%s/TCP;", trans_pref); |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
983 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
|
984 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
|
985 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
|
986 "interleaved=%d-%d", |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
987 interleave, interleave + 1); |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
988 interleave += 2; |
0 | 989 } |
990 | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
991 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
|
992 snprintf(transport, sizeof(transport) - 1, |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
993 "%s/UDP;multicast", trans_pref); |
0 | 994 } |
4332
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
995 if (rt->server_type == RTSP_SERVER_REAL || |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
996 rt->server_type == RTSP_SERVER_WMS) |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
997 av_strlcat(transport, ";mode=play", sizeof(transport)); |
885 | 998 snprintf(cmd, sizeof(cmd), |
172 | 999 "SETUP %s RTSP/1.0\r\n" |
1000 "Transport: %s\r\n", | |
0 | 1001 rtsp_st->control_url, transport); |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1002 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
|
1003 char real_res[41], real_csum[9]; |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1004 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
|
1005 real_challenge); |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1006 av_strlcatf(cmd, sizeof(cmd), |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1007 "If-Match: %s\r\n" |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1008 "RealChallenge2: %s, sd=%s\r\n", |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1009 rt->session_id, real_res, real_csum); |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1010 } |
0 | 1011 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
|
1012 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
|
1013 err = 1; |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1014 goto fail; |
3151 | 1015 } else if (reply->status_code != RTSP_STATUS_OK || |
1016 reply->nb_transports != 1) { | |
0 | 1017 err = AVERROR_INVALIDDATA; |
1018 goto fail; | |
1019 } | |
1020 | |
1021 /* XXX: same protocol for all streams is required */ | |
1022 if (i > 0) { | |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
1023 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
|
1024 reply->transports[0].transport != rt->transport) { |
0 | 1025 err = AVERROR_INVALIDDATA; |
1026 goto fail; | |
1027 } | |
1028 } else { | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1029 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
|
1030 rt->transport = reply->transports[0].transport; |
0 | 1031 } |
1032 | |
1033 /* close RTP connection if not choosen */ | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1034 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
|
1035 (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
|
1036 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
|
1037 rtsp_st->rtp_handle = NULL; |
0 | 1038 } |
1039 | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1040 switch(reply->transports[0].lower_transport) { |
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1041 case RTSP_LOWER_TRANSPORT_TCP: |
0 | 1042 rtsp_st->interleaved_min = reply->transports[0].interleaved_min; |
1043 rtsp_st->interleaved_max = reply->transports[0].interleaved_max; | |
1044 break; | |
885 | 1045 |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1046 case RTSP_LOWER_TRANSPORT_UDP: |
0 | 1047 { |
1048 char url[1024]; | |
885 | 1049 |
0 | 1050 /* XXX: also use address if specified */ |
885 | 1051 snprintf(url, sizeof(url), "rtp://%s:%d", |
0 | 1052 host, reply->transports[0].server_port_min); |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1053 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
|
1054 rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) { |
0 | 1055 err = AVERROR_INVALIDDATA; |
1056 goto fail; | |
1057 } | |
1058 } | |
1059 break; | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1060 case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: |
0 | 1061 { |
1062 char url[1024]; | |
2246
6dade35dc9b3
rtsp multicast fix by Thijs Vermeir $1$2@gmail.com
lu_zero
parents:
2222
diff
changeset
|
1063 struct in_addr in; |
0 | 1064 |
2246
6dade35dc9b3
rtsp multicast fix by Thijs Vermeir $1$2@gmail.com
lu_zero
parents:
2222
diff
changeset
|
1065 in.s_addr = htonl(reply->transports[0].destination); |
3221 | 1066 snprintf(url, sizeof(url), "rtp://%s:%d?ttl=%d", |
2246
6dade35dc9b3
rtsp multicast fix by Thijs Vermeir $1$2@gmail.com
lu_zero
parents:
2222
diff
changeset
|
1067 inet_ntoa(in), |
6dade35dc9b3
rtsp multicast fix by Thijs Vermeir $1$2@gmail.com
lu_zero
parents:
2222
diff
changeset
|
1068 reply->transports[0].port_min, |
6dade35dc9b3
rtsp multicast fix by Thijs Vermeir $1$2@gmail.com
lu_zero
parents:
2222
diff
changeset
|
1069 reply->transports[0].ttl); |
1425
00d9393a126f
make ffmpeg able to send back a RTCP receiver report.
gpoirier
parents:
1424
diff
changeset
|
1070 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { |
0 | 1071 err = AVERROR_INVALIDDATA; |
1072 goto fail; | |
1073 } | |
1074 } | |
1075 break; | |
1076 } | |
774 | 1077 |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
1078 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
|
1079 goto fail; |
0 | 1080 } |
1081 | |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1082 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
|
1083 rt->need_subscription = 1; |
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1084 |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1085 return 0; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1086 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1087 fail: |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1088 for (i=0; i<rt->nb_rtsp_streams; i++) { |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1089 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
|
1090 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
|
1091 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
|
1092 } |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1093 } |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1094 return err; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1095 } |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1096 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1097 static int rtsp_read_header(AVFormatContext *s, |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1098 AVFormatParameters *ap) |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1099 { |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1100 RTSPState *rt = s->priv_data; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1101 char host[1024], path[1024], tcpname[1024], cmd[2048], *option_list, *option; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1102 URLContext *rtsp_hd; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1103 int port, ret, err; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1104 RTSPMessageHeader reply1, *reply = &reply1; |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1105 unsigned char *content = NULL; |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1106 int lower_transport_mask = 0; |
3856 | 1107 char real_challenge[64]; |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1108 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1109 /* extract hostname and port */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1110 url_split(NULL, 0, NULL, 0, |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1111 host, sizeof(host), &port, path, sizeof(path), s->filename); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1112 if (port < 0) |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1113 port = RTSP_DEFAULT_PORT; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1114 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1115 /* search for options */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1116 option_list = strchr(path, '?'); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1117 if (option_list) { |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1118 /* remove the options from the path */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1119 *option_list++ = 0; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1120 while(option_list) { |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1121 /* move the option pointer */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1122 option = option_list; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1123 option_list = strchr(option_list, '&'); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1124 if (option_list) |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1125 *(option_list++) = 0; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1126 /* handle the options */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1127 if (strcmp(option, "udp") == 0) |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1128 lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_UDP); |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1129 else if (strcmp(option, "multicast") == 0) |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1130 lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_UDP_MULTICAST); |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1131 else if (strcmp(option, "tcp") == 0) |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1132 lower_transport_mask = (1<< RTSP_LOWER_TRANSPORT_TCP); |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1133 } |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1134 } |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1135 |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1136 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
|
1137 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
|
1138 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1139 /* open the tcp connexion */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1140 snprintf(tcpname, sizeof(tcpname), "tcp://%s:%d", host, port); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1141 if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0) |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1142 return AVERROR(EIO); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1143 rt->rtsp_hd = rtsp_hd; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1144 rt->seq = 0; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1145 |
3856 | 1146 /* request options supported by the server; this also detects server type */ |
1147 for (rt->server_type = RTSP_SERVER_RTP;;) { | |
1148 snprintf(cmd, sizeof(cmd), | |
1149 "OPTIONS %s RTSP/1.0\r\n", s->filename); | |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1150 if (rt->server_type == RTSP_SERVER_REAL) |
3856 | 1151 av_strlcat(cmd, |
1152 /** | |
1153 * The following entries are required for proper | |
1154 * streaming from a Realmedia server. They are | |
1155 * interdependent in some way although we currently | |
1156 * don't quite understand how. Values were copied | |
1157 * from mplayer SVN r23589. | |
1158 * @param CompanyID is a 16-byte ID in base64 | |
1159 * @param ClientChallenge is a 16-byte ID in hex | |
1160 */ | |
1161 "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n" | |
1162 "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n" | |
1163 "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n" | |
1164 "GUID: 00000000-0000-0000-0000-000000000000\r\n", | |
1165 sizeof(cmd)); | |
1166 rtsp_send_cmd(s, cmd, reply, NULL); | |
1167 if (reply->status_code != RTSP_STATUS_OK) { | |
1168 err = AVERROR_INVALIDDATA; | |
1169 goto fail; | |
1170 } | |
1171 | |
1172 /* 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
|
1173 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
|
1174 rt->server_type = RTSP_SERVER_REAL; |
3856 | 1175 continue; |
4169
619845a9bab3
Use the "server" RTSP field to detect whether the server that we're talking
rbultje
parents:
4168
diff
changeset
|
1176 } 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
|
1177 rt->server_type = RTSP_SERVER_WMS; |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1178 } else if (rt->server_type == RTSP_SERVER_REAL) { |
3856 | 1179 strcpy(real_challenge, reply->real_challenge); |
1180 } | |
1181 break; | |
1182 } | |
1183 | |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1184 /* describe the stream */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1185 snprintf(cmd, sizeof(cmd), |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1186 "DESCRIBE %s RTSP/1.0\r\n" |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1187 "Accept: application/sdp\r\n", |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1188 s->filename); |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1189 if (rt->server_type == RTSP_SERVER_REAL) { |
3859 | 1190 /** |
1191 * The Require: attribute is needed for proper streaming from | |
1192 * Realmedia servers. | |
1193 */ | |
1194 av_strlcat(cmd, | |
1195 "Require: com.real.retain-entity-for-setup\r\n", | |
1196 sizeof(cmd)); | |
1197 } | |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1198 rtsp_send_cmd(s, cmd, reply, &content); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1199 if (!content) { |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1200 err = AVERROR_INVALIDDATA; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1201 goto fail; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1202 } |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1203 if (reply->status_code != RTSP_STATUS_OK) { |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1204 err = AVERROR_INVALIDDATA; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1205 goto fail; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1206 } |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1207 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1208 /* now we got the SDP description, we parse it */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1209 ret = sdp_parse(s, (const char *)content); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1210 av_freep(&content); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1211 if (ret < 0) { |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1212 err = AVERROR_INVALIDDATA; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1213 goto fail; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1214 } |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1215 |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1216 do { |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1217 int lower_transport = ff_log2_tab[lower_transport_mask & ~(lower_transport_mask - 1)]; |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1218 |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1219 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
|
1220 rt->server_type == RTSP_SERVER_REAL ? |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1221 real_challenge : NULL); |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1222 if (err < 0) |
3151 | 1223 goto fail; |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1224 lower_transport_mask &= ~(1 << lower_transport); |
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1225 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
|
1226 err = AVERROR(FF_NETERROR(EPROTONOSUPPORT)); |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1227 goto fail; |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1228 } |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1229 } while (err); |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1230 |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1231 rt->state = RTSP_STATE_IDLE; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1232 rt->seek_timestamp = 0; /* default is to start stream at position |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1233 zero */ |
1003 | 1234 if (ap->initial_pause) { |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1235 /* do not start immediately */ |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1236 } else { |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1237 if (rtsp_read_play(s) < 0) { |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1238 err = AVERROR_INVALIDDATA; |
0 | 1239 goto fail; |
1240 } | |
1241 } | |
1242 return 0; | |
1243 fail: | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1244 rtsp_close_streams(rt); |
0 | 1245 av_freep(&content); |
1246 url_close(rt->rtsp_hd); | |
1247 return err; | |
1248 } | |
1249 | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1250 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
|
1251 uint8_t *buf, int buf_size) |
0 | 1252 { |
1253 RTSPState *rt = s->priv_data; | |
172 | 1254 int id, len, i, ret; |
0 | 1255 RTSPStream *rtsp_st; |
1256 | |
172 | 1257 #ifdef DEBUG_RTP_TCP |
1258 printf("tcp_read_packet:\n"); | |
1259 #endif | |
0 | 1260 redo: |
1261 for(;;) { | |
391
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
1262 ret = url_readbuf(rt->rtsp_hd, buf, 1); |
172 | 1263 #ifdef DEBUG_RTP_TCP |
1264 printf("ret=%d c=%02x [%c]\n", ret, buf[0], buf[0]); | |
1265 #endif | |
1266 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
|
1267 return -1; |
172 | 1268 if (buf[0] == '$') |
0 | 1269 break; |
1270 } | |
391
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
1271 ret = url_readbuf(rt->rtsp_hd, buf, 3); |
172 | 1272 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
|
1273 return -1; |
172 | 1274 id = buf[0]; |
2222 | 1275 len = AV_RB16(buf + 1); |
172 | 1276 #ifdef DEBUG_RTP_TCP |
1277 printf("id=%d len=%d\n", id, len); | |
1278 #endif | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1279 if (len > buf_size || len < 12) |
0 | 1280 goto redo; |
1281 /* get the data */ | |
391
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
1282 ret = url_readbuf(rt->rtsp_hd, buf, len); |
172 | 1283 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
|
1284 return -1; |
3962
72efef66f566
This patch refactors RDT packet header parsing so that it can be used in
rbultje
parents:
3961
diff
changeset
|
1285 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
|
1286 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
|
1287 return -1; |
885 | 1288 |
0 | 1289 /* find the matching stream */ |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1290 for(i = 0; i < rt->nb_rtsp_streams; i++) { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1291 rtsp_st = rt->rtsp_streams[i]; |
885 | 1292 if (id >= rtsp_st->interleaved_min && |
1293 id <= rtsp_st->interleaved_max) | |
0 | 1294 goto found; |
1295 } | |
1296 goto redo; | |
1297 found: | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1298 *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
|
1299 return len; |
0 | 1300 } |
1301 | |
885 | 1302 static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1303 uint8_t *buf, int buf_size) |
0 | 1304 { |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1305 RTSPState *rt = s->priv_data; |
0 | 1306 RTSPStream *rtsp_st; |
1307 fd_set rfds; | |
1308 int fd1, fd2, fd_max, n, i, ret; | |
1309 struct timeval tv; | |
1310 | |
1311 for(;;) { | |
179 | 1312 if (url_interrupt_cb()) |
2772
b43dc2901f83
Make av_read_frame with rtsp client return EINTR on interrupt
lu_zero
parents:
2771
diff
changeset
|
1313 return AVERROR(EINTR); |
0 | 1314 FD_ZERO(&rfds); |
1315 fd_max = -1; | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1316 for(i = 0; i < rt->nb_rtsp_streams; i++) { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1317 rtsp_st = rt->rtsp_streams[i]; |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1318 if (rtsp_st->rtp_handle) { |
0 | 1319 /* currently, we cannot probe RTCP handle because of blocking restrictions */ |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1320 rtp_get_file_handles(rtsp_st->rtp_handle, &fd1, &fd2); |
0 | 1321 if (fd1 > fd_max) |
1322 fd_max = fd1; | |
1323 FD_SET(fd1, &rfds); | |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1324 } |
0 | 1325 } |
1326 tv.tv_sec = 0; | |
179 | 1327 tv.tv_usec = 100 * 1000; |
0 | 1328 n = select(fd_max + 1, &rfds, NULL, NULL, &tv); |
1329 if (n > 0) { | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1330 for(i = 0; i < rt->nb_rtsp_streams; i++) { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1331 rtsp_st = rt->rtsp_streams[i]; |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1332 if (rtsp_st->rtp_handle) { |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1333 rtp_get_file_handles(rtsp_st->rtp_handle, &fd1, &fd2); |
0 | 1334 if (FD_ISSET(fd1, &rfds)) { |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1335 ret = url_read(rtsp_st->rtp_handle, buf, buf_size); |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1336 if (ret > 0) { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1337 *prtsp_st = rtsp_st; |
0 | 1338 return ret; |
1339 } | |
1340 } | |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
1341 } |
0 | 1342 } |
1343 } | |
1344 } | |
1345 } | |
1346 | |
1347 static int rtsp_read_packet(AVFormatContext *s, | |
1348 AVPacket *pkt) | |
1349 { | |
1350 RTSPState *rt = s->priv_data; | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1351 RTSPStream *rtsp_st; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1352 int ret, len; |
4182
313d987dd2b4
Increase buffer size for RTP packet data because some ASF streams use a
rbultje
parents:
4169
diff
changeset
|
1353 uint8_t buf[10 * RTP_MAX_PACKET_LENGTH]; |
0 | 1354 |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1355 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
|
1356 int i; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1357 RTSPMessageHeader reply1, *reply = &reply1; |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1358 enum AVDiscard cache[MAX_STREAMS]; |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1359 char cmd[1024]; |
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1360 |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1361 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
|
1362 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
|
1363 |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1364 if (!rt->need_subscription) { |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1365 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
|
1366 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
|
1367 av_strlcatf(cmd, sizeof(cmd), |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1368 "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
|
1369 "Unsubscribe: %s\r\n", |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1370 s->filename, rt->last_subscription); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1371 rtsp_send_cmd(s, cmd, reply, NULL); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1372 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
|
1373 return AVERROR_INVALIDDATA; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1374 rt->need_subscription = 1; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1375 } |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1376 } |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1377 |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1378 if (rt->need_subscription) { |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1379 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
|
1380 |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1381 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
|
1382 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
|
1383 rt->last_subscription[0] = 0; |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1384 |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1385 snprintf(cmd, sizeof(cmd), |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1386 "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
|
1387 "Subscribe: ", |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1388 s->filename); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1389 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
|
1390 rule_nr = 0; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1391 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
|
1392 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
|
1393 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
|
1394 if (!first) |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1395 av_strlcat(rt->last_subscription, ",", |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1396 sizeof(rt->last_subscription)); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1397 ff_rdt_subscribe_rule( |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1398 rt->last_subscription, |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1399 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
|
1400 first = 0; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1401 } |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1402 rule_nr++; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1403 } |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1404 } |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1405 } |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1406 av_strlcatf(cmd, sizeof(cmd), "%s\r\n", rt->last_subscription); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1407 rtsp_send_cmd(s, cmd, reply, NULL); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1408 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
|
1409 return AVERROR_INVALIDDATA; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1410 rt->need_subscription = 0; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1411 |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1412 if (rt->state == RTSP_STATE_PLAYING) |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1413 rtsp_read_play (s); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1414 } |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1415 } |
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1416 |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1417 /* get next frames from the same RTP packet */ |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1418 if (rt->cur_transport_priv) { |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
1419 if (rt->transport == RTSP_TRANSPORT_RDT) |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1420 ret = ff_rdt_parse_packet(rt->cur_transport_priv, pkt, NULL, 0); |
3905
91987686113d
Implement RDT-specific data parsing routines. After these changes, simple
rbultje
parents:
3904
diff
changeset
|
1421 else |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1422 ret = rtp_parse_packet(rt->cur_transport_priv, pkt, NULL, 0); |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1423 if (ret == 0) { |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1424 rt->cur_transport_priv = NULL; |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1425 return 0; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1426 } else if (ret == 1) { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1427 return 0; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1428 } else { |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1429 rt->cur_transport_priv = NULL; |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1430 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1431 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1432 |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1433 /* read next RTP packet */ |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1434 redo: |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1435 switch(rt->lower_transport) { |
0 | 1436 default: |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1437 case RTSP_LOWER_TRANSPORT_TCP: |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1438 len = tcp_read_packet(s, &rtsp_st, buf, sizeof(buf)); |
0 | 1439 break; |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1440 case RTSP_LOWER_TRANSPORT_UDP: |
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1441 case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1442 len = udp_read_packet(s, &rtsp_st, buf, sizeof(buf)); |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1443 if (len >=0 && rtsp_st->transport_priv && rt->transport == RTSP_TRANSPORT_RTP) |
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1444 rtp_check_and_send_back_rr(rtsp_st->transport_priv, len); |
0 | 1445 break; |
1446 } | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1447 if (len < 0) |
2775
1301147d9450
Make av_read_frame with rtsp client return EINTR on interrupt
lu_zero
parents:
2772
diff
changeset
|
1448 return len; |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
1449 if (rt->transport == RTSP_TRANSPORT_RDT) |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1450 ret = ff_rdt_parse_packet(rtsp_st->transport_priv, pkt, buf, len); |
3905
91987686113d
Implement RDT-specific data parsing routines. After these changes, simple
rbultje
parents:
3904
diff
changeset
|
1451 else |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1452 ret = rtp_parse_packet(rtsp_st->transport_priv, pkt, buf, len); |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1453 if (ret < 0) |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1454 goto redo; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1455 if (ret == 1) { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1456 /* more packets may follow, so we save the RTP context */ |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1457 rt->cur_transport_priv = rtsp_st->transport_priv; |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1458 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1459 return 0; |
0 | 1460 } |
1461 | |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1462 static int rtsp_read_play(AVFormatContext *s) |
179 | 1463 { |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1464 RTSPState *rt = s->priv_data; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1465 RTSPMessageHeader reply1, *reply = &reply1; |
179 | 1466 char cmd[1024]; |
1467 | |
370
845f9de2c883
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
304
diff
changeset
|
1468 av_log(s, AV_LOG_DEBUG, "hello state=%d\n", rt->state); |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1469 |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1470 if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { |
3904 | 1471 if (rt->state == RTSP_STATE_PAUSED) { |
1472 snprintf(cmd, sizeof(cmd), | |
1473 "PLAY %s RTSP/1.0\r\n", | |
1474 s->filename); | |
1475 } else { | |
1476 snprintf(cmd, sizeof(cmd), | |
1477 "PLAY %s RTSP/1.0\r\n" | |
1478 "Range: npt=%0.3f-\r\n", | |
1479 s->filename, | |
1480 (double)rt->seek_timestamp / AV_TIME_BASE); | |
1481 } | |
1482 rtsp_send_cmd(s, cmd, reply, NULL); | |
1483 if (reply->status_code != RTSP_STATUS_OK) { | |
1484 return -1; | |
1485 } | |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1486 } |
3861
a0098594ab90
Remove useless "else" case in if X { A; return }; else { B }. See discussion
rbultje
parents:
3860
diff
changeset
|
1487 rt->state = RTSP_STATE_PLAYING; |
a0098594ab90
Remove useless "else" case in if X { A; return }; else { B }. See discussion
rbultje
parents:
3860
diff
changeset
|
1488 return 0; |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1489 } |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1490 |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1491 /* pause the stream */ |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1492 static int rtsp_read_pause(AVFormatContext *s) |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1493 { |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1494 RTSPState *rt = s->priv_data; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1495 RTSPMessageHeader reply1, *reply = &reply1; |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1496 char cmd[1024]; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1497 |
179 | 1498 rt = s->priv_data; |
885 | 1499 |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1500 if (rt->state != RTSP_STATE_PLAYING) |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1501 return 0; |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1502 else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { |
3904 | 1503 snprintf(cmd, sizeof(cmd), |
1504 "PAUSE %s RTSP/1.0\r\n", | |
1505 s->filename); | |
1506 rtsp_send_cmd(s, cmd, reply, NULL); | |
1507 if (reply->status_code != RTSP_STATUS_OK) { | |
1508 return -1; | |
1509 } | |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1510 } |
3861
a0098594ab90
Remove useless "else" case in if X { A; return }; else { B }. See discussion
rbultje
parents:
3860
diff
changeset
|
1511 rt->state = RTSP_STATE_PAUSED; |
a0098594ab90
Remove useless "else" case in if X { A; return }; else { B }. See discussion
rbultje
parents:
3860
diff
changeset
|
1512 return 0; |
179 | 1513 } |
1514 | |
885 | 1515 static int rtsp_read_seek(AVFormatContext *s, int stream_index, |
558 | 1516 int64_t timestamp, int flags) |
179 | 1517 { |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1518 RTSPState *rt = s->priv_data; |
885 | 1519 |
2408 | 1520 rt->seek_timestamp = av_rescale_q(timestamp, s->streams[stream_index]->time_base, AV_TIME_BASE_Q); |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1521 switch(rt->state) { |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1522 default: |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1523 case RTSP_STATE_IDLE: |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1524 break; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1525 case RTSP_STATE_PLAYING: |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1526 if (rtsp_read_play(s) != 0) |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1527 return -1; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1528 break; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1529 case RTSP_STATE_PAUSED: |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1530 rt->state = RTSP_STATE_IDLE; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1531 break; |
179 | 1532 } |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1533 return 0; |
179 | 1534 } |
1535 | |
0 | 1536 static int rtsp_read_close(AVFormatContext *s) |
1537 { | |
1538 RTSPState *rt = s->priv_data; | |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1539 RTSPMessageHeader reply1, *reply = &reply1; |
0 | 1540 char cmd[1024]; |
1541 | |
172 | 1542 #if 0 |
0 | 1543 /* 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
|
1544 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) { |
0 | 1545 url_fclose(&rt->rtsp_gb); |
1546 } | |
172 | 1547 #endif |
885 | 1548 snprintf(cmd, sizeof(cmd), |
172 | 1549 "TEARDOWN %s RTSP/1.0\r\n", |
0 | 1550 s->filename); |
1551 rtsp_send_cmd(s, cmd, reply, NULL); | |
1552 | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1553 rtsp_close_streams(rt); |
0 | 1554 url_close(rt->rtsp_hd); |
1555 return 0; | |
1556 } | |
1557 | |
4206 | 1558 #if CONFIG_RTSP_DEMUXER |
1167 | 1559 AVInputFormat rtsp_demuxer = { |
0 | 1560 "rtsp", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3286
diff
changeset
|
1561 NULL_IF_CONFIG_SMALL("RTSP input format"), |
0 | 1562 sizeof(RTSPState), |
1563 rtsp_probe, | |
1564 rtsp_read_header, | |
1565 rtsp_read_packet, | |
1566 rtsp_read_close, | |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1567 rtsp_read_seek, |
0 | 1568 .flags = AVFMT_NOFILE, |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1569 .read_play = rtsp_read_play, |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1570 .read_pause = rtsp_read_pause, |
0 | 1571 }; |
2054 | 1572 #endif |
0 | 1573 |
1574 static int sdp_probe(AVProbeData *p1) | |
1575 { | |
706
fc254f396f15
buffer overflow in sdp_probe() fix by (Gildas Bazin )gbazin altern org)
michael
parents:
587
diff
changeset
|
1576 const char *p = p1->buf, *p_end = p1->buf + p1->buf_size; |
0 | 1577 |
1578 /* 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
|
1579 while (p < p_end && *p != '\0') { |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
1580 if (p + sizeof("c=IN IP4") - 1 < p_end && av_strstart(p, "c=IN IP4", NULL)) |
0 | 1581 return AVPROBE_SCORE_MAX / 2; |
706
fc254f396f15
buffer overflow in sdp_probe() fix by (Gildas Bazin )gbazin altern org)
michael
parents:
587
diff
changeset
|
1582 |
fc254f396f15
buffer overflow in sdp_probe() fix by (Gildas Bazin )gbazin altern org)
michael
parents:
587
diff
changeset
|
1583 while(p < p_end - 1 && *p != '\n') p++; |
fc254f396f15
buffer overflow in sdp_probe() fix by (Gildas Bazin )gbazin altern org)
michael
parents:
587
diff
changeset
|
1584 if (++p >= p_end) |
0 | 1585 break; |
1586 if (*p == '\r') | |
1587 p++; | |
1588 } | |
1589 return 0; | |
1590 } | |
1591 | |
1592 #define SDP_MAX_SIZE 8192 | |
1593 | |
1594 static int sdp_read_header(AVFormatContext *s, | |
1595 AVFormatParameters *ap) | |
1596 { | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1597 RTSPState *rt = s->priv_data; |
0 | 1598 RTSPStream *rtsp_st; |
1599 int size, i, err; | |
1600 char *content; | |
1601 char url[1024]; | |
1602 | |
1603 /* read the whole sdp file */ | |
1604 /* XXX: better loading */ | |
1605 content = av_malloc(SDP_MAX_SIZE); | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2759
diff
changeset
|
1606 size = get_buffer(s->pb, content, SDP_MAX_SIZE - 1); |
0 | 1607 if (size <= 0) { |
1608 av_free(content); | |
1609 return AVERROR_INVALIDDATA; | |
1610 } | |
1611 content[size] ='\0'; | |
1612 | |
1613 sdp_parse(s, content); | |
1614 av_free(content); | |
1615 | |
1616 /* open each RTP stream */ | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1617 for(i=0;i<rt->nb_rtsp_streams;i++) { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1618 rtsp_st = rt->rtsp_streams[i]; |
885 | 1619 |
3222 | 1620 snprintf(url, sizeof(url), "rtp://%s:%d?localport=%d&ttl=%d", |
885 | 1621 inet_ntoa(rtsp_st->sdp_ip), |
0 | 1622 rtsp_st->sdp_port, |
3222 | 1623 rtsp_st->sdp_port, |
0 | 1624 rtsp_st->sdp_ttl); |
1425
00d9393a126f
make ffmpeg able to send back a RTCP receiver report.
gpoirier
parents:
1424
diff
changeset
|
1625 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { |
0 | 1626 err = AVERROR_INVALIDDATA; |
1627 goto fail; | |
1628 } | |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
1629 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
|
1630 goto fail; |
0 | 1631 } |
1632 return 0; | |
1633 fail: | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1634 rtsp_close_streams(rt); |
0 | 1635 return err; |
1636 } | |
1637 | |
1638 static int sdp_read_packet(AVFormatContext *s, | |
1639 AVPacket *pkt) | |
1640 { | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1641 return rtsp_read_packet(s, pkt); |
0 | 1642 } |
1643 | |
1644 static int sdp_read_close(AVFormatContext *s) | |
1645 { | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1646 RTSPState *rt = s->priv_data; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1647 rtsp_close_streams(rt); |
0 | 1648 return 0; |
1649 } | |
1650 | |
4206 | 1651 #if CONFIG_SDP_DEMUXER |
1169 | 1652 AVInputFormat sdp_demuxer = { |
0 | 1653 "sdp", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3286
diff
changeset
|
1654 NULL_IF_CONFIG_SMALL("SDP"), |
0 | 1655 sizeof(RTSPState), |
1656 sdp_probe, | |
1657 sdp_read_header, | |
1658 sdp_read_packet, | |
1659 sdp_read_close, | |
1660 }; | |
1169 | 1661 #endif |
0 | 1662 |
4206 | 1663 #if CONFIG_REDIR_DEMUXER |
0 | 1664 /* dummy redirector format (used directly in av_open_input_file now) */ |
1665 static int redir_probe(AVProbeData *pd) | |
1666 { | |
1667 const char *p; | |
1668 p = pd->buf; | |
1669 while (redir_isspace(*p)) | |
1670 p++; | |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
1671 if (av_strstart(p, "http://", NULL) || |
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
1672 av_strstart(p, "rtsp://", NULL)) |
0 | 1673 return AVPROBE_SCORE_MAX; |
1674 return 0; | |
1675 } | |
1676 | |
2785
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1677 static int redir_read_header(AVFormatContext *s, AVFormatParameters *ap) |
0 | 1678 { |
1679 char buf[4096], *q; | |
1680 int c; | |
1681 AVFormatContext *ic = NULL; | |
2785
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1682 ByteIOContext *f = s->pb; |
0 | 1683 |
1684 /* parse each URL and try to open it */ | |
1685 c = url_fgetc(f); | |
1686 while (c != URL_EOF) { | |
1687 /* skip spaces */ | |
1688 for(;;) { | |
1689 if (!redir_isspace(c)) | |
1690 break; | |
1691 c = url_fgetc(f); | |
1692 } | |
1693 if (c == URL_EOF) | |
1694 break; | |
1695 /* record url */ | |
1696 q = buf; | |
1697 for(;;) { | |
1698 if (c == URL_EOF || redir_isspace(c)) | |
1699 break; | |
1700 if ((q - buf) < sizeof(buf) - 1) | |
1701 *q++ = c; | |
1702 c = url_fgetc(f); | |
1703 } | |
1704 *q = '\0'; | |
1705 //printf("URL='%s'\n", buf); | |
1706 /* try to open the media file */ | |
1707 if (av_open_input_file(&ic, buf, NULL, 0, NULL) == 0) | |
1708 break; | |
1709 } | |
1710 if (!ic) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
1711 return AVERROR(EIO); |
2785
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1712 |
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1713 *s = *ic; |
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1714 url_fclose(f); |
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1715 |
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1716 return 0; |
0 | 1717 } |
1718 | |
1167 | 1719 AVInputFormat redir_demuxer = { |
0 | 1720 "redir", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3286
diff
changeset
|
1721 NULL_IF_CONFIG_SMALL("Redirector format"), |
0 | 1722 0, |
1723 redir_probe, | |
2785
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1724 redir_read_header, |
0 | 1725 NULL, |
1726 NULL, | |
1727 }; | |
2053 | 1728 #endif |