forked from len0rd/rockbox
Fix FS8069, because Nico_P made it easy
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15840 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
05784b52ab
commit
3386dd7be9
5 changed files with 107 additions and 0 deletions
|
|
@ -657,6 +657,7 @@ static bool buffer_handle(int handle_id)
|
||||||
/* finished buffering the file */
|
/* finished buffering the file */
|
||||||
close(h->fd);
|
close(h->fd);
|
||||||
h->fd = -1;
|
h->fd = -1;
|
||||||
|
call_buffering_callbacks(EVENT_HANDLE_FINISHED, h->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -1138,6 +1139,58 @@ ssize_t bufgetdata(int handle_id, size_t size, void **data)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t bufgettail(int handle_id, size_t size, void **data)
|
||||||
|
{
|
||||||
|
size_t tidx;
|
||||||
|
|
||||||
|
const struct memory_handle *h;
|
||||||
|
|
||||||
|
h = find_handle(handle_id);
|
||||||
|
|
||||||
|
if (!h)
|
||||||
|
return ERR_HANDLE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (h->filerem)
|
||||||
|
return ERR_HANDLE_NOT_DONE;
|
||||||
|
|
||||||
|
/* We don't support tail requests of > guardbuf_size, for simplicity */
|
||||||
|
if (size > GUARD_BUFSIZE)
|
||||||
|
return ERR_INVALID_VALUE;
|
||||||
|
|
||||||
|
tidx = RINGBUF_SUB(h->widx, size);
|
||||||
|
|
||||||
|
if (tidx + size > buffer_len)
|
||||||
|
{
|
||||||
|
size_t copy_n = tidx + size - buffer_len;
|
||||||
|
memcpy(guard_buffer, (unsigned char *)buffer, copy_n);
|
||||||
|
}
|
||||||
|
|
||||||
|
*data = &buffer[tidx];
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t bufcuttail(int handle_id, size_t size)
|
||||||
|
{
|
||||||
|
struct memory_handle *h;
|
||||||
|
|
||||||
|
h = find_handle(handle_id);
|
||||||
|
|
||||||
|
if (!h)
|
||||||
|
return ERR_HANDLE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (h->filerem)
|
||||||
|
return ERR_HANDLE_NOT_DONE;
|
||||||
|
|
||||||
|
if (h->available < size)
|
||||||
|
size = h->available;
|
||||||
|
|
||||||
|
h->available -= size;
|
||||||
|
h->filesize -= size;
|
||||||
|
h->widx = RINGBUF_SUB(h->widx, size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SECONDARY EXPORTED FUNCTIONS
|
SECONDARY EXPORTED FUNCTIONS
|
||||||
============================
|
============================
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ enum callback_event {
|
||||||
EVENT_HANDLE_REBUFFER,
|
EVENT_HANDLE_REBUFFER,
|
||||||
EVENT_HANDLE_CLOSED,
|
EVENT_HANDLE_CLOSED,
|
||||||
EVENT_HANDLE_MOVED,
|
EVENT_HANDLE_MOVED,
|
||||||
|
EVENT_HANDLE_FINISHED,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Error return values */
|
/* Error return values */
|
||||||
|
|
@ -48,6 +49,7 @@ enum callback_event {
|
||||||
#define ERR_BUFFER_FULL -2
|
#define ERR_BUFFER_FULL -2
|
||||||
#define ERR_INVALID_VALUE -3
|
#define ERR_INVALID_VALUE -3
|
||||||
#define ERR_FILE_ERROR -4
|
#define ERR_FILE_ERROR -4
|
||||||
|
#define ERR_HANDLE_NOT_DONE -5
|
||||||
|
|
||||||
|
|
||||||
/* Initialise the buffering subsystem */
|
/* Initialise the buffering subsystem */
|
||||||
|
|
@ -68,9 +70,12 @@ bool buffering_reset(char *buf, size_t buflen);
|
||||||
* bufadvance: Move handle reading index, relatively to current position
|
* bufadvance: Move handle reading index, relatively to current position
|
||||||
* bufread : Copy data from a handle to a buffer
|
* bufread : Copy data from a handle to a buffer
|
||||||
* bufgetdata: Obtain a pointer for linear access to a "size" amount of data
|
* bufgetdata: Obtain a pointer for linear access to a "size" amount of data
|
||||||
|
* bufgettail: Out-of-band get the last size bytes of a handle.
|
||||||
|
* bufcuttail: Out-of-band remove the trailing 'size' bytes of a handle.
|
||||||
*
|
*
|
||||||
* NOTE: bufread and bufgetdata will block the caller until the requested
|
* NOTE: bufread and bufgetdata will block the caller until the requested
|
||||||
* amount of data is ready (unless EOF is reached).
|
* amount of data is ready (unless EOF is reached).
|
||||||
|
* NOTE: Tail operations are only legal when the end of the file is buffered.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define BUF_MAX_HANDLES 256
|
#define BUF_MAX_HANDLES 256
|
||||||
|
|
@ -82,6 +87,8 @@ int bufseek(int handle_id, size_t newpos);
|
||||||
int bufadvance(int handle_id, off_t offset);
|
int bufadvance(int handle_id, off_t offset);
|
||||||
ssize_t bufread(int handle_id, size_t size, void *dest);
|
ssize_t bufread(int handle_id, size_t size, void *dest);
|
||||||
ssize_t bufgetdata(int handle_id, size_t size, void **data);
|
ssize_t bufgetdata(int handle_id, size_t size, void **data);
|
||||||
|
ssize_t bufgettail(int handle_id, size_t size, void **data);
|
||||||
|
ssize_t bufcuttail(int handle_id, size_t size);
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC
|
#if CONFIG_CODEC == SWCODEC
|
||||||
|
|
||||||
|
/* For trailing tag stripping */
|
||||||
|
#include "buffering.h"
|
||||||
|
|
||||||
#include "metadata/metadata_common.h"
|
#include "metadata/metadata_common.h"
|
||||||
#include "metadata/metadata_parsers.h"
|
#include "metadata/metadata_parsers.h"
|
||||||
|
|
||||||
|
|
@ -322,3 +325,42 @@ bool get_metadata(struct mp3entry* id3, int fd, const char* trackname)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void strip_tags(int handle_id)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
static const unsigned char tag[] = "TAG";
|
||||||
|
static const unsigned char apetag[] = "APETAGEX";
|
||||||
|
size_t len, version;
|
||||||
|
unsigned char *tail;
|
||||||
|
|
||||||
|
if (bufgettail(handle_id, 128, (void **)&tail) != 128)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(i = 0;i < 3;i++)
|
||||||
|
if(tail[i] != tag[i])
|
||||||
|
goto strip_ape_tag;
|
||||||
|
|
||||||
|
/* Skip id3v1 tag */
|
||||||
|
logf("Cutting off ID3v1 tag");
|
||||||
|
bufcuttail(handle_id, 128);
|
||||||
|
|
||||||
|
strip_ape_tag:
|
||||||
|
/* Check for APE tag (look for the APE tag footer) */
|
||||||
|
|
||||||
|
if (bufgettail(handle_id, 32, (void **)&tail) != 32)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for(i = 0;i < 8;i++)
|
||||||
|
if(tail[i] != apetag[i])
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Read the version and length from the footer */
|
||||||
|
version = tail[8] | (tail[9] << 8) | (tail[10] << 16) | (tail[11] << 24);
|
||||||
|
len = tail[12] | (tail[13] << 8) | (tail[14] << 16) | (tail[15] << 24);
|
||||||
|
if (version == 2000)
|
||||||
|
len += 32; /* APEv2 has a 32 byte header */
|
||||||
|
|
||||||
|
/* Skip APE tag */
|
||||||
|
logf("Cutting off APE tag (%ldB)", len);
|
||||||
|
bufcuttail(handle_id, len);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
unsigned int probe_file_format(const char *filename);
|
unsigned int probe_file_format(const char *filename);
|
||||||
bool get_metadata(struct mp3entry* id3, int fd, const char* trackname);
|
bool get_metadata(struct mp3entry* id3, int fd, const char* trackname);
|
||||||
|
void strip_tags(int handle_id);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1485,6 +1485,10 @@ static void buffering_audio_callback(enum callback_event ev, int value)
|
||||||
queue_send(&audio_queue, Q_AUDIO_FLUSH, 0);
|
queue_send(&audio_queue, Q_AUDIO_FLUSH, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EVENT_HANDLE_FINISHED:
|
||||||
|
strip_tags(value);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue