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

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;
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_packet;
typedef struct {
ogg_reference *header;
int header_len;
ogg_reference *body;
long body_len;
} ogg_page;
/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/
extern void oggpack_readinit(oggpack_buffer *b,ogg_reference *r);
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);
/* Ogg BITSTREAM PRIMITIVES: decoding **************************/
extern ogg_sync_state *ogg_sync_create(void);
extern int ogg_sync_destroy(ogg_sync_state *oy);
extern int ogg_sync_reset(ogg_sync_state *oy);
extern unsigned char *ogg_sync_bufferin(ogg_sync_state *oy, long size);