Removed ugly boosting solutions from playback code and let scheduler
handle unboosting instead. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11226 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
450f619dcf
commit
7058752789
6 changed files with 67 additions and 93 deletions
|
@ -94,7 +94,6 @@ static size_t pcmbuf_mix_sample IDATA_ATTR;
|
|||
|
||||
static bool low_latency_mode = false;
|
||||
static bool pcmbuf_flush;
|
||||
static volatile bool output_completed = false;
|
||||
|
||||
extern struct thread_entry *codec_thread_p;
|
||||
|
||||
|
@ -109,44 +108,6 @@ static bool prepare_insert(size_t length);
|
|||
static void pcmbuf_under_watermark(void);
|
||||
static bool pcmbuf_flush_fillpos(void);
|
||||
|
||||
#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && !defined(SIMULATOR)
|
||||
void pcmbuf_boost(bool state)
|
||||
{
|
||||
static bool boost_state = false;
|
||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
static bool priority_modified = false;
|
||||
#endif
|
||||
|
||||
if (crossfade_init || crossfade_active)
|
||||
return;
|
||||
|
||||
if (state != boost_state)
|
||||
{
|
||||
cpu_boost_id(state, CPUBOOSTID_PCMBUF);
|
||||
boost_state = state;
|
||||
}
|
||||
|
||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
if (state && LOW_DATA(2) && pcm_is_playing())
|
||||
{
|
||||
if (!priority_modified)
|
||||
{
|
||||
/* Buffer is critically low so override UI priority. */
|
||||
priority_modified = true;
|
||||
thread_set_priority(codec_thread_p, PRIORITY_REALTIME);
|
||||
}
|
||||
}
|
||||
else if (priority_modified)
|
||||
{
|
||||
/* Set back the original priority. */
|
||||
thread_set_priority(codec_thread_p, PRIORITY_PLAYBACK);
|
||||
priority_modified = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CALL_IF_EXISTS(function, args...) if (function) function(args)
|
||||
/* This function has 2 major logical parts (separated by brackets both for
|
||||
* readability and variable scoping). The first part performs the
|
||||
|
@ -204,7 +165,6 @@ process_new_buffer:
|
|||
*realsize = 0;
|
||||
*realstart = NULL;
|
||||
CALL_IF_EXISTS(pcmbuf_event_handler);
|
||||
output_completed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -268,8 +228,25 @@ static inline void pcmbuf_add_chunk(void)
|
|||
|
||||
static void pcmbuf_under_watermark(void)
|
||||
{
|
||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
static int old_priority = 0;
|
||||
|
||||
if (LOW_DATA(2) && !old_priority && pcm_is_playing())
|
||||
{
|
||||
/* Buffer is critically low so override UI priority. */
|
||||
old_priority = thread_set_priority(codec_thread_p, PRIORITY_REALTIME);
|
||||
}
|
||||
else if (old_priority)
|
||||
{
|
||||
/* Set back the original priority. */
|
||||
thread_set_priority(codec_thread_p, old_priority);
|
||||
old_priority = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Fill audio buffer by boosting cpu */
|
||||
pcmbuf_boost(true);
|
||||
trigger_cpu_boost();
|
||||
|
||||
/* Disable crossfade if < .5s of audio */
|
||||
if (LOW_DATA(2))
|
||||
{
|
||||
|
@ -328,17 +305,16 @@ bool pcmbuf_crossfade_init(bool manual_skip)
|
|||
return false;
|
||||
}
|
||||
|
||||
trigger_cpu_boost();
|
||||
|
||||
/* Not enough data, or crossfade disabled, flush the old data instead */
|
||||
if (LOW_DATA(2) || !pcmbuf_is_crossfade_enabled() || low_latency_mode)
|
||||
{
|
||||
pcmbuf_boost(true);
|
||||
pcmbuf_flush_fillpos();
|
||||
pcmbuf_flush = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
pcmbuf_boost(true);
|
||||
|
||||
/* Don't enable mix mode when skipping tracks manually. */
|
||||
if (manual_skip)
|
||||
crossfade_mixmode = false;
|
||||
|
@ -371,9 +347,6 @@ void pcmbuf_play_stop(void)
|
|||
crossfade_init = false;
|
||||
crossfade_active = false;
|
||||
pcmbuf_flush = false;
|
||||
|
||||
pcmbuf_boost(false);
|
||||
|
||||
}
|
||||
|
||||
int pcmbuf_used_descs(void) {
|
||||
|
@ -433,7 +406,7 @@ void pcmbuf_pause(bool pause) {
|
|||
pcm_play_pause(!pause);
|
||||
if (!pause)
|
||||
pcm_mute(false);
|
||||
pcmbuf_boost(!pause && pcm_is_playing());
|
||||
trigger_cpu_boost();
|
||||
}
|
||||
|
||||
/* Force playback. */
|
||||
|
@ -466,8 +439,6 @@ static bool pcmbuf_flush_fillpos(void)
|
|||
if (audiobuffer_fillpos) {
|
||||
/* Never use the last buffer descriptor */
|
||||
while (pcmbuf_write == pcmbuf_write_end) {
|
||||
/* Deboost to let the playback catchup */
|
||||
pcmbuf_boost(false);
|
||||
/* If this happens, something is being stupid */
|
||||
if (!pcm_is_playing()) {
|
||||
logf("pcmbuf_flush_fillpos error");
|
||||
|
@ -762,14 +733,12 @@ static bool prepare_insert(size_t length)
|
|||
|
||||
/* Need to save PCMBUF_MIN_CHUNK to prevent wrapping overwriting */
|
||||
if (pcmbuf_free() < length + PCMBUF_MIN_CHUNK)
|
||||
{
|
||||
pcmbuf_boost(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pcm_is_playing())
|
||||
{
|
||||
pcmbuf_boost(true);
|
||||
trigger_cpu_boost();
|
||||
|
||||
/* Pre-buffer 1s. */
|
||||
#if MEM <= 1
|
||||
if (!LOW_DATA(1))
|
||||
|
@ -1031,12 +1000,3 @@ bool pcmbuf_is_crossfade_enabled(void)
|
|||
return crossfade_enabled;
|
||||
}
|
||||
|
||||
bool pcmbuf_output_completed(void)
|
||||
{
|
||||
if (output_completed)
|
||||
{
|
||||
output_completed = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@ size_t get_pcmbuf_descsize(void);
|
|||
void pcmbuf_pause(bool pause);
|
||||
void pcmbuf_play_stop(void);
|
||||
bool pcmbuf_is_crossfade_active(void);
|
||||
bool pcmbuf_output_completed(void);
|
||||
|
||||
/* These functions are for playing chained buffers of PCM data */
|
||||
#if defined(HAVE_ADJUSTABLE_CPU_FREQ) && !defined(SIMULATOR)
|
||||
|
|
|
@ -292,11 +292,6 @@ struct voice_info {
|
|||
char *buf;
|
||||
};
|
||||
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
static void voice_boost_cpu(bool state);
|
||||
#else
|
||||
#define voice_boost_cpu(state) do { } while(0)
|
||||
#endif
|
||||
static void voice_thread(void);
|
||||
|
||||
#endif /* PLAYBACK_VOICE */
|
||||
|
@ -316,7 +311,7 @@ void mp3_play_data(const unsigned char* start, int size,
|
|||
LOGFQUEUE("mp3 > voice Q_VOICE_PLAY");
|
||||
queue_post(&voice_queue, Q_VOICE_PLAY, &voice_clip);
|
||||
voice_thread_start = true;
|
||||
voice_boost_cpu(true);
|
||||
trigger_cpu_boost();
|
||||
#else
|
||||
(void) start;
|
||||
(void) size;
|
||||
|
@ -815,19 +810,6 @@ static const char * get_codec_filename(int enc_spec)
|
|||
|
||||
#ifdef PLAYBACK_VOICE
|
||||
|
||||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
|
||||
static void voice_boost_cpu(bool state)
|
||||
{
|
||||
static bool voice_cpu_boosted = false;
|
||||
|
||||
if (state != voice_cpu_boosted)
|
||||
{
|
||||
voice_cpu_boosted = state;
|
||||
cpu_boost_id(state, CPUBOOSTID_PLAYBACK_VOICE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool voice_pcmbuf_insert_split_callback(
|
||||
const void *ch1, const void *ch2, size_t length)
|
||||
{
|
||||
|
@ -976,7 +958,6 @@ static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize)
|
|||
voice_getmore = NULL;
|
||||
voice_remaining = 0;
|
||||
voicebuf = NULL;
|
||||
voice_boost_cpu(false);
|
||||
|
||||
/* Force the codec to think it's changing tracks */
|
||||
ci_voice.new_track = 1;
|
||||
|
@ -1005,7 +986,7 @@ static void* voice_request_buffer_callback(size_t *realsize, size_t reqsize)
|
|||
/* Set up new voice data */
|
||||
struct voice_info *voice_data;
|
||||
voice_is_playing = true;
|
||||
voice_boost_cpu(true);
|
||||
trigger_cpu_boost();
|
||||
voice_data = ev.data;
|
||||
voice_remaining = voice_data->size;
|
||||
voicebuf = voice_data->buf;
|
||||
|
@ -1666,7 +1647,7 @@ static bool codec_load_next_track(void)
|
|||
automatic_skip = true;
|
||||
}
|
||||
|
||||
cpu_boost_id(true, CPUBOOSTID_PLAYBACK_CODEC);
|
||||
trigger_cpu_boost();
|
||||
LOGFQUEUE("codec > audio Q_AUDIO_CHECK_NEW_TRACK");
|
||||
queue_post(&audio_queue, Q_AUDIO_CHECK_NEW_TRACK, 0);
|
||||
while (1)
|
||||
|
@ -1680,7 +1661,7 @@ static bool codec_load_next_track(void)
|
|||
else
|
||||
break;
|
||||
}
|
||||
cpu_boost_id(false, CPUBOOSTID_PLAYBACK_CODEC);
|
||||
|
||||
switch (ev.id)
|
||||
{
|
||||
case Q_CODEC_REQUEST_COMPLETE:
|
||||
|
@ -2153,7 +2134,7 @@ static void audio_read_file(bool quick)
|
|||
return ;
|
||||
}
|
||||
|
||||
cpu_boost_id(true, CPUBOOSTID_PLAYBACK_AUDIO);
|
||||
trigger_cpu_boost();
|
||||
while (tracks[track_widx].filerem > 0)
|
||||
{
|
||||
int overlap;
|
||||
|
@ -2218,7 +2199,6 @@ static void audio_read_file(bool quick)
|
|||
logf("Partially buf:%dB",
|
||||
tracks[track_widx].filesize - tracks[track_widx].filerem);
|
||||
}
|
||||
cpu_boost_id(false, CPUBOOSTID_PLAYBACK_AUDIO);
|
||||
}
|
||||
|
||||
static bool audio_loadcodec(bool start_play)
|
||||
|
@ -3338,8 +3318,6 @@ static void audio_thread(void)
|
|||
|
||||
case SYS_TIMEOUT:
|
||||
LOGFQUEUE("audio < SYS_TIMEOUT");
|
||||
if (pcmbuf_output_completed())
|
||||
pcmbuf_play_stop(); /* Stop to ensure unboosted */
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -222,6 +222,7 @@
|
|||
|
||||
#if (CONFIG_CODEC == SWCODEC) && !defined(SIMULATOR) && !defined(BOOTLOADER)
|
||||
#define HAVE_PRIORITY_SCHEDULING
|
||||
#define HAVE_SCHEDULER_BOOSTCTRL
|
||||
#endif
|
||||
|
||||
/* define for all cpus from coldfire family */
|
||||
|
|
|
@ -131,12 +131,18 @@ struct thread_entry*
|
|||
const char *name
|
||||
IF_PRIO(, int priority));
|
||||
|
||||
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
||||
void trigger_cpu_boost(void);
|
||||
#else
|
||||
#define trigger_cpu_boost()
|
||||
#endif
|
||||
|
||||
void remove_thread(struct thread_entry *thread);
|
||||
void switch_thread(bool save_context, struct thread_entry **blocked_list);
|
||||
void sleep_thread(int ticks);
|
||||
void block_thread(struct thread_entry **thread, int timeout);
|
||||
void wakeup_thread(struct thread_entry **thread);
|
||||
void thread_set_priority(struct thread_entry *thread, int priority);
|
||||
int thread_set_priority(struct thread_entry *thread, int priority);
|
||||
void init_threads(void);
|
||||
int thread_stack_usage(const struct thread_entry *thread);
|
||||
int thread_get_status(const struct thread_entry *thread);
|
||||
|
|
|
@ -35,6 +35,9 @@ struct core_entry cores[NUM_CORES] IBSS_ATTR;
|
|||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
static unsigned short highest_priority IBSS_ATTR;
|
||||
#endif
|
||||
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
||||
static bool cpu_boosted IBSS_ATTR;
|
||||
#endif
|
||||
|
||||
/* Define to enable additional checks for blocking violations etc. */
|
||||
// #define THREAD_EXTRA_CHECKS
|
||||
|
@ -332,6 +335,14 @@ static inline void sleep_core(void)
|
|||
if (cores[CURRENT_CORE].running != NULL)
|
||||
break;
|
||||
|
||||
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
||||
if (cpu_boosted)
|
||||
{
|
||||
cpu_boost(false);
|
||||
cpu_boosted = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Enter sleep mode to reduce power usage, woken up on interrupt */
|
||||
#ifdef CPU_COLDFIRE
|
||||
asm volatile ("stop #0x2000");
|
||||
|
@ -646,6 +657,17 @@ struct thread_entry*
|
|||
return thread;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
||||
void trigger_cpu_boost(void)
|
||||
{
|
||||
if (!cpu_boosted)
|
||||
{
|
||||
cpu_boost(true);
|
||||
cpu_boosted = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
* Remove a thread on the current core from the scheduler.
|
||||
* Parameter is the ID as returned from create_thread().
|
||||
|
@ -676,13 +698,18 @@ void remove_thread(struct thread_entry *thread)
|
|||
}
|
||||
|
||||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
void thread_set_priority(struct thread_entry *thread, int priority)
|
||||
int thread_set_priority(struct thread_entry *thread, int priority)
|
||||
{
|
||||
int old_priority;
|
||||
|
||||
if (thread == NULL)
|
||||
thread = cores[CURRENT_CORE].running;
|
||||
|
||||
old_priority = thread->priority;
|
||||
thread->priority = priority;
|
||||
highest_priority = 100;
|
||||
|
||||
return old_priority;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -698,6 +725,9 @@ void init_threads(void)
|
|||
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||
cores[core].threads[0].priority = PRIORITY_USER_INTERFACE;
|
||||
highest_priority = 100;
|
||||
#endif
|
||||
#ifdef HAVE_SCHEDULER_BOOSTCTRL
|
||||
cpu_boosted = false;
|
||||
#endif
|
||||
add_to_list(&cores[core].running, &cores[core].threads[0]);
|
||||
|
||||
|
|
Loading…
Reference in a new issue