forked from len0rd/rockbox
At last, really short load times
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1385 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
f952ba7548
commit
4e46ac78ae
1 changed files with 86 additions and 43 deletions
131
firmware/mpeg.c
131
firmware/mpeg.c
|
@ -34,13 +34,12 @@
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MPEG_CHUNKSIZE 0x20000
|
#define MPEG_FIRST_CHUNKSIZE 0x20000
|
||||||
#ifdef ARCHOS_RECORDER
|
#define MPEG_CHUNKSIZE 0x180000
|
||||||
/* recorder is slower and needs more load time */
|
#define MPEG_FIRST_SWAP_CHUNKSIZE 0x20000
|
||||||
#define MPEG_LOW_WATER 0x40000
|
#define MPEG_SWAP_CHUNKSIZE 0x8000
|
||||||
#else
|
#define MPEG_HIGHWATER 0x10000
|
||||||
#define MPEG_LOW_WATER 0x30000
|
#define MPEG_LOW_WATER 0x30000
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MPEG_PLAY 1
|
#define MPEG_PLAY 1
|
||||||
#define MPEG_STOP 2
|
#define MPEG_STOP 2
|
||||||
|
@ -49,6 +48,7 @@
|
||||||
#define MPEG_NEXT 5
|
#define MPEG_NEXT 5
|
||||||
#define MPEG_PREV 6
|
#define MPEG_PREV 6
|
||||||
#define MPEG_NEED_DATA 100
|
#define MPEG_NEED_DATA 100
|
||||||
|
#define MPEG_SWAP_DATA 101
|
||||||
|
|
||||||
extern char* peek_next_track(int type);
|
extern char* peek_next_track(int type);
|
||||||
extern char* peek_prev_track(int type);
|
extern char* peek_prev_track(int type);
|
||||||
|
@ -274,6 +274,7 @@ extern unsigned char mp3end[];
|
||||||
|
|
||||||
static int mp3buflen;
|
static int mp3buflen;
|
||||||
static int mp3buf_write;
|
static int mp3buf_write;
|
||||||
|
static int mp3buf_swapwrite;
|
||||||
static int mp3buf_read;
|
static int mp3buf_read;
|
||||||
|
|
||||||
static int last_dma_chunk_size;
|
static int last_dma_chunk_size;
|
||||||
|
@ -379,6 +380,7 @@ static void reset_mp3_buffer(void)
|
||||||
{
|
{
|
||||||
mp3buf_read = 0;
|
mp3buf_read = 0;
|
||||||
mp3buf_write = 0;
|
mp3buf_write = 0;
|
||||||
|
mp3buf_swapwrite = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma interrupt
|
#pragma interrupt
|
||||||
|
@ -497,6 +499,7 @@ static void mpeg_thread(void)
|
||||||
int len;
|
int len;
|
||||||
int free_space_left;
|
int free_space_left;
|
||||||
int amount_to_read;
|
int amount_to_read;
|
||||||
|
int amount_to_swap;
|
||||||
|
|
||||||
play_pending = false;
|
play_pending = false;
|
||||||
playing = false;
|
playing = false;
|
||||||
|
@ -505,6 +508,7 @@ static void mpeg_thread(void)
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
DEBUGF("S\n");
|
DEBUGF("S\n");
|
||||||
|
yield();
|
||||||
queue_wait(&mpeg_queue, &ev);
|
queue_wait(&mpeg_queue, &ev);
|
||||||
switch(ev.id)
|
switch(ev.id)
|
||||||
{
|
{
|
||||||
|
@ -614,49 +618,36 @@ static void mpeg_thread(void)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MPEG_NEED_DATA:
|
case MPEG_SWAP_DATA:
|
||||||
free_space_left = mp3buf_read - mp3buf_write;
|
free_space_left = mp3buf_write - mp3buf_swapwrite;
|
||||||
|
|
||||||
/* We interpret 0 as "empty buffer" */
|
if(free_space_left == 0)
|
||||||
if(free_space_left <= 0)
|
break;
|
||||||
|
|
||||||
|
if(free_space_left < 0)
|
||||||
free_space_left = mp3buflen + free_space_left;
|
free_space_left = mp3buflen + free_space_left;
|
||||||
|
|
||||||
/* do we have any more buffer space to fill? */
|
if(play_pending)
|
||||||
if(free_space_left <= MPEG_CHUNKSIZE)
|
amount_to_swap = MIN(MPEG_FIRST_SWAP_CHUNKSIZE,
|
||||||
|
free_space_left);
|
||||||
|
else
|
||||||
|
amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
|
||||||
|
amount_to_swap = MIN(mp3buflen - mp3buf_swapwrite,
|
||||||
|
amount_to_swap);
|
||||||
|
|
||||||
|
DEBUGF("B %x\n", amount_to_swap);
|
||||||
|
bitswap((unsigned short *)(mp3buf + mp3buf_swapwrite),
|
||||||
|
(amount_to_swap+1)/2);
|
||||||
|
|
||||||
|
mp3buf_swapwrite += amount_to_swap;
|
||||||
|
if(mp3buf_swapwrite >= mp3buflen)
|
||||||
{
|
{
|
||||||
DEBUGF("0\n");
|
mp3buf_swapwrite = 0;
|
||||||
filling = false;
|
DEBUGF("BW\n");
|
||||||
ata_sleep();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
amount_to_read = MIN(MPEG_CHUNKSIZE, free_space_left);
|
/* Tell ourselves that we must swap more data */
|
||||||
amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read);
|
queue_post(&mpeg_queue, MPEG_SWAP_DATA, 0);
|
||||||
|
|
||||||
/* Read in a few seconds worth of MP3 data. We don't want to
|
|
||||||
read too large chunks because the bitswapping will take
|
|
||||||
too much time. We must keep the DMA happy and also give
|
|
||||||
the other threads a chance to run. */
|
|
||||||
if(mpeg_file >= 0)
|
|
||||||
{
|
|
||||||
DEBUGF("R\n");
|
|
||||||
len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);
|
|
||||||
if(len > 0)
|
|
||||||
{
|
|
||||||
DEBUGF("B\n");
|
|
||||||
|
|
||||||
bitswap((unsigned short *)(mp3buf + mp3buf_write),
|
|
||||||
(len+1)/2);
|
|
||||||
|
|
||||||
mp3buf_write += len;
|
|
||||||
if(mp3buf_write >= mp3buflen)
|
|
||||||
{
|
|
||||||
mp3buf_write = 0;
|
|
||||||
DEBUGF("W\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Tell ourselves that we want more data */
|
|
||||||
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
|
|
||||||
|
|
||||||
/* And while we're at it, see if we have started
|
/* And while we're at it, see if we have started
|
||||||
playing yet. If not, do it. */
|
playing yet. If not, do it. */
|
||||||
|
@ -669,6 +660,59 @@ static void mpeg_thread(void)
|
||||||
init_dma();
|
init_dma();
|
||||||
start_dma();
|
start_dma();
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MPEG_NEED_DATA:
|
||||||
|
free_space_left = mp3buf_read - mp3buf_write;
|
||||||
|
|
||||||
|
/* We interpret 0 as "empty buffer" */
|
||||||
|
if(free_space_left <= 0)
|
||||||
|
free_space_left = mp3buflen + free_space_left;
|
||||||
|
|
||||||
|
/* Make sure that we don't fill the entire buffer */
|
||||||
|
free_space_left -= 2;
|
||||||
|
|
||||||
|
/* do we have any more buffer space to fill? */
|
||||||
|
if(free_space_left <= MPEG_HIGHWATER)
|
||||||
|
{
|
||||||
|
DEBUGF("0\n");
|
||||||
|
filling = false;
|
||||||
|
ata_sleep();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(play_pending)
|
||||||
|
{
|
||||||
|
amount_to_read = MIN(MPEG_FIRST_CHUNKSIZE, free_space_left);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
amount_to_read = MIN(MPEG_CHUNKSIZE, free_space_left);
|
||||||
|
}
|
||||||
|
amount_to_read = MIN(mp3buflen - mp3buf_write, amount_to_read);
|
||||||
|
|
||||||
|
/* Read in a few seconds worth of MP3 data. We don't want to
|
||||||
|
read too large chunks because the bitswapping will take
|
||||||
|
too much time. We must keep the DMA happy and also give
|
||||||
|
the other threads a chance to run. */
|
||||||
|
if(mpeg_file >= 0)
|
||||||
|
{
|
||||||
|
DEBUGF("R\n");
|
||||||
|
len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);
|
||||||
|
if(len > 0)
|
||||||
|
{
|
||||||
|
/* Tell ourselves that we need to swap some data */
|
||||||
|
queue_post(&mpeg_queue, MPEG_SWAP_DATA, 0);
|
||||||
|
|
||||||
|
mp3buf_write += len;
|
||||||
|
if(mp3buf_write >= mp3buflen)
|
||||||
|
{
|
||||||
|
mp3buf_write = 0;
|
||||||
|
DEBUGF("W\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tell ourselves that we want more data */
|
||||||
|
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -696,7 +740,6 @@ static void mpeg_thread(void)
|
||||||
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
|
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
yield(); /* To be safe */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue