Index: apps/codecs/libtremor/codebook.c =================================================================== --- apps/codecs/libtremor/codebook.c (revision 20567) +++ apps/codecs/libtremor/codebook.c (working copy) @@ -199,78 +199,6 @@ return(-1); } -static long decode_packed_block(codebook *book, oggpack_buffer *b, - long *buf, int n){ - long *bufptr = buf; - long *bufend = buf + n; - - while (bufptrheadend > 8) { - ogg_uint32_t *ptr; - unsigned long bit, bitend; - unsigned long adr; - ogg_uint32_t cache = 0; - int cachesize = 0; - - adr = (unsigned long)b->headptr; - bit = (adr&3)*8+b->headbit; - ptr = (ogg_uint32_t *)(adr&~3); - bitend = ((adr&3)+b->headend)*8; - while (bufptrdec_maxlength)) { - if (bit-cachesize+32>=bitend) - break; - bit-=cachesize; - cache=letoh32(ptr[bit>>5]) >> (bit&31); - if (bit&31) - cache|=letoh32(ptr[(bit>>5)+1]) << (32-(bit&31)); - cachesize=32; - bit+=32; - } - - entry=book->dec_firsttable[cache&((1<dec_firsttablen)-1)]; - if(UNLIKELY(entry&0x80000000UL)){ - lo=(entry>>15)&0x7fff; - hi=book->used_entries-(entry&0x7fff); - { - ogg_uint32_t testword=bitreverse((ogg_uint32_t)cache); - - while(LIKELY(hi-lo>1)){ - long p=(hi-lo)>>1; - if (book->codelist[lo+p]>testword) - hi-=p; - else - lo+=p; - } - entry=lo; - } - }else - entry--; - - *bufptr++=entry; - { - int l=book->dec_codelengths[entry]; - cachesize-=l; - cache>>=l; - } - } - - adr=(unsigned long)b->headptr; - bit-=(adr&3)*8+cachesize; - b->headend-=(bit/8); - b->headptr+=bit/8; - b->headbit=bit%8; - } else { - long r = decode_packed_entry_number(book, b); - if (r == -1) return bufptr-buf; - *bufptr++ = r; - } - } - return n; -} - - /* Decode side is specced and easier, because we don't need to find matches using different criteria; we simply read and map. There are two things we need to do 'depending': @@ -399,76 +327,24 @@ return(0); } -static long vorbis_book_decodevv_add_2ch_even(codebook *book,ogg_int32_t **a, - long offset,oggpack_buffer *b, - int n,int point){ - long i,k,chunk,read; - int shift=point-book->binarypoint; - long entries[32]; - ogg_int32_t *p0 = &(a[0][offset]); - ogg_int32_t *p1 = &(a[1][offset]); - - if(shift>=0){ - - for(i=0;idim>(n-i)*2) - chunk=((n-i)*2+book->dim-1)/book->dim; - read = decode_packed_block(book,b,entries,chunk); - for(k=0;kvaluelist+entries[k]*book->dim; - const ogg_int32_t *u = t+book->dim; - do{ - *p0++ += *t++>>shift; - *p1++ += *t++>>shift; - }while(tdim/2; - } - }else{ - shift = -shift; - for(i=0;idim>(n-i)*2) - chunk=((n-i)*2+book->dim-1)/book->dim; - read = decode_packed_block(book,b,entries,chunk); - for(k=0;kvaluelist+entries[k]*book->dim; - const ogg_int32_t *u = t+book->dim; - do{ - *p0++ += *t++<dim/2; - } - } - return(0); -} - long vorbis_book_decodevv_add(codebook *book,ogg_int32_t **a, long offset,int ch, oggpack_buffer *b,int n,int point){ if(LIKELY(book->used_entries>0)){ - long i,j,k,chunk,read; + long i,j,entry; int chptr=0; int shift=point-book->binarypoint; - long entries[32]; - if (!(book->dim&1) && ch==2) - return vorbis_book_decodevv_add_2ch_even(book,a,offset,b,n,point); +// if (!(book->dim&1) && ch==2) +// return vorbis_book_decodevv_add_2ch_even(book,a,offset,b,n,point); if(shift>=0){ for(i=offset;idim>(offset+n-i)*ch) - chunk=((offset+n-i)*ch+book->dim-1)/book->dim; - read = decode_packed_block(book,b,entries,chunk); - for(k=0;kvaluelist+entries[k]*book->dim; + entry = decode_packed_entry_number(book,b); + if(entry==-1)return(-1); + { + const ogg_int32_t *t = book->valuelist+entry*book->dim; for (j=0;jdim;j++){ a[chptr++][i]+=t[j]>>shift; if(chptr==ch){ @@ -477,17 +353,14 @@ } } } - if (readdim>(offset+n-i)*ch) - chunk=((offset+n-i)*ch+book->dim-1)/book->dim; - read = decode_packed_block(book,b,entries,chunk); - for(k=0;kvaluelist+entries[k]*book->dim; + entry = decode_packed_entry_number(book,b); + if(entry==-1)return(-1); + { + const ogg_int32_t *t = book->valuelist+entry*book->dim; for (j=0;jdim;j++){ a[chptr++][i]+=t[j]< +#include "misc.h" #include "ogg.h" +#if !defined(ARM_LITTLE_ENDIAN) const unsigned long oggpack_mask[] ICONST_ATTR = {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, @@ -30,7 +32,61 @@ 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, 0x3fffffff,0x7fffffff,0xffffffff }; +#endif +#ifdef ARM_LITTLE_ENDIAN +int oggpack_eop(oggpack_buffer *b){ + int ret; + if(b->bitsLeftInSegment<0)ret= -1; + else ret = 0; + return ret; +} + +long oggpack_bytes(oggpack_buffer *b){ + long ret; + if(b->bitsLeftInSegment<0) ret = b->count+b->head->length; + else ret = b->count + b->head->length - (b->bitsLeftInSegment)/8; + return ret; +} + +long oggpack_bits(oggpack_buffer *b){ + long ret; + if(b->bitsLeftInSegment<0) ret=(b->count+b->head->length)*8; + else ret = b->count*8 + b->head->length*8 - b->bitsLeftInSegment; + return ret; +} + +#else + +/* 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-(b->headbit>>3)<1){ + b->headend-=b->headbit>>3; + b->headbit&=0x7; + + if(b->head->next){ + b->count+=b->head->length; + b->head=b->head->next; + + if(b->headend+b->head->length>0) + 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*8headbit) + /* read has fallen off the end */ + b->headend=-1; + break; + } + } +} + void oggpack_readinit(oggpack_buffer *b,ogg_reference *r){ memset(b,0,sizeof(*b)); @@ -49,10 +105,10 @@ } /* Read in bits without advancing the bitptr; bits <= 32 */ -long oggpack_look_full(oggpack_buffer *b,int bits) ICODE_ATTR_TREMOR_NOT_MDCT; -long oggpack_look_full(oggpack_buffer *b,int bits){ +long oggpack_look(oggpack_buffer *b,int bits){ unsigned long m=oggpack_mask[bits]; - unsigned long ret=-1; + unsigned long ret; + int BITS = bits; bits+=b->headbit; @@ -62,22 +118,22 @@ ogg_reference *head=b->head; if(end<0)return -1; - + if(bits){ _lookspan(); ret=*ptr++>>b->headbit; if(bits>8){ --end; _lookspan(); - ret|=*ptr++<<(8-b->headbit); + ret|=*ptr++<<(8-b->headbit); if(bits>16){ --end; _lookspan(); - ret|=*ptr++<<(16-b->headbit); + ret|=*ptr++<<(16-b->headbit); if(bits>24){ --end; _lookspan(); - ret|=*ptr++<<(24-b->headbit); + ret|=*ptr++<<(24-b->headbit); if(bits>32 && b->headbit){ --end; _lookspan(); @@ -93,11 +149,11 @@ /* make this a switch jump-table */ ret=b->headptr[0]>>b->headbit; if(bits>8){ - ret|=b->headptr[1]<<(8-b->headbit); + ret|=b->headptr[1]<<(8-b->headbit); if(bits>16){ - ret|=b->headptr[2]<<(16-b->headbit); + ret|=b->headptr[2]<<(16-b->headbit); if(bits>24){ - ret|=b->headptr[3]<<(24-b->headbit); + ret|=b->headptr[3]<<(24-b->headbit); if(bits>32 && b->headbit) ret|=b->headptr[4]<<(32-b->headbit); } @@ -109,106 +165,42 @@ return ret; } -/* spans forward and finds next byte. Never halts */ -static void _span_one(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->head->length; - }else - break; - } +/* limited to 32 at a time */ +void oggpack_adv(oggpack_buffer *b,int bits){ + int BITS=bits; + bits+=b->headbit; + b->headbit=bits&7; + b->headend-=(bits>>3); + b->headptr+=(bits>>3); + if(b->headend<1)_span(b); } -static int _halt_one(oggpack_buffer *b){ - if(b->headend<1){ - _adv_halt(b); - return -1; - } - return 0; +int oggpack_eop(oggpack_buffer *b){ + int ret; + if(b->headend<0)ret= -1; + else ret = 0; + return ret; } -/* bits <= 32 */ -long oggpack_read(oggpack_buffer *b,register int bits) ICODE_ATTR_TREMOR_NOT_MDCT; -long oggpack_read(oggpack_buffer *b,register int bits){ - unsigned long m=oggpack_mask[bits]; - ogg_uint32_t ret=-1; +long oggpack_bytes(oggpack_buffer *b){ + long ret; + if(b->headend<0) ret = b->count+b->head->length; + ret = b->count + b->head->length-b->headend + (b->headbit+7)/8; + return ret; +} - bits+=b->headbit; - - if(bits >= b->headend<<3){ - - if(b->headend<0)return -1; - - if(bits){ - if (_halt_one(b)) return -1; - ret=*b->headptr>>b->headbit; - - if(bits>=8){ - ++b->headptr; - --b->headend; - _span_one(b); - if(bits>8){ - if (_halt_one(b)) return -1; - ret|=*b->headptr<<(8-b->headbit); - - if(bits>=16){ - ++b->headptr; - --b->headend; - _span_one(b); - if(bits>16){ - if (_halt_one(b)) return -1; - ret|=*b->headptr<<(16-b->headbit); - - if(bits>=24){ - ++b->headptr; - --b->headend; - _span_one(b); - if(bits>24){ - if (_halt_one(b)) return -1; - ret|=*b->headptr<<(24-b->headbit); - - if(bits>=32){ - ++b->headptr; - --b->headend; - _span_one(b); - if(bits>32){ - if (_halt_one(b)) return -1; - if(b->headbit)ret|=*b->headptr<<(32-b->headbit); - - } - } - } - } - } - } - } - } - } - }else{ - - 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); - } - } - } - } - - b->headptr+=((unsigned)bits)/8; - b->headend-=((unsigned)bits)/8; - } - - ret&=m; - b->headbit=bits&7; +long oggpack_bits(oggpack_buffer *b){ + long ret; + if(b->headend<0) ret = (b->count+b->head->length)*8; + else ret = (b->count + b->head->length-b->headend)*8 + b->headbit; return ret; } +/* bits <= 32 */ +long oggpack_read(oggpack_buffer *b,int bits){ + long ret=oggpack_look(b,bits); + oggpack_adv(b,bits); + return(ret); +} + +#endif \ No newline at end of file Index: apps/codecs/libtremor/ogg.h =================================================================== --- apps/codecs/libtremor/ogg.h (revision 20567) +++ apps/codecs/libtremor/ogg.h (working copy) @@ -23,6 +23,10 @@ #include "os_types.h" +#ifndef ONLY_C +#define ARM_LITTLE_ENDIAN +#endif + typedef struct ogg_buffer_state{ struct ogg_buffer *unused_buffers; struct ogg_reference *unused_references; @@ -34,7 +38,7 @@ unsigned char *data; long size; int refcount; - + union { ogg_buffer_state *owner; struct ogg_buffer *next; @@ -50,10 +54,15 @@ } ogg_reference; typedef struct oggpack_buffer { +#ifdef ARM_LITTLE_ENDIAN + int bitsLeftInSegment; + ogg_uint32_t *ptr; + long bitsLeftInWord; +#else int headbit; unsigned char *headptr; long headend; - +#endif /* ARM_LITTLE_ENDIAN */ /* memory management */ ogg_reference *head; ogg_reference *tail; @@ -115,7 +124,7 @@ int clearflag; int laceptr; ogg_uint32_t body_fill_next; - + } ogg_stream_state; typedef struct { @@ -141,74 +150,13 @@ /* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ extern void oggpack_readinit(oggpack_buffer *b,ogg_reference *r); -extern long oggpack_look_full(oggpack_buffer *b,int bits); -extern long oggpack_read(oggpack_buffer *b,register int bits); +extern long oggpack_look(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_bytes(oggpack_buffer *b); +extern long oggpack_bits(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-=((unsigned)bits)/8)<1)_span(b); -} - -static inline long oggpack_look(oggpack_buffer *b, int bits){ - if(bits+b->headbit < b->headend<<3){ - extern const unsigned long oggpack_mask[]; - unsigned long m=oggpack_mask[bits]; - unsigned long ret=-1; - - 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 **************************/ extern ogg_sync_state *ogg_sync_create(void); @@ -218,6 +166,7 @@ extern unsigned char *ogg_sync_bufferin(ogg_sync_state *oy, long size); extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); @@ -239,6 +188,7 @@ extern ogg_int64_t ogg_page_granulepos(ogg_page *og); extern ogg_uint32_t ogg_page_serialno(ogg_page *og); extern ogg_uint32_t ogg_page_pageno(ogg_page *og); +extern int ogg_page_packets(ogg_page *og); extern int ogg_page_getbuffer(ogg_page *og, unsigned char **buffer); extern int ogg_packet_release(ogg_packet *op); Index: apps/codecs/libtremor/libtremor.make =================================================================== --- apps/codecs/libtremor/libtremor.make (revision 20567) +++ apps/codecs/libtremor/libtremor.make (working copy) @@ -17,12 +17,6 @@ $(SILENT)$(shell rm -f $@) $(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null -$(CODECDIR)/libtremor/%.o: $(ROOTDIR)/apps/codecs/libtremor/%.c - $(SILENT)mkdir -p $(dir $@) - $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) \ - -I$(APPSDIR)/codecs/libtremor \ - $(CODECFLAGS) $(CFLAGS) -c $< -o $@ - TREMORFLAGS = -I$(APPSDIR)/codecs/libtremor $(filter-out -O%,$(CODECFLAGS)) # Tremor is slightly faster on coldfire with -O3 @@ -32,6 +26,9 @@ TREMORFLAGS += -O2 endif +$(CODECDIR)/libtremor/bitwiseARM.o: $(ROOTDIR)/apps/codecs/libtremor/bitwiseARM.S + $(CC) $(TREMORFLAGS) -c $< -o $@ + $(CODECDIR)/libtremor/%.o: $(ROOTDIR)/apps/codecs/libtremor/%.c $(SILENT)mkdir -p $(dir $@) $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) $(TREMORFLAGS) -c $< -o $@