summaryrefslogtreecommitdiff
authorharlekin <harlekin>2002-04-22 22:05:28 (UTC)
committer harlekin <harlekin>2002-04-22 22:05:28 (UTC)
commit1ce5e1128e3c062d45e6dcfbcda20f195b4d5b13 (patch) (unidiff)
tree81303ba33d6f6aa7e56b9ea6ff6d85a7a894ede0
parentf77f012023dbe7582a4b4297f61c6521ad8a3aa5 (diff)
downloadopie-1ce5e1128e3c062d45e6dcfbcda20f195b4d5b13.zip
opie-1ce5e1128e3c062d45e6dcfbcda20f195b4d5b13.tar.gz
opie-1ce5e1128e3c062d45e6dcfbcda20f195b4d5b13.tar.bz2
more updates for shoutcast
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/libmad/libmadplugin.cpp17
1 files changed, 7 insertions, 10 deletions
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.cpp b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
index 0f952f4..8b692ef 100644
--- a/core/multimedia/opieplayer/libmad/libmadplugin.cpp
+++ b/core/multimedia/opieplayer/libmad/libmadplugin.cpp
@@ -217,282 +217,279 @@ int LibMadPlugin::udp_open(char *address, int port) {
217 /* Allow multiple instance of the client to share the same address and port */ 217 /* Allow multiple instance of the client to share the same address and port */
218 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&enable, sizeof(unsigned long int)) < 0) { 218 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&enable, sizeof(unsigned long int)) < 0) {
219 return (0); 219 return (0);
220 } 220 }
221 221
222 /* If the address is multicast, register to the multicast group */ 222 /* If the address is multicast, register to the multicast group */
223 if (is_address_multicast(stAddr.sin_addr.s_addr)) { 223 if (is_address_multicast(stAddr.sin_addr.s_addr)) {
224 /* Bind the socket to port */ 224 /* Bind the socket to port */
225 stLclAddr.sin_family = AF_INET; 225 stLclAddr.sin_family = AF_INET;
226 stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); 226 stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY);
227 stLclAddr.sin_port = stAddr.sin_port; 227 stLclAddr.sin_port = stAddr.sin_port;
228 if (bind(sock, (struct sockaddr *)&stLclAddr, sizeof(stLclAddr)) < 0) { 228 if (bind(sock, (struct sockaddr *)&stLclAddr, sizeof(stLclAddr)) < 0) {
229 return (0); 229 return (0);
230 } 230 }
231 231
232 /* Register to a multicast address */ 232 /* Register to a multicast address */
233 stMreq.imr_multiaddr.s_addr = stAddr.sin_addr.s_addr; 233 stMreq.imr_multiaddr.s_addr = stAddr.sin_addr.s_addr;
234 stMreq.imr_interface.s_addr = INADDR_ANY; 234 stMreq.imr_interface.s_addr = INADDR_ANY;
235 if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&stMreq, sizeof(stMreq)) < 0) { 235 if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&stMreq, sizeof(stMreq)) < 0) {
236 return (0); 236 return (0);
237 } 237 }
238 } else { 238 } else {
239 /* Bind the socket to port */ 239 /* Bind the socket to port */
240 stLclAddr.sin_family = AF_INET; 240 stLclAddr.sin_family = AF_INET;
241 stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); 241 stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY);
242 stLclAddr.sin_port = htons(0); 242 stLclAddr.sin_port = htons(0);
243 if (bind(sock, (struct sockaddr *)&stLclAddr, sizeof(stLclAddr)) < 0) { 243 if (bind(sock, (struct sockaddr *)&stLclAddr, sizeof(stLclAddr)) < 0) {
244 return (0); 244 return (0);
245 } 245 }
246 } 246 }
247 return (sock); 247 return (sock);
248} 248}
249 249
250int LibMadPlugin::tcp_open(char *address, int port) { 250int LibMadPlugin::tcp_open(char *address, int port) {
251 struct sockaddr_in stAddr; 251 struct sockaddr_in stAddr;
252 struct hostent *host; 252 struct hostent *host;
253 int sock; 253 int sock;
254 struct linger l; 254 struct linger l;
255 255
256 memset(&stAddr, 0, sizeof(stAddr)); 256 memset(&stAddr, 0, sizeof(stAddr));
257 stAddr.sin_family = AF_INET; 257 stAddr.sin_family = AF_INET;
258 stAddr.sin_port = htons(port); 258 stAddr.sin_port = htons(port);
259 259
260 if ((host = gethostbyname(address)) == NULL) { 260 if ((host = gethostbyname(address)) == NULL) {
261 return (0); 261 return (0);
262 } 262 }
263 263
264 stAddr.sin_addr = *((struct in_addr *)host->h_addr_list[0]); 264 stAddr.sin_addr = *((struct in_addr *)host->h_addr_list[0]);
265 265
266 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { 266 if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
267 return (0); 267 return (0);
268 } 268 }
269 269
270 l.l_onoff = 1; 270 l.l_onoff = 1;
271 l.l_linger = 5; 271 l.l_linger = 5;
272 if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)) < 0) { 272 if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)) < 0) {
273 return (0); 273 return (0);
274 } 274 }
275 275
276 if (connect(sock, (struct sockaddr *)&stAddr, sizeof(stAddr)) < 0) { 276 if (connect(sock, (struct sockaddr *)&stAddr, sizeof(stAddr)) < 0) {
277 return (0); 277 return (0);
278 } 278 }
279 279
280 return (sock); 280 return (sock);
281} 281}
282 282
283 283
284/** 284/**
285 * Read a http line header. 285 * Read a http line header.
286 * This function read character by character. 286 * This function read character by character.
287 * @param tcp_sock the socket use to read the stream 287 * @param tcp_sock the socket use to read the stream
288 * @param buf a buffer to receive the data 288 * @param buf a buffer to receive the data
289 * @param size size of the buffer 289 * @param size size of the buffer
290 * @return the size of the stream read or -1 if an error occured 290 * @return the size of the stream read or -1 if an error occured
291 */ 291 */
292int LibMadPlugin::http_read_line(int tcp_sock, char *buf, int size) { 292int LibMadPlugin::http_read_line(int tcp_sock, char *buf, int size) {
293 int offset = 0; 293 int offset = 0;
294 294
295 do { 295 do {
296 if (std::read(tcp_sock, buf + offset, 1) < 0) 296 if (std::read(tcp_sock, buf + offset, 1) < 0)
297 return -1; 297 return -1;
298 if (buf[offset] != '\r') /* Strip \r from answer */ 298 if (buf[offset] != '\r') /* Strip \r from answer */
299 offset++; 299 offset++;
300 } while (offset < size - 1 && buf[offset - 1] != '\n'); 300 } while (offset < size - 1 && buf[offset - 1] != '\n');
301 301
302 buf[offset] = 0; 302 buf[offset] = 0;
303 return offset; 303 return offset;
304} 304}
305 305
306int LibMadPlugin::http_open(const QString& path ) { 306int LibMadPlugin::http_open(const QString& path ) {
307 char *host; 307 char *host;
308 int port; 308 int port;
309 char *request; 309 char *request;
310 int tcp_sock; 310 int tcp_sock;
311 char http_request[PATH_MAX]; 311 char http_request[PATH_MAX];
312 char filename[PATH_MAX]; 312 char filename[PATH_MAX];
313 char c; 313 //char c;
314 char *arg =strdup(path.latin1()); 314 char *arg =strdup(path.latin1());
315 315
316 /* Check for URL syntax */ 316 /* Check for URL syntax */
317 if (strncmp(arg, "http://", strlen("http://"))) { 317 if (strncmp(arg, "http://", strlen("http://"))) {
318 return (0); 318 return (0);
319 } 319 }
320 320
321 /* Parse URL */ 321 /* Parse URL */
322 port = 80; 322 port = 80;
323 host = arg + strlen("http://"); 323 host = arg + strlen("http://");
324 if ((request = strchr(host, '/')) == NULL) { 324 if ((request = strchr(host, '/')) == NULL) {
325 return (0); 325 return (0);
326 } 326 }
327 327
328 *request++ = 0; 328 *request++ = 0;
329 329
330 if (strchr(host, ':') != NULL) { /* port is specified */ 330 if (strchr(host, ':') != NULL) { /* port is specified */
331 port = atoi(strchr(host, ':') + 1); 331 port = atoi(strchr(host, ':') + 1);
332 *strchr(host, ':') = 0; 332 *strchr(host, ':') = 0;
333 } 333 }
334 334
335 /* Open a TCP socket */ 335 /* Open a TCP socket */
336 if (!(tcp_sock = tcp_open(host, port))) { 336 if (!(tcp_sock = tcp_open(host, port))) {
337 perror("http_open"); 337 perror("http_open");
338 return (0); 338 return (0);
339 } 339 }
340 340
341 snprintf(filename, sizeof(filename) - strlen(host) - 75, "%s", request); 341 snprintf(filename, sizeof(filename) - strlen(host) - 75, "%s", request);
342 342
343 /* Send HTTP GET request */ 343 /* Send HTTP GET request */
344 /* Please don't use a Agent know by shoutcast (Lynx, Mozilla) seems to be reconized and print 344 /* Please don't use a Agent know by shoutcast (Lynx, Mozilla) seems to be reconized and print
345 * a html page and not the stream */ 345 * a html page and not the stream */
346 snprintf(http_request, sizeof(http_request), "GET /%s HTTP/1.0\r\n" 346 snprintf(http_request, sizeof(http_request), "GET /%s HTTP/1.0\r\n"
347 /* "User-Agent: Mozilla/2.0 (Win95; I)\r\n" */ 347 /* "User-Agent: Mozilla/2.0 (Win95; I)\r\n" */
348 "Pragma: no-cache\r\n" "Host: %s\r\n" "Accept: */*\r\n" "\r\n", filename, host); 348 "Pragma: no-cache\r\n" "Host: %s\r\n" "Accept: */*\r\n" "\r\n", filename, host);
349 349
350 send(tcp_sock, http_request, strlen(http_request), 0); 350 send(tcp_sock, http_request, strlen(http_request), 0);
351 351
352 /* Parse server reply */ 352 /* Parse server reply */
353#if 0 353#if 0
354 do 354 do
355 read(tcp_sock, &c, sizeof(char)); 355 read(tcp_sock, &c, sizeof(char));
356 while (c != ' '); 356 while (c != ' ');
357 read(tcp_sock, http_request, 4 * sizeof(char)); 357 read(tcp_sock, http_request, 4 * sizeof(char));
358 http_request[4] = 0; 358 http_request[4] = 0;
359 if (strcmp(http_request, "200 ")) { 359 if (strcmp(http_request, "200 ")) {
360 fprintf(stderr, "http_open: "); 360 fprintf(stderr, "http_open: ");
361 do { 361 do {
362 read(tcp_sock, &c, sizeof(char)); 362 read(tcp_sock, &c, sizeof(char));
363 fprintf(stderr, "%c", c); 363 fprintf(stderr, "%c", c);
364 } while (c != '\r'); 364 } while (c != '\r');
365 fprintf(stderr, "\n"); 365 fprintf(stderr, "\n");
366 return (0); 366 return (0);
367 } 367 }
368#endif 368#endif
369 369
370 QString name; 370 QString name;
371 QString genre; 371 QString genre;
372 QString bitrate; 372 QString bitrate;
373 QString url; 373 QString url;
374 QString message = tr("Info: "); 374 QString message = tr("Info: ");
375
376 do { 375 do {
377 376
378 int len; 377 int len;
379 378
380 len = http_read_line(tcp_sock, http_request, sizeof(http_request)); 379 len = http_read_line(tcp_sock, http_request, sizeof(http_request));
381 380
382 if (len == -1) { 381 if (len == -1) {
383 fprintf(stderr, "http_open: %s\n", strerror(errno)); 382 qDebug( "http_open: "+ QString(strerror(errno)) +"\n");
384 return 0; 383 return 0;
385 } 384 }
386 385
387 if (strncmp(http_request, "Location:", 9) == 0) { 386 if (QString(http_request).left(9) == "Location:") {
388 /* redirect */ 387 /* redirect */
389 std::close(tcp_sock); 388 std::close(tcp_sock);
390
391 http_request[strlen(http_request) - 1] = '\0'; 389 http_request[strlen(http_request) - 1] = '\0';
392
393 return http_open(&http_request[10]); 390 return http_open(&http_request[10]);
394 } 391 }
395 392
396 if (strncmp(http_request, "ICY ", 4) == 0) { 393 if (QString(http_request).left(4) == "ICY ") {
397 /* This is icecast streaming */ 394 /* This is shoutcast/icecast streaming */
398 if (strncmp(http_request + 4, "200 ", 4)) { 395 if (strncmp(http_request + 4, "200 ", 4)) {
399 fprintf(stderr, "http_open: %s\n", http_request); 396 qDebug("http_open: " + QString(http_request) + "\n");
400 return 0; 397 return 0;
401 } 398 }
402 } else if (strncmp(http_request, "icy-", 4) == 0) { 399 } else if (QString(http_request).left(4) == "icy-") {
403 /* we can have: icy-noticeX, icy-name, icy-genre, icy-url, icy-pub, icy-metaint, icy-br */ 400 /* we can have: icy-noticeX, icy-name, icy-genre, icy-url, icy-pub, icy-metaint, icy-br */
404 if ( QString( http_request ).left( 8 ) == "icy-name" ) { 401 if ( QString( http_request ).left( 8 ) == "icy-name" ) {
405 name = tr("Name: ") + QString(http_request).mid(9, (QString(http_request).length())- 9 ); 402 name = tr("Name: ") + QString(http_request).mid(9, (QString(http_request).length())- 9 );
406 } else if ( QString( http_request ).left( 9 ) == "icy-genre" ) { 403 } else if ( QString( http_request ).left( 9 ) == "icy-genre" ) {
407 genre = tr("Genre: ") + QString(http_request).mid(10, (QString(http_request).length())-10 ); 404 genre = tr("Genre: ") + QString(http_request).mid(10, (QString(http_request).length())-10 );
408 } else if ( QString( http_request ).left( 6 ) == "icy-br" ) { 405 } else if ( QString( http_request ).left( 6 ) == "icy-br" ) {
409 bitrate = tr("Bitrate: ") + QString(http_request).mid(7, (QString(http_request).length())- 7 ); 406 bitrate = tr("Bitrate: ") + QString(http_request).mid(7, (QString(http_request).length())- 7 );
410 } else if ( QString( http_request ).left( 7 ) == "icy-url" ) { 407 } else if ( QString( http_request ).left( 7 ) == "icy-url" ) {
411 url = tr("URL: ") + QString(http_request).mid(8, (QString(http_request).length())- 8 ); 408 url = tr("URL: ") + QString(http_request).mid(8, (QString(http_request).length())- 8 );
412 } else if ( QString( http_request ).left( 10 ) == "icy-notice" ) { 409 } else if ( QString( http_request ).left( 10 ) == "icy-notice" ) {
413 message += QString(http_request).mid(11, QString(http_request).length()-11 ) ; 410 message += QString(http_request).mid(11, QString(http_request).length()-11 ) ;
414 } 411 }
415 } 412 }
416 } while (strcmp(http_request, "\n") != 0); 413 } while (strcmp(http_request, "\n") != 0);
417 414
418 info = QString(name + genre + url + bitrate + message).replace( QRegExp("\n"), " : " ); 415 info = QString(name + genre + url + bitrate + message).replace( QRegExp("\n"), " : " );
419 416
420 qDebug("Stream info: " + info); 417 qDebug("Stream info: " + info);
421 418
422 return (tcp_sock); 419 return (tcp_sock);
423} 420}
424 421
425 422
426 423
427bool LibMadPlugin::open( const QString& path ) { 424bool LibMadPlugin::open( const QString& path ) {
428 debugMsg( "LibMadPlugin::open" ); 425 debugMsg( "LibMadPlugin::open" );
429 Config cfg("MediaPlayer"); 426 Config cfg("MediaPlayer");
430 cfg.setGroup("Options"); 427 cfg.setGroup("Options");
431 bufferSize = cfg.readNumEntry("MPeg_BufferSize",MPEG_BUFFER_SIZE); 428 bufferSize = cfg.readNumEntry("MPeg_BufferSize",MPEG_BUFFER_SIZE);
432 qDebug("buffer size is %d", bufferSize); 429 qDebug("buffer size is %d", bufferSize);
433 d->bad_last_frame = 0; 430 d->bad_last_frame = 0;
434 d->flush = TRUE; 431 d->flush = TRUE;
435 info = QString( "" ); 432 info = QString( "" );
436 433
437 //qDebug( "Opening %s", path.latin1() ); 434 //qDebug( "Opening %s", path.latin1() );
438 435
439 436
440 if (path.left( 4 ) == "http" ) { 437 if (path.left( 4 ) == "http" ) {
441 // in case of any error we get 0 here 438 // in case of any error we get 0 here
442 if ( !(http_open(path)==0) ) { 439 if ( !(http_open(path)==0) ) {
443 d->input.fd = http_open(path); 440 d->input.fd = http_open(path);
444 } 441 }
445 } else { 442 } else {
446 d->input.path = path.latin1(); 443 d->input.path = path.latin1();
447 d->input.fd = ::open( d->input.path, O_RDONLY ); 444 d->input.fd = ::open( d->input.path, O_RDONLY );
448 // thats a better place, since it should only seek for ID3 tags on mp3 files, not streams 445 // thats a better place, since it should only seek for ID3 tags on mp3 files, not streams
449 printID3Tags(); 446 printID3Tags();
450 } 447 }
451 if (d->input.fd == -1) { 448 if (d->input.fd == -1) {
452// qDebug("error opening %s", d->input.path ); 449// qDebug("error opening %s", d->input.path );
453 return FALSE; 450 return FALSE;
454 } 451 }
455 452
456// printID3Tags(); 453// printID3Tags();
457 454
458#if defined(HAVE_MMAP) 455#if defined(HAVE_MMAP)
459 struct stat stat; 456 struct stat stat;
460 if (fstat(d->input.fd, &stat) == -1) { 457 if (fstat(d->input.fd, &stat) == -1) {
461 //qDebug("error calling fstat"); return FALSE; 458 //qDebug("error calling fstat"); return FALSE;
462 } 459 }
463 if (S_ISREG(stat.st_mode) && stat.st_size > 0) { 460 if (S_ISREG(stat.st_mode) && stat.st_size > 0) {
464 d->input.length = stat.st_size; 461 d->input.length = stat.st_size;
465 d->input.fdm = map_file(d->input.fd, &d->input.length); 462 d->input.fdm = map_file(d->input.fd, &d->input.length);
466 if (d->input.fdm == 0) { 463 if (d->input.fdm == 0) {
467 qDebug("error mmapping file"); return FALSE; 464 qDebug("error mmapping file"); return FALSE;
468 } 465 }
469 d->input.data = (unsigned char *)d->input.fdm; 466 d->input.data = (unsigned char *)d->input.fdm;
470 } 467 }
471#endif 468#endif
472 469
473 if (d->input.data == 0) { 470 if (d->input.data == 0) {
474 d->input.data = (unsigned char *)malloc( bufferSize /*MPEG_BUFFER_SIZE*/); 471 d->input.data = (unsigned char *)malloc( bufferSize /*MPEG_BUFFER_SIZE*/);
475 if (d->input.data == 0) { 472 if (d->input.data == 0) {
476 qDebug("error allocating input buffer"); 473 qDebug("error allocating input buffer");
477 return FALSE; 474 return FALSE;
478 } 475 }
479 d->input.length = 0; 476 d->input.length = 0;
480 } 477 }
481 478
482 d->input.eof = 0; 479 d->input.eof = 0;
483 480
484 mad_stream_init(&d->stream); 481 mad_stream_init(&d->stream);
485 mad_frame_init(&d->frame); 482 mad_frame_init(&d->frame);
486 mad_synth_init(&d->synth); 483 mad_synth_init(&d->synth);
487 484
488 return TRUE; 485 return TRUE;
489} 486}
490 487
491 488
492bool LibMadPlugin::close() { 489bool LibMadPlugin::close() {
493 debugMsg( "LibMadPlugin::close" ); 490 debugMsg( "LibMadPlugin::close" );
494 491
495 int result = TRUE; 492 int result = TRUE;
496 493
497 mad_synth_finish(&d->synth); 494 mad_synth_finish(&d->synth);
498 mad_frame_finish(&d->frame); 495 mad_frame_finish(&d->frame);