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:
parent
b0dd9eb5bc
commit
5323fe996b
8 changed files with 20 additions and 165 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue