Commit 8886a280 authored by Timothy B. Terriberry's avatar Timothy B. Terriberry
Browse files

Convert Tremor to use libogg instead of its own internal libogg2.

This makes it easier to use Tremor as a drop-in replacement for libvorbis and
 reduces code size and overhead for those who don't want to use its built-in
 Ogg demuxer.
This commit also backports all of the changes that have accumulated in
 libvorbis's vorbisfile implementation, with the exception of halfrate decoding
 and cross-lapped seeking.
Those should not be too hard to add if someone really wants them.


git-svn-id: https://svn.xiph.org/trunk/Tremor@17375 0101bb08-14d6-0310-b084-bc0e0c8e3800
parent 7125eb63
AUTOMAKE_OPTIONS = foreign
INCLUDES = -I./
INCLUDES = -I./ @OGG_CFLAGS@
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = vorbisidec.pc
......@@ -11,28 +11,29 @@ libvorbisidec_la_SOURCES = mdct.c block.c window.c \
synthesis.c info.c \
floor1.c floor0.c vorbisfile.c \
res012.c mapping0.c registry.c codebook.c \
sharedbook.c framing.c bitwise.c \
sharedbook.c \
codebook.h misc.h mdct_lookup.h\
os.h mdct.h block.h ivorbisfile.h lsp_lookup.h\
registry.h window.h window_lookup.h\
codec_internal.h backends.h ogg.h \
codec_internal.h backends.h \
asm_arm.h ivorbiscodec.h
libvorbisidec_la_LDFLAGS = -version-info @V_LIB_CURRENT@:@V_LIB_REVISION@:@V_LIB_AGE@
libvorbisidec_la_LIBADD = @OGG_LIBS@
EXTRA_PROGRAMS = ivorbisfile_example iseeking_example
CLEANFILES = $(EXTRA_PROGRAMS) $(lib_LTLIBRARIES)
ivorbisfile_example_SOURCES = ivorbisfile_example.c
ivorbisfile_example_LDFLAGS = -static
ivorbisfile_example_LDADD = libvorbisidec.la
ivorbisfile_example_LDADD = libvorbisidec.la @OGG_LIBS@
iseeking_example_SOURCES = iseeking_example.c
iseeking_example_LDFLAGS = -static
iseeking_example_LDADD = libvorbisidec.la
iseeking_example_LDADD = libvorbisidec.la @OGG_LIBS@
includedir = $(prefix)/include/tremor
include_HEADERS = ivorbiscodec.h ivorbisfile.h ogg.h os_types.h config_types.h
include_HEADERS = ivorbiscodec.h ivorbisfile.h config_types.h
EXTRA_DIST = vorbisidec.pc.in \
$(srcdir)/doc/*.html $(srcdir)/win32/VS*/libtremor/*.vcproj
......
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
function: packing variable sized words into an octet stream
********************************************************************/
/* We're 'LSb' endian; if we write a word but read individual bits,
then we'll read the lsb first */
#include <string.h>
#include <stdlib.h>
#include "ogg.h"
static unsigned long mask[]=
{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){
memset(b,0,sizeof(*b));
b->tail=b->head=r;
b->count=0;
b->headptr=b->head->buffer->data+b->head->begin;
b->headend=b->head->length;
_span(b);
}
#define _lookspan() while(!end){\
head=head->next;\
if(!head) return -1;\
ptr=head->buffer->data + head->begin;\
end=head->length;\
}
/* Read in bits without advancing the bitptr; bits <= 32 */
long oggpack_look(oggpack_buffer *b,int bits){
unsigned long m=mask[bits];
unsigned long ret=-1;
bits+=b->headbit;
if(bits >= b->headend<<3){
int end=b->headend;
unsigned char *ptr=b->headptr;
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);
if(bits>16){
--end;
_lookspan();
ret|=*ptr++<<(16-b->headbit);
if(bits>24){
--end;
_lookspan();
ret|=*ptr++<<(24-b->headbit);
if(bits>32 && b->headbit){
--end;
_lookspan();
ret|=*ptr<<(32-b->headbit);
}
}
}
}
}
}else{
/* make this a switch jump-table */
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);
}
}
}
}
ret&=m;
return ret;
}
/* limited to 32 at a time */
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 */
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;
}
}
static int _halt_one(oggpack_buffer *b){
if(b->headend<1){
_adv_halt(b);
return -1;
}
return 0;
}
int oggpack_eop(oggpack_buffer *b){
if(b->headend<0)return -1;
return 0;
}
/* bits <= 32 */
long oggpack_read(oggpack_buffer *b,int bits){
unsigned long m=mask[bits];
ogg_uint32_t ret=-1;
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+=bits/8;
b->headend-=bits/8;
}
ret&=m;
b->headbit=bits&7;
return ret;
}
long oggpack_bytes(oggpack_buffer *b){
return(b->count+b->headptr-b->head->buffer->data-b->head->begin+
(b->headbit+7)/8);
}
long oggpack_bits(oggpack_buffer *b){
return((b->count+b->headptr-b->head->buffer->data-b->head->begin)*8+
b->headbit);
}
......@@ -18,7 +18,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ogg.h"
#include <ogg/ogg.h>
#include "ivorbiscodec.h"
#include "codec_internal.h"
......
......@@ -18,7 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "ogg.h"
#include <ogg/ogg.h>
#include "ivorbiscodec.h"
#include "codebook.h"
#include "misc.h"
......
......@@ -18,7 +18,7 @@
#ifndef _V_CODEBOOK_H_
#define _V_CODEBOOK_H_
#include "ogg.h"
#include <ogg/ogg.h>
/* This structure encapsulates huffman and VQ style encoding books; it
doesn't do anything specific to either.
......
......@@ -114,6 +114,27 @@ dnl --------------------------------------------------
dnl none
dnl --------------------------------------------------
dnl Check for libraries
dnl --------------------------------------------------
PKG_PROG_PKG_CONFIG
HAVE_OGG=no
if test "x$PKG_CONFIG" != "x"
then
PKG_CHECK_MODULES(OGG, ogg >= 1.0, HAVE_OGG=yes, HAVE_OGG=no)
fi
if test "x$HAVE_OGG" = "xno"
then
dnl fall back to the old school test
XIPH_PATH_OGG(, AC_MSG_ERROR(must have Ogg installed!))
libs_save=$LIBS
LIBS="$OGG_LIBS"
AC_CHECK_FUNC(oggpack_writealign, , AC_MSG_ERROR(Ogg >= 1.0 required !))
LIBS=$libs_save
fi
dnl --------------------------------------------------
dnl Check for library functions
dnl --------------------------------------------------
......
......@@ -18,7 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "ogg.h"
#include <ogg/ogg.h>
#include "ivorbiscodec.h"
#include "codec_internal.h"
#include "registry.h"
......
......@@ -18,7 +18,7 @@
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "ogg.h"
#include <ogg/ogg.h>
#include "ivorbiscodec.h"
#include "codec_internal.h"
#include "registry.h"
......
This diff is collapsed.
......@@ -21,7 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "ogg.h"
#include <ogg/ogg.h>
#include "ivorbiscodec.h"
#include "codec_internal.h"
#include "codebook.h"
......@@ -299,7 +299,7 @@ int vorbis_synthesis_idheader(ogg_packet *op){
char buffer[6];
if(op){
oggpack_readinit(&opb,op->packet);
oggpack_readinit(&opb,op->packet,op->bytes);
if(!op->b_o_s)
return(0); /* Not the initial packet */
......@@ -327,7 +327,7 @@ int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op)
oggpack_buffer opb;
if(op){
oggpack_readinit(&opb,op->packet);
oggpack_readinit(&opb,op->packet,op->bytes);
/* Which of the three types of header is this? */
/* Also verify header-ness, vorbis */
......
......@@ -23,7 +23,7 @@ extern "C"
{
#endif /* __cplusplus */
#include "ogg.h"
#include <ogg/ogg.h>
typedef struct vorbis_info{
int version;
......
......@@ -55,7 +55,7 @@ typedef struct OggVorbis_File {
int seekable;
ogg_int64_t offset;
ogg_int64_t end;
ogg_sync_state *oy;
ogg_sync_state oy;
/* If the FILE handle isn't seekable (eg, a pipe), only the current
stream appears */
......@@ -76,7 +76,7 @@ typedef struct OggVorbis_File {
ogg_int64_t bittrack;
ogg_int64_t samptrack;
ogg_stream_state *os; /* take physical pages, weld into a logical
ogg_stream_state os; /* take physical pages, weld into a logical
stream of packets */
vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
vorbis_block vb; /* local working space for packet->PCM decode */
......@@ -86,13 +86,13 @@ typedef struct OggVorbis_File {
} OggVorbis_File;
extern int ov_clear(OggVorbis_File *vf);
extern int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
extern int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
char *initial, long ibytes, ov_callbacks callbacks);
const char *initial, long ibytes, ov_callbacks callbacks);
extern int ov_test(FILE *f,OggVorbis_File *vf,char *initial,long ibytes);
extern int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes);
extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf,
char *initial, long ibytes, ov_callbacks callbacks);
const char *initial, long ibytes, ov_callbacks callbacks);
extern int ov_test_open(OggVorbis_File *vf);
extern long ov_bitrate(OggVorbis_File *vf,int i);
......
......@@ -18,7 +18,7 @@
#ifndef _V_LOOKUP_DATA_H_
#define _V_LOOKUP_DATA_H_
#include "os_types.h"
#include <ogg/os_types.h>
#define FROMdB_LOOKUP_SZ 35
#define FROMdB2_LOOKUP_SZ 32
......
......@@ -19,7 +19,7 @@
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "ogg.h"
#include <ogg/ogg.h>
#include "ivorbiscodec.h"
#include "mdct.h"
#include "codec_internal.h"
......
......@@ -15,7 +15,7 @@
********************************************************************/
#include "os_types.h"
#include "misc.h"
/* {sin(2*i*PI/4096), cos(2*i*PI/4096)}, with i = 0 to 512 */
static LOOKUP_T sincos_lookup0[1026] = {
......
......@@ -20,6 +20,14 @@
#include "ivorbiscodec.h"
#include "os.h"
#ifdef _LOW_ACCURACY_
# define X(n) (((((n)>>22)+1)>>1) - ((((n)>>22)+1)>>9))
# define LOOKUP_T const unsigned char
#else
# define X(n) (n)
# define LOOKUP_T const ogg_int32_t
#endif
#include "asm_arm.h"
#include <stdlib.h> /* for abs() */
......
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE. *
* *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003 *
* BY THE Xiph.Org FOUNDATION http://www.xiph.org/ *
* *
********************************************************************
function: subsumed libogg includes
********************************************************************/
#ifndef _OGG_H
#define _OGG_H
#ifdef __cplusplus
extern "C" {
#endif
#include "os_types.h"
typedef struct ogg_buffer_state{
struct ogg_buffer *unused_buffers;
struct ogg_reference *unused_references;
int outstanding;
int shutdown;
} ogg_buffer_state;
typedef struct ogg_buffer {
unsigned char *data;
long size;
int refcount;
union {
ogg_buffer_state *owner;
struct ogg_buffer *next;
} ptr;
} ogg_buffer;
typedef struct ogg_reference {
ogg_buffer *buffer;
long begin;
long length;
struct ogg_reference *next;
} ogg_reference;
typedef struct oggpack_buffer {
int headbit;
unsigned char *headptr;
long headend;
/* memory management */
ogg_reference *head;
ogg_reference *tail;
/* render the byte/bit counter API constant time */
long count; /* doesn't count the tail */
} oggpack_buffer;
typedef struct oggbyte_buffer {
ogg_reference *baseref;
ogg_reference *ref;
unsigned char *ptr;
long pos;
long end;
} oggbyte_buffer;
typedef struct ogg_sync_state {
/* decode memory management pool */
ogg_buffer_state *bufferpool;
/* stream buffers */
ogg_reference *fifo_head;
ogg_reference *fifo_tail;
long fifo_fill;
/* stream sync management */
int unsynced;
int headerbytes;
int bodybytes;
} ogg_sync_state;
typedef struct ogg_stream_state {
ogg_reference *header_head;
ogg_reference *header_tail;
ogg_reference *body_head;
ogg_reference *body_tail;
int e_o_s; /* set when we have buffered the last
packet in the logical bitstream */
int b_o_s; /* set after we've written the initial page
of a logical bitstream */
long serialno;
long pageno;
ogg_int64_t packetno; /* sequence number for decode; the framing
knows where there's a hole in the data,
but we need coupling so that the codec
(which is in a seperate abstraction
layer) also knows about the gap */
ogg_int64_t granulepos;
int lacing_fill;
ogg_uint32_t body_fill;
/* decode-side state data */
int holeflag;
int spanflag;
int clearflag;
int laceptr;
ogg_uint32_t body_fill_next;
} ogg_stream_state;
typedef struct {
ogg_reference *packet;
long bytes;
long b_o_s;
long e_o_s;
ogg_int64_t granulepos;