Real rstp:// streaming support, ported from xine
[mplayer/greg.git] / libmpdemux / realrtsp / rtsp_session.c
blob2574dd9f60c016311c6bb45024487de342861f7a
1 /*
2 * This file was ported to MPlayer from xine CVS rtsp_session.c,v 1.9 2003/02/11 16:20:40
3 */
5 /*
6 * Copyright (C) 2000-2002 the xine project
8 * This file is part of xine, a free video player.
10 * xine is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * xine is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
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
25 * high level interface to rtsp servers.
28 #include <sys/types.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include <netdb.h>
32 #include <unistd.h>
33 #include <stdio.h>
34 #include <fcntl.h>
35 #include <stdlib.h>
36 #include <string.h>
38 #include "rtsp.h"
39 #include "rtsp_session.h"
40 #include "real.h"
41 #include "rmff.h"
42 #include "asmrp.h"
45 #define LOG
48 #define BUF_SIZE 4096
49 #define HEADER_SIZE 4096
51 struct rtsp_session_s {
53 rtsp_t *s;
55 /* receive buffer */
56 uint8_t recv[BUF_SIZE];
57 int recv_size;
58 int recv_read;
60 /* header buffer */
61 uint8_t header[HEADER_SIZE];
62 int header_len;
63 int header_read;
67 //rtsp_session_t *rtsp_session_start(char *mrl) {
68 rtsp_session_t *rtsp_session_start(int fd, char *mrl, char *path, char *host, int port) {
70 rtsp_session_t *rtsp_session=malloc(sizeof(rtsp_session_t));
71 char *server;
72 char *mrl_line = NULL;
73 rmff_header_t *h;
74 uint32_t bandwidth=10485800;
76 connect:
78 /* connect to server */
79 rtsp_session->s=rtsp_connect(fd,mrl,path,host,port,NULL);
80 if (!rtsp_session->s)
82 printf("rtsp_session: failed to connect to server %s\n", path);
83 free(rtsp_session);
84 return NULL;
87 /* looking for server type */
88 if (rtsp_search_answers(rtsp_session->s,"Server"))
89 server=strdup(rtsp_search_answers(rtsp_session->s,"Server"));
90 else {
91 if (rtsp_search_answers(rtsp_session->s,"RealChallenge1"))
92 server=strdup("Real");
93 else
94 server=strdup("unknown");
96 if (strstr(server,"Real"))
98 /* we are talking to a real server ... */
100 h=real_setup_and_get_header(rtsp_session->s, bandwidth);
101 if (!h) {
102 /* got an redirect? */
103 if (rtsp_search_answers(rtsp_session->s, "Location"))
105 free(mrl_line);
106 mrl_line=strdup(rtsp_search_answers(rtsp_session->s, "Location"));
107 printf("rtsp_session: redirected to %s\n", mrl_line);
108 rtsp_close(rtsp_session->s);
109 free(server);
110 /* FIXME: this won't work in MPlayer, connection opened by caller */
111 goto connect; /* *shudder* i made a design mistake somewhere */
112 } else
114 printf("rtsp_session: session can not be established.\n");
115 rtsp_close(rtsp_session->s);
116 free(rtsp_session);
117 return NULL;
121 rtsp_session->header_len=rmff_dump_header(h,rtsp_session->header,1024);
123 memcpy(rtsp_session->recv, rtsp_session->header, rtsp_session->header_len);
124 rtsp_session->recv_size = rtsp_session->header_len;
125 rtsp_session->recv_read = 0;
127 } else
129 printf("rtsp_session: rtsp server type is '%s' instead of Real. Please report.\n",server);
130 rtsp_close(rtsp_session->s);
131 free(server);
132 free(rtsp_session);
133 return NULL;
135 free(server);
137 return rtsp_session;
140 int rtsp_session_read (rtsp_session_t *this, char *data, int len) {
142 int to_copy=len;
143 char *dest=data;
144 char *source=this->recv + this->recv_read;
145 int fill=this->recv_size - this->recv_read;
147 if (len < 0) return 0;
148 while (to_copy > fill) {
150 memcpy(dest, source, fill);
151 to_copy -= fill;
152 dest += fill;
153 this->recv_read = 0;
154 source = this->recv;
155 this->recv_size = real_get_rdt_chunk (this->s, source);
156 fill = this->recv_size;
158 if (this->recv_size == 0) {
159 #ifdef LOG
160 printf ("librtsp: %d of %d bytes provided\n", len-to_copy, len);
161 #endif
162 return len-to_copy;
166 memcpy(dest, source, to_copy);
167 this->recv_read += to_copy;
169 #ifdef LOG
170 printf ("librtsp: %d bytes provided\n", len);
171 #endif
173 return len;
176 int rtsp_session_peek_header(rtsp_session_t *this, char *buf, int maxsize) {
178 int len;
180 len = (this->header_len < maxsize) ? this->header_len : maxsize;
182 memcpy(buf, this->header, len);
183 return len;
186 void rtsp_session_end(rtsp_session_t *session) {
188 rtsp_close(session->s);
189 free(session);