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