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 }