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