forked from len0rd/rockbox
Swapping is now done without the MPEG_SWAP message. Added some debugging functionality
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2623 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
2f8f1c7dcf
commit
402502fc6f
2 changed files with 128 additions and 78 deletions
185
firmware/mpeg.c
185
firmware/mpeg.c
|
@ -37,11 +37,15 @@
|
|||
|
||||
extern void bitswap(unsigned char *data, int length);
|
||||
|
||||
#define MPEG_CHUNKSIZE 0x180000
|
||||
#define MPEG_SWAP_CHUNKSIZE 0x8000
|
||||
#define MPEG_HIGH_WATER 2
|
||||
static int get_unplayed_space(void);
|
||||
static int get_unswapped_space(void);
|
||||
|
||||
#define MPEG_SWAP_CHUNKSIZE 0x2000
|
||||
#define MPEG_HIGH_WATER 2 /* We leave 2 bytes empty because otherwise we
|
||||
wouldn't be able to see the difference between
|
||||
an empty buffer and a full one. */
|
||||
#define MPEG_LOW_WATER 0x40000
|
||||
#define MPEG_LOW_WATER_CHUNKSIZE 0x10000
|
||||
#define MPEG_LOW_WATER_CHUNKSIZE 0x40000
|
||||
|
||||
#define MPEG_PLAY 1
|
||||
#define MPEG_STOP 2
|
||||
|
@ -52,8 +56,7 @@ extern void bitswap(unsigned char *data, int length);
|
|||
#define MPEG_FF_REWIND 7
|
||||
#define MPEG_FLUSH_RELOAD 8
|
||||
#define MPEG_NEED_DATA 100
|
||||
#define MPEG_SWAP_DATA 101
|
||||
#define MPEG_TRACK_CHANGE 102
|
||||
#define MPEG_TRACK_CHANGE 101
|
||||
|
||||
extern char* playlist_peek(int steps);
|
||||
extern int playlist_next(int steps);
|
||||
|
@ -439,6 +442,26 @@ static bool dma_underrun; /* True when the DMA has stopped because of
|
|||
|
||||
static int mpeg_file;
|
||||
|
||||
void mpeg_get_debugdata(struct mpeg_debug *dbgdata)
|
||||
{
|
||||
dbgdata->mp3buflen = mp3buflen;
|
||||
dbgdata->mp3buf_write = mp3buf_write;
|
||||
dbgdata->mp3buf_swapwrite = mp3buf_swapwrite;
|
||||
dbgdata->mp3buf_read = mp3buf_read;
|
||||
|
||||
dbgdata->last_dma_chunk_size = last_dma_chunk_size;
|
||||
|
||||
dbgdata->dma_on = dma_on;
|
||||
dbgdata->playing = playing;
|
||||
dbgdata->play_pending = play_pending;
|
||||
dbgdata->is_playing = is_playing;
|
||||
dbgdata->filling = filling;
|
||||
dbgdata->dma_underrun = dma_underrun;
|
||||
|
||||
dbgdata->unplayed_space = get_unplayed_space();
|
||||
dbgdata->unswapped_space = get_unswapped_space();
|
||||
}
|
||||
|
||||
static void mas_poll_start(int interval_in_ms)
|
||||
{
|
||||
unsigned int count;
|
||||
|
@ -480,8 +503,8 @@ static void dbg_timer_start(void)
|
|||
TSNC &= ~0x04; /* No synchronization */
|
||||
TMDR &= ~0x44; /* Operate normally */
|
||||
|
||||
TCNT1 = 0; /* Start counting at 0 */
|
||||
TCR1 = 0x03; /* Sysclock/8 */
|
||||
TCNT2 = 0; /* Start counting at 0 */
|
||||
TCR2 = 0x03; /* Sysclock/8 */
|
||||
|
||||
TSTR |= 0x04; /* Start timer 2 */
|
||||
}
|
||||
|
@ -492,7 +515,7 @@ static int dbg_cnt2us(unsigned int cnt)
|
|||
}
|
||||
#endif
|
||||
|
||||
int get_unplayed_space(void)
|
||||
static int get_unplayed_space(void)
|
||||
{
|
||||
int space = mp3buf_write - mp3buf_read;
|
||||
if (space < 0)
|
||||
|
@ -815,6 +838,65 @@ void hexdump(unsigned char *buf, int len)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void swap_one_chunk(void)
|
||||
{
|
||||
int free_space_left;
|
||||
int amount_to_swap;
|
||||
int t1, t2;
|
||||
|
||||
free_space_left = get_unswapped_space();
|
||||
|
||||
if(free_space_left == 0 && !play_pending)
|
||||
return;
|
||||
|
||||
amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
|
||||
if(mp3buf_write < mp3buf_swapwrite)
|
||||
amount_to_swap = MIN(mp3buflen - mp3buf_swapwrite,
|
||||
amount_to_swap);
|
||||
else
|
||||
amount_to_swap = MIN(mp3buf_write - mp3buf_swapwrite,
|
||||
amount_to_swap);
|
||||
|
||||
DEBUGF("B %x\n", amount_to_swap);
|
||||
t1 = current_tick;
|
||||
bitswap(mp3buf + mp3buf_swapwrite, amount_to_swap);
|
||||
t2 = current_tick;
|
||||
DEBUGF("time: %d\n", t2 - t1);
|
||||
|
||||
mp3buf_swapwrite += amount_to_swap;
|
||||
if(mp3buf_swapwrite >= mp3buflen)
|
||||
{
|
||||
mp3buf_swapwrite = 0;
|
||||
DEBUGF("BW\n");
|
||||
}
|
||||
|
||||
/* And while we're at it, see if we have started
|
||||
playing yet. If not, do it. */
|
||||
if(play_pending || dma_underrun)
|
||||
{
|
||||
/* If the filling has stopped, and we still haven't reached
|
||||
the watermark, the file must be smaller than the
|
||||
watermark. We must still play it. */
|
||||
if(((mp3buf_swapwrite - mp3buf_read) >= MPEG_LOW_WATER) ||
|
||||
!filling)
|
||||
{
|
||||
DEBUGF("P\n");
|
||||
play_pending = false;
|
||||
playing = true;
|
||||
|
||||
init_dma();
|
||||
if (!paused)
|
||||
{
|
||||
last_dma_tick = current_tick;
|
||||
start_dma();
|
||||
}
|
||||
|
||||
/* Tell ourselves that we need more data */
|
||||
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mpeg_thread(void)
|
||||
{
|
||||
static int pause_tick = 0;
|
||||
|
@ -824,7 +906,6 @@ static void mpeg_thread(void)
|
|||
int free_space_left;
|
||||
int unplayed_space_left;
|
||||
int amount_to_read;
|
||||
int amount_to_swap;
|
||||
int t1, t2;
|
||||
int start_offset;
|
||||
|
||||
|
@ -838,7 +919,18 @@ static void mpeg_thread(void)
|
|||
DEBUGF("S R:%x W:%x SW:%x\n",
|
||||
mp3buf_read, mp3buf_write, mp3buf_swapwrite);
|
||||
yield();
|
||||
queue_wait(&mpeg_queue, &ev);
|
||||
|
||||
/* Swap if necessary, and don't block on the queue_wait() */
|
||||
if(get_unswapped_space())
|
||||
{
|
||||
swap_one_chunk();
|
||||
queue_wait_w_tmo(&mpeg_queue, &ev, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
queue_wait(&mpeg_queue, &ev);
|
||||
}
|
||||
|
||||
switch(ev.id)
|
||||
{
|
||||
case MPEG_PLAY:
|
||||
|
@ -1221,64 +1313,6 @@ static void mpeg_thread(void)
|
|||
break;
|
||||
}
|
||||
|
||||
case MPEG_SWAP_DATA:
|
||||
free_space_left = get_unswapped_space();
|
||||
|
||||
if(free_space_left == 0 && !play_pending)
|
||||
break;
|
||||
|
||||
amount_to_swap = MIN(MPEG_SWAP_CHUNKSIZE, free_space_left);
|
||||
if(mp3buf_write < mp3buf_swapwrite)
|
||||
amount_to_swap = MIN(mp3buflen - mp3buf_swapwrite,
|
||||
amount_to_swap);
|
||||
else
|
||||
amount_to_swap = MIN(mp3buf_write - mp3buf_swapwrite,
|
||||
amount_to_swap);
|
||||
|
||||
DEBUGF("B %x\n", amount_to_swap);
|
||||
t1 = current_tick;
|
||||
bitswap(mp3buf + mp3buf_swapwrite, amount_to_swap);
|
||||
t2 = current_tick;
|
||||
DEBUGF("time: %d\n", t2 - t1);
|
||||
|
||||
mp3buf_swapwrite += amount_to_swap;
|
||||
if(mp3buf_swapwrite >= mp3buflen)
|
||||
{
|
||||
mp3buf_swapwrite = 0;
|
||||
DEBUGF("BW\n");
|
||||
}
|
||||
|
||||
/* Tell ourselves that we must swap more data */
|
||||
queue_post(&mpeg_queue, MPEG_SWAP_DATA, 0);
|
||||
|
||||
/* And while we're at it, see if we have started
|
||||
playing yet. If not, do it. */
|
||||
if(play_pending || dma_underrun)
|
||||
{
|
||||
/* If the filling has stopped, and we still haven't reached
|
||||
the watermark, the file must be smaller than the
|
||||
watermark. We must still play it. */
|
||||
if(((mp3buf_swapwrite - mp3buf_read) >= MPEG_LOW_WATER) ||
|
||||
!filling)
|
||||
{
|
||||
DEBUGF("P\n");
|
||||
play_pending = false;
|
||||
playing = true;
|
||||
|
||||
init_dma();
|
||||
if (!paused)
|
||||
{
|
||||
last_dma_tick = current_tick;
|
||||
start_dma();
|
||||
}
|
||||
|
||||
/* Tell ourselves that we need more data */
|
||||
queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MPEG_NEED_DATA:
|
||||
free_space_left = mp3buf_read - mp3buf_write;
|
||||
|
||||
|
@ -1289,7 +1323,7 @@ static void mpeg_thread(void)
|
|||
unplayed_space_left = mp3buflen - free_space_left;
|
||||
|
||||
/* Make sure that we don't fill the entire buffer */
|
||||
free_space_left -= 2;
|
||||
free_space_left -= MPEG_HIGH_WATER;
|
||||
|
||||
/* do we have any more buffer space to fill? */
|
||||
if(free_space_left <= MPEG_HIGH_WATER)
|
||||
|
@ -1305,15 +1339,12 @@ static void mpeg_thread(void)
|
|||
amount_to_read = MIN(MPEG_LOW_WATER_CHUNKSIZE,
|
||||
free_space_left);
|
||||
else
|
||||
amount_to_read = MIN(MPEG_CHUNKSIZE, free_space_left);
|
||||
amount_to_read = free_space_left;
|
||||
|
||||
/* Don't read more than until the end of the buffer */
|
||||
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. */
|
||||
|
||||
/* Read as much mpeg data as we can fit in the buffer */
|
||||
if(mpeg_file >= 0)
|
||||
{
|
||||
DEBUGF("R\n");
|
||||
|
@ -1325,8 +1356,6 @@ static void mpeg_thread(void)
|
|||
t2 = current_tick;
|
||||
DEBUGF("time: %d\n", t2 - t1);
|
||||
DEBUGF("R: %x\n", len);
|
||||
/* Tell ourselves that we need to swap some data */
|
||||
queue_post(&mpeg_queue, MPEG_SWAP_DATA, 0);
|
||||
|
||||
/* Make sure that the write pointer is at a word
|
||||
boundary when we reach the end of the file */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue