Move encoder CPU boost control to the core. Allow CPU to sleep a bit when PCM buffer is empty and save some power. Codec API becomes incompatible so full updates! :)

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15854 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Michael Sevakis 2007-11-30 05:16:56 +00:00
parent b0dd9eb5bc
commit 5323fe996b
8 changed files with 20 additions and 165 deletions

View file

@ -131,7 +131,6 @@ struct codec_api ci = {
enc_set_parameters,
enc_get_chunk,
enc_finish_chunk,
enc_pcm_buf_near_empty,
enc_get_pcm_data,
enc_unget_pcm_data,
@ -141,15 +140,6 @@ struct codec_api ci = {
(read_func)read,
PREFIX(lseek),
(write_func)write,
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
#ifdef CPU_BOOST_LOGGING
cpu_boost_,
#else
cpu_boost,
#endif
#endif
round_value_to_list32,
#endif

View file

@ -80,12 +80,12 @@
#define CODEC_ENC_MAGIC 0x52454E43 /* RENC */
/* increase this every time the api struct changes */
#define CODEC_API_VERSION 21
#define CODEC_API_VERSION 22
/* update this to latest version if a change to the api struct breaks
backwards compatibility (and please take the opportunity to sort in any
new function which are "waiting" at the end of the function table) */
#define CODEC_MIN_API_VERSION 18
#define CODEC_MIN_API_VERSION 22
/* codec return codes */
enum codec_status {
@ -200,7 +200,6 @@ struct codec_api {
void (*enc_set_parameters)(struct enc_parameters *params);
struct enc_chunk_hdr * (*enc_get_chunk)(void);
void (*enc_finish_chunk)(void);
int (*enc_pcm_buf_near_empty)(void);
unsigned char * (*enc_get_pcm_data)(size_t size);
size_t (*enc_unget_pcm_data)(size_t size);
@ -210,21 +209,10 @@ struct codec_api {
ssize_t (*read)(int fd, void* buf, size_t count);
off_t (*PREFIX(lseek))(int fd, off_t offset, int whence);
ssize_t (*write)(int fd, const void* buf, size_t count);
/* Encoder codecs adjust CPU boost themselves */
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
#ifdef CPU_BOOST_LOGGING
void (*cpu_boost_)(bool on_off,char*location,int line);
#else
void (*cpu_boost)(bool on_off);
#endif
#endif
int (*round_value_to_list32)(unsigned long value,
const unsigned long list[],
int count,
bool signd);
#endif
/* new stuff at the end, sort into place next time

View file

@ -304,9 +304,6 @@ static bool init_encoder(void)
ci->enc_set_parameters == NULL ||
ci->enc_get_chunk == NULL ||
ci->enc_finish_chunk == NULL ||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
ci->enc_pcm_buf_near_empty == NULL ||
#endif
ci->enc_get_pcm_data == NULL )
return false;
@ -334,10 +331,6 @@ static bool init_encoder(void)
/* main codec entry point */
enum codec_status codec_main(void)
{
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
bool cpu_boosted;
#endif
if (!init_encoder())
{
ci->enc_codec_loaded = -1;
@ -347,11 +340,6 @@ enum codec_status codec_main(void)
/* main application waits for this flag during encoder loading */
ci->enc_codec_loaded = 1;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
ci->cpu_boost(true);
cpu_boosted = true;
#endif
/* main encoding loop */
while(!ci->stop_encoder)
{
@ -364,13 +352,6 @@ enum codec_status codec_main(void)
if (ci->stop_encoder)
break;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (!cpu_boosted && ci->enc_pcm_buf_near_empty() == 0)
{
ci->cpu_boost(true);
cpu_boosted = true;
}
#endif
chunk = ci->enc_get_chunk();
chunk->enc_size = enc_size;
chunk->num_pcm = PCM_SAMP_PER_CHUNK;
@ -382,21 +363,9 @@ enum codec_status codec_main(void)
ci->yield();
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (cpu_boosted && ci->enc_pcm_buf_near_empty() != 0)
{
ci->cpu_boost(false);
cpu_boosted = false;
}
#endif
ci->yield();
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (cpu_boosted) /* set initial boost state */
ci->cpu_boost(false);
#endif
/* reset parameters to initial state */
ci->enc_set_parameters(NULL);

View file

@ -2423,9 +2423,6 @@ static bool enc_init(void)
ci->enc_set_parameters == NULL ||
ci->enc_get_chunk == NULL ||
ci->enc_finish_chunk == NULL ||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
ci->enc_pcm_buf_near_empty == NULL ||
#endif
ci->enc_get_pcm_data == NULL ||
ci->enc_unget_pcm_data == NULL )
return false;
@ -2461,10 +2458,6 @@ static bool enc_init(void)
enum codec_status codec_main(void)
{
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
bool cpu_boosted;
#endif
/* Generic codec initialisation */
if (!enc_init())
{
@ -2475,11 +2468,6 @@ enum codec_status codec_main(void)
/* main application waits for this flag during encoder loading */
ci->enc_codec_loaded = 1;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
ci->cpu_boost(true);
cpu_boosted = true;
#endif
/* main encoding loop */
while (!ci->stop_encoder)
{
@ -2492,13 +2480,6 @@ enum codec_status codec_main(void)
if (ci->stop_encoder)
break;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (!cpu_boosted && ci->enc_pcm_buf_near_empty() == 0)
{
ci->cpu_boost(true);
cpu_boosted = true;
}
#endif
chunk = ci->enc_get_chunk();
chunk->enc_data = ENC_CHUNK_SKIP_HDR(chunk->enc_data, chunk);
@ -2515,21 +2496,9 @@ enum codec_status codec_main(void)
ci->yield();
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (cpu_boosted && ci->enc_pcm_buf_near_empty())
{
ci->cpu_boost(false);
cpu_boosted = false;
}
#endif
ci->yield();
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (cpu_boosted) /* set initial boost state */
ci->cpu_boost(false);
#endif
/* reset parameters to initial state */
ci->enc_set_parameters(NULL);

View file

@ -291,9 +291,6 @@ static bool init_encoder(void)
ci->enc_set_parameters == NULL ||
ci->enc_get_chunk == NULL ||
ci->enc_finish_chunk == NULL ||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
ci->enc_pcm_buf_near_empty == NULL ||
#endif
ci->enc_get_pcm_data == NULL )
return false;
@ -321,10 +318,6 @@ static bool init_encoder(void)
/* main codec entry point */
enum codec_status codec_main(void)
{
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
bool cpu_boosted;
#endif
if (!init_encoder())
{
ci->enc_codec_loaded = -1;
@ -334,11 +327,6 @@ enum codec_status codec_main(void)
/* main application waits for this flag during encoder loading */
ci->enc_codec_loaded = 1;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
ci->cpu_boost(true);
cpu_boosted = true;
#endif
/* main encoding loop */
while(!ci->stop_encoder)
{
@ -351,13 +339,6 @@ enum codec_status codec_main(void)
if (ci->stop_encoder)
break;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (!cpu_boosted && ci->enc_pcm_buf_near_empty() == 0)
{
ci->cpu_boost(true);
cpu_boosted = true;
}
#endif
chunk = ci->enc_get_chunk();
chunk->enc_size = enc_size;
chunk->num_pcm = PCM_SAMP_PER_CHUNK;
@ -369,21 +350,9 @@ enum codec_status codec_main(void)
ci->yield();
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (cpu_boosted && ci->enc_pcm_buf_near_empty() != 0)
{
ci->cpu_boost(false);
cpu_boosted = false;
}
#endif
ci->yield();
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (cpu_boosted) /* set initial boost state */
ci->cpu_boost(false);
#endif
/* reset parameters to initial state */
ci->enc_set_parameters(NULL);

View file

@ -343,9 +343,6 @@ static bool init_encoder(void)
ci->enc_set_parameters == NULL ||
ci->enc_get_chunk == NULL ||
ci->enc_finish_chunk == NULL ||
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
ci->enc_pcm_buf_near_empty == NULL ||
#endif
ci->enc_get_pcm_data == NULL ||
ci->enc_unget_pcm_data == NULL )
return false;
@ -386,10 +383,6 @@ static bool init_encoder(void)
enum codec_status codec_main(void)
{
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
bool cpu_boosted;
#endif
/* initialize params and config */
if (!init_encoder())
{
@ -400,11 +393,6 @@ enum codec_status codec_main(void)
/* main application waits for this flag during encoder loading */
ci->enc_codec_loaded = 1;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
ci->cpu_boost(true);
cpu_boosted = true;
#endif
/* main encoding loop */
while(!ci->stop_encoder)
{
@ -422,13 +410,6 @@ enum codec_status codec_main(void)
abort_chunk = true;
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (!cpu_boosted && ci->enc_pcm_buf_near_empty() == 0)
{
ci->cpu_boost(true);
cpu_boosted = true;
}
#endif
chunk = ci->enc_get_chunk();
/* reset counts and pointer */
@ -472,21 +453,9 @@ enum codec_status codec_main(void)
}
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (cpu_boosted && ci->enc_pcm_buf_near_empty() != 0)
{
ci->cpu_boost(false);
cpu_boosted = false;
}
#endif
ci->yield();
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
if (cpu_boosted) /* set initial boost state */
ci->cpu_boost(false);
#endif
/* reset parameters to initial state */
ci->enc_set_parameters(NULL);

View file

@ -275,8 +275,6 @@ void enc_set_parameters(struct enc_parameters *params);
struct enc_chunk_hdr * enc_get_chunk(void);
/* releases the current chunk into the available chunks */
void enc_finish_chunk(void);
/* checks near empty state on pcm input buffer */
int enc_pcm_buf_near_empty(void);
#define PCM_MAX_FEED_SIZE 20000 /* max pcm size passed to encoder */

View file

@ -108,17 +108,16 @@ static unsigned long pre_record_ticks; /* pre-record time in ticks */
3.encoder: enc_set_parameters(); set the encoder parameters
4.encoder: enc_get_pcm_data(); get n bytes of unprocessed pcm data
5.encoder: enc_unget_pcm_data(); put n bytes of data back (optional)
6.encoder: enc_pcm_buf_near_empty(); if !0: reduce cpu_boost
7.encoder: enc_get_chunk(); get a ptr to next enc chunk
8.encoder: <process enc chunk> compress and store data to enc chunk
9.encoder: enc_finish_chunk(); inform main about chunk processed and
6.encoder: enc_get_chunk(); get a ptr to next enc chunk
7.encoder: <process enc chunk> compress and store data to enc chunk
8.encoder: enc_finish_chunk(); inform main about chunk processed and
is available to be written to a file.
Encoder can place any number of chunks
of PCM data in a single output chunk
but must stay within its output chunk
size
A.encoder: repeat 4. to 9.
B.pcmrec: enc_events_callback(); called for certain events
9.encoder: repeat 4. to 8.
A.pcmrec: enc_events_callback(); called for certain events
(*) Optional step
****************************************************************************/
@ -1541,6 +1540,7 @@ void enc_set_parameters(struct enc_parameters *params)
/* Encoder is terminating */
memset(&enc_config, 0, sizeof (enc_config));
enc_sample_rate = 0;
cancel_cpu_boost(); /* Make sure no boost remains */
return;
}
@ -1709,15 +1709,6 @@ void enc_finish_chunk(void)
}
} /* enc_finish_chunk */
/* checks near empty state on pcm input buffer */
int enc_pcm_buf_near_empty(void)
{
/* less than 1sec raw data? => unboost encoder */
int wp = dma_wr_pos;
size_t avail = (wp - pcm_rd_pos) & PCM_CHUNK_MASK;
return avail < (sample_rate << 2) ? 1 : 0;
} /* enc_pcm_buf_near_empty */
/* passes a pointer to next chunk of unprocessed wav data */
/* TODO: this really should give the actual size returned */
unsigned char * enc_get_pcm_data(size_t size)
@ -1744,12 +1735,24 @@ unsigned char * enc_get_pcm_data(size_t size)
pcm_buffer, pcm_rd_pos);
}
if (avail >= (sample_rate << 2))
{
/* Filling up - boost codec */
trigger_cpu_boost();
}
pcm_buffer_empty = false;
return ptr;
}
/* not enough data available - encoder should idle */
pcm_buffer_empty = true;
cancel_cpu_boost();
/* Sleep long enough to allow one frame on average */
sleep(0);
return NULL;
} /* enc_get_pcm_data */