mirror of
http://mpg123.de/trunk/.git
synced 2025-08-06 10:02:38 +03:00
Essential part of ICY support. It's in reader and http_open.
Missing is only proper output - and, that it actually works:-/ There is something fishy in the reader... git-svn-id: svn://scm.orgis.org/mpg123/trunk@536 35dc7657-300d-0410-a2e5-dc2837fedb53
This commit is contained in:
@@ -57,7 +57,7 @@ sub printdefs
|
||||
unshift(@args, '') if(@args);
|
||||
print ' #define '.$type.($i > 1 ? ($i-1) : '').'(s';
|
||||
print join(', ', @args).') ';
|
||||
if($forreal){ print 'fprintf(stderr, "[" __FILE__ ":%i] '.$type.': " s "\n", __LINE__'.join(', ', @args).")\n"; }
|
||||
if($forreal){ print 'fprintf(stderr, "[" __FILE__ ":%i] '.$type.': " s "\n", __LINE__'.join(', ', @args).");\n"; }
|
||||
else{ print "{}\n"; }
|
||||
}
|
||||
}
|
||||
|
@@ -32,6 +32,8 @@ mpg123_SOURCES = \
|
||||
getlopt.h \
|
||||
httpget.c \
|
||||
huffman.h \
|
||||
icy.c \
|
||||
icy.h \
|
||||
id3.c \
|
||||
id3.h \
|
||||
genre.h \
|
||||
|
@@ -610,12 +610,12 @@ generic:
|
||||
mpg123-make:
|
||||
@ $(MAKE) BINNAME=mpg123 mpg123
|
||||
|
||||
mpg123: mpg123.o playlist.o stringbuf.o common.o id3.o $(OBJECTS) decode_2to1.o decode_4to1.o \
|
||||
mpg123: mpg123.o playlist.o stringbuf.o common.o id3.o icy.o $(OBJECTS) decode_2to1.o decode_4to1.o \
|
||||
tabinit.o audio.o layer1.o layer2.o layer3.o buffer.o \
|
||||
getlopt.o httpget.o xfermem.o equalizer.o \
|
||||
decode_ntom.o $(MAKEFILE) wav.o readers.o getbits.o \
|
||||
control_generic.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) mpg123.o playlist.o stringbuf.o tabinit.o common.o id3.o layer1.o \
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) mpg123.o playlist.o stringbuf.o tabinit.o common.o id3.o icy.o layer1.o \
|
||||
layer2.o layer3.o audio.o buffer.o decode_2to1.o equalizer.o \
|
||||
decode_4to1.o getlopt.o httpget.o xfermem.o decode_ntom.o \
|
||||
wav.o readers.o getbits.o control_generic.o \
|
||||
@@ -653,7 +653,7 @@ buffer.o: mpg123.h xfermem.h buffer.h debug.h config.h
|
||||
getbits.o: common.h mpg123.h debug.h config.h
|
||||
tabinit.o: mpg123.h audio.h debug.h config.h
|
||||
getlopt.o: getlopt.h debug.h config.h
|
||||
httpget.o: mpg123.h debug.h config.h
|
||||
httpget.o: mpg123.h debug.h config.h icy.h stringbuf.h
|
||||
dct64.o: mpg123.h debug.h config.h
|
||||
dct64_i386.o: mpg123.h debug.h config.h
|
||||
xfermem.o: xfermem.h debug.h config.h
|
||||
@@ -664,6 +664,7 @@ term.o: mpg123.h buffer.h term.h common.h debug.h config.h
|
||||
playlist.o: mpg123.h term.h getlopt.h debug.h config.h stringbuf.h
|
||||
stringbuf.o: stringbuf.h config.h debug.h
|
||||
id3.o: config.h mpg123.h stringbuf.h genre.h id3.h debug.h common.h
|
||||
icy.o: icy.h stringbuf.h
|
||||
control_generic.o: config.h mpg123.h common.h debug.h layer3.h
|
||||
|
||||
|
||||
|
66
src/debug.h
66
src/debug.h
@@ -26,17 +26,17 @@
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#define debug(s) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__)
|
||||
#define debug1(s, a) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a)
|
||||
#define debug2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b)
|
||||
#define debug3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c)
|
||||
#define debug4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d)
|
||||
#define debug5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e)
|
||||
#define debug6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f)
|
||||
#define debug7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g)
|
||||
#define debug8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
|
||||
#define debug9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
|
||||
#define debug10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
|
||||
#define debug(s) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__);
|
||||
#define debug1(s, a) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a);
|
||||
#define debug2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b);
|
||||
#define debug3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c);
|
||||
#define debug4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d);
|
||||
#define debug5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e);
|
||||
#define debug6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f);
|
||||
#define debug7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g);
|
||||
#define debug8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h);
|
||||
#define debug9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i);
|
||||
#define debug10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] debug: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j);
|
||||
#else
|
||||
#define debug(s) {}
|
||||
#define debug1(s, a) {}
|
||||
@@ -52,27 +52,27 @@
|
||||
#endif
|
||||
|
||||
/* warning macros also here... */
|
||||
#define warning(s) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__)
|
||||
#define warning1(s, a) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a)
|
||||
#define warning2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b)
|
||||
#define warning3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c)
|
||||
#define warning4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d)
|
||||
#define warning5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e)
|
||||
#define warning6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f)
|
||||
#define warning7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g)
|
||||
#define warning8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
|
||||
#define warning9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
|
||||
#define warning10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
|
||||
#define warning(s) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__);
|
||||
#define warning1(s, a) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a);
|
||||
#define warning2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b);
|
||||
#define warning3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c);
|
||||
#define warning4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d);
|
||||
#define warning5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e);
|
||||
#define warning6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f);
|
||||
#define warning7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g);
|
||||
#define warning8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h);
|
||||
#define warning9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i);
|
||||
#define warning10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] warning: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j);
|
||||
|
||||
/* error macros also here... */
|
||||
#define error(s) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__)
|
||||
#define error1(s, a) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a)
|
||||
#define error2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b)
|
||||
#define error3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c)
|
||||
#define error4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d)
|
||||
#define error5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e)
|
||||
#define error6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f)
|
||||
#define error7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g)
|
||||
#define error8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h)
|
||||
#define error9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i)
|
||||
#define error10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j)
|
||||
#define error(s) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__);
|
||||
#define error1(s, a) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a);
|
||||
#define error2(s, a, b) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b);
|
||||
#define error3(s, a, b, c) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c);
|
||||
#define error4(s, a, b, c, d) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d);
|
||||
#define error5(s, a, b, c, d, e) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e);
|
||||
#define error6(s, a, b, c, d, e, f) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f);
|
||||
#define error7(s, a, b, c, d, e, f, g) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g);
|
||||
#define error8(s, a, b, c, d, e, f, g, h) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h);
|
||||
#define error9(s, a, b, c, d, e, f, g, h, i) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i);
|
||||
#define error10(s, a, b, c, d, e, f, g, h, i, j) fprintf(stderr, "[" __FILE__ ":%i] error: " s "\n", __LINE__, a, b, c, d, e, f, g, h, i, j);
|
||||
|
@@ -58,6 +58,8 @@
|
||||
#include "config.h"
|
||||
#include "mpg123.h"
|
||||
#include "debug.h"
|
||||
#include "stringbuf.h"
|
||||
#include "icy.h"
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE 0xffffffff
|
||||
@@ -207,6 +209,29 @@ char *url2hostport (char *url, char **hname, unsigned long *hip, unsigned int *p
|
||||
return (cptr);
|
||||
}
|
||||
|
||||
char* get_header_val(const char *hname, char* response, size_t *length)
|
||||
{
|
||||
char *tmp = NULL;
|
||||
size_t len = 0;
|
||||
size_t prelen = strlen(hname);
|
||||
/* if header name found, next char is at least something, so just check for : */
|
||||
if(!strncasecmp(hname, response, prelen) && (response[prelen] == ':'))
|
||||
{
|
||||
++prelen;
|
||||
if((tmp = strchr(response, '\r')) != NULL ) tmp[0] = 0;
|
||||
if((tmp = strchr(response, '\n')) != NULL ) tmp[0] = 0;
|
||||
len = strlen(response)-prelen;
|
||||
tmp = response+prelen;
|
||||
while(len && ((tmp[0] == ' ') || (tmp[0] == '\t')))
|
||||
{
|
||||
++tmp;
|
||||
--len;
|
||||
}
|
||||
}
|
||||
*length = len;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char *proxyurl = NULL;
|
||||
unsigned long proxyip = 0;
|
||||
unsigned int proxyport;
|
||||
@@ -215,6 +240,9 @@ unsigned int proxyport;
|
||||
/* #define CONN_HEAD "Connection: close\r\n" */
|
||||
#define CONN_HEAD ""
|
||||
|
||||
/* shoutcsast meta data: 1=on, 0=off */
|
||||
#define ACCEPT_ICY_META "Icy-MetaData: 0\r\n"
|
||||
|
||||
char *httpauth = NULL;
|
||||
char *httpauth1 = NULL;
|
||||
|
||||
@@ -320,9 +348,10 @@ int http_open (char* url, char** content_type)
|
||||
* ACCEPT_HEAD strlen(ACCEPT_HEAD)
|
||||
* "Authorization: Basic \r\n" 23
|
||||
* "\r\n" 2
|
||||
* ... plus the other predefined header lines
|
||||
*/
|
||||
linelengthbase = 62 + strlen(PACKAGE_NAME) + strlen(PACKAGE_VERSION)
|
||||
+ strlen(ACCEPT_HEAD) + strlen(CONN_HEAD);
|
||||
+ strlen(ACCEPT_HEAD) + strlen(CONN_HEAD) + strlen(ACCEPT_ICY_META);
|
||||
|
||||
if(httpauth) {
|
||||
tmp = (strlen(httpauth) + 1) * 4;
|
||||
@@ -482,6 +511,7 @@ int http_open (char* url, char** content_type)
|
||||
} */
|
||||
strcat (request, ACCEPT_HEAD);
|
||||
strcat (request, CONN_HEAD);
|
||||
strcat (request, ACCEPT_ICY_META);
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons(myport);
|
||||
server.sin_addr.s_addr = myip;
|
||||
@@ -622,24 +652,14 @@ int http_open (char* url, char** content_type)
|
||||
}
|
||||
else
|
||||
{
|
||||
char *tmp;
|
||||
size_t len;
|
||||
/* watch out for content type */
|
||||
debug1("searching for content-type... %s", response);
|
||||
if(!strncasecmp("content-type:", response, 13))
|
||||
debug1("searching for header values... %s", response);
|
||||
if((tmp = get_header_val("content-type", response, &len)))
|
||||
{
|
||||
if(content_type != NULL)
|
||||
{
|
||||
char *tmp = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
if((tmp = strchr(response, '\r')) != NULL ) tmp[0] = 0;
|
||||
if((tmp = strchr(response, '\n')) != NULL ) tmp[0] = 0;
|
||||
len = strlen(response)-13;
|
||||
tmp = response+13;
|
||||
while(len && ((tmp[0] == ' ') || (tmp[0] == '\t')))
|
||||
{
|
||||
++tmp;
|
||||
--len;
|
||||
}
|
||||
if(len)
|
||||
{
|
||||
if(*content_type != NULL) free(*content_type);
|
||||
@@ -650,10 +670,28 @@ int http_open (char* url, char** content_type)
|
||||
(*content_type)[len] = 0;
|
||||
debug1("got type %s", *content_type);
|
||||
}
|
||||
else fprintf(stderr, "Error: canno allocate memory for content type!\n");
|
||||
else error("cannot allocate memory for content type!");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* watch out for icy-name */
|
||||
else if((tmp = get_header_val("icy-name", response, &len)))
|
||||
{
|
||||
if(set_stringbuf(&icy.name, tmp)) debug1("got icy-name %s", icy.name.p)
|
||||
else error1("unable to set icy name to %s!", tmp)
|
||||
}
|
||||
/* watch out for icy-url */
|
||||
else if((tmp = get_header_val("icy-url", response, &len)))
|
||||
{
|
||||
if(set_stringbuf(&icy.url, tmp)) debug1("got icy-url %s", icy.name.p)
|
||||
else error1("unable to set icy url to %s!", tmp)
|
||||
}
|
||||
/* watch out for icy-metaint */
|
||||
else if((tmp = get_header_val("icy-metaint", response, &len)))
|
||||
{
|
||||
icy.interval = atoi(tmp);
|
||||
debug1("got icy-metaint %li", (long int)icy.interval);
|
||||
}
|
||||
}
|
||||
} while (response[0] != '\r' && response[0] != '\n');
|
||||
} while (relocate && purl[0] && numrelocs++ < HTTP_MAX_RELOCATIONS);
|
||||
|
30
src/icy.c
Normal file
30
src/icy.c
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "icy.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
struct icy_meta icy;
|
||||
|
||||
void init_icy()
|
||||
{
|
||||
init_stringbuf(&icy.name);
|
||||
init_stringbuf(&icy.url);
|
||||
icy.data = NULL;
|
||||
icy.interval = 0;
|
||||
icy.next = 0;
|
||||
icy.changed = 0;
|
||||
}
|
||||
|
||||
void clear_icy()
|
||||
{
|
||||
/* if pointers are non-null, they have some memory */
|
||||
free_stringbuf(&icy.name);
|
||||
free_stringbuf(&icy.url);
|
||||
free(icy.data);
|
||||
init_icy();
|
||||
}
|
||||
|
||||
void set_data(char* new_data)
|
||||
{
|
||||
if(icy.data) free(icy.data);
|
||||
icy.data = new_data;
|
||||
icy.changed = 1;
|
||||
}
|
26
src/icy.h
Normal file
26
src/icy.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
icy: support for SHOUTcast ICY meta info, an attempt to keep it organized
|
||||
|
||||
copyright 2006 by the mpg123 project - free software under the terms of the LGPL 2.1
|
||||
see COPYING and AUTHORS files in distribution or http://mpg123.de
|
||||
initially written by Thomas Orgis and modelled after patch by Honza
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "stringbuf.h"
|
||||
|
||||
struct icy_meta
|
||||
{
|
||||
struct stringbuf name;
|
||||
struct stringbuf url;
|
||||
char* data;
|
||||
off_t interval;
|
||||
off_t next;
|
||||
int changed;
|
||||
};
|
||||
|
||||
/* bah, just make it global... why bother with all that poiner passing to "methods" when there will be only one? */
|
||||
extern struct icy_meta icy;
|
||||
|
||||
void init_icy();
|
||||
void clear_icy();
|
@@ -36,6 +36,7 @@
|
||||
#endif
|
||||
#include "playlist.h"
|
||||
#include "id3.h"
|
||||
#include "icy.h"
|
||||
|
||||
static void usage(int err);
|
||||
static void want_usage(char* arg);
|
||||
@@ -814,12 +815,15 @@ int main(int argc, char *argv[])
|
||||
if(param.remote) {
|
||||
int ret;
|
||||
init_id3();
|
||||
init_icy();
|
||||
ret = control_generic(&fr);
|
||||
clear_icy();
|
||||
exit_id3();
|
||||
safe_exit(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
init_icy();
|
||||
init_id3(); /* prepare id3 memory */
|
||||
while ((fname = get_next_file())) {
|
||||
char *dirname, *filename;
|
||||
@@ -1025,6 +1029,7 @@ tc_hack:
|
||||
#endif
|
||||
}
|
||||
} /* end of loop over input files */
|
||||
clear_icy();
|
||||
exit_id3(); /* free id3 memory */
|
||||
#ifndef NOXFERMEM
|
||||
if (param.usebuffer) {
|
||||
|
@@ -17,11 +17,87 @@
|
||||
#include "debug.h"
|
||||
#include "buffer.h"
|
||||
#include "common.h"
|
||||
#include "icy.h"
|
||||
|
||||
static off_t get_fileinfo(struct reader *,char *buf);
|
||||
|
||||
static ssize_t icy_fullread(struct reader *rds,unsigned char *buf, ssize_t count);
|
||||
static ssize_t plain_fullread(struct reader *rds,unsigned char *buf, ssize_t count);
|
||||
ssize_t (*fullread)(struct reader *,unsigned char *, ssize_t) = plain_fullread;
|
||||
|
||||
/* stream based operation with icy meta data*/
|
||||
static ssize_t icy_fullread(struct reader *rds,unsigned char *buf, ssize_t count)
|
||||
{
|
||||
ssize_t ret,cnt;
|
||||
cnt = 0;
|
||||
|
||||
/*
|
||||
We check against READER_ID3TAG instead of rds->filelen >= 0 because if we got the ID3 TAG we know we have the end of the file.
|
||||
If we don't have an ID3 TAG, then it is possible the file has grown since we started playing, so we want to keep reading from it if possible.
|
||||
*/
|
||||
if((rds->flags & READER_ID3TAG) && rds->filepos + count > rds->filelen) count = rds->filelen - rds->filepos;
|
||||
|
||||
while(cnt < count)
|
||||
{
|
||||
/* all icy code is inside this if block, everything else is the plain fullread we know */
|
||||
if(icy.interval && (rds->filepos+count > icy.next))
|
||||
{
|
||||
char temp_buff;
|
||||
int meta_size;
|
||||
ssize_t cut_pos;
|
||||
|
||||
/* we are near icy-metaint boundary, read up to the boundary */
|
||||
cut_pos = icy.next-rds->filepos;
|
||||
ret = read(rds->filept,buf,cut_pos);
|
||||
if(ret < 0) return ret;
|
||||
|
||||
rds->filepos += ret;
|
||||
cnt += ret;
|
||||
|
||||
/* now off to read icy data */
|
||||
|
||||
/* one byte icy-meta size (must be multiplied by 16 to get icy-meta length) */
|
||||
ret = read(rds->filept,&temp_buff,1);
|
||||
if(ret < 0) return ret;
|
||||
if(ret == 0) break;
|
||||
|
||||
rds->filepos += ret; /* 1... */
|
||||
|
||||
if((meta_size = (unsigned int) temp_buff * 16))
|
||||
{
|
||||
/* we have got some metadata */
|
||||
char *meta_buff;
|
||||
meta_buff = (char*) malloc(meta_size+1);
|
||||
meta_buff[meta_size] = 0; /* string paranoia */
|
||||
if(meta_buff != NULL)
|
||||
{
|
||||
ret = read(rds->filept,meta_buff,meta_size);
|
||||
if(ret < 0) return ret;
|
||||
|
||||
rds->filepos += ret;
|
||||
|
||||
if(icy.data) free(icy.data);
|
||||
icy.data = meta_buff;
|
||||
icy.changed = 1;
|
||||
debug2("icy-meta: %s size: %d bytes", icy.data, meta_size);
|
||||
}
|
||||
else error("cannot allocate memory for meta_buff!");
|
||||
}
|
||||
icy.next = rds->filepos+icy.interval;
|
||||
}
|
||||
|
||||
ret = read(rds->filept,buf+cnt,count-cnt);
|
||||
if(ret < 0) return ret;
|
||||
if(ret == 0) break;
|
||||
|
||||
rds->filepos += ret;
|
||||
cnt += ret;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
/* stream based operation */
|
||||
static ssize_t fullread(struct reader *rds,unsigned char *buf, ssize_t count)
|
||||
static ssize_t plain_fullread(struct reader *rds,unsigned char *buf, ssize_t count)
|
||||
{
|
||||
ssize_t ret,cnt=0;
|
||||
|
||||
@@ -275,6 +351,7 @@ int open_stream(char *bs_filenam,int fd)
|
||||
int filept_opened = 1;
|
||||
int filept; /* descriptor of opened file/stream */
|
||||
|
||||
clear_icy();
|
||||
if(!bs_filenam) /* no file to open, got a descriptor (stdin) */
|
||||
{
|
||||
if(fd < 0) /* special: read from stdin */
|
||||
@@ -328,6 +405,8 @@ int open_stream(char *bs_filenam,int fd)
|
||||
}
|
||||
}
|
||||
|
||||
if(icy.interval) fullread = icy_fullread;
|
||||
fullread = icy_fullread;
|
||||
/* id3tag printing moved to read_frame */
|
||||
return filept;
|
||||
}
|
||||
|
@@ -82,3 +82,9 @@ int add_to_stringbuf(struct stringbuf* sb, char* stuff)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int set_stringbuf(struct stringbuf* sb, char* stuff)
|
||||
{
|
||||
sb->fill = 0;
|
||||
return add_to_stringbuf(sb, stuff);
|
||||
}
|
||||
|
@@ -23,5 +23,6 @@ void free_stringbuf(struct stringbuf* sb);
|
||||
int resize_stringbuf(struct stringbuf* sb, size_t new);
|
||||
int copy_stringbuf(struct stringbuf* from, struct stringbuf* to);
|
||||
int add_to_stringbuf(struct stringbuf* sb, char* stuff);
|
||||
int set_stringbuf(struct stringbuf* sb, char* stuff);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user