Mercurial > libavformat.hg
annotate rtsp.c @ 4874:5370b0c1653c libavformat
Increase the SDP buffer size (again!) and also increase the temporary
buffer size of the fmtp parameter buffer. For Vorbis RT(S)P, these
contain full Vorbis headers, which can be up to 12kb each, formatted
in base64, so 16kb total. Patch required for proper Vorbis/RTP playback,
submitted as GSoC qualification task in the thread "RTP/Vorbis payload
implementation (GSoC qual task)" by Colin McQuillan m.niloc googlemail
com.
author | rbultje |
---|---|
date | Tue, 14 Apr 2009 13:22:40 +0000 |
parents | c18ea19a9771 |
children | 13a2a1a475d5 |
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]; | |
4874
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
264 /* Vorbis setup headers can be up to 12KB and are sent base64 |
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
265 * encoded, giving a 12KB * (4/3) = 16KB FMTP line. */ |
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
266 char value[16384]; |
774 | 267 int i; |
268 | |
269 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
|
270 AVCodecContext *codec = st->codec; |
4101
af2c0aef892b
Rename rtp_payload_data_t to avoid clashes with the POSIX namespace
lucabe
parents:
4088
diff
changeset
|
271 RTPPayloadData *rtp_payload_data = &rtsp_st->rtp_payload_data; |
0 | 272 |
273 /* loop on each attribute */ | |
1514
958decd51c1f
remove duplicate code, patch by Ryan Martell rdm4 A martellventures P com
gpoirier
parents:
1472
diff
changeset
|
274 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
|
275 { |
887 | 276 /* grab the codec extra_data from the config parameter of the fmtp line */ |
774 | 277 sdp_parse_fmtp_config(codec, attr, value); |
278 /* Looking for a known attribute */ | |
279 for (i = 0; attr_names[i].str; ++i) { | |
280 if (!strcasecmp(attr, attr_names[i].str)) { | |
281 if (attr_names[i].type == ATTR_NAME_TYPE_INT) | |
282 *(int *)((char *)rtp_payload_data + attr_names[i].offset) = atoi(value); | |
283 else if (attr_names[i].type == ATTR_NAME_TYPE_STR) | |
284 *(char **)((char *)rtp_payload_data + attr_names[i].offset) = av_strdup(value); | |
887 | 285 } |
0 | 286 } |
287 } | |
288 } | |
289 | |
1453
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
290 /** 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
|
291 * and end time. |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
292 * 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
|
293 */ |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
294 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
|
295 { |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
296 char buf[256]; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
297 |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
298 skip_spaces(&p); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
299 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
|
300 return; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
301 |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
302 *start = AV_NOPTS_VALUE; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
303 *end = AV_NOPTS_VALUE; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
304 |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
305 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
|
306 *start = parse_date(buf, 1); |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
307 if (*p == '-') { |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
308 p++; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
309 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
|
310 *end = parse_date(buf, 1); |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
311 } |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
312 // 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
|
313 // 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
|
314 } |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
315 |
0 | 316 typedef struct SDPParseState { |
317 /* SDP only */ | |
318 struct in_addr default_ip; | |
319 int default_ttl; | |
4281
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
320 int skip_media; ///< set if an unknown m= line occurs |
0 | 321 } SDPParseState; |
322 | |
323 static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, | |
324 int letter, const char *buf) | |
325 { | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
326 RTSPState *rt = s->priv_data; |
0 | 327 char buf1[64], st_type[64]; |
328 const char *p; | |
3967 | 329 enum CodecType codec_type; |
330 int payload_type, i; | |
0 | 331 AVStream *st; |
332 RTSPStream *rtsp_st; | |
333 struct in_addr sdp_ip; | |
334 int ttl; | |
335 | |
336 #ifdef DEBUG | |
337 printf("sdp: %c='%s'\n", letter, buf); | |
338 #endif | |
339 | |
340 p = buf; | |
4281
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
341 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
|
342 return; |
0 | 343 switch(letter) { |
344 case 'c': | |
345 get_word(buf1, sizeof(buf1), &p); | |
346 if (strcmp(buf1, "IN") != 0) | |
347 return; | |
348 get_word(buf1, sizeof(buf1), &p); | |
349 if (strcmp(buf1, "IP4") != 0) | |
350 return; | |
351 get_word_sep(buf1, sizeof(buf1), "/", &p); | |
352 if (inet_aton(buf1, &sdp_ip) == 0) | |
353 return; | |
354 ttl = 16; | |
355 if (*p == '/') { | |
356 p++; | |
357 get_word_sep(buf1, sizeof(buf1), "/", &p); | |
358 ttl = atoi(buf1); | |
359 } | |
360 if (s->nb_streams == 0) { | |
361 s1->default_ip = sdp_ip; | |
362 s1->default_ttl = ttl; | |
363 } else { | |
364 st = s->streams[s->nb_streams - 1]; | |
365 rtsp_st = st->priv_data; | |
366 rtsp_st->sdp_ip = sdp_ip; | |
367 rtsp_st->sdp_ttl = ttl; | |
368 } | |
369 break; | |
370 case 's': | |
4361 | 371 av_metadata_set(&s->metadata, "title", p); |
0 | 372 break; |
373 case 'i': | |
374 if (s->nb_streams == 0) { | |
4361 | 375 av_metadata_set(&s->metadata, "comment", p); |
0 | 376 break; |
377 } | |
378 break; | |
379 case 'm': | |
380 /* new stream */ | |
4281
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
381 s1->skip_media = 0; |
0 | 382 get_word(st_type, sizeof(st_type), &p); |
383 if (!strcmp(st_type, "audio")) { | |
384 codec_type = CODEC_TYPE_AUDIO; | |
385 } else if (!strcmp(st_type, "video")) { | |
386 codec_type = CODEC_TYPE_VIDEO; | |
4637
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
387 } else if (!strcmp(st_type, "application")) { |
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
388 codec_type = CODEC_TYPE_DATA; |
0 | 389 } else { |
4281
f1d8951d6813
Skip m= blocks in the SDP if the media type is unknown. This prevents
rbultje
parents:
4251
diff
changeset
|
390 s1->skip_media = 1; |
0 | 391 return; |
392 } | |
393 rtsp_st = av_mallocz(sizeof(RTSPStream)); | |
394 if (!rtsp_st) | |
395 return; | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
396 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
|
397 dynarray_add(&rt->rtsp_streams, &rt->nb_rtsp_streams, rtsp_st); |
0 | 398 |
399 rtsp_st->sdp_ip = s1->default_ip; | |
400 rtsp_st->sdp_ttl = s1->default_ttl; | |
401 | |
402 get_word(buf1, sizeof(buf1), &p); /* port */ | |
403 rtsp_st->sdp_port = atoi(buf1); | |
404 | |
405 get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */ | |
885 | 406 |
0 | 407 /* XXX: handle list of formats */ |
408 get_word(buf1, sizeof(buf1), &p); /* format list */ | |
409 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
|
410 |
2759
b252e318023a
Remove the "AVRtpPayloadTypes[i].pt == i" assumption from RTP and RTSP
lucabe
parents:
2711
diff
changeset
|
411 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
|
412 /* 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
|
413 } else { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
414 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
|
415 if (!st) |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
416 return; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
417 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
|
418 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
|
419 st->codec->codec_type = codec_type; |
774 | 420 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
|
421 /* 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
|
422 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
|
423 } |
0 | 424 } |
425 /* put a default control url */ | |
2189 | 426 av_strlcpy(rtsp_st->control_url, s->filename, sizeof(rtsp_st->control_url)); |
0 | 427 break; |
428 case 'a': | |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
429 if (av_strstart(p, "control:", &p) && s->nb_streams > 0) { |
0 | 430 char proto[32]; |
431 /* get the control url */ | |
432 st = s->streams[s->nb_streams - 1]; | |
433 rtsp_st = st->priv_data; | |
885 | 434 |
0 | 435 /* 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
|
436 url_split(proto, sizeof(proto), NULL, 0, NULL, 0, NULL, NULL, 0, p); |
0 | 437 if (proto[0] == '\0') { |
438 /* relative control URL */ | |
2189 | 439 av_strlcat(rtsp_st->control_url, "/", sizeof(rtsp_st->control_url)); |
440 av_strlcat(rtsp_st->control_url, p, sizeof(rtsp_st->control_url)); | |
0 | 441 } else { |
2189 | 442 av_strlcpy(rtsp_st->control_url, p, sizeof(rtsp_st->control_url)); |
0 | 443 } |
4185
023976c45ae1
Apply rtpmap: SDP lines to the last m= line only, since they generally just
rbultje
parents:
4182
diff
changeset
|
444 } else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) { |
0 | 445 /* NOTE: rtpmap is only supported AFTER the 'm=' tag */ |
885 | 446 get_word(buf1, sizeof(buf1), &p); |
0 | 447 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
|
448 st = s->streams[s->nb_streams - 1]; |
4186 | 449 rtsp_st = st->priv_data; |
450 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
|
451 } else if (av_strstart(p, "fmtp:", &p)) { |
0 | 452 /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */ |
885 | 453 get_word(buf1, sizeof(buf1), &p); |
0 | 454 payload_type = atoi(buf1); |
455 for(i = 0; i < s->nb_streams;i++) { | |
456 st = s->streams[i]; | |
457 rtsp_st = st->priv_data; | |
458 if (rtsp_st->sdp_payload_type == payload_type) { | |
1419 | 459 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
|
460 if(!rtsp_st->dynamic_handler->parse_sdp_a_line(s, i, rtsp_st->dynamic_protocol_context, buf)) { |
1419 | 461 sdp_parse_fmtp(st, p); |
462 } | |
463 } else { | |
1424
1c39ce5c6a5d
indentation fix, patch by Ryan Martell % rdm4 A martellventures P com %
gpoirier
parents:
1419
diff
changeset
|
464 sdp_parse_fmtp(st, p); |
1419 | 465 } |
0 | 466 } |
467 } | |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
468 } else if(av_strstart(p, "framesize:", &p)) { |
1431
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
469 // 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
|
470 get_word(buf1, sizeof(buf1), &p); |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
471 payload_type = atoi(buf1); |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
472 for(i = 0; i < s->nb_streams;i++) { |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
473 st = s->streams[i]; |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
474 rtsp_st = st->priv_data; |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
475 if (rtsp_st->sdp_payload_type == payload_type) { |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
476 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
|
477 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
|
478 } |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
479 } |
2d8a17631520
fix more dynamic protocol stuff, needed by the forthcoming h264
gpoirier
parents:
1425
diff
changeset
|
480 } |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
481 } 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
|
482 int64_t start, end; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
483 |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
484 // 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
|
485 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
|
486 s->start_time= start; |
c0235bab9e92
Add support for getting duration of a RTP stream (for seeking in stream)
gpoirier
parents:
1431
diff
changeset
|
487 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
|
488 } else if (av_strstart(p, "IsRealDataType:integer;",&p)) { |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
489 if (atoi(p) == 1) |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
490 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
|
491 } else { |
51899c07a4f1
Add RTP/ASF header parsing, which is part of the SDP of these streams. See
rbultje
parents:
4667
diff
changeset
|
492 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
|
493 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
|
494 if (s->nb_streams > 0) { |
4745 | 495 if (rt->server_type == RTSP_SERVER_REAL) |
496 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
|
497 |
4745 | 498 rtsp_st = s->streams[s->nb_streams - 1]->priv_data; |
499 if (rtsp_st->dynamic_handler && | |
500 rtsp_st->dynamic_handler->parse_sdp_a_line) | |
501 rtsp_st->dynamic_handler->parse_sdp_a_line(s, s->nb_streams - 1, | |
502 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
|
503 } |
0 | 504 } |
505 break; | |
506 } | |
507 } | |
508 | |
64 | 509 static int sdp_parse(AVFormatContext *s, const char *content) |
0 | 510 { |
511 const char *p; | |
512 int letter; | |
4187 | 513 /* Some SDP lines, particularly for Realmedia or ASF RTSP streams, |
514 * contain long SDP lines containing complete ASF Headers (several | |
515 * kB) or arrays of MDPR (RM stream descriptor) headers plus | |
516 * "rulebooks" describing their properties. Therefore, the SDP line | |
4874
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
517 * buffer is large. |
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
518 * |
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
519 * The Vorbis FMTP line can be up to 16KB - see sdp_parse_fmtp. */ |
5370b0c1653c
Increase the SDP buffer size (again!) and also increase the temporary
rbultje
parents:
4789
diff
changeset
|
520 char buf[16384], *q; |
0 | 521 SDPParseState sdp_parse_state, *s1 = &sdp_parse_state; |
885 | 522 |
0 | 523 memset(s1, 0, sizeof(SDPParseState)); |
524 p = content; | |
525 for(;;) { | |
526 skip_spaces(&p); | |
527 letter = *p; | |
528 if (letter == '\0') | |
529 break; | |
530 p++; | |
531 if (*p != '=') | |
532 goto next_line; | |
533 p++; | |
534 /* get the content */ | |
535 q = buf; | |
172 | 536 while (*p != '\n' && *p != '\r' && *p != '\0') { |
0 | 537 if ((q - buf) < sizeof(buf) - 1) |
538 *q++ = *p; | |
539 p++; | |
540 } | |
541 *q = '\0'; | |
542 sdp_parse_line(s, s1, letter, buf); | |
543 next_line: | |
544 while (*p != '\n' && *p != '\0') | |
545 p++; | |
546 if (*p == '\n') | |
547 p++; | |
548 } | |
549 return 0; | |
550 } | |
551 | |
552 static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp) | |
553 { | |
554 const char *p; | |
555 int v; | |
556 | |
557 p = *pp; | |
558 skip_spaces(&p); | |
559 v = strtol(p, (char **)&p, 10); | |
560 if (*p == '-') { | |
561 p++; | |
562 *min_ptr = v; | |
563 v = strtol(p, (char **)&p, 10); | |
564 *max_ptr = v; | |
565 } else { | |
566 *min_ptr = v; | |
567 *max_ptr = v; | |
568 } | |
569 *pp = p; | |
570 } | |
571 | |
572 /* XXX: only one transport specification is parsed */ | |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
573 static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p) |
0 | 574 { |
575 char transport_protocol[16]; | |
576 char profile[16]; | |
577 char lower_transport[16]; | |
578 char parameter[16]; | |
579 RTSPTransportField *th; | |
580 char buf[256]; | |
885 | 581 |
0 | 582 reply->nb_transports = 0; |
885 | 583 |
0 | 584 for(;;) { |
585 skip_spaces(&p); | |
586 if (*p == '\0') | |
587 break; | |
588 | |
589 th = &reply->transports[reply->nb_transports]; | |
590 | |
885 | 591 get_word_sep(transport_protocol, sizeof(transport_protocol), |
0 | 592 "/", &p); |
2865
51aa1054528c
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 2 x-pn-tng support
lu_zero
parents:
2864
diff
changeset
|
593 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
|
594 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
|
595 lower_transport[0] = '\0'; |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
596 /* rtp/avp/<protocol> */ |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
597 if (*p == '/') { |
ccbca87ccd5e
Real RTSP support, from Ronald S. Bultje rsbultje gmail - part 3 Reindent
lu_zero
parents:
2865
diff
changeset
|
598 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
|
599 ";,", &p); |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
600 } |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
601 th->transport = RTSP_TRANSPORT_RTP; |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
602 } else if (!strcasecmp (transport_protocol, "x-pn-tng") || |
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
603 !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
|
604 /* 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
|
605 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
|
606 profile[0] = '\0'; |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
607 th->transport = RTSP_TRANSPORT_RDT; |
0 | 608 } |
172 | 609 if (!strcasecmp(lower_transport, "TCP")) |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
610 th->lower_transport = RTSP_LOWER_TRANSPORT_TCP; |
0 | 611 else |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
612 th->lower_transport = RTSP_LOWER_TRANSPORT_UDP; |
885 | 613 |
0 | 614 if (*p == ';') |
615 p++; | |
616 /* get each parameter */ | |
617 while (*p != '\0' && *p != ',') { | |
618 get_word_sep(parameter, sizeof(parameter), "=;,", &p); | |
619 if (!strcmp(parameter, "port")) { | |
620 if (*p == '=') { | |
621 p++; | |
622 rtsp_parse_range(&th->port_min, &th->port_max, &p); | |
623 } | |
624 } else if (!strcmp(parameter, "client_port")) { | |
625 if (*p == '=') { | |
626 p++; | |
885 | 627 rtsp_parse_range(&th->client_port_min, |
0 | 628 &th->client_port_max, &p); |
629 } | |
630 } else if (!strcmp(parameter, "server_port")) { | |
631 if (*p == '=') { | |
632 p++; | |
885 | 633 rtsp_parse_range(&th->server_port_min, |
0 | 634 &th->server_port_max, &p); |
635 } | |
636 } else if (!strcmp(parameter, "interleaved")) { | |
637 if (*p == '=') { | |
638 p++; | |
885 | 639 rtsp_parse_range(&th->interleaved_min, |
0 | 640 &th->interleaved_max, &p); |
641 } | |
642 } else if (!strcmp(parameter, "multicast")) { | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
643 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
|
644 th->lower_transport = RTSP_LOWER_TRANSPORT_UDP_MULTICAST; |
0 | 645 } else if (!strcmp(parameter, "ttl")) { |
646 if (*p == '=') { | |
647 p++; | |
648 th->ttl = strtol(p, (char **)&p, 10); | |
649 } | |
650 } else if (!strcmp(parameter, "destination")) { | |
651 struct in_addr ipaddr; | |
652 | |
653 if (*p == '=') { | |
654 p++; | |
655 get_word_sep(buf, sizeof(buf), ";,", &p); | |
885 | 656 if (inet_aton(buf, &ipaddr)) |
0 | 657 th->destination = ntohl(ipaddr.s_addr); |
658 } | |
659 } | |
660 while (*p != ';' && *p != '\0' && *p != ',') | |
661 p++; | |
662 if (*p == ';') | |
663 p++; | |
664 } | |
665 if (*p == ',') | |
666 p++; | |
667 | |
668 reply->nb_transports++; | |
669 } | |
670 } | |
671 | |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
672 void rtsp_parse_line(RTSPMessageHeader *reply, const char *buf) |
0 | 673 { |
674 const char *p; | |
675 | |
676 /* NOTE: we do case independent match for broken servers */ | |
677 p = buf; | |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
678 if (av_stristart(p, "Session:", &p)) { |
0 | 679 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
|
680 } else if (av_stristart(p, "Content-Length:", &p)) { |
0 | 681 reply->content_length = 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, "Transport:", &p)) { |
0 | 683 rtsp_parse_transport(reply, p); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
684 } else if (av_stristart(p, "CSeq:", &p)) { |
0 | 685 reply->seq = strtol(p, NULL, 10); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
686 } 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
|
687 rtsp_parse_range_npt(p, &reply->range_start, &reply->range_end); |
3855 | 688 } else if (av_stristart(p, "RealChallenge1:", &p)) { |
689 skip_spaces(&p); | |
690 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
|
691 } 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
|
692 skip_spaces(&p); |
619845a9bab3
Use the "server" RTSP field to detect whether the server that we're talking
rbultje
parents:
4168
diff
changeset
|
693 av_strlcpy(reply->server, p, sizeof(reply->server)); |
0 | 694 } |
695 } | |
696 | |
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
|
697 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
|
698 { |
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 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
|
700 |
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 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
|
702 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
|
703 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
|
704 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
|
705 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
|
706 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
|
707 } |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
708 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
|
709 } |
1cf22651d33b
support url_read which reads less then requested patch by (Leon van Stuivenberg <l dot vanstuivenberg at chello dot nl>)
michael
parents:
370
diff
changeset
|
710 |
179 | 711 /* skip a RTP/TCP interleaved packet */ |
712 static void rtsp_skip_packet(AVFormatContext *s) | |
713 { | |
714 RTSPState *rt = s->priv_data; | |
715 int ret, len, len1; | |
716 uint8_t buf[1024]; | |
717 | |
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
|
718 ret = url_readbuf(rt->rtsp_hd, buf, 3); |
179 | 719 if (ret != 3) |
720 return; | |
2222 | 721 len = AV_RB16(buf + 1); |
179 | 722 #ifdef DEBUG |
723 printf("skipping RTP packet len=%d\n", len); | |
724 #endif | |
725 /* skip payload */ | |
726 while (len > 0) { | |
727 len1 = len; | |
728 if (len1 > sizeof(buf)) | |
729 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
|
730 ret = url_readbuf(rt->rtsp_hd, buf, len1); |
179 | 731 if (ret != len1) |
732 return; | |
733 len -= len1; | |
734 } | |
735 } | |
0 | 736 |
4772
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 * 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
|
739 * 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
|
740 * connection as well. |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
741 * |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
742 * @param s RTSP demuxer context |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
743 * @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
|
744 * @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
|
745 * be stored (length is in \p reply) |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
746 * @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
|
747 * encounter a data marker ('$'), which precedes data |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
748 * packets over interleaved TCP/RTSP connections. If this |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
749 * 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
|
750 * 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
|
751 * 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
|
752 * 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
|
753 * 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
|
754 * |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
755 * @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
|
756 * and 0 on success. |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
757 */ |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
758 static int |
4644
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
759 rtsp_read_reply (AVFormatContext *s, RTSPMessageHeader *reply, |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
760 unsigned char **content_ptr, int return_on_interleaved_data) |
0 | 761 { |
762 RTSPState *rt = s->priv_data; | |
763 char buf[4096], buf1[1024], *q; | |
764 unsigned char ch; | |
765 const char *p; | |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
766 int ret, content_length, line_count = 0; |
0 | 767 unsigned char *content = NULL; |
768 | |
4549 | 769 memset(reply, 0, sizeof(*reply)); |
0 | 770 |
771 /* parse reply (XXX: use buffers) */ | |
772 rt->last_reply[0] = '\0'; | |
773 for(;;) { | |
774 q = buf; | |
775 for(;;) { | |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
776 ret = url_readbuf(rt->rtsp_hd, &ch, 1); |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
777 #ifdef DEBUG_RTP_TCP |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
778 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
|
779 #endif |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
780 if (ret != 1) |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
781 return -1; |
0 | 782 if (ch == '\n') |
783 break; | |
179 | 784 if (ch == '$') { |
785 /* 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
|
786 if (return_on_interleaved_data) { |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
787 return 1; |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
788 } else |
179 | 789 rtsp_skip_packet(s); |
790 } else if (ch != '\r') { | |
0 | 791 if ((q - buf) < sizeof(buf) - 1) |
792 *q++ = ch; | |
793 } | |
794 } | |
795 *q = '\0'; | |
796 #ifdef DEBUG | |
797 printf("line='%s'\n", buf); | |
798 #endif | |
799 /* test if last line */ | |
800 if (buf[0] == '\0') | |
801 break; | |
802 p = buf; | |
803 if (line_count == 0) { | |
804 /* get reply code */ | |
805 get_word(buf1, sizeof(buf1), &p); | |
806 get_word(buf1, sizeof(buf1), &p); | |
807 reply->status_code = atoi(buf1); | |
808 } else { | |
809 rtsp_parse_line(reply, p); | |
2189 | 810 av_strlcat(rt->last_reply, p, sizeof(rt->last_reply)); |
811 av_strlcat(rt->last_reply, "\n", sizeof(rt->last_reply)); | |
0 | 812 } |
813 line_count++; | |
814 } | |
885 | 815 |
0 | 816 if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0') |
2189 | 817 av_strlcpy(rt->session_id, reply->session_id, sizeof(rt->session_id)); |
885 | 818 |
0 | 819 content_length = reply->content_length; |
820 if (content_length > 0) { | |
821 /* leave some room for a trailing '\0' (useful for simple parsing) */ | |
822 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
|
823 (void)url_readbuf(rt->rtsp_hd, content, content_length); |
0 | 824 content[content_length] = '\0'; |
825 } | |
826 if (content_ptr) | |
827 *content_ptr = content; | |
2263 | 828 else |
829 av_free(content); | |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
830 |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
831 return 0; |
0 | 832 } |
833 | |
4644
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
834 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
|
835 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
|
836 unsigned char **content_ptr) |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
837 { |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
838 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
|
839 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
|
840 |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
841 rt->seq++; |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
842 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
|
843 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
|
844 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
|
845 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
|
846 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
|
847 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
|
848 } |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
849 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
|
850 #ifdef DEBUG |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
851 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
|
852 #endif |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
853 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
|
854 |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
855 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
|
856 } |
2962d395431b
Split rtsp_send_cmd() into two functions, one for the actual sending of the
rbultje
parents:
4641
diff
changeset
|
857 |
0 | 858 |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
859 /* 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
|
860 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
|
861 { |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
862 int i; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
863 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
|
864 |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
865 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
|
866 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
|
867 if (rtsp_st) { |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
868 if (rtsp_st->transport_priv) { |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
869 if (rt->transport == RTSP_TRANSPORT_RDT) |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
870 ff_rdt_parse_close(rtsp_st->transport_priv); |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
871 else |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
872 rtp_parse_close(rtsp_st->transport_priv); |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
873 } |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
874 if (rtsp_st->rtp_handle) |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
875 url_close(rtsp_st->rtp_handle); |
1419 | 876 if (rtsp_st->dynamic_handler && rtsp_st->dynamic_protocol_context) |
877 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
|
878 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
879 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
880 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
|
881 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
|
882 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
|
883 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
|
884 } |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
885 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
886 |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
887 static int |
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
888 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
|
889 { |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
890 RTSPState *rt = s->priv_data; |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
891 AVStream *st = NULL; |
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
892 |
3920
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
893 /* open the RTP context */ |
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
894 if (rtsp_st->stream_index >= 0) |
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
895 st = s->streams[rtsp_st->stream_index]; |
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
896 if (!st) |
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
897 s->ctx_flags |= AVFMTCTX_NOHEADER; |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
898 |
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
899 if (rt->transport == RTSP_TRANSPORT_RDT) |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
900 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
|
901 rtsp_st->dynamic_protocol_context, |
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
902 rtsp_st->dynamic_handler); |
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
903 else |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
904 rtsp_st->transport_priv = rtp_parse_open(s, st, rtsp_st->rtp_handle, |
3980 | 905 rtsp_st->sdp_payload_type, |
906 &rtsp_st->rtp_payload_data); | |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
907 |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
908 if (!rtsp_st->transport_priv) { |
3920
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
909 return AVERROR(ENOMEM); |
3979
e6bf0896a019
Implement RDTDemuxContext, which contains RDT-specific data (similar to
rbultje
parents:
3978
diff
changeset
|
910 } 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
|
911 if(rtsp_st->dynamic_handler) { |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
912 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
|
913 rtsp_st->dynamic_protocol_context, |
1f1c4535f421
Remove access into RTPDemuxContext in rtsp.c, which allows making it opaque
rbultje
parents:
3975
diff
changeset
|
914 rtsp_st->dynamic_handler); |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
915 } |
3920
ae2d4ee06a94
Reindent after r15927, see discussion in "[PATCH] rtsp cleanup part 1:
rbultje
parents:
3919
diff
changeset
|
916 } |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
917 |
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
918 return 0; |
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
919 } |
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
920 |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
921 /** |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
922 * @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
|
923 */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
924 static int |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
925 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
|
926 int lower_transport, const char *real_challenge) |
0 | 927 { |
928 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
|
929 int rtx, j, i, err, interleave = 0; |
0 | 930 RTSPStream *rtsp_st; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
931 RTSPMessageHeader reply1, *reply = &reply1; |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
932 char cmd[2048]; |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
933 const char *trans_pref; |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
934 |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
935 if (rt->transport == RTSP_TRANSPORT_RDT) |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
936 trans_pref = "x-pn-tng"; |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
937 else |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
938 trans_pref = "RTP/AVP"; |
885 | 939 |
0 | 940 /* for each stream, make the setup request */ |
941 /* XXX: we assume the same server is used for the control of each | |
942 RTSP stream */ | |
774 | 943 |
944 for(j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) { | |
0 | 945 char transport[2048]; |
946 | |
4638
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 * 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
|
949 * 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
|
950 * 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
|
951 */ |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
952 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
|
953 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
|
954 if (i == 0) { |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
955 /* rtx first */ |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
956 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
|
957 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
|
958 if (len >= 4 && |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
959 !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
|
960 break; |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
961 } |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
962 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
|
963 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
|
964 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
|
965 } else |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
966 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
|
967 } else |
4639 | 968 rtsp_st = rt->rtsp_streams[i]; |
0 | 969 |
970 /* RTP/UDP */ | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
971 if (lower_transport == RTSP_LOWER_TRANSPORT_UDP) { |
0 | 972 char buf[256]; |
973 | |
4638
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
974 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
|
975 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
|
976 goto have_port; |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
977 } |
801468f16243
Make RTSP-MS-over-UDP negotiation work. See "[PATCH] RTSP-MS 8/15: fix
rbultje
parents:
4637
diff
changeset
|
978 |
0 | 979 /* first try in specified port range */ |
774 | 980 if (RTSP_RTP_PORT_MIN != 0) { |
981 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
|
982 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
|
983 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
|
984 if (url_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0) { |
0 | 985 goto rtp_opened; |
774 | 986 } |
0 | 987 } |
988 } | |
989 | |
774 | 990 /* then try on any port |
991 ** if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) { | |
992 ** err = AVERROR_INVALIDDATA; | |
993 ** goto fail; | |
994 ** } | |
995 */ | |
0 | 996 |
997 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
|
998 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
|
999 have_port: |
3877
3e0c7ad2a675
Remove unused code that used to handle protocol concatenation, i.e. trying
rbultje
parents:
3876
diff
changeset
|
1000 snprintf(transport, sizeof(transport) - 1, |
3958
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
1001 "%s/UDP;", trans_pref); |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
1002 if (rt->server_type != RTSP_SERVER_REAL) |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
1003 av_strlcat(transport, "unicast;", sizeof(transport)); |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
1004 av_strlcatf(transport, sizeof(transport), |
ab2d2bc3a6e7
Send improper UDP SETUP request, which is what Realmedia servers expect.
rbultje
parents:
3957
diff
changeset
|
1005 "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
|
1006 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
|
1007 !(rt->server_type == RTSP_SERVER_WMS && i > 0)) |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1008 av_strlcatf(transport, sizeof(transport), "-%d", port + 1); |
0 | 1009 } |
1010 | |
1011 /* RTP/TCP */ | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1012 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
|
1013 /** 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
|
1014 * 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
|
1015 * 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
|
1016 if (rt->server_type == RTSP_SERVER_WMS && |
eaf90db8cc42
Recognize the "application" data type, which is required for WMS/UDP
rbultje
parents:
4557
diff
changeset
|
1017 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
|
1018 continue; |
3877
3e0c7ad2a675
Remove unused code that used to handle protocol concatenation, i.e. trying
rbultje
parents:
3876
diff
changeset
|
1019 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
|
1020 "%s/TCP;", trans_pref); |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
1021 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
|
1022 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
|
1023 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
|
1024 "interleaved=%d-%d", |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
1025 interleave, interleave + 1); |
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
1026 interleave += 2; |
0 | 1027 } |
1028 | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1029 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
|
1030 snprintf(transport, sizeof(transport) - 1, |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1031 "%s/UDP;multicast", trans_pref); |
0 | 1032 } |
4332
0d776969b708
Fix the Transport: line in the SETUP request so that it works with WMS
rbultje
parents:
4291
diff
changeset
|
1033 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
|
1034 rt->server_type == RTSP_SERVER_WMS) |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1035 av_strlcat(transport, ";mode=play", sizeof(transport)); |
885 | 1036 snprintf(cmd, sizeof(cmd), |
172 | 1037 "SETUP %s RTSP/1.0\r\n" |
1038 "Transport: %s\r\n", | |
0 | 1039 rtsp_st->control_url, transport); |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1040 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
|
1041 char real_res[41], real_csum[9]; |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1042 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
|
1043 real_challenge); |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1044 av_strlcatf(cmd, sizeof(cmd), |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1045 "If-Match: %s\r\n" |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1046 "RealChallenge2: %s, sd=%s\r\n", |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1047 rt->session_id, real_res, real_csum); |
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1048 } |
0 | 1049 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
|
1050 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
|
1051 err = 1; |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1052 goto fail; |
3151 | 1053 } else if (reply->status_code != RTSP_STATUS_OK || |
1054 reply->nb_transports != 1) { | |
0 | 1055 err = AVERROR_INVALIDDATA; |
1056 goto fail; | |
1057 } | |
1058 | |
1059 /* XXX: same protocol for all streams is required */ | |
1060 if (i > 0) { | |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
1061 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
|
1062 reply->transports[0].transport != rt->transport) { |
0 | 1063 err = AVERROR_INVALIDDATA; |
1064 goto fail; | |
1065 } | |
1066 } else { | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1067 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
|
1068 rt->transport = reply->transports[0].transport; |
0 | 1069 } |
1070 | |
1071 /* close RTP connection if not choosen */ | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1072 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
|
1073 (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
|
1074 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
|
1075 rtsp_st->rtp_handle = NULL; |
0 | 1076 } |
1077 | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1078 switch(reply->transports[0].lower_transport) { |
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1079 case RTSP_LOWER_TRANSPORT_TCP: |
0 | 1080 rtsp_st->interleaved_min = reply->transports[0].interleaved_min; |
1081 rtsp_st->interleaved_max = reply->transports[0].interleaved_max; | |
1082 break; | |
885 | 1083 |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1084 case RTSP_LOWER_TRANSPORT_UDP: |
0 | 1085 { |
1086 char url[1024]; | |
885 | 1087 |
0 | 1088 /* XXX: also use address if specified */ |
885 | 1089 snprintf(url, sizeof(url), "rtp://%s:%d", |
0 | 1090 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
|
1091 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
|
1092 rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) { |
0 | 1093 err = AVERROR_INVALIDDATA; |
1094 goto fail; | |
1095 } | |
1096 } | |
1097 break; | |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1098 case RTSP_LOWER_TRANSPORT_UDP_MULTICAST: |
0 | 1099 { |
1100 char url[1024]; | |
2246
6dade35dc9b3
rtsp multicast fix by Thijs Vermeir $1$2@gmail.com
lu_zero
parents:
2222
diff
changeset
|
1101 struct in_addr in; |
0 | 1102 |
2246
6dade35dc9b3
rtsp multicast fix by Thijs Vermeir $1$2@gmail.com
lu_zero
parents:
2222
diff
changeset
|
1103 in.s_addr = htonl(reply->transports[0].destination); |
3221 | 1104 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
|
1105 inet_ntoa(in), |
6dade35dc9b3
rtsp multicast fix by Thijs Vermeir $1$2@gmail.com
lu_zero
parents:
2222
diff
changeset
|
1106 reply->transports[0].port_min, |
6dade35dc9b3
rtsp multicast fix by Thijs Vermeir $1$2@gmail.com
lu_zero
parents:
2222
diff
changeset
|
1107 reply->transports[0].ttl); |
1425
00d9393a126f
make ffmpeg able to send back a RTCP receiver report.
gpoirier
parents:
1424
diff
changeset
|
1108 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { |
0 | 1109 err = AVERROR_INVALIDDATA; |
1110 goto fail; | |
1111 } | |
1112 } | |
1113 break; | |
1114 } | |
774 | 1115 |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
1116 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
|
1117 goto fail; |
0 | 1118 } |
1119 | |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1120 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
|
1121 rt->need_subscription = 1; |
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1122 |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1123 return 0; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1124 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1125 fail: |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1126 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
|
1127 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
|
1128 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
|
1129 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
|
1130 } |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1131 } |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1132 return err; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1133 } |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1134 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1135 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
|
1136 AVFormatParameters *ap) |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1137 { |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1138 RTSPState *rt = s->priv_data; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1139 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
|
1140 URLContext *rtsp_hd; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1141 int port, ret, err; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1142 RTSPMessageHeader reply1, *reply = &reply1; |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1143 unsigned char *content = NULL; |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1144 int lower_transport_mask = 0; |
3856 | 1145 char real_challenge[64]; |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1146 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1147 /* extract hostname and port */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1148 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
|
1149 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
|
1150 if (port < 0) |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1151 port = RTSP_DEFAULT_PORT; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1152 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1153 /* search for options */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1154 option_list = strchr(path, '?'); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1155 if (option_list) { |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1156 /* 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
|
1157 *option_list++ = 0; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1158 while(option_list) { |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1159 /* move the option pointer */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1160 option = option_list; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1161 option_list = strchr(option_list, '&'); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1162 if (option_list) |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1163 *(option_list++) = 0; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1164 /* handle the options */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1165 if (strcmp(option, "udp") == 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_UDP); |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1167 else if (strcmp(option, "multicast") == 0) |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1168 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
|
1169 else if (strcmp(option, "tcp") == 0) |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1170 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
|
1171 } |
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 |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1174 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
|
1175 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
|
1176 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1177 /* open the tcp connexion */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1178 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
|
1179 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
|
1180 return AVERROR(EIO); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1181 rt->rtsp_hd = rtsp_hd; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1182 rt->seq = 0; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1183 |
3856 | 1184 /* request options supported by the server; this also detects server type */ |
1185 for (rt->server_type = RTSP_SERVER_RTP;;) { | |
1186 snprintf(cmd, sizeof(cmd), | |
1187 "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
|
1188 if (rt->server_type == RTSP_SERVER_REAL) |
3856 | 1189 av_strlcat(cmd, |
1190 /** | |
1191 * The following entries are required for proper | |
1192 * streaming from a Realmedia server. They are | |
1193 * interdependent in some way although we currently | |
1194 * don't quite understand how. Values were copied | |
1195 * from mplayer SVN r23589. | |
1196 * @param CompanyID is a 16-byte ID in base64 | |
1197 * @param ClientChallenge is a 16-byte ID in hex | |
1198 */ | |
1199 "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7\r\n" | |
1200 "PlayerStarttime: [28/03/2003:22:50:23 00:00]\r\n" | |
1201 "CompanyID: KnKV4M4I/B2FjJ1TToLycw==\r\n" | |
1202 "GUID: 00000000-0000-0000-0000-000000000000\r\n", | |
1203 sizeof(cmd)); | |
1204 rtsp_send_cmd(s, cmd, reply, NULL); | |
1205 if (reply->status_code != RTSP_STATUS_OK) { | |
1206 err = AVERROR_INVALIDDATA; | |
1207 goto fail; | |
1208 } | |
1209 | |
1210 /* 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
|
1211 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
|
1212 rt->server_type = RTSP_SERVER_REAL; |
3856 | 1213 continue; |
4169
619845a9bab3
Use the "server" RTSP field to detect whether the server that we're talking
rbultje
parents:
4168
diff
changeset
|
1214 } 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
|
1215 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
|
1216 } else if (rt->server_type == RTSP_SERVER_REAL) { |
3856 | 1217 strcpy(real_challenge, reply->real_challenge); |
1218 } | |
1219 break; | |
1220 } | |
1221 | |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1222 /* describe the stream */ |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1223 snprintf(cmd, sizeof(cmd), |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1224 "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
|
1225 "Accept: application/sdp\r\n", |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1226 s->filename); |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1227 if (rt->server_type == RTSP_SERVER_REAL) { |
3859 | 1228 /** |
1229 * The Require: attribute is needed for proper streaming from | |
1230 * Realmedia servers. | |
1231 */ | |
1232 av_strlcat(cmd, | |
1233 "Require: com.real.retain-entity-for-setup\r\n", | |
1234 sizeof(cmd)); | |
1235 } | |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1236 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
|
1237 if (!content) { |
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 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
|
1242 err = AVERROR_INVALIDDATA; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1243 goto fail; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1244 } |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1245 |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1246 /* 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
|
1247 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
|
1248 av_freep(&content); |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1249 if (ret < 0) { |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1250 err = AVERROR_INVALIDDATA; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1251 goto fail; |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1252 } |
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1253 |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1254 do { |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1255 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
|
1256 |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1257 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
|
1258 rt->server_type == RTSP_SERVER_REAL ? |
3876
1026953d4ffe
Implement Realmedia/RTSP-compatible SETUP command. This includes calculation
rbultje
parents:
3861
diff
changeset
|
1259 real_challenge : NULL); |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1260 if (err < 0) |
3151 | 1261 goto fail; |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1262 lower_transport_mask &= ~(1 << lower_transport); |
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1263 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
|
1264 err = AVERROR(FF_NETERROR(EPROTONOSUPPORT)); |
3149
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1265 goto fail; |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1266 } |
5a7a7406ab1f
Allow cycling between different protocols (TCP, UDP or multicast) so that if
rbultje
parents:
3147
diff
changeset
|
1267 } while (err); |
3147
91d65fdf91e1
Split the SETUP request into a separate function, as a prelude into allowing
rbultje
parents:
2884
diff
changeset
|
1268 |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1269 rt->state = RTSP_STATE_IDLE; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1270 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
|
1271 zero */ |
1003 | 1272 if (ap->initial_pause) { |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1273 /* do not start immediately */ |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1274 } else { |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1275 if (rtsp_read_play(s) < 0) { |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1276 err = AVERROR_INVALIDDATA; |
0 | 1277 goto fail; |
1278 } | |
1279 } | |
1280 return 0; | |
1281 fail: | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1282 rtsp_close_streams(rt); |
0 | 1283 av_freep(&content); |
1284 url_close(rt->rtsp_hd); | |
1285 return err; | |
1286 } | |
1287 | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1288 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
|
1289 uint8_t *buf, int buf_size) |
0 | 1290 { |
1291 RTSPState *rt = s->priv_data; | |
172 | 1292 int id, len, i, ret; |
0 | 1293 RTSPStream *rtsp_st; |
1294 | |
172 | 1295 #ifdef DEBUG_RTP_TCP |
1296 printf("tcp_read_packet:\n"); | |
1297 #endif | |
0 | 1298 redo: |
1299 for(;;) { | |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1300 RTSPMessageHeader reply; |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1301 |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1302 ret = rtsp_read_reply(s, &reply, NULL, 1); |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1303 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
|
1304 return -1; |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1305 if (ret == 1) /* received '$' */ |
0 | 1306 break; |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1307 /* XXX: parse message */ |
0 | 1308 } |
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
|
1309 ret = url_readbuf(rt->rtsp_hd, buf, 3); |
172 | 1310 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
|
1311 return -1; |
172 | 1312 id = buf[0]; |
2222 | 1313 len = AV_RB16(buf + 1); |
172 | 1314 #ifdef DEBUG_RTP_TCP |
1315 printf("id=%d len=%d\n", id, len); | |
1316 #endif | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1317 if (len > buf_size || len < 12) |
0 | 1318 goto redo; |
1319 /* 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
|
1320 ret = url_readbuf(rt->rtsp_hd, buf, len); |
172 | 1321 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
|
1322 return -1; |
3962
72efef66f566
This patch refactors RDT packet header parsing so that it can be used in
rbultje
parents:
3961
diff
changeset
|
1323 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
|
1324 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
|
1325 return -1; |
885 | 1326 |
0 | 1327 /* 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
|
1328 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
|
1329 rtsp_st = rt->rtsp_streams[i]; |
885 | 1330 if (id >= rtsp_st->interleaved_min && |
1331 id <= rtsp_st->interleaved_max) | |
0 | 1332 goto found; |
1333 } | |
1334 goto redo; | |
1335 found: | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1336 *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
|
1337 return len; |
0 | 1338 } |
1339 | |
885 | 1340 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
|
1341 uint8_t *buf, int buf_size) |
0 | 1342 { |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1343 RTSPState *rt = s->priv_data; |
0 | 1344 RTSPStream *rtsp_st; |
1345 fd_set rfds; | |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1346 int fd, fd_max, n, i, ret, tcp_fd; |
0 | 1347 struct timeval tv; |
1348 | |
1349 for(;;) { | |
179 | 1350 if (url_interrupt_cb()) |
2772
b43dc2901f83
Make av_read_frame with rtsp client return EINTR on interrupt
lu_zero
parents:
2771
diff
changeset
|
1351 return AVERROR(EINTR); |
0 | 1352 FD_ZERO(&rfds); |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1353 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
|
1354 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
|
1355 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
|
1356 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
|
1357 if (rtsp_st->rtp_handle) { |
4639 | 1358 /* currently, we cannot probe RTCP handle because of |
1359 * blocking restrictions */ | |
4641
aa5dcae3f210
Rename "fd1" variable ro "fd". There were previously two variables (fd1 and
rbultje
parents:
4640
diff
changeset
|
1360 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
|
1361 if (fd > fd_max) |
aa5dcae3f210
Rename "fd1" variable ro "fd". There were previously two variables (fd1 and
rbultje
parents:
4640
diff
changeset
|
1362 fd_max = fd; |
aa5dcae3f210
Rename "fd1" variable ro "fd". There were previously two variables (fd1 and
rbultje
parents:
4640
diff
changeset
|
1363 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
|
1364 } |
0 | 1365 } |
1366 tv.tv_sec = 0; | |
179 | 1367 tv.tv_usec = 100 * 1000; |
0 | 1368 n = select(fd_max + 1, &rfds, NULL, NULL, &tv); |
1369 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
|
1370 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
|
1371 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
|
1372 if (rtsp_st->rtp_handle) { |
4641
aa5dcae3f210
Rename "fd1" variable ro "fd". There were previously two variables (fd1 and
rbultje
parents:
4640
diff
changeset
|
1373 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
|
1374 if (FD_ISSET(fd, &rfds)) { |
4639 | 1375 ret = url_read(rtsp_st->rtp_handle, buf, buf_size); |
1376 if (ret > 0) { | |
1377 *prtsp_st = rtsp_st; | |
1378 return ret; | |
1379 } | |
0 | 1380 } |
1381 } | |
1382 } | |
4772
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1383 if (FD_ISSET(tcp_fd, &rfds)) { |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1384 RTSPMessageHeader reply; |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1385 |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1386 rtsp_read_reply(s, &reply, NULL, 0); |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1387 /* XXX: parse message */ |
fb0b1e68356c
Allow (and parse) incoming server messages (notices) interleaved with TCP
rbultje
parents:
4745
diff
changeset
|
1388 } |
0 | 1389 } |
1390 } | |
1391 } | |
1392 | |
1393 static int rtsp_read_packet(AVFormatContext *s, | |
1394 AVPacket *pkt) | |
1395 { | |
1396 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
|
1397 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
|
1398 int ret, len; |
4182
313d987dd2b4
Increase buffer size for RTP packet data because some ASF streams use a
rbultje
parents:
4169
diff
changeset
|
1399 uint8_t buf[10 * RTP_MAX_PACKET_LENGTH]; |
0 | 1400 |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1401 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
|
1402 int i; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1403 RTSPMessageHeader reply1, *reply = &reply1; |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1404 enum AVDiscard cache[MAX_STREAMS]; |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1405 char cmd[1024]; |
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1406 |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1407 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
|
1408 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
|
1409 |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1410 if (!rt->need_subscription) { |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1411 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
|
1412 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
|
1413 av_strlcatf(cmd, sizeof(cmd), |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1414 "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
|
1415 "Unsubscribe: %s\r\n", |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1416 s->filename, rt->last_subscription); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1417 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
|
1418 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
|
1419 return AVERROR_INVALIDDATA; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1420 rt->need_subscription = 1; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1421 } |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1422 } |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1423 |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1424 if (rt->need_subscription) { |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1425 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
|
1426 |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1427 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
|
1428 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
|
1429 rt->last_subscription[0] = 0; |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1430 |
4166
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1431 snprintf(cmd, sizeof(cmd), |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1432 "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
|
1433 "Subscribe: ", |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1434 s->filename); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1435 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
|
1436 rule_nr = 0; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1437 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
|
1438 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
|
1439 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
|
1440 if (!first) |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1441 av_strlcat(rt->last_subscription, ",", |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1442 sizeof(rt->last_subscription)); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1443 ff_rdt_subscribe_rule( |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1444 rt->last_subscription, |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1445 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
|
1446 first = 0; |
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 rule_nr++; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1449 } |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1450 } |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1451 } |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1452 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
|
1453 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
|
1454 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
|
1455 return AVERROR_INVALIDDATA; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1456 rt->need_subscription = 0; |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1457 |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1458 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
|
1459 rtsp_read_play (s); |
1dbda91eaebd
Allow subscription to any of the streams, not just the first, available in
rbultje
parents:
4165
diff
changeset
|
1460 } |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1461 } |
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1462 |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1463 /* 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
|
1464 if (rt->cur_transport_priv) { |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
1465 if (rt->transport == RTSP_TRANSPORT_RDT) |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1466 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
|
1467 else |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1468 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
|
1469 if (ret == 0) { |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1470 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
|
1471 return 0; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1472 } 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
|
1473 return 0; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1474 } else { |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1475 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
|
1476 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1477 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1478 |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1479 /* 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
|
1480 redo: |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1481 switch(rt->lower_transport) { |
0 | 1482 default: |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1483 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
|
1484 len = tcp_read_packet(s, &rtsp_st, buf, sizeof(buf)); |
0 | 1485 break; |
3957
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1486 case RTSP_LOWER_TRANSPORT_UDP: |
9f943bb755f9
Rename RTSPProtocol to RTSPLowerTransport, so that its name properly tells us
rbultje
parents:
3941
diff
changeset
|
1487 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
|
1488 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
|
1489 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
|
1490 rtp_check_and_send_back_rr(rtsp_st->transport_priv, len); |
0 | 1491 break; |
1492 } | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1493 if (len < 0) |
2775
1301147d9450
Make av_read_frame with rtsp client return EINTR on interrupt
lu_zero
parents:
2772
diff
changeset
|
1494 return len; |
3960
13e9b0d3a314
Implement a RTSPTransport field, which allows proper separation of server
rbultje
parents:
3959
diff
changeset
|
1495 if (rt->transport == RTSP_TRANSPORT_RDT) |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1496 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
|
1497 else |
4386
3dbd7fa2c2af
Rename "tx_ctx" and "cur_tx" variables to "transport_priv" and
rbultje
parents:
4361
diff
changeset
|
1498 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
|
1499 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
|
1500 goto redo; |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1501 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
|
1502 /* 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
|
1503 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
|
1504 } |
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1505 return 0; |
0 | 1506 } |
1507 | |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1508 static int rtsp_read_play(AVFormatContext *s) |
179 | 1509 { |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1510 RTSPState *rt = s->priv_data; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1511 RTSPMessageHeader reply1, *reply = &reply1; |
179 | 1512 char cmd[1024]; |
1513 | |
370
845f9de2c883
av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
304
diff
changeset
|
1514 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
|
1515 |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1516 if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { |
3904 | 1517 if (rt->state == RTSP_STATE_PAUSED) { |
1518 snprintf(cmd, sizeof(cmd), | |
1519 "PLAY %s RTSP/1.0\r\n", | |
1520 s->filename); | |
1521 } else { | |
1522 snprintf(cmd, sizeof(cmd), | |
1523 "PLAY %s RTSP/1.0\r\n" | |
1524 "Range: npt=%0.3f-\r\n", | |
1525 s->filename, | |
1526 (double)rt->seek_timestamp / AV_TIME_BASE); | |
1527 } | |
1528 rtsp_send_cmd(s, cmd, reply, NULL); | |
1529 if (reply->status_code != RTSP_STATUS_OK) { | |
1530 return -1; | |
1531 } | |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1532 } |
3861
a0098594ab90
Remove useless "else" case in if X { A; return }; else { B }. See discussion
rbultje
parents:
3860
diff
changeset
|
1533 rt->state = RTSP_STATE_PLAYING; |
a0098594ab90
Remove useless "else" case in if X { A; return }; else { B }. See discussion
rbultje
parents:
3860
diff
changeset
|
1534 return 0; |
304
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 |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1537 /* pause the stream */ |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1538 static int rtsp_read_pause(AVFormatContext *s) |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1539 { |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1540 RTSPState *rt = s->priv_data; |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1541 RTSPMessageHeader reply1, *reply = &reply1; |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1542 char cmd[1024]; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1543 |
179 | 1544 rt = s->priv_data; |
885 | 1545 |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1546 if (rt->state != RTSP_STATE_PLAYING) |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1547 return 0; |
3923
83e51bcb03c2
Rename RTSP_SERVER_RDT to RTSP_SERVER_REAL, because RDT (the transport
rbultje
parents:
3920
diff
changeset
|
1548 else if (!(rt->server_type == RTSP_SERVER_REAL && rt->need_subscription)) { |
3904 | 1549 snprintf(cmd, sizeof(cmd), |
1550 "PAUSE %s RTSP/1.0\r\n", | |
1551 s->filename); | |
1552 rtsp_send_cmd(s, cmd, reply, NULL); | |
1553 if (reply->status_code != RTSP_STATUS_OK) { | |
1554 return -1; | |
1555 } | |
3903
aeb79f68ba7e
Implement a RDT-specific SET_PARAMETER command that subscribes to the
rbultje
parents:
3877
diff
changeset
|
1556 } |
3861
a0098594ab90
Remove useless "else" case in if X { A; return }; else { B }. See discussion
rbultje
parents:
3860
diff
changeset
|
1557 rt->state = RTSP_STATE_PAUSED; |
a0098594ab90
Remove useless "else" case in if X { A; return }; else { B }. See discussion
rbultje
parents:
3860
diff
changeset
|
1558 return 0; |
179 | 1559 } |
1560 | |
885 | 1561 static int rtsp_read_seek(AVFormatContext *s, int stream_index, |
558 | 1562 int64_t timestamp, int flags) |
179 | 1563 { |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1564 RTSPState *rt = s->priv_data; |
885 | 1565 |
2408 | 1566 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
|
1567 switch(rt->state) { |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1568 default: |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1569 case RTSP_STATE_IDLE: |
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_PLAYING: |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1572 if (rtsp_read_play(s) != 0) |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1573 return -1; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1574 break; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1575 case RTSP_STATE_PAUSED: |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1576 rt->state = RTSP_STATE_IDLE; |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1577 break; |
179 | 1578 } |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1579 return 0; |
179 | 1580 } |
1581 | |
0 | 1582 static int rtsp_read_close(AVFormatContext *s) |
1583 { | |
1584 RTSPState *rt = s->priv_data; | |
4557
bfe6fb676d46
Rename RTSPHeader to RTSPMessageHeader to reflect more clearly what the
rbultje
parents:
4549
diff
changeset
|
1585 RTSPMessageHeader reply1, *reply = &reply1; |
0 | 1586 char cmd[1024]; |
1587 | |
172 | 1588 #if 0 |
0 | 1589 /* 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
|
1590 if (rt->lower_transport == RTSP_LOWER_TRANSPORT_TCP) { |
0 | 1591 url_fclose(&rt->rtsp_gb); |
1592 } | |
172 | 1593 #endif |
885 | 1594 snprintf(cmd, sizeof(cmd), |
172 | 1595 "TEARDOWN %s RTSP/1.0\r\n", |
0 | 1596 s->filename); |
1597 rtsp_send_cmd(s, cmd, reply, NULL); | |
1598 | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1599 rtsp_close_streams(rt); |
0 | 1600 url_close(rt->rtsp_hd); |
1601 return 0; | |
1602 } | |
1603 | |
4206 | 1604 #if CONFIG_RTSP_DEMUXER |
1167 | 1605 AVInputFormat rtsp_demuxer = { |
0 | 1606 "rtsp", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3286
diff
changeset
|
1607 NULL_IF_CONFIG_SMALL("RTSP input format"), |
0 | 1608 sizeof(RTSPState), |
1609 rtsp_probe, | |
1610 rtsp_read_header, | |
1611 rtsp_read_packet, | |
1612 rtsp_read_close, | |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1613 rtsp_read_seek, |
0 | 1614 .flags = AVFMT_NOFILE, |
304
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1615 .read_play = rtsp_read_play, |
d58c8859ff8c
initial seek support - more generic play/pause support
bellard
parents:
294
diff
changeset
|
1616 .read_pause = rtsp_read_pause, |
0 | 1617 }; |
2054 | 1618 #endif |
0 | 1619 |
1620 static int sdp_probe(AVProbeData *p1) | |
1621 { | |
706
fc254f396f15
buffer overflow in sdp_probe() fix by (Gildas Bazin )gbazin altern org)
michael
parents:
587
diff
changeset
|
1622 const char *p = p1->buf, *p_end = p1->buf + p1->buf_size; |
0 | 1623 |
1624 /* 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
|
1625 while (p < p_end && *p != '\0') { |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
1626 if (p + sizeof("c=IN IP4") - 1 < p_end && av_strstart(p, "c=IN IP4", NULL)) |
0 | 1627 return AVPROBE_SCORE_MAX / 2; |
706
fc254f396f15
buffer overflow in sdp_probe() fix by (Gildas Bazin )gbazin altern org)
michael
parents:
587
diff
changeset
|
1628 |
fc254f396f15
buffer overflow in sdp_probe() fix by (Gildas Bazin )gbazin altern org)
michael
parents:
587
diff
changeset
|
1629 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
|
1630 if (++p >= p_end) |
0 | 1631 break; |
1632 if (*p == '\r') | |
1633 p++; | |
1634 } | |
1635 return 0; | |
1636 } | |
1637 | |
1638 #define SDP_MAX_SIZE 8192 | |
1639 | |
1640 static int sdp_read_header(AVFormatContext *s, | |
1641 AVFormatParameters *ap) | |
1642 { | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1643 RTSPState *rt = s->priv_data; |
0 | 1644 RTSPStream *rtsp_st; |
1645 int size, i, err; | |
1646 char *content; | |
1647 char url[1024]; | |
1648 | |
1649 /* read the whole sdp file */ | |
1650 /* XXX: better loading */ | |
1651 content = av_malloc(SDP_MAX_SIZE); | |
2771
d52c718e83f9
Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents:
2759
diff
changeset
|
1652 size = get_buffer(s->pb, content, SDP_MAX_SIZE - 1); |
0 | 1653 if (size <= 0) { |
1654 av_free(content); | |
1655 return AVERROR_INVALIDDATA; | |
1656 } | |
1657 content[size] ='\0'; | |
1658 | |
1659 sdp_parse(s, content); | |
1660 av_free(content); | |
1661 | |
1662 /* 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
|
1663 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
|
1664 rtsp_st = rt->rtsp_streams[i]; |
885 | 1665 |
3222 | 1666 snprintf(url, sizeof(url), "rtp://%s:%d?localport=%d&ttl=%d", |
885 | 1667 inet_ntoa(rtsp_st->sdp_ip), |
0 | 1668 rtsp_st->sdp_port, |
3222 | 1669 rtsp_st->sdp_port, |
0 | 1670 rtsp_st->sdp_ttl); |
1425
00d9393a126f
make ffmpeg able to send back a RTCP receiver report.
gpoirier
parents:
1424
diff
changeset
|
1671 if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) { |
0 | 1672 err = AVERROR_INVALIDDATA; |
1673 goto fail; | |
1674 } | |
3919
1879eab34f88
Factorize out common code for opening of the RTP parsing context between
rbultje
parents:
3905
diff
changeset
|
1675 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
|
1676 goto fail; |
0 | 1677 } |
1678 return 0; | |
1679 fail: | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1680 rtsp_close_streams(rt); |
0 | 1681 return err; |
1682 } | |
1683 | |
1684 static int sdp_read_packet(AVFormatContext *s, | |
1685 AVPacket *pkt) | |
1686 { | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1687 return rtsp_read_packet(s, pkt); |
0 | 1688 } |
1689 | |
1690 static int sdp_read_close(AVFormatContext *s) | |
1691 { | |
294
6091b76cfc2a
added MPEG2TS support in RTP, SDP and RTSP - replaced fake RTP demux by a specific API
bellard
parents:
229
diff
changeset
|
1692 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
|
1693 rtsp_close_streams(rt); |
0 | 1694 return 0; |
1695 } | |
1696 | |
4206 | 1697 #if CONFIG_SDP_DEMUXER |
1169 | 1698 AVInputFormat sdp_demuxer = { |
0 | 1699 "sdp", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3286
diff
changeset
|
1700 NULL_IF_CONFIG_SMALL("SDP"), |
0 | 1701 sizeof(RTSPState), |
1702 sdp_probe, | |
1703 sdp_read_header, | |
1704 sdp_read_packet, | |
1705 sdp_read_close, | |
1706 }; | |
1169 | 1707 #endif |
0 | 1708 |
4206 | 1709 #if CONFIG_REDIR_DEMUXER |
0 | 1710 /* dummy redirector format (used directly in av_open_input_file now) */ |
1711 static int redir_probe(AVProbeData *pd) | |
1712 { | |
1713 const char *p; | |
1714 p = pd->buf; | |
4774
beca7e13cc3f
Use skip_spaces() in the "redir" demuxer instead of "while (isspace(&p)) p++".
rbultje
parents:
4773
diff
changeset
|
1715 skip_spaces(&p); |
2193
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
1716 if (av_strstart(p, "http://", NULL) || |
5ce5fad0dfac
replace the uses of old string functions that Reimar missed
mru
parents:
2189
diff
changeset
|
1717 av_strstart(p, "rtsp://", NULL)) |
0 | 1718 return AVPROBE_SCORE_MAX; |
1719 return 0; | |
1720 } | |
1721 | |
2785
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1722 static int redir_read_header(AVFormatContext *s, AVFormatParameters *ap) |
0 | 1723 { |
1724 char buf[4096], *q; | |
1725 int c; | |
1726 AVFormatContext *ic = NULL; | |
2785
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1727 ByteIOContext *f = s->pb; |
0 | 1728 |
1729 /* parse each URL and try to open it */ | |
1730 c = url_fgetc(f); | |
1731 while (c != URL_EOF) { | |
1732 /* skip spaces */ | |
1733 for(;;) { | |
1734 if (!redir_isspace(c)) | |
1735 break; | |
1736 c = url_fgetc(f); | |
1737 } | |
1738 if (c == URL_EOF) | |
1739 break; | |
1740 /* record url */ | |
1741 q = buf; | |
1742 for(;;) { | |
1743 if (c == URL_EOF || redir_isspace(c)) | |
1744 break; | |
1745 if ((q - buf) < sizeof(buf) - 1) | |
1746 *q++ = c; | |
1747 c = url_fgetc(f); | |
1748 } | |
1749 *q = '\0'; | |
1750 //printf("URL='%s'\n", buf); | |
1751 /* try to open the media file */ | |
1752 if (av_open_input_file(&ic, buf, NULL, 0, NULL) == 0) | |
1753 break; | |
1754 } | |
1755 if (!ic) | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2273
diff
changeset
|
1756 return AVERROR(EIO); |
2785
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1757 |
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1758 *s = *ic; |
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1759 url_fclose(f); |
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1760 |
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1761 return 0; |
0 | 1762 } |
1763 | |
1167 | 1764 AVInputFormat redir_demuxer = { |
0 | 1765 "redir", |
3424
7a0230981402
Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents:
3286
diff
changeset
|
1766 NULL_IF_CONFIG_SMALL("Redirector format"), |
0 | 1767 0, |
1768 redir_probe, | |
2785
d3b3cfb538d8
Suppress the "redirector hack" from libavformat/utils.c:av_open_input_stream(),
lucabe
parents:
2775
diff
changeset
|
1769 redir_read_header, |
0 | 1770 NULL, |
1771 NULL, | |
1772 }; | |
2053 | 1773 #endif |