Mercurial > mplayer.hg
comparison libmpdemux/librtsp/rtsp_session.c @ 18829:317e0fd394c5
added new native rtsp demuxer code for mpeg-ts over rtp (now both real and non-real servers should be handled)
author | ben |
---|---|
date | Mon, 26 Jun 2006 21:27:57 +0000 |
parents | a48dead7424a |
children |
comparison
equal
deleted
inserted
replaced
18828:55ebe20fadbc | 18829:317e0fd394c5 |
---|---|
21 * along with this program; if not, write to the Free Software | 21 * along with this program; if not, write to the Free Software |
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | 22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA |
23 * | 23 * |
24 * | 24 * |
25 * high level interface to rtsp servers. | 25 * high level interface to rtsp servers. |
26 * | |
27 * 2006, Benjamin Zores and Vincent Mussard | |
28 * Support for MPEG-TS streaming through RFC compliant RTSP servers | |
26 */ | 29 */ |
27 | 30 |
28 #include <sys/types.h> | 31 #include <sys/types.h> |
29 #include "config.h" | 32 #include "config.h" |
30 #ifndef HAVE_WINSOCK2 | 33 #ifndef HAVE_WINSOCK2 |
40 #include <stdlib.h> | 43 #include <stdlib.h> |
41 #include <string.h> | 44 #include <string.h> |
42 #include <inttypes.h> | 45 #include <inttypes.h> |
43 | 46 |
44 #include "mp_msg.h" | 47 #include "mp_msg.h" |
48 #include "../rtp.h" | |
45 #include "rtsp.h" | 49 #include "rtsp.h" |
50 #include "rtsp_rtp.h" | |
46 #include "rtsp_session.h" | 51 #include "rtsp_session.h" |
47 #include "../realrtsp/real.h" | 52 #include "../realrtsp/real.h" |
48 #include "../realrtsp/rmff.h" | 53 #include "../realrtsp/rmff.h" |
49 #include "../realrtsp/asmrp.h" | 54 #include "../realrtsp/asmrp.h" |
50 #include "../realrtsp/xbuffer.h" | 55 #include "../realrtsp/xbuffer.h" |
51 | 56 |
52 /* | 57 /* |
53 #define LOG | 58 #define LOG |
54 */ | 59 */ |
55 | 60 |
61 #define RTSP_OPTIONS_PUBLIC "Public" | |
56 #define RTSP_OPTIONS_SERVER "Server" | 62 #define RTSP_OPTIONS_SERVER "Server" |
57 #define RTSP_OPTIONS_LOCATION "Location" | 63 #define RTSP_OPTIONS_LOCATION "Location" |
58 #define RTSP_OPTIONS_REAL "RealChallenge1" | 64 #define RTSP_OPTIONS_REAL "RealChallenge1" |
59 #define RTSP_SERVER_TYPE_REAL "Real" | 65 #define RTSP_SERVER_TYPE_REAL "Real" |
60 #define RTSP_SERVER_TYPE_HELIX "Helix" | 66 #define RTSP_SERVER_TYPE_HELIX "Helix" |
61 #define RTSP_SERVER_TYPE_UNKNOWN "unknown" | 67 #define RTSP_SERVER_TYPE_UNKNOWN "unknown" |
62 | 68 |
63 struct rtsp_session_s { | 69 struct rtsp_session_s { |
64 rtsp_t *s; | 70 rtsp_t *s; |
65 struct real_rtsp_session_t* real_session; | 71 struct real_rtsp_session_t* real_session; |
72 struct rtp_rtsp_session_t* rtp_session; | |
66 }; | 73 }; |
67 | 74 |
68 //rtsp_session_t *rtsp_session_start(char *mrl) { | 75 //rtsp_session_t *rtsp_session_start(char *mrl) { |
69 rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, int port, int *redir, uint32_t bandwidth) { | 76 rtsp_session_t *rtsp_session_start(int fd, char **mrl, char *path, char *host, int port, int *redir, uint32_t bandwidth) { |
70 | 77 |
74 rmff_header_t *h; | 81 rmff_header_t *h; |
75 | 82 |
76 rtsp_session = malloc (sizeof (rtsp_session_t)); | 83 rtsp_session = malloc (sizeof (rtsp_session_t)); |
77 rtsp_session->s = NULL; | 84 rtsp_session->s = NULL; |
78 rtsp_session->real_session = NULL; | 85 rtsp_session->real_session = NULL; |
86 rtsp_session->rtp_session = NULL; | |
79 | 87 |
80 //connect: | 88 //connect: |
81 *redir = 0; | 89 *redir = 0; |
82 | 90 |
83 /* connect to server */ | 91 /* connect to server */ |
139 rtsp_session->real_session->header_len); | 147 rtsp_session->real_session->header_len); |
140 | 148 |
141 rtsp_session->real_session->recv_size = | 149 rtsp_session->real_session->recv_size = |
142 rtsp_session->real_session->header_len; | 150 rtsp_session->real_session->header_len; |
143 rtsp_session->real_session->recv_read = 0; | 151 rtsp_session->real_session->recv_read = 0; |
144 } else | 152 } else /* not a Real server : try RTP instead */ |
145 { | 153 { |
146 mp_msg (MSGT_OPEN, MSGL_ERR,"rtsp_session: Not a Real server. Server type is '%s'.\n",server); | 154 char *public = NULL; |
147 rtsp_close(rtsp_session->s); | 155 |
148 free(server); | 156 /* look for the Public: field in response to RTSP OPTIONS */ |
149 free(rtsp_session); | 157 public = strdup (rtsp_search_answers (rtsp_session->s, |
150 return NULL; | 158 RTSP_OPTIONS_PUBLIC)); |
159 if (!public) | |
160 { | |
161 rtsp_close (rtsp_session->s); | |
162 free (server); | |
163 free (mrl_line); | |
164 free (rtsp_session); | |
165 return NULL; | |
166 } | |
167 | |
168 /* check for minimalistic RTSP RFC compliance */ | |
169 if (!strstr (public, RTSP_METHOD_DESCRIBE) | |
170 || !strstr (public, RTSP_METHOD_SETUP) | |
171 || !strstr (public, RTSP_METHOD_PLAY) | |
172 || !strstr (public, RTSP_METHOD_TEARDOWN)) | |
173 { | |
174 free (public); | |
175 mp_msg (MSGT_OPEN, MSGL_ERR, | |
176 "Remote server does not meet minimal RTSP 1.0 compliance.\n"); | |
177 rtsp_close (rtsp_session->s); | |
178 free (server); | |
179 free (mrl_line); | |
180 free (rtsp_session); | |
181 return NULL; | |
182 } | |
183 | |
184 free (public); | |
185 rtsp_session->rtp_session = rtp_setup_and_play (rtsp_session->s); | |
186 | |
187 /* neither a Real or an RTP server */ | |
188 if (!rtsp_session->rtp_session) | |
189 { | |
190 mp_msg (MSGT_OPEN, MSGL_ERR, "rtsp_session: unsupported RTSP server. "); | |
191 mp_msg (MSGT_OPEN, MSGL_ERR, "Server type is '%s'.\n", server); | |
192 rtsp_close (rtsp_session->s); | |
193 free (server); | |
194 free (mrl_line); | |
195 free (rtsp_session); | |
196 return NULL; | |
197 } | |
151 } | 198 } |
152 free(server); | 199 free(server); |
153 | 200 |
154 return rtsp_session; | 201 return rtsp_session; |
155 } | 202 } |
192 mp_msg (MSGT_OPEN, MSGL_INFO, "librtsp: %d bytes provided\n", len); | 239 mp_msg (MSGT_OPEN, MSGL_INFO, "librtsp: %d bytes provided\n", len); |
193 #endif | 240 #endif |
194 | 241 |
195 return len; | 242 return len; |
196 } | 243 } |
244 else if (this->rtp_session) | |
245 { | |
246 int l = 0; | |
247 | |
248 l = read_rtp_from_server (this->rtp_session->rtp_socket, data, len); | |
249 /* send RTSP and RTCP keepalive */ | |
250 rtcp_send_rr (this->s, this->rtp_session); | |
251 | |
252 if (l == 0) | |
253 rtsp_session_end (this); | |
254 | |
255 return l; | |
256 } | |
197 | 257 |
198 return 0; | 258 return 0; |
199 } | 259 } |
200 | 260 |
201 void rtsp_session_end(rtsp_session_t *session) { | 261 void rtsp_session_end(rtsp_session_t *session) { |
202 | 262 |
203 rtsp_close(session->s); | 263 rtsp_close(session->s); |
204 if (session->real_session) | 264 if (session->real_session) |
205 free_real_rtsp_session (session->real_session); | 265 free_real_rtsp_session (session->real_session); |
266 if (session->rtp_session) | |
267 rtp_session_free (session->rtp_session); | |
206 free(session); | 268 free(session); |
207 } | 269 } |