summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmad/libmadplugin.cpp189
-rw-r--r--core/multimedia/opieplayer/libmad/libmadplugin.h9
2 files changed, 193 insertions, 5 deletions
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.cpp b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
index 8ede537..0fcc230 100644
--- a/core/multimedia/opieplayer/libmad/libmadplugin.cpp
+++ b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
@@ -34,6 +34,14 @@
34#include <qapplication.h> 34#include <qapplication.h>
35#include <qpe/config.h> 35#include <qpe/config.h>
36 36
37// for network handling
38#include <netinet/in.h>
39#include <netdb.h>
40#include <sys/socket.h>
41#include <arpa/inet.h>
42#include <unistd.h>
43
44
37//#define HAVE_MMAP 45//#define HAVE_MMAP
38 46
39#if defined(HAVE_MMAP) 47#if defined(HAVE_MMAP)
@@ -160,11 +168,180 @@ bool LibMadPlugin::isFileSupported( const QString& path ) {
160 if ( strncasecmp(ext, ".mp3", 4) == 0 ) 168 if ( strncasecmp(ext, ".mp3", 4) == 0 )
161 return TRUE; 169 return TRUE;
162 } 170 }
171 // UGLY - just for fast testing
172 if ( path.left(4) == "http") {
173 return TRUE;
174 }
175
163 176
164 return FALSE; 177 return FALSE;
165} 178}
166 179
167 180
181int LibMadPlugin::tcp_open(char *address, int port) {
182 struct sockaddr_in stAddr;
183 struct hostent *host;
184 int sock;
185 struct linger l;
186
187 memset(&stAddr, 0, sizeof(stAddr));
188 stAddr.sin_family = AF_INET;
189 stAddr.sin_port = htons(port);
190
191 if ((host = gethostbyname(address)) == NULL)
192 return (0);
193
194 stAddr.sin_addr = *((struct in_addr *)host->h_addr_list[0]);
195
196 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
197 return (0);
198
199 l.l_onoff = 1;
200 l.l_linger = 5;
201 if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)) < 0)
202 return (0);
203
204 if (connect(sock, (struct sockaddr *)&stAddr, sizeof(stAddr)) < 0)
205 return (0);
206
207 return (sock);
208}
209
210
211/**
212 * Read a http line header.
213 * This function read character by character.
214 * @param tcp_sock the socket use to read the stream
215 * @param buf a buffer to receive the data
216 * @param size size of the buffer
217 * @return the size of the stream read or -1 if an error occured
218 */
219int LibMadPlugin::http_read_line(int tcp_sock, char *buf, int size) {
220 int offset = 0;
221
222 do
223 {
224 if (std::read(tcp_sock, buf + offset, 1) < 0)
225 return -1;
226 if (buf[offset] != '\r') /* Strip \r from answer */
227 offset++;
228 }
229 while (offset < size - 1 && buf[offset - 1] != '\n');
230
231 buf[offset] = 0;
232 return offset;
233}
234
235int LibMadPlugin::http_open(const QString& path ) {
236 char *host;
237 int port;
238 char *request;
239 int tcp_sock;
240 char http_request[PATH_MAX];
241 char filename[PATH_MAX];
242 char c;
243 char *arg =strdup(path.latin1());
244
245 /* Check for URL syntax */
246 if (strncmp(arg, "http://", strlen("http://")))
247 return (0);
248
249 /* Parse URL */
250 port = 80;
251 host = arg + strlen("http://");
252 if ((request = strchr(host, '/')) == NULL)
253 return (0);
254 *request++ = 0;
255
256 if (strchr(host, ':') != NULL) /* port is specified */
257 {
258 port = atoi(strchr(host, ':') + 1);
259 *strchr(host, ':') = 0;
260 }
261
262 /* Open a TCP socket */
263 if (!(tcp_sock = tcp_open(host, port)))
264 {
265 perror("http_open");
266 return (0);
267 }
268
269 snprintf(filename, sizeof(filename) - strlen(host) - 75, "%s", request);
270
271 /* Send HTTP GET request */
272 /* Please don't use a Agent know by shoutcast (Lynx, Mozilla) seems to be reconized and print
273 * a html page and not the stream */
274 snprintf(http_request, sizeof(http_request), "GET /%s HTTP/1.0\r\n"
275/* "User-Agent: Mozilla/2.0 (Win95; I)\r\n" */
276 "Pragma: no-cache\r\n" "Host: %s\r\n" "Accept: */*\r\n" "\r\n", filename, host);
277
278 send(tcp_sock, http_request, strlen(http_request), 0);
279
280 /* Parse server reply */
281#if 0
282 do
283 read(tcp_sock, &c, sizeof(char));
284 while (c != ' ');
285 read(tcp_sock, http_request, 4 * sizeof(char));
286 http_request[4] = 0;
287 if (strcmp(http_request, "200 "))
288 {
289 fprintf(stderr, "http_open: ");
290 do
291 {
292 read(tcp_sock, &c, sizeof(char));
293 fprintf(stderr, "%c", c);
294 }
295 while (c != '\r');
296 fprintf(stderr, "\n");
297 return (0);
298 }
299#endif
300
301 do
302 {
303 int len;
304
305 len = http_read_line(tcp_sock, http_request, sizeof(http_request));
306
307 if (len == -1)
308 {
309 fprintf(stderr, "http_open: %s\n", strerror(errno));
310 return 0;
311 }
312
313 if (strncmp(http_request, "Location:", 9) == 0)
314 {
315 /* redirect */
316 std::close(tcp_sock);
317
318 http_request[strlen(http_request) - 1] = '\0';
319
320 return http_open(&http_request[10]);
321 }
322
323 if (strncmp(http_request, "ICY ", 4) == 0)
324 {
325 /* This is icecast streaming */
326 if (strncmp(http_request + 4, "200 ", 4))
327 {
328 fprintf(stderr, "http_open: %s\n", http_request);
329 return 0;
330 }
331 }
332 else if (strncmp(http_request, "icy-", 4) == 0)
333 {
334 /* we can have: icy-noticeX, icy-name, icy-genre, icy-url, icy-pub, icy-metaint, icy-br */
335 /* Don't print these - mpg123 doesn't */
336 /* fprintf(stderr,"%s\n",http_request); */
337 }
338 }
339 while (strcmp(http_request, "\n") != 0);
340
341 return (tcp_sock);
342}
343
344
168bool LibMadPlugin::open( const QString& path ) { 345bool LibMadPlugin::open( const QString& path ) {
169 debugMsg( "LibMadPlugin::open" ); 346 debugMsg( "LibMadPlugin::open" );
170 Config cfg("MediaPlayer"); 347 Config cfg("MediaPlayer");
@@ -177,8 +354,14 @@ bool LibMadPlugin::open( const QString& path ) {
177 354
178 //qDebug( "Opening %s", path.latin1() ); 355 //qDebug( "Opening %s", path.latin1() );
179 356
180 d->input.path = path.latin1(); 357
181 d->input.fd = ::open( d->input.path, O_RDONLY ); 358 if (path.left( 4 ) == "http" ) {
359 d->input.fd = http_open(path);
360
361 } else {
362 d->input.path = path.latin1();
363 d->input.fd = ::open( d->input.path, O_RDONLY );
364 }
182 if (d->input.fd == -1) { 365 if (d->input.fd == -1) {
183 qDebug("error opening %s", d->input.path ); 366 qDebug("error opening %s", d->input.path );
184 return FALSE; 367 return FALSE;
@@ -496,7 +679,7 @@ bool LibMadPlugin::audioReadSamples( short *output, int /*channels*/, long sampl
496 debugMsg( "LibMadPlugin::audioReadStereoSamples" ); 679 debugMsg( "LibMadPlugin::audioReadStereoSamples" );
497 680
498 static bool needInput = TRUE; 681 static bool needInput = TRUE;
499 682
500 if ( samples == 0 ) 683 if ( samples == 0 )
501 return FALSE; 684 return FALSE;
502 685
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.h b/core/multimedia/opieplayer/libmad/libmadplugin.h
index 46cd4a1..ee1ca9d 100644
--- a/core/multimedia/opieplayer/libmad/libmadplugin.h
+++ b/core/multimedia/opieplayer/libmad/libmadplugin.h
@@ -17,7 +17,7 @@
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20#ifndef LIBMAD_PLUGIN_H 20#ifndef LIBMAD_PLUGIN_H
21#define LIBMAD_PLUGIN_H 21#define LIBMAD_PLUGIN_H
22 22
23#include <qstring.h> 23#include <qstring.h>
@@ -43,13 +43,14 @@ public:
43 43
44 bool isFileSupported( const QString& ); 44 bool isFileSupported( const QString& );
45 bool open( const QString& ); 45 bool open( const QString& );
46
46 bool close(); 47 bool close();
47 bool isOpen(); 48 bool isOpen();
48 const QString &fileInfo() { return info; } 49 const QString &fileInfo() { return info; }
49 50
50 // If decoder doesn't support audio then return 0 here 51 // If decoder doesn't support audio then return 0 here
51 int audioStreams(); 52 int audioStreams();
52 int audioChannels( int stream ); 53 int audioChannels( int stream );
53 int audioFrequency( int stream ); 54 int audioFrequency( int stream );
54 int audioSamples( int stream ); 55 int audioSamples( int stream );
55 bool audioSetSample( long sample, int stream ); 56 bool audioSetSample( long sample, int stream );
@@ -101,6 +102,10 @@ public:
101 long getPlayTime() { return -1; } 102 long getPlayTime() { return -1; }
102 103
103private: 104private:
105 int tcp_open(char *address, int port);
106 int http_read_line(int tcp_sock, char *buf, int size) ;
107 int http_open(const QString& path );
108
104 LibMadPluginData *d; 109 LibMadPluginData *d;
105 QString info; 110 QString info;
106int bufferSize; 111int bufferSize;