Commit 8bc503a5 authored by Monty's avatar Monty
Browse files

Fixed a memory management error in the new codebook code
Removed final-stage infinite shift buffer; now a no-copy
 double buffer; removes another 70kB nominal from decode
 with slight speed improvement (~2%)

there's still an exact-position seek bug found by seeking_example to
track down.  The seek succeeds, but the position is off.

Monty

svn path=/trunk/vorbis/; revision=2975
parent 65edd8f4
......@@ -11,7 +11,7 @@
********************************************************************
function: simple example decoder
last mod: $Id: decoder_example.c,v 1.24 2001/12/19 23:13:32 segher Exp $
last mod: $Id: decoder_example.c,v 1.25 2002/01/22 08:06:05 xiphmont Exp $
********************************************************************/
......@@ -38,6 +38,8 @@
ogg_int16_t convbuffer[4096]; /* take 8k out of the data segment, not the stack */
int convsize=4096;
extern void _VDBG_dump(void);
int main(){
ogg_sync_state oy; /* sync and verify incoming physical bitstream */
ogg_stream_state os; /* take physical pages, weld into a logical
......
......@@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
function: single-block PCM analysis mode dispatch
last mod: $Id: analysis.c,v 1.47 2001/12/12 09:45:24 xiphmont Exp $
last mod: $Id: analysis.c,v 1.48 2002/01/22 08:06:06 xiphmont Exp $
********************************************************************/
......@@ -24,6 +24,7 @@
#include "registry.h"
#include "scales.h"
#include "os.h"
#include "misc.h"
int analysis_noisy=1;
......
......@@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
function: bitrate tracking and management
last mod: $Id: bitrate.c,v 1.10 2002/01/22 02:19:09 xiphmont Exp $
last mod: $Id: bitrate.c,v 1.11 2002/01/22 08:06:06 xiphmont Exp $
********************************************************************/
......@@ -23,6 +23,7 @@
#include "vorbis/codec.h"
#include "codec_internal.h"
#include "os.h"
#include "misc.h"
#include "bitrate.h"
......
......@@ -11,7 +11,7 @@
********************************************************************
function: PCM data vector blocking, windowing and dis/reassembly
last mod: $Id: block.c,v 1.56 2002/01/19 04:52:39 xiphmont Exp $
last mod: $Id: block.c,v 1.57 2002/01/22 08:06:06 xiphmont Exp $
Handle windowing, overlap-add, etc of the PCM vectors. This is made
more amusing by Vorbis' current two allowed block sizes.
......@@ -214,27 +214,28 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
if(encp){ /* encode/decode differ here */
/* finish the codebooks */
b->fullbooks=_ogg_calloc(ci->books,sizeof(*b->fullbooks));
for(i=0;i<ci->books;i++)
vorbis_book_init_encode(b->fullbooks+i,ci->book_param[i]);
if(!ci->fullbooks){
ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
for(i=0;i<ci->books;i++)
vorbis_book_init_encode(ci->fullbooks+i,ci->book_param[i]);
}
v->analysisp=1;
}else{
/* finish the codebooks */
b->fullbooks=_ogg_calloc(ci->books,sizeof(*b->fullbooks));
for(i=0;i<ci->books;i++){
vorbis_book_init_decode(b->fullbooks+i,ci->book_param[i]);
/* decode codebooks are now standalone after init */
vorbis_staticbook_destroy(ci->book_param[i]);
ci->book_param[i]=NULL;
if(!ci->fullbooks){
ci->fullbooks=_ogg_calloc(ci->books,sizeof(*ci->fullbooks));
for(i=0;i<ci->books;i++){
vorbis_book_init_decode(ci->fullbooks+i,ci->book_param[i]);
/* decode codebooks are now standalone after init */
vorbis_staticbook_destroy(ci->book_param[i]);
ci->book_param[i]=NULL;
}
}
}
/* initialize the storage vectors to a decent size greater than the
minimum */
v->pcm_storage=8192; /* we'll assume later that we have
a minimum of twice the blocksize of
accumulated samples in analysis */
/* initialize the storage vectors. blocksize[1] is small for encode,
but the correct size for decode */
v->pcm_storage=ci->blocksizes[1];
v->pcm=_ogg_malloc(vi->channels*sizeof(*v->pcm));
v->pcmret=_ogg_malloc(vi->channels*sizeof(*v->pcmret));
{
......@@ -336,14 +337,10 @@ void vorbis_dsp_clear(vorbis_dsp_state *v){
int maptype=ci->map_type[mapnum];
if(b && b->mode)_mapping_P[maptype]->free_look(b->mode[i]);
}
/* free codebooks */
for(i=0;i<ci->books;i++)
if(b && b->fullbooks)vorbis_book_clear(b->fullbooks+i);
}
if(b){
if(b->mode)_ogg_free(b->mode);
if(b->fullbooks)_ogg_free(b->fullbooks);
/* free header, header1, header2 */
if(b->header)_ogg_free(b->header);
......@@ -647,33 +644,9 @@ int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
vorbis_info *vi=v->vi;
codec_setup_info *ci=vi->codec_setup;
int i,j;
/* Shift out any PCM that we returned previously */
/* centerW is currently the center of the last block added */
if(v->centerW>ci->blocksizes[1]/2 &&
/* Quick additional hack; to avoid *alot* of shifts, use an
oversized buffer. This increases memory usage, but doesn't make
much difference wrt L1/L2 cache pressure. */
v->pcm_returned>8192){
/* don't shift too much; we need to have a minimum PCM buffer of
1/2 long block */
int shiftPCM=v->centerW-ci->blocksizes[1]/2;
shiftPCM=(v->pcm_returned<shiftPCM?v->pcm_returned:shiftPCM);
v->pcm_current-=shiftPCM;
v->centerW-=shiftPCM;
v->pcm_returned-=shiftPCM;
if(shiftPCM){
int i;
for(i=0;i<vi->channels;i++)
memmove(v->pcm[i],v->pcm[i]+shiftPCM,
v->pcm_current*sizeof(*v->pcm[i]));
}
}
if(v->pcm_current>v->pcm_returned && v->pcm_returned!=-1)return(OV_EINVAL);
v->lW=v->W;
v->W=vb->W;
......@@ -688,59 +661,90 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
lose count */
v->sequence=vb->sequence;
{
int sizeW=ci->blocksizes[v->W];
int centerW=v->centerW+ci->blocksizes[v->lW]/4+sizeW/4;
int beginW=centerW-sizeW/2;
int endW=beginW+sizeW;
int beginSl;
int endSl;
int i,j;
/* Do we have enough PCM/mult storage for the block? */
if(endW>v->pcm_storage){
/* expand the storage */
v->pcm_storage=endW+ci->blocksizes[1];
for(i=0;i<vi->channels;i++)
v->pcm[i]=_ogg_realloc(v->pcm[i],v->pcm_storage*sizeof(*v->pcm[i]));
int n=ci->blocksizes[v->W]/2;
int n0=ci->blocksizes[0]/2;
int n1=ci->blocksizes[1]/2;
int thisCenter;
int prevCenter;
if(v->centerW){
thisCenter=n1;
prevCenter=0;
}else{
thisCenter=0;
prevCenter=n1;
}
/* v->pcm is now used like a two-stage double buffer. We don't want
to have to constantly shift *or* adjust memory usage. Don't
accept a new block until the old is shifted out */
/* overlap/add PCM */
switch((int)v->W){
case 0:
beginSl=0;
endSl=ci->blocksizes[0]/2;
break;
case 1:
beginSl=ci->blocksizes[1]/4-ci->blocksizes[v->lW]/4;
endSl=beginSl+ci->blocksizes[v->lW]/2;
break;
default:
return(-1);
}
for(j=0;j<vi->channels;j++){
float *pcm=v->pcm[j]+beginW;
float *p=vb->pcm[j];
/* the overlap/add section */
for(i=beginSl;i<endSl;i++)
pcm[i]+=p[i];
/* the remaining section */
for(;i<sizeW;i++)
pcm[i]=p[i];
if(v->lW){
if(v->W){
/* large/large */
float *pcm=v->pcm[j]+prevCenter;
float *p=vb->pcm[j];
for(i=0;i<n1;i++)
pcm[i]+=p[i];
}else{
/* large/small */
float *pcm=v->pcm[j]+prevCenter+n1/2-n0/2;
float *p=vb->pcm[j];
for(i=0;i<n0;i++)
pcm[i]+=p[i];
}
}else{
if(v->W){
/* small/large */
float *pcm=v->pcm[j]+prevCenter;
float *p=vb->pcm[j]+n1/2-n0/2;
for(i=0;i<n0;i++)
pcm[i]+=p[i];
for(;i<n1/2+n0/2;i++)
pcm[i]=p[i];
}else{
/* small/small */
float *pcm=v->pcm[j]+prevCenter;
float *p=vb->pcm[j];
for(i=0;i<n0;i++)
pcm[i]+=p[i];
}
}
/* the copy section */
{
float *pcm=v->pcm[j]+thisCenter;
float *p=vb->pcm[j]+n;
for(i=0;i<n;i++)
pcm[i]=p[i];
}
}
if(v->centerW)
v->centerW=0;
else
v->centerW=n1;
/* deal with initial packet state; we do this using the explicit
pcm_returned==-1 flag otherwise we're sensitive to first block
being short or long */
if(v->pcm_returned==-1)
v->pcm_returned=centerW;
if(v->pcm_returned==-1){
v->pcm_returned=thisCenter;
v->pcm_current=thisCenter;
}else{
v->pcm_returned=prevCenter;
v->pcm_current=prevCenter+
ci->blocksizes[v->lW]/4+
ci->blocksizes[v->W]/4;
}
/* track the frame number... This is for convenience, but also
making sure our last packet doesn't end with added padding. If
......@@ -760,7 +764,7 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
v->granulepos=vb->granulepos;
}
else{
v->granulepos+=(centerW-v->centerW);
v->granulepos+=ci->blocksizes[v->lW]/4+ci->blocksizes[v->W]/4;
if(vb->granulepos!=-1 && v->granulepos!=vb->granulepos){
if(v->granulepos>vb->granulepos){
......@@ -768,14 +772,15 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
if(vb->eofflag){
/* partial last frame. Strip the extra samples off */
centerW-=extra;
v->pcm_current-=extra;
}else if(vb->sequence == 1){
/* ^^^ argh, this can be 1 from seeking! */
/* partial first frame. Discard extra leading samples */
v->pcm_returned+=extra;
if(v->pcm_returned>centerW)v->pcm_returned=centerW;
if(v->pcm_returned>v->pcm_current)
v->pcm_returned=v->pcm_current;
}
......@@ -784,35 +789,32 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
v->granulepos=vb->granulepos;
}
}
/* Update, cleanup */
v->centerW=centerW;
v->pcm_current=endW;
if(vb->eofflag)v->eofflag=1;
}
return(0);
}
/* pcm==NULL indicates we just want the pending samples, no more */
int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm){
vorbis_info *vi=v->vi;
if(v->pcm_returned>-1 && v->pcm_returned<v->centerW){
if(v->pcm_returned>-1 && v->pcm_returned<v->pcm_current){
if(pcm){
int i;
for(i=0;i<vi->channels;i++)
v->pcmret[i]=v->pcm[i]+v->pcm_returned;
*pcm=v->pcmret;
}
return(v->centerW-v->pcm_returned);
return(v->pcm_current-v->pcm_returned);
}
return(0);
}
int vorbis_synthesis_read(vorbis_dsp_state *v,int bytes){
if(bytes && v->pcm_returned+bytes>v->centerW)return(OV_EINVAL);
if(bytes && v->pcm_returned+bytes>v->pcm_current)return(OV_EINVAL);
v->pcm_returned+=bytes;
return(0);
}
......
......@@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
function: libvorbis codec headers
last mod: $Id: codec_internal.h,v 1.12 2001/12/20 01:00:26 segher Exp $
last mod: $Id: codec_internal.h,v 1.13 2002/01/22 08:06:06 xiphmont Exp $
********************************************************************/
......@@ -61,7 +61,6 @@ typedef struct backend_lookup_state {
envelope_lookup *ve; /* envelope lookup */
float **window[2][2][2]; /* block, leadin, leadout, type */
vorbis_look_transform **transform[2]; /* block, type */
codebook *fullbooks;
vorbis_look_psy_global *psy_g_look;
/* backend lookups are tied to the mode, not the backend or naked mapping */
......@@ -157,6 +156,7 @@ typedef struct codec_setup_info {
int residue_type[64];
vorbis_info_residue *residue_param[64];
static_codebook *book_param[256];
codebook *fullbooks;
vorbis_info_psy *psy_param[64]; /* encode only */
vorbis_info_psy_global psy_g_param;
......
......@@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
function: floor backend 0 implementation
last mod: $Id: floor0.c,v 1.49 2001/12/21 14:52:35 segher Exp $
last mod: $Id: floor0.c,v 1.50 2002/01/22 08:06:06 xiphmont Exp $
********************************************************************/
......@@ -327,7 +327,7 @@ static int floor0_forward(vorbis_block *vb,vorbis_look_floor *in,
/* the spec supports using one of a number of codebooks. Right
now, encode using this lib supports only one */
backend_lookup_state *be=vb->vd->backend_state;
codec_setup_info *ci=vb->vd->vi->codec_setup;
codebook *b;
int booknum;
......@@ -348,7 +348,7 @@ static int floor0_forward(vorbis_block *vb,vorbis_look_floor *in,
}else
booknum=0;
b=be->fullbooks+info->books[booknum];
b=ci->fullbooks+info->books[booknum];
oggpack_write(&vb->opb,booknum,_ilog(info->numbooks));
look->bits+=_ilog(info->numbooks);
......@@ -421,8 +421,8 @@ static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
backend_lookup_state *be=vb->vd->backend_state;
codebook *b=be->fullbooks+info->books[booknum];
codec_setup_info *ci=vb->vd->vi->codec_setup;
codebook *b=ci->fullbooks+info->books[booknum];
float last=0.f;
float *lsp=_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+1));
......
......@@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
function: floor backend 1 implementation
last mod: $Id: floor1.c,v 1.19 2001/12/19 23:13:33 segher Exp $
last mod: $Id: floor1.c,v 1.20 2002/01/22 08:06:06 xiphmont Exp $
********************************************************************/
......@@ -647,8 +647,7 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
int writeflag=0;
if(vb->vd->backend_state){
books=((backend_lookup_state *)(vb->vd->backend_state))->
fullbooks;
books=ci->fullbooks;
writeflag=1;
}
......@@ -1025,10 +1024,10 @@ static int floor1_forward(vorbis_block *vb,vorbis_look_floor *in,
static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
vorbis_info_floor1 *info=look->vi;
codec_setup_info *ci=vb->vd->vi->codec_setup;
int i,j,k;
codebook *books=((backend_lookup_state *)(vb->vd->backend_state))->
fullbooks;
codebook *books=ci->fullbooks;
/* unpack wrapped/predicted values from stream */
if(oggpack_read(&vb->opb,1)==1){
......
......@@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
function: Direct Form II IIR filters, plus some specializations
last mod: $Id: iir.c,v 1.12 2001/12/20 01:00:26 segher Exp $
last mod: $Id: iir.c,v 1.13 2002/01/22 08:06:07 xiphmont Exp $
********************************************************************/
......@@ -23,6 +23,7 @@
#include <string.h>
#include <math.h>
#include "iir.h"
#include "misc.h"
void IIR_init(IIR_state *s,int stages,float gain, float *A, float *B){
memset(s,0,sizeof(*s));
......
......@@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
function: maintain the info structure, info <-> header packets
last mod: $Id: info.c,v 1.52 2002/01/01 00:00:32 xiphmont Exp $
last mod: $Id: info.c,v 1.53 2002/01/22 08:06:07 xiphmont Exp $
********************************************************************/
......@@ -177,7 +177,11 @@ void vorbis_info_clear(vorbis_info *vi){
/* knows if the book was not alloced */
vorbis_staticbook_destroy(ci->book_param[i]);
}
if(ci->fullbooks)
vorbis_book_clear(ci->fullbooks+i);
}
if(ci->fullbooks)
_ogg_free(ci->fullbooks);
for(i=0;i<ci->psys;i++)
_vi_psy_free(ci->psy_param[i]);
......
......@@ -5,13 +5,13 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
function: lookup based functions
last mod: $Id: lookup.c,v 1.8 2001/12/20 01:00:27 segher Exp $
last mod: $Id: lookup.c,v 1.9 2002/01/22 08:06:07 xiphmont Exp $
********************************************************************/
......@@ -19,6 +19,7 @@
#include "lookup.h"
#include "lookup_data.h"
#include "os.h"
#include "misc.h"
#ifdef FLOAT_LOOKUP
......
......@@ -5,14 +5,14 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************
function: normalized modified discrete cosine transform
power of two length transform only [64 <= n ]
last mod: $Id: mdct.c,v 1.28 2001/12/21 14:52:35 segher Exp $
last mod: $Id: mdct.c,v 1.29 2002/01/22 08:06:07 xiphmont Exp $
Original algorithm adapted long ago from _The use of multirate filter
banks for coding of high quality digital audio_, by T. Sporer,
......@@ -44,6 +44,7 @@
#include "vorbis/codec.h"
#include "mdct.h"
#include "os.h"
#include "misc.h"
/* build lookups for trig functions; also pre-figure scaling and
some window function algebra. */
......
......@@ -5,7 +5,7 @@
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 *
* by the XIPHOPHORUS Company http://www.xiph.org/ *
* *
********************************************************************/
......@@ -13,29 +13,41 @@
#define HEAD_ALIGN 32
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "vorbis/codec.h"
#define MISC_C
#include "misc.h"
#include <sys/time.h>
static pthread_mutex_t memlock=PTHREAD_MUTEX_INITIALIZER;
void **pointers=NULL;
long *insertlist=NULL; /* We can't embed this in the pointer list;
static void **pointers=NULL;
static long *insertlist=NULL; /* We can't embed this in the pointer list;
a pointer can have any value... */
int ptop=0;
int palloced=0;
int pinsert=0;
static char **files=NULL;
static long *file_bytes=NULL;
static int filecount=0;
static int ptop=0;
static int palloced=0;
static int pinsert=0;
typedef struct {
char *file;
long line;