forked from len0rd/rockbox
Use a separate thread in test_codec, with the same (IRAM) stack as the main codec thread. Add a function to the plugin API to steal the codec thread, which test_codec copies and then restores. Now libmad can be benchmarked.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13347 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
173b611921
commit
f4a9dab4d1
5 changed files with 64 additions and 21 deletions
|
@ -299,6 +299,13 @@ struct thread_entry *codec_thread_p; /* For modifying thread priority later. */
|
||||||
|
|
||||||
static volatile int current_codec IDATA_ATTR; /* Current codec (normal/voice) */
|
static volatile int current_codec IDATA_ATTR; /* Current codec (normal/voice) */
|
||||||
|
|
||||||
|
/* test_codec steals the codec stack */
|
||||||
|
void steal_codec_stack(unsigned char** stack, size_t* size)
|
||||||
|
{
|
||||||
|
*stack = (unsigned char*)codec_stack;
|
||||||
|
*size = sizeof(codec_stack);
|
||||||
|
}
|
||||||
|
|
||||||
/* Voice thread */
|
/* Voice thread */
|
||||||
#ifdef PLAYBACK_VOICE
|
#ifdef PLAYBACK_VOICE
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,7 @@ void audio_set_track_buffer_event(void (*handler)(struct mp3entry *id3,
|
||||||
bool last_track));
|
bool last_track));
|
||||||
void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3,
|
void audio_set_track_unbuffer_event(void (*handler)(struct mp3entry *id3,
|
||||||
bool last_track));
|
bool last_track));
|
||||||
|
void steal_codec_stack(unsigned char** stack, size_t* size);
|
||||||
|
|
||||||
#if CONFIG_CODEC == SWCODEC /* This #ifdef is better here than gui/gwps.c */
|
#if CONFIG_CODEC == SWCODEC /* This #ifdef is better here than gui/gwps.c */
|
||||||
extern void audio_next_dir(void);
|
extern void audio_next_dir(void);
|
||||||
|
|
|
@ -493,6 +493,7 @@ static const struct plugin_api rockbox_api = {
|
||||||
codec_load_file,
|
codec_load_file,
|
||||||
get_metadata,
|
get_metadata,
|
||||||
get_codec_filename,
|
get_codec_filename,
|
||||||
|
steal_codec_stack,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -611,6 +611,7 @@ struct plugin_api {
|
||||||
bool (*get_metadata)(struct track_info* track, int fd, const char* trackname,
|
bool (*get_metadata)(struct track_info* track, int fd, const char* trackname,
|
||||||
bool v1first);
|
bool v1first);
|
||||||
const char *(*get_codec_filename)(int cod_spec);
|
const char *(*get_codec_filename)(int cod_spec);
|
||||||
|
void (*steal_codec_stack)(unsigned char** stack, size_t* size);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,11 @@ static char str[40];
|
||||||
/* Our local implementation of the codec API */
|
/* Our local implementation of the codec API */
|
||||||
static struct codec_api ci;
|
static struct codec_api ci;
|
||||||
|
|
||||||
|
|
||||||
static struct track_info track;
|
static struct track_info track;
|
||||||
|
|
||||||
static bool taginfo_ready = true;
|
static bool taginfo_ready = true;
|
||||||
|
|
||||||
|
static volatile unsigned int elapsed;
|
||||||
|
static volatile bool codec_playing;
|
||||||
|
|
||||||
/* Returns buffer to malloc array. Only codeclib should need this. */
|
/* Returns buffer to malloc array. Only codeclib should need this. */
|
||||||
static void* get_codec_memory(size_t *size)
|
static void* get_codec_memory(size_t *size)
|
||||||
|
@ -44,7 +44,6 @@ static void* get_codec_memory(size_t *size)
|
||||||
return codec_mallocbuf;
|
return codec_mallocbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Insert PCM data into audio buffer for playback. Playback will start
|
/* Insert PCM data into audio buffer for playback. Playback will start
|
||||||
automatically. */
|
automatically. */
|
||||||
static bool pcmbuf_insert(const void *ch1, const void *ch2, int count)
|
static bool pcmbuf_insert(const void *ch1, const void *ch2, int count)
|
||||||
|
@ -58,18 +57,10 @@ static bool pcmbuf_insert(const void *ch1, const void *ch2, int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static unsigned int prev_value = 0;
|
|
||||||
|
|
||||||
/* Set song position in WPS (value in ms). */
|
/* Set song position in WPS (value in ms). */
|
||||||
static void set_elapsed(unsigned int value)
|
static void set_elapsed(unsigned int value)
|
||||||
{
|
{
|
||||||
if ((value - prev_value) > 2000)
|
elapsed = value;
|
||||||
{
|
|
||||||
rb->snprintf(str,sizeof(str),"%d of %d",value,(int)track.id3.length);
|
|
||||||
rb->lcd_puts(0,0,str);
|
|
||||||
rb->lcd_update();
|
|
||||||
prev_value = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -230,17 +221,36 @@ static void init_ci(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void codec_thread(void)
|
||||||
|
{
|
||||||
|
const char* codecname;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
codecname = rb->get_codec_filename(track.id3.codectype);
|
||||||
|
|
||||||
|
/* Load the codec and start decoding. */
|
||||||
|
res = rb->codec_load_file(codecname,&ci);
|
||||||
|
|
||||||
|
/* Signal to the main thread that we are done */
|
||||||
|
codec_playing = false;
|
||||||
|
|
||||||
|
/* Commit suicide */
|
||||||
|
rb->remove_thread(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* plugin entry point */
|
/* plugin entry point */
|
||||||
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n;
|
||||||
int fd;
|
int fd;
|
||||||
const char* codecname;
|
|
||||||
int res;
|
|
||||||
unsigned long starttick;
|
unsigned long starttick;
|
||||||
unsigned long ticks;
|
unsigned long ticks;
|
||||||
unsigned long speed;
|
unsigned long speed;
|
||||||
unsigned long duration;
|
unsigned long duration;
|
||||||
|
unsigned char* codec_stack;
|
||||||
|
unsigned char* codec_stack_copy;
|
||||||
|
size_t codec_stack_size;
|
||||||
|
struct thread_entry* codecthread_id;
|
||||||
|
|
||||||
rb = api;
|
rb = api;
|
||||||
|
|
||||||
|
@ -250,9 +260,15 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
return PLUGIN_ERROR;
|
return PLUGIN_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rb->steal_codec_stack(&codec_stack,&codec_stack_size);
|
||||||
|
|
||||||
codec_mallocbuf = rb->plugin_get_audio_buffer(&audiosize);
|
codec_mallocbuf = rb->plugin_get_audio_buffer(&audiosize);
|
||||||
audiobuf = codec_mallocbuf + 512*1024;
|
codec_stack_copy = codec_mallocbuf + 512*1024;
|
||||||
audiosize -= 512*1024;
|
audiobuf = codec_stack_copy + codec_stack_size;
|
||||||
|
audiosize -= 512*1024 + codec_stack_size;
|
||||||
|
|
||||||
|
/* Backup the codec thread's stack */
|
||||||
|
rb->memcpy(codec_stack_copy,codec_stack,codec_stack_size);
|
||||||
|
|
||||||
fd = rb->open(parameter,O_RDONLY);
|
fd = rb->open(parameter,O_RDONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
|
@ -298,8 +314,6 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
ci.new_track = 0;
|
ci.new_track = 0;
|
||||||
ci.seek_time = 0;
|
ci.seek_time = 0;
|
||||||
|
|
||||||
codecname = rb->get_codec_filename(track.id3.codectype);
|
|
||||||
|
|
||||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||||
rb->cpu_boost(true);
|
rb->cpu_boost(true);
|
||||||
#endif
|
#endif
|
||||||
|
@ -311,9 +325,24 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
|
|
||||||
starttick = *rb->current_tick;
|
starttick = *rb->current_tick;
|
||||||
|
|
||||||
/* Load the codec and start decoding. */
|
codec_playing = true;
|
||||||
res = rb->codec_load_file(codecname,&ci);
|
|
||||||
|
|
||||||
|
if ((codecthread_id = rb->create_thread(codec_thread,
|
||||||
|
(uint8_t*)codec_stack, codec_stack_size, "testcodec" IF_PRIO(,PRIORITY_PLAYBACK)
|
||||||
|
IF_COP(, CPU, false))) == NULL)
|
||||||
|
{
|
||||||
|
rb->splash(HZ, "Cannot create codec thread!");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for codec thread to die */
|
||||||
|
while (codec_playing)
|
||||||
|
{
|
||||||
|
rb->sleep(HZ);
|
||||||
|
rb->snprintf(str,sizeof(str),"%d of %d",elapsed,(int)track.id3.length);
|
||||||
|
rb->lcd_puts(0,0,str);
|
||||||
|
rb->lcd_update();
|
||||||
|
}
|
||||||
|
|
||||||
/* Display benchmark information */
|
/* Display benchmark information */
|
||||||
|
|
||||||
|
@ -337,6 +366,10 @@ enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
|
||||||
|
|
||||||
while (rb->button_get(true) != BUTTON_SELECT);
|
while (rb->button_get(true) != BUTTON_SELECT);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
/* Restore the codec thread's stack */
|
||||||
|
rb->memcpy(codec_stack, codec_stack_copy, codec_stack_size);
|
||||||
|
|
||||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||||
rb->cpu_boost(false);
|
rb->cpu_boost(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue