forked from len0rd/rockbox
Inspired by patch #1377739 by Brandon Low: Inline oggpack_adv and the most used part of oggpack_look. Reduces CPU boost on a test track (208 kbps) by 2-3 percentage points.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8274 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
783428d2ee
commit
085f2f428e
2 changed files with 70 additions and 59 deletions
|
|
@ -22,45 +22,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "ogg.h"
|
#include "ogg.h"
|
||||||
|
|
||||||
static const unsigned long mask[] ICONST_ATTR =
|
|
||||||
{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
|
|
||||||
0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
|
|
||||||
0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff,
|
|
||||||
0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff,
|
|
||||||
0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff,
|
|
||||||
0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
|
|
||||||
0x3fffffff,0x7fffffff,0xffffffff };
|
|
||||||
|
|
||||||
/* mark read process as having run off the end */
|
|
||||||
static void _adv_halt(oggpack_buffer *b){
|
|
||||||
b->headptr=b->head->buffer->data+b->head->begin+b->head->length;
|
|
||||||
b->headend=-1;
|
|
||||||
b->headbit=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* spans forward, skipping as many bytes as headend is negative; if
|
|
||||||
headend is zero, simply finds next byte. If we're up to the end
|
|
||||||
of the buffer, leaves headend at zero. If we've read past the end,
|
|
||||||
halt the decode process. */
|
|
||||||
static void _span(oggpack_buffer *b){
|
|
||||||
while(b->headend<1){
|
|
||||||
if(b->head->next){
|
|
||||||
b->count+=b->head->length;
|
|
||||||
b->head=b->head->next;
|
|
||||||
b->headptr=b->head->buffer->data+b->head->begin-b->headend;
|
|
||||||
b->headend+=b->head->length;
|
|
||||||
}else{
|
|
||||||
/* we've either met the end of decode, or gone past it. halt
|
|
||||||
only if we're past */
|
|
||||||
if(b->headend<0 || b->headbit)
|
|
||||||
/* read has fallen off the end */
|
|
||||||
_adv_halt(b);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
|
void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
|
||||||
memset(b,0,sizeof(*b));
|
memset(b,0,sizeof(*b));
|
||||||
|
|
||||||
|
|
@ -79,9 +40,9 @@ void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read in bits without advancing the bitptr; bits <= 32 */
|
/* Read in bits without advancing the bitptr; bits <= 32 */
|
||||||
long oggpack_look(oggpack_buffer *b,int bits) ICODE_ATTR;
|
long oggpack_look_full(oggpack_buffer *b,int bits) ICODE_ATTR;
|
||||||
long oggpack_look(oggpack_buffer *b,int bits){
|
long oggpack_look_full(oggpack_buffer *b,int bits){
|
||||||
unsigned long m=mask[bits];
|
unsigned long m=(1<<bits)-1;
|
||||||
unsigned long ret=0;
|
unsigned long ret=0;
|
||||||
|
|
||||||
bits+=b->headbit;
|
bits+=b->headbit;
|
||||||
|
|
@ -139,19 +100,6 @@ long oggpack_look(oggpack_buffer *b,int bits){
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* limited to 32 at a time */
|
|
||||||
#if CONFIG_CPU!=PP5020
|
|
||||||
/* TODO: This function (and this function only) causes a "relocation
|
|
||||||
truncated to fit: R_ARM_PC24" error when in IRAM on ARM targets */
|
|
||||||
void oggpack_adv(oggpack_buffer *b,int bits) ICODE_ATTR;
|
|
||||||
#endif
|
|
||||||
void oggpack_adv(oggpack_buffer *b,int bits){
|
|
||||||
bits+=b->headbit;
|
|
||||||
b->headbit=bits&7;
|
|
||||||
b->headptr+=bits/8;
|
|
||||||
if((b->headend-=bits/8)<1)_span(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* spans forward and finds next byte. Never halts */
|
/* spans forward and finds next byte. Never halts */
|
||||||
static void _span_one(oggpack_buffer *b){
|
static void _span_one(oggpack_buffer *b){
|
||||||
while(b->headend<1){
|
while(b->headend<1){
|
||||||
|
|
@ -180,7 +128,7 @@ int oggpack_eop(oggpack_buffer *b){
|
||||||
|
|
||||||
/* bits <= 32 */
|
/* bits <= 32 */
|
||||||
long oggpack_read(oggpack_buffer *b,int bits){
|
long oggpack_read(oggpack_buffer *b,int bits){
|
||||||
unsigned long m=mask[bits];
|
unsigned long m=(1<<bits)-1;
|
||||||
ogg_uint32_t ret=0;
|
ogg_uint32_t ret=0;
|
||||||
|
|
||||||
bits+=b->headbit;
|
bits+=b->headbit;
|
||||||
|
|
@ -235,7 +183,7 @@ long oggpack_read(oggpack_buffer *b,int bits){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
ret=b->headptr[0]>>b->headbit;
|
ret=b->headptr[0]>>b->headbit;
|
||||||
if(bits>8){
|
if(bits>8){
|
||||||
ret|=b->headptr[1]<<(8-b->headbit);
|
ret|=b->headptr[1]<<(8-b->headbit);
|
||||||
|
|
|
||||||
|
|
@ -141,13 +141,76 @@ typedef struct {
|
||||||
/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
|
/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
|
||||||
|
|
||||||
extern void oggpack_readinit(oggpack_buffer *b,ogg_reference *r);
|
extern void oggpack_readinit(oggpack_buffer *b,ogg_reference *r);
|
||||||
extern long oggpack_look(oggpack_buffer *b,int bits);
|
extern long oggpack_look_full(oggpack_buffer *b,int bits);
|
||||||
extern void oggpack_adv(oggpack_buffer *b,int bits);
|
|
||||||
extern long oggpack_read(oggpack_buffer *b,int bits);
|
extern long oggpack_read(oggpack_buffer *b,int bits);
|
||||||
extern long oggpack_bytes(oggpack_buffer *b);
|
extern long oggpack_bytes(oggpack_buffer *b);
|
||||||
extern long oggpack_bits(oggpack_buffer *b);
|
extern long oggpack_bits(oggpack_buffer *b);
|
||||||
extern int oggpack_eop(oggpack_buffer *b);
|
extern int oggpack_eop(oggpack_buffer *b);
|
||||||
|
|
||||||
|
/* Inline a few, often called functions */
|
||||||
|
|
||||||
|
/* mark read process as having run off the end */
|
||||||
|
static inline void _adv_halt(oggpack_buffer *b){
|
||||||
|
b->headptr=b->head->buffer->data+b->head->begin+b->head->length;
|
||||||
|
b->headend=-1;
|
||||||
|
b->headbit=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* spans forward, skipping as many bytes as headend is negative; if
|
||||||
|
headend is zero, simply finds next byte. If we're up to the end
|
||||||
|
of the buffer, leaves headend at zero. If we've read past the end,
|
||||||
|
halt the decode process. */
|
||||||
|
static inline void _span(oggpack_buffer *b){
|
||||||
|
while(b->headend<1){
|
||||||
|
if(b->head->next){
|
||||||
|
b->count+=b->head->length;
|
||||||
|
b->head=b->head->next;
|
||||||
|
b->headptr=b->head->buffer->data+b->head->begin-b->headend;
|
||||||
|
b->headend+=b->head->length;
|
||||||
|
}else{
|
||||||
|
/* we've either met the end of decode, or gone past it. halt
|
||||||
|
only if we're past */
|
||||||
|
if(b->headend<0 || b->headbit)
|
||||||
|
/* read has fallen off the end */
|
||||||
|
_adv_halt(b);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* limited to 32 at a time */
|
||||||
|
static inline void oggpack_adv(oggpack_buffer *b,int bits){
|
||||||
|
bits+=b->headbit;
|
||||||
|
b->headbit=bits&7;
|
||||||
|
b->headptr+=bits/8;
|
||||||
|
if((b->headend-=bits/8)<1)_span(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline long oggpack_look(oggpack_buffer *b, int bits){
|
||||||
|
if(bits+b->headbit < b->headend<<3){
|
||||||
|
unsigned long m=(1<<bits)-1;
|
||||||
|
unsigned long ret=0;
|
||||||
|
|
||||||
|
bits+=b->headbit;
|
||||||
|
ret=b->headptr[0]>>b->headbit;
|
||||||
|
if(bits>8){
|
||||||
|
ret|=b->headptr[1]<<(8-b->headbit);
|
||||||
|
if(bits>16){
|
||||||
|
ret|=b->headptr[2]<<(16-b->headbit);
|
||||||
|
if(bits>24){
|
||||||
|
ret|=b->headptr[3]<<(24-b->headbit);
|
||||||
|
if(bits>32 && b->headbit)
|
||||||
|
ret|=b->headptr[4]<<(32-b->headbit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret&m;
|
||||||
|
}else{
|
||||||
|
return oggpack_look_full(b, bits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
|
/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
|
||||||
|
|
||||||
extern ogg_sync_state *ogg_sync_create(void);
|
extern ogg_sync_state *ogg_sync_create(void);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue