mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
Update libvorbis from 1.3.4 to 1.3.5
This commit is contained in:
parent
d87bd792c3
commit
bba263d634
15 changed files with 342 additions and 263 deletions
|
@ -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-2009 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: PCM data vector blocking, windowing and dis/reassembly
|
||||
last mod: $Id: block.c 19031 2013-12-03 19:20:50Z tterribe $
|
||||
last mod: $Id: block.c 19457 2015-03-03 00:15:29Z giles $
|
||||
|
||||
Handle windowing, overlap-add, etc of the PCM vectors. This is made
|
||||
more amusing by Vorbis' current two allowed block sizes.
|
||||
|
@ -31,16 +31,6 @@
|
|||
#include "registry.h"
|
||||
#include "misc.h"
|
||||
|
||||
static int ilog2(unsigned int v){
|
||||
int ret=0;
|
||||
if(v)--v;
|
||||
while(v){
|
||||
ret++;
|
||||
v>>=1;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/* pcm accumulator examples (not exhaustive):
|
||||
|
||||
<-------------- lW ---------------->
|
||||
|
@ -184,14 +174,19 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
|
|||
private_state *b=NULL;
|
||||
int hs;
|
||||
|
||||
if(ci==NULL) return 1;
|
||||
if(ci==NULL||
|
||||
ci->modes<=0||
|
||||
ci->blocksizes[0]<64||
|
||||
ci->blocksizes[1]<ci->blocksizes[0]){
|
||||
return 1;
|
||||
}
|
||||
hs=ci->halfrate_flag;
|
||||
|
||||
memset(v,0,sizeof(*v));
|
||||
b=v->backend_state=_ogg_calloc(1,sizeof(*b));
|
||||
|
||||
v->vi=vi;
|
||||
b->modebits=ilog2(ci->modes);
|
||||
b->modebits=ov_ilog(ci->modes-1);
|
||||
|
||||
b->transform[0]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[0]));
|
||||
b->transform[1]=_ogg_calloc(VI_TRANSFORMB,sizeof(*b->transform[1]));
|
||||
|
@ -204,8 +199,14 @@ static int _vds_shared_init(vorbis_dsp_state *v,vorbis_info *vi,int encp){
|
|||
mdct_init(b->transform[1][0],ci->blocksizes[1]>>hs);
|
||||
|
||||
/* Vorbis I uses only window type 0 */
|
||||
b->window[0]=ilog2(ci->blocksizes[0])-6;
|
||||
b->window[1]=ilog2(ci->blocksizes[1])-6;
|
||||
/* note that the correct computation below is technically:
|
||||
b->window[0]=ov_ilog(ci->blocksizes[0]-1)-6;
|
||||
b->window[1]=ov_ilog(ci->blocksizes[1]-1)-6;
|
||||
but since blocksizes are always powers of two,
|
||||
the below is equivalent.
|
||||
*/
|
||||
b->window[0]=ov_ilog(ci->blocksizes[0])-7;
|
||||
b->window[1]=ov_ilog(ci->blocksizes[1])-7;
|
||||
|
||||
if(encp){ /* encode/decode differ here */
|
||||
|
||||
|
|
|
@ -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-2009 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: basic codebook pack/unpack/code/decode operations
|
||||
last mod: $Id: codebook.c 19057 2014-01-22 12:32:31Z xiphmont $
|
||||
last mod: $Id: codebook.c 19457 2015-03-03 00:15:29Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -57,12 +57,12 @@ int vorbis_staticbook_pack(const static_codebook *c,oggpack_buffer *opb){
|
|||
char last=c->lengthlist[i-1];
|
||||
if(this>last){
|
||||
for(j=last;j<this;j++){
|
||||
oggpack_write(opb,i-count,_ilog(c->entries-count));
|
||||
oggpack_write(opb,i-count,ov_ilog(c->entries-count));
|
||||
count=i;
|
||||
}
|
||||
}
|
||||
}
|
||||
oggpack_write(opb,i-count,_ilog(c->entries-count));
|
||||
oggpack_write(opb,i-count,ov_ilog(c->entries-count));
|
||||
|
||||
}else{
|
||||
/* length random. Again, we don't code the codeword itself, just
|
||||
|
@ -159,7 +159,7 @@ static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
|
|||
s->entries=oggpack_read(opb,24);
|
||||
if(s->entries==-1)goto _eofout;
|
||||
|
||||
if(_ilog(s->dim)+_ilog(s->entries)>24)goto _eofout;
|
||||
if(ov_ilog(s->dim)+ov_ilog(s->entries)>24)goto _eofout;
|
||||
|
||||
/* codeword ordering.... length ordered or unordered? */
|
||||
switch((int)oggpack_read(opb,1)){
|
||||
|
@ -203,7 +203,7 @@ static_codebook *vorbis_staticbook_unpack(oggpack_buffer *opb){
|
|||
s->lengthlist=_ogg_malloc(sizeof(*s->lengthlist)*s->entries);
|
||||
|
||||
for(i=0;i<s->entries;){
|
||||
long num=oggpack_read(opb,_ilog(s->entries-i));
|
||||
long num=oggpack_read(opb,ov_ilog(s->entries-i));
|
||||
if(num==-1)goto _eofout;
|
||||
if(length>32 || num>s->entries-i ||
|
||||
(num>0 && (num-1)>>(length-1)>1)){
|
||||
|
@ -312,6 +312,12 @@ STIN long decode_packed_entry_number(codebook *book, oggpack_buffer *b){
|
|||
hi=book->used_entries;
|
||||
}
|
||||
|
||||
/* Single entry codebooks use a firsttablen of 1 and a
|
||||
dec_maxlength of 1. If a single-entry codebook gets here (due to
|
||||
failure to read one bit above), the next look attempt will also
|
||||
fail and we'll correctly kick out instead of trying to walk the
|
||||
underformed tree */
|
||||
|
||||
lok = oggpack_look(b, read);
|
||||
|
||||
while(lok<0 && read>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-2014 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: basic shared codebook operations
|
||||
last mod: $Id: codebook.h 19057 2014-01-22 12:32:31Z xiphmont $
|
||||
last mod: $Id: codebook.h 19457 2015-03-03 00:15:29Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -89,7 +89,6 @@ extern float *_book_logdist(const static_codebook *b,float *vals);
|
|||
extern float _float32_unpack(long val);
|
||||
extern long _float32_pack(float val);
|
||||
extern int _best(codebook *book, float *a, int step);
|
||||
extern int _ilog(unsigned int v);
|
||||
extern long _book_maptype1_quantvals(const static_codebook *b);
|
||||
|
||||
extern int vorbis_book_besterror(codebook *book,float *a,int step,int addmul);
|
||||
|
|
|
@ -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-2009 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: floor backend 0 implementation
|
||||
last mod: $Id: floor0.c 19031 2013-12-03 19:20:50Z tterribe $
|
||||
last mod: $Id: floor0.c 19457 2015-03-03 00:15:29Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -168,7 +168,7 @@ static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
|
|||
if(ampraw>0){ /* also handles the -1 out of data case */
|
||||
long maxval=(1<<info->ampbits)-1;
|
||||
float amp=(float)ampraw/maxval*info->ampdB;
|
||||
int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
|
||||
int booknum=oggpack_read(&vb->opb,ov_ilog(info->numbooks));
|
||||
|
||||
if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
|
||||
codec_setup_info *ci=vb->vd->vi->codec_setup;
|
||||
|
|
|
@ -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-2009 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: floor backend 1 implementation
|
||||
last mod: $Id: floor1.c 19031 2013-12-03 19:20:50Z tterribe $
|
||||
last mod: $Id: floor1.c 19457 2015-03-03 00:15:29Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -72,25 +72,6 @@ static void floor1_free_look(vorbis_look_floor *i){
|
|||
}
|
||||
}
|
||||
|
||||
static int ilog(unsigned int v){
|
||||
int ret=0;
|
||||
while(v){
|
||||
ret++;
|
||||
v>>=1;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static int ilog2(unsigned int v){
|
||||
int ret=0;
|
||||
if(v)--v;
|
||||
while(v){
|
||||
ret++;
|
||||
v>>=1;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
|
||||
vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
|
||||
int j,k;
|
||||
|
@ -117,8 +98,10 @@ static void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
|
|||
|
||||
/* save out the post list */
|
||||
oggpack_write(opb,info->mult-1,2); /* only 1,2,3,4 legal now */
|
||||
oggpack_write(opb,ilog2(maxposit),4);
|
||||
rangebits=ilog2(maxposit);
|
||||
/* maxposit cannot legally be less than 1; this is encode-side, we
|
||||
can assume our setup is OK */
|
||||
oggpack_write(opb,ov_ilog(maxposit-1),4);
|
||||
rangebits=ov_ilog(maxposit-1);
|
||||
|
||||
for(j=0,k=0;j<info->partitions;j++){
|
||||
count+=info->class_dim[info->partitionclass[j]];
|
||||
|
@ -854,9 +837,9 @@ int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
|
|||
|
||||
/* beginning/end post */
|
||||
look->frames++;
|
||||
look->postbits+=ilog(look->quant_q-1)*2;
|
||||
oggpack_write(opb,out[0],ilog(look->quant_q-1));
|
||||
oggpack_write(opb,out[1],ilog(look->quant_q-1));
|
||||
look->postbits+=ov_ilog(look->quant_q-1)*2;
|
||||
oggpack_write(opb,out[0],ov_ilog(look->quant_q-1));
|
||||
oggpack_write(opb,out[1],ov_ilog(look->quant_q-1));
|
||||
|
||||
|
||||
/* partition by partition */
|
||||
|
@ -872,7 +855,9 @@ int floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
|
|||
|
||||
/* generate the partition's first stage cascade value */
|
||||
if(csubbits){
|
||||
int maxval[8] = {0};
|
||||
int maxval[8]={0,0,0,0,0,0,0,0}; /* gcc's static analysis
|
||||
issues a warning without
|
||||
initialization */
|
||||
for(k=0;k<csub;k++){
|
||||
int booknum=info->class_subbook[class][k];
|
||||
if(booknum<0){
|
||||
|
@ -980,8 +965,8 @@ static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
|
|||
if(oggpack_read(&vb->opb,1)==1){
|
||||
int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
|
||||
|
||||
fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
|
||||
fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
|
||||
fit_value[0]=oggpack_read(&vb->opb,ov_ilog(look->quant_q-1));
|
||||
fit_value[1]=oggpack_read(&vb->opb,ov_ilog(look->quant_q-1));
|
||||
|
||||
/* partition by partition */
|
||||
for(i=0,j=2;i<info->partitions;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-2010 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: maintain the info structure, info <-> header packets
|
||||
last mod: $Id: info.c 19058 2014-01-22 18:03:15Z xiphmont $
|
||||
last mod: $Id: info.c 19441 2015-01-21 01:17:41Z xiphmont $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -31,20 +31,10 @@
|
|||
#include "misc.h"
|
||||
#include "os.h"
|
||||
|
||||
#define GENERAL_VENDOR_STRING "Xiph.Org libVorbis 1.3.4"
|
||||
#define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20140122 (Turpakäräjiin)"
|
||||
#define GENERAL_VENDOR_STRING "Xiph.Org libVorbis 1.3.5"
|
||||
#define ENCODE_VENDOR_STRING "Xiph.Org libVorbis I 20150105 (⛄⛄⛄⛄)"
|
||||
|
||||
/* helpers */
|
||||
static int ilog2(unsigned int v){
|
||||
int ret=0;
|
||||
if(v)--v;
|
||||
while(v){
|
||||
ret++;
|
||||
v>>=1;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static void _v_writestring(oggpack_buffer *o,const char *s, int bytes){
|
||||
|
||||
while(bytes--){
|
||||
|
@ -272,7 +262,6 @@ static int _vorbis_unpack_comment(vorbis_comment *vc,oggpack_buffer *opb){
|
|||
static int _vorbis_unpack_books(vorbis_info *vi,oggpack_buffer *opb){
|
||||
codec_setup_info *ci=vi->codec_setup;
|
||||
int i;
|
||||
if(!ci)return(OV_EFAULT);
|
||||
|
||||
/* codebooks */
|
||||
ci->books=oggpack_read(opb,8)+1;
|
||||
|
@ -411,6 +400,10 @@ int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op)
|
|||
/* um... we didn't get the initial header */
|
||||
return(OV_EBADHEADER);
|
||||
}
|
||||
if(vc->vendor!=NULL){
|
||||
/* previously initialized comment header */
|
||||
return(OV_EBADHEADER);
|
||||
}
|
||||
|
||||
return(_vorbis_unpack_comment(vc,&opb));
|
||||
|
||||
|
@ -419,6 +412,14 @@ int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op)
|
|||
/* um... we didn;t get the initial header or comments yet */
|
||||
return(OV_EBADHEADER);
|
||||
}
|
||||
if(vi->codec_setup==NULL){
|
||||
/* improperly initialized vorbis_info */
|
||||
return(OV_EFAULT);
|
||||
}
|
||||
if(((codec_setup_info *)vi->codec_setup)->books>0){
|
||||
/* previously initialized setup header */
|
||||
return(OV_EBADHEADER);
|
||||
}
|
||||
|
||||
return(_vorbis_unpack_books(vi,&opb));
|
||||
|
||||
|
@ -436,7 +437,11 @@ int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc,ogg_packet *op)
|
|||
|
||||
static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
|
||||
codec_setup_info *ci=vi->codec_setup;
|
||||
if(!ci)return(OV_EFAULT);
|
||||
if(!ci||
|
||||
ci->blocksizes[0]<64||
|
||||
ci->blocksizes[1]<ci->blocksizes[0]){
|
||||
return(OV_EFAULT);
|
||||
}
|
||||
|
||||
/* preamble */
|
||||
oggpack_write(opb,0x01,8);
|
||||
|
@ -451,8 +456,8 @@ static int _vorbis_pack_info(oggpack_buffer *opb,vorbis_info *vi){
|
|||
oggpack_write(opb,vi->bitrate_nominal,32);
|
||||
oggpack_write(opb,vi->bitrate_lower,32);
|
||||
|
||||
oggpack_write(opb,ilog2(ci->blocksizes[0]),4);
|
||||
oggpack_write(opb,ilog2(ci->blocksizes[1]),4);
|
||||
oggpack_write(opb,ov_ilog(ci->blocksizes[0]-1),4);
|
||||
oggpack_write(opb,ov_ilog(ci->blocksizes[1]-1),4);
|
||||
oggpack_write(opb,1,1);
|
||||
|
||||
return(0);
|
||||
|
@ -578,7 +583,7 @@ int vorbis_analysis_headerout(vorbis_dsp_state *v,
|
|||
oggpack_buffer opb;
|
||||
private_state *b=v->backend_state;
|
||||
|
||||
if(!b){
|
||||
if(!b||vi->channels<=0){
|
||||
ret=OV_EFAULT;
|
||||
goto err_out;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
********************************************************************
|
||||
|
||||
function: LSP (also called LSF) conversion routines
|
||||
last mod: $Id: lsp.c 17538 2010-10-15 02:52:29Z tterribe $
|
||||
last mod: $Id: lsp.c 19453 2015-03-02 22:35:34Z xiphmont $
|
||||
|
||||
The LSP generation code is taken (with minimal modification and a
|
||||
few bugfixes) from "On the Computation of the LSP Frequencies" by
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
********************************************************************
|
||||
|
||||
function: channel mapping 0 implementation
|
||||
last mod: $Id: mapping0.c 17022 2010-03-25 03:45:42Z xiphmont $
|
||||
last mod: $Id: mapping0.c 19441 2015-01-21 01:17:41Z xiphmont $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -45,16 +45,6 @@ static void mapping0_free_info(vorbis_info_mapping *i){
|
|||
}
|
||||
}
|
||||
|
||||
static int ilog(unsigned int v){
|
||||
int ret=0;
|
||||
if(v)--v;
|
||||
while(v){
|
||||
ret++;
|
||||
v>>=1;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,
|
||||
oggpack_buffer *opb){
|
||||
int i;
|
||||
|
@ -78,8 +68,8 @@ static void mapping0_pack(vorbis_info *vi,vorbis_info_mapping *vm,
|
|||
oggpack_write(opb,info->coupling_steps-1,8);
|
||||
|
||||
for(i=0;i<info->coupling_steps;i++){
|
||||
oggpack_write(opb,info->coupling_mag[i],ilog(vi->channels));
|
||||
oggpack_write(opb,info->coupling_ang[i],ilog(vi->channels));
|
||||
oggpack_write(opb,info->coupling_mag[i],ov_ilog(vi->channels-1));
|
||||
oggpack_write(opb,info->coupling_ang[i],ov_ilog(vi->channels-1));
|
||||
}
|
||||
}else
|
||||
oggpack_write(opb,0,1);
|
||||
|
@ -104,6 +94,7 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb)
|
|||
vorbis_info_mapping0 *info=_ogg_calloc(1,sizeof(*info));
|
||||
codec_setup_info *ci=vi->codec_setup;
|
||||
memset(info,0,sizeof(*info));
|
||||
if(vi->channels<=0)goto err_out;
|
||||
|
||||
b=oggpack_read(opb,1);
|
||||
if(b<0)goto err_out;
|
||||
|
@ -119,8 +110,11 @@ static vorbis_info_mapping *mapping0_unpack(vorbis_info *vi,oggpack_buffer *opb)
|
|||
info->coupling_steps=oggpack_read(opb,8)+1;
|
||||
if(info->coupling_steps<=0)goto err_out;
|
||||
for(i=0;i<info->coupling_steps;i++){
|
||||
int testM=info->coupling_mag[i]=oggpack_read(opb,ilog(vi->channels));
|
||||
int testA=info->coupling_ang[i]=oggpack_read(opb,ilog(vi->channels));
|
||||
/* vi->channels > 0 is enforced in the caller */
|
||||
int testM=info->coupling_mag[i]=
|
||||
oggpack_read(opb,ov_ilog(vi->channels-1));
|
||||
int testA=info->coupling_ang[i]=
|
||||
oggpack_read(opb,ov_ilog(vi->channels-1));
|
||||
|
||||
if(testM<0 ||
|
||||
testA<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-2009 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: miscellaneous prototypes
|
||||
last mod: $Id: misc.h 16227 2009-07-08 06:58:46Z xiphmont $
|
||||
last mod: $Id: misc.h 19457 2015-03-03 00:15:29Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
|||
|
||||
extern void *_vorbis_block_alloc(vorbis_block *vb,long bytes);
|
||||
extern void _vorbis_block_ripcord(vorbis_block *vb);
|
||||
extern int ov_ilog(ogg_uint32_t v);
|
||||
|
||||
#ifdef ANALYSIS
|
||||
extern int analysis_noisy;
|
||||
|
|
|
@ -7,13 +7,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-2009 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: #ifdef jail to whip a few platforms into the UNIX ideal.
|
||||
last mod: $Id: os.h 19031 2013-12-03 19:20:50Z tterribe $
|
||||
last mod: $Id: os.h 19457 2015-03-03 00:15:29Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -119,8 +119,9 @@ static inline int vorbis_ftoi(double f){ /* yes, double! Otherwise,
|
|||
|
||||
|
||||
/* MSVC inline assembly. 32 bit only; inline ASM isn't implemented in the
|
||||
* 64 bit compiler */
|
||||
#if defined(_MSC_VER) && !defined(_WIN64) && !defined(_WIN32_WCE)
|
||||
* 64 bit compiler and doesn't work on arm. */
|
||||
#if defined(_MSC_VER) && !defined(_WIN64) && \
|
||||
!defined(_WIN32_WCE) && !defined(_M_ARM)
|
||||
# define VORBIS_FPU_CONTROL
|
||||
|
||||
typedef ogg_int16_t vorbis_fpu_control;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
********************************************************************
|
||||
|
||||
function: residue backend 0, 1 and 2 implementation
|
||||
last mod: $Id: res0.c 19031 2013-12-03 19:20:50Z tterribe $
|
||||
last mod: $Id: res0.c 19441 2015-01-21 01:17:41Z xiphmont $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -152,15 +152,6 @@ void res0_free_look(vorbis_look_residue *i){
|
|||
}
|
||||
}
|
||||
|
||||
static int ilog(unsigned int v){
|
||||
int ret=0;
|
||||
while(v){
|
||||
ret++;
|
||||
v>>=1;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
|
||||
static int icount(unsigned int v){
|
||||
int ret=0;
|
||||
while(v){
|
||||
|
@ -186,7 +177,7 @@ void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){
|
|||
bitmask of one indicates this partition class has bits to write
|
||||
this pass */
|
||||
for(j=0;j<info->partitions;j++){
|
||||
if(ilog(info->secondstages[j])>3){
|
||||
if(ov_ilog(info->secondstages[j])>3){
|
||||
/* yes, this is a minor hack due to not thinking ahead */
|
||||
oggpack_write(opb,info->secondstages[j],3);
|
||||
oggpack_write(opb,1,1);
|
||||
|
@ -284,7 +275,7 @@ vorbis_look_residue *res0_look(vorbis_dsp_state *vd,
|
|||
look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks));
|
||||
|
||||
for(j=0;j<look->parts;j++){
|
||||
int stages=ilog(info->secondstages[j]);
|
||||
int stages=ov_ilog(info->secondstages[j]);
|
||||
if(stages){
|
||||
if(stages>maxstage)maxstage=stages;
|
||||
look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j]));
|
||||
|
|
|
@ -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-2009 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: basic shared codebook operations
|
||||
last mod: $Id: sharedbook.c 19057 2014-01-22 12:32:31Z xiphmont $
|
||||
last mod: $Id: sharedbook.c 19457 2015-03-03 00:15:29Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -26,13 +26,11 @@
|
|||
#include "scales.h"
|
||||
|
||||
/**** pack/unpack helpers ******************************************/
|
||||
int _ilog(unsigned int v){
|
||||
int ret=0;
|
||||
while(v){
|
||||
ret++;
|
||||
v>>=1;
|
||||
}
|
||||
return(ret);
|
||||
|
||||
int ov_ilog(ogg_uint32_t v){
|
||||
int ret;
|
||||
for(ret=0;v;ret++)v>>=1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 32 bit float (not IEEE; nonnormalized mantissa +
|
||||
|
@ -125,16 +123,15 @@ ogg_uint32_t *_make_words(char *l,long n,long sparsecount){
|
|||
if(sparsecount==0)count++;
|
||||
}
|
||||
|
||||
/* sanity check the huffman tree; an underpopulated tree must be
|
||||
rejected. The only exception is the one-node pseudo-nil tree,
|
||||
which appears to be underpopulated because the tree doesn't
|
||||
really exist; there's only one possible 'codeword' or zero bits,
|
||||
but the above tree-gen code doesn't mark that. */
|
||||
if(sparsecount != 1){
|
||||
/* any underpopulated tree must be rejected. */
|
||||
/* Single-entry codebooks are a retconned extension to the spec.
|
||||
They have a single codeword '0' of length 1 that results in an
|
||||
underpopulated tree. Shield that case from the underformed tree check. */
|
||||
if(!(count==1 && marker[2]==2)){
|
||||
for(i=1;i<33;i++)
|
||||
if(marker[i] & (0xffffffffUL>>(32-i))){
|
||||
_ogg_free(r);
|
||||
return(NULL);
|
||||
_ogg_free(r);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,9 +310,10 @@ static int sort32a(const void *a,const void *b){
|
|||
int vorbis_book_init_decode(codebook *c,const static_codebook *s){
|
||||
int i,j,n=0,tabn;
|
||||
int *sortindex;
|
||||
|
||||
memset(c,0,sizeof(*c));
|
||||
|
||||
/* count actually used entries */
|
||||
/* count actually used entries and find max length */
|
||||
for(i=0;i<s->entries;i++)
|
||||
if(s->lengthlist[i]>0)
|
||||
n++;
|
||||
|
@ -325,7 +323,6 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
|
|||
c->dim=s->dim;
|
||||
|
||||
if(n>0){
|
||||
|
||||
/* two different remappings go on here.
|
||||
|
||||
First, we collapse the likely sparse codebook down only to
|
||||
|
@ -361,7 +358,6 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
|
|||
c->codelist[sortindex[i]]=codes[i];
|
||||
_ogg_free(codes);
|
||||
|
||||
|
||||
c->valuelist=_book_unquantize(s,n,sortindex);
|
||||
c->dec_index=_ogg_malloc(n*sizeof(*c->dec_index));
|
||||
|
||||
|
@ -370,51 +366,62 @@ int vorbis_book_init_decode(codebook *c,const static_codebook *s){
|
|||
c->dec_index[sortindex[n++]]=i;
|
||||
|
||||
c->dec_codelengths=_ogg_malloc(n*sizeof(*c->dec_codelengths));
|
||||
for(n=0,i=0;i<s->entries;i++)
|
||||
if(s->lengthlist[i]>0)
|
||||
c->dec_codelengths[sortindex[n++]]=s->lengthlist[i];
|
||||
|
||||
c->dec_firsttablen=_ilog(c->used_entries)-4; /* this is magic */
|
||||
if(c->dec_firsttablen<5)c->dec_firsttablen=5;
|
||||
if(c->dec_firsttablen>8)c->dec_firsttablen=8;
|
||||
|
||||
tabn=1<<c->dec_firsttablen;
|
||||
c->dec_firsttable=_ogg_calloc(tabn,sizeof(*c->dec_firsttable));
|
||||
c->dec_maxlength=0;
|
||||
|
||||
for(i=0;i<n;i++){
|
||||
if(c->dec_maxlength<c->dec_codelengths[i])
|
||||
c->dec_maxlength=c->dec_codelengths[i];
|
||||
if(c->dec_codelengths[i]<=c->dec_firsttablen){
|
||||
ogg_uint32_t orig=bitreverse(c->codelist[i]);
|
||||
for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++)
|
||||
c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1;
|
||||
for(n=0,i=0;i<s->entries;i++)
|
||||
if(s->lengthlist[i]>0){
|
||||
c->dec_codelengths[sortindex[n++]]=s->lengthlist[i];
|
||||
if(s->lengthlist[i]>c->dec_maxlength)
|
||||
c->dec_maxlength=s->lengthlist[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* now fill in 'unused' entries in the firsttable with hi/lo search
|
||||
hints for the non-direct-hits */
|
||||
{
|
||||
ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen);
|
||||
long lo=0,hi=0;
|
||||
if(n==1 && c->dec_maxlength==1){
|
||||
/* special case the 'single entry codebook' with a single bit
|
||||
fastpath table (that always returns entry 0 )in order to use
|
||||
unmodified decode paths. */
|
||||
c->dec_firsttablen=1;
|
||||
c->dec_firsttable=_ogg_calloc(2,sizeof(*c->dec_firsttable));
|
||||
c->dec_firsttable[0]=c->dec_firsttable[1]=1;
|
||||
|
||||
for(i=0;i<tabn;i++){
|
||||
ogg_uint32_t word=i<<(32-c->dec_firsttablen);
|
||||
if(c->dec_firsttable[bitreverse(word)]==0){
|
||||
while((lo+1)<n && c->codelist[lo+1]<=word)lo++;
|
||||
while( hi<n && word>=(c->codelist[hi]&mask))hi++;
|
||||
}else{
|
||||
c->dec_firsttablen=ov_ilog(c->used_entries)-4; /* this is magic */
|
||||
if(c->dec_firsttablen<5)c->dec_firsttablen=5;
|
||||
if(c->dec_firsttablen>8)c->dec_firsttablen=8;
|
||||
|
||||
/* we only actually have 15 bits per hint to play with here.
|
||||
In order to overflow gracefully (nothing breaks, efficiency
|
||||
just drops), encode as the difference from the extremes. */
|
||||
{
|
||||
unsigned long loval=lo;
|
||||
unsigned long hival=n-hi;
|
||||
tabn=1<<c->dec_firsttablen;
|
||||
c->dec_firsttable=_ogg_calloc(tabn,sizeof(*c->dec_firsttable));
|
||||
|
||||
if(loval>0x7fff)loval=0x7fff;
|
||||
if(hival>0x7fff)hival=0x7fff;
|
||||
c->dec_firsttable[bitreverse(word)]=
|
||||
0x80000000UL | (loval<<15) | hival;
|
||||
for(i=0;i<n;i++){
|
||||
if(c->dec_codelengths[i]<=c->dec_firsttablen){
|
||||
ogg_uint32_t orig=bitreverse(c->codelist[i]);
|
||||
for(j=0;j<(1<<(c->dec_firsttablen-c->dec_codelengths[i]));j++)
|
||||
c->dec_firsttable[orig|(j<<c->dec_codelengths[i])]=i+1;
|
||||
}
|
||||
}
|
||||
|
||||
/* now fill in 'unused' entries in the firsttable with hi/lo search
|
||||
hints for the non-direct-hits */
|
||||
{
|
||||
ogg_uint32_t mask=0xfffffffeUL<<(31-c->dec_firsttablen);
|
||||
long lo=0,hi=0;
|
||||
|
||||
for(i=0;i<tabn;i++){
|
||||
ogg_uint32_t word=i<<(32-c->dec_firsttablen);
|
||||
if(c->dec_firsttable[bitreverse(word)]==0){
|
||||
while((lo+1)<n && c->codelist[lo+1]<=word)lo++;
|
||||
while( hi<n && word>=(c->codelist[hi]&mask))hi++;
|
||||
|
||||
/* we only actually have 15 bits per hint to play with here.
|
||||
In order to overflow gracefully (nothing breaks, efficiency
|
||||
just drops), encode as the difference from the extremes. */
|
||||
{
|
||||
unsigned long loval=lo;
|
||||
unsigned long hival=n-hi;
|
||||
|
||||
if(loval>0x7fff)loval=0x7fff;
|
||||
if(hival>0x7fff)hival=0x7fff;
|
||||
c->dec_firsttable[bitreverse(word)]=
|
||||
0x80000000UL | (loval<<15) | hival;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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-2009 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: single-block PCM synthesis
|
||||
last mod: $Id: synthesis.c 17474 2010-09-30 03:41:41Z gmaxwell $
|
||||
last mod: $Id: synthesis.c 19441 2015-01-21 01:17:41Z xiphmont $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -145,6 +145,11 @@ long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
|
|||
oggpack_buffer opb;
|
||||
int mode;
|
||||
|
||||
if(ci==NULL || ci->modes<=0){
|
||||
/* codec setup not properly intialized */
|
||||
return(OV_EFAULT);
|
||||
}
|
||||
|
||||
oggpack_readinit(&opb,op->packet,op->bytes);
|
||||
|
||||
/* Check the packet type */
|
||||
|
@ -153,18 +158,9 @@ long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op){
|
|||
return(OV_ENOTAUDIO);
|
||||
}
|
||||
|
||||
{
|
||||
int modebits=0;
|
||||
int v=ci->modes;
|
||||
while(v>1){
|
||||
modebits++;
|
||||
v>>=1;
|
||||
}
|
||||
|
||||
/* read our mode and pre/post windowsize */
|
||||
mode=oggpack_read(&opb,modebits);
|
||||
}
|
||||
if(mode==-1)return(OV_EBADPACKET);
|
||||
/* read our mode and pre/post windowsize */
|
||||
mode=oggpack_read(&opb,ov_ilog(ci->modes-1));
|
||||
if(mode==-1 || !ci->mode_param[mode])return(OV_EBADPACKET);
|
||||
return(ci->blocksizes[ci->mode_param[mode]->blockflag]);
|
||||
}
|
||||
|
||||
|
|
|
@ -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-2009 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: simple programmatic interface for encoder mode setup
|
||||
last mod: $Id: vorbisenc.c 17028 2010-03-25 05:22:15Z xiphmont $
|
||||
last mod: $Id: vorbisenc.c 19457 2015-03-03 00:15:29Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -903,8 +903,12 @@ int vorbis_encode_setup_vbr(vorbis_info *vi,
|
|||
long channels,
|
||||
long rate,
|
||||
float quality){
|
||||
codec_setup_info *ci=vi->codec_setup;
|
||||
highlevel_encode_setup *hi=&ci->hi;
|
||||
codec_setup_info *ci;
|
||||
highlevel_encode_setup *hi;
|
||||
if(rate<=0) return OV_EINVAL;
|
||||
|
||||
ci=vi->codec_setup;
|
||||
hi=&ci->hi;
|
||||
|
||||
quality+=.0000001;
|
||||
if(quality>=1.)quality=.9999;
|
||||
|
@ -948,9 +952,14 @@ int vorbis_encode_setup_managed(vorbis_info *vi,
|
|||
long nominal_bitrate,
|
||||
long min_bitrate){
|
||||
|
||||
codec_setup_info *ci=vi->codec_setup;
|
||||
highlevel_encode_setup *hi=&ci->hi;
|
||||
double tnominal=nominal_bitrate;
|
||||
codec_setup_info *ci;
|
||||
highlevel_encode_setup *hi;
|
||||
double tnominal;
|
||||
if(rate<=0) return OV_EINVAL;
|
||||
|
||||
ci=vi->codec_setup;
|
||||
hi=&ci->hi;
|
||||
tnominal=nominal_bitrate;
|
||||
|
||||
if(nominal_bitrate<=0.){
|
||||
if(max_bitrate>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-2009 *
|
||||
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2015 *
|
||||
* by the Xiph.Org Foundation http://www.xiph.org/ *
|
||||
* *
|
||||
********************************************************************
|
||||
|
||||
function: stdio-based convenience library for opening/seeking/decoding
|
||||
last mod: $Id: vorbisfile.c 19031 2013-12-03 19:20:50Z tterribe $
|
||||
last mod: $Id: vorbisfile.c 19457 2015-03-03 00:15:29Z giles $
|
||||
|
||||
********************************************************************/
|
||||
|
||||
|
@ -80,11 +80,14 @@ static long _get_data(OggVorbis_File *vf){
|
|||
/* save a tiny smidge of verbosity to make the code more readable */
|
||||
static int _seek_helper(OggVorbis_File *vf,ogg_int64_t offset){
|
||||
if(vf->datasource){
|
||||
if(!(vf->callbacks.seek_func)||
|
||||
(vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
|
||||
return OV_EREAD;
|
||||
vf->offset=offset;
|
||||
ogg_sync_reset(&vf->oy);
|
||||
/* only seek if the file position isn't already there */
|
||||
if(vf->offset != offset){
|
||||
if(!(vf->callbacks.seek_func)||
|
||||
(vf->callbacks.seek_func)(vf->datasource, offset, SEEK_SET) == -1)
|
||||
return OV_EREAD;
|
||||
vf->offset=offset;
|
||||
ogg_sync_reset(&vf->oy);
|
||||
}
|
||||
}else{
|
||||
/* shouldn't happen unless someone writes a broken callback */
|
||||
return OV_EFAULT;
|
||||
|
@ -138,14 +141,12 @@ static ogg_int64_t _get_next_page(OggVorbis_File *vf,ogg_page *og,
|
|||
}
|
||||
}
|
||||
|
||||
/* find the latest page beginning before the current stream cursor
|
||||
position. Much dirtier than the above as Ogg doesn't have any
|
||||
backward search linkage. no 'readp' as it will certainly have to
|
||||
read. */
|
||||
/* find the latest page beginning before the passed in position. Much
|
||||
dirtier than the above as Ogg doesn't have any backward search
|
||||
linkage. no 'readp' as it will certainly have to read. */
|
||||
/* returns offset or OV_EREAD, OV_FAULT */
|
||||
static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_page *og){
|
||||
ogg_int64_t begin=vf->offset;
|
||||
ogg_int64_t end=begin;
|
||||
static ogg_int64_t _get_prev_page(OggVorbis_File *vf,ogg_int64_t begin,ogg_page *og){
|
||||
ogg_int64_t end = begin;
|
||||
ogg_int64_t ret;
|
||||
ogg_int64_t offset=-1;
|
||||
|
||||
|
@ -220,11 +221,10 @@ static int _lookup_page_serialno(ogg_page *og, long *serialno_list, int n){
|
|||
info of last page of the matching serial number instead of the very
|
||||
last page. If no page of the specified serialno is seen, it will
|
||||
return the info of last page and alter *serialno. */
|
||||
static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf,
|
||||
static ogg_int64_t _get_prev_page_serial(OggVorbis_File *vf, ogg_int64_t begin,
|
||||
long *serial_list, int serial_n,
|
||||
int *serialno, ogg_int64_t *granpos){
|
||||
ogg_page og;
|
||||
ogg_int64_t begin=vf->offset;
|
||||
ogg_int64_t end=begin;
|
||||
ogg_int64_t ret;
|
||||
|
||||
|
@ -438,9 +438,11 @@ static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
|
|||
while((result=ogg_stream_packetout(&vf->os,&op))){
|
||||
if(result>0){ /* ignore holes */
|
||||
long thisblock=vorbis_packet_blocksize(vi,&op);
|
||||
if(lastblock!=-1)
|
||||
accumulated+=(lastblock+thisblock)>>2;
|
||||
lastblock=thisblock;
|
||||
if(thisblock>=0){
|
||||
if(lastblock!=-1)
|
||||
accumulated+=(lastblock+thisblock)>>2;
|
||||
lastblock=thisblock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -494,10 +496,10 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
|
|||
down to (or just started with) a single link. Now we need to
|
||||
find the last vorbis page belonging to the first vorbis stream
|
||||
for this link. */
|
||||
|
||||
searched = end;
|
||||
while(endserial != serialno){
|
||||
endserial = serialno;
|
||||
vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&endserial,&endgran);
|
||||
searched=_get_prev_page_serial(vf,searched,currentno_list,currentnos,&endserial,&endgran);
|
||||
}
|
||||
|
||||
vf->links=m+1;
|
||||
|
@ -518,10 +520,15 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
|
|||
|
||||
}else{
|
||||
|
||||
/* last page is not in the starting stream's serial number list,
|
||||
so we have multiple links. Find where the stream that begins
|
||||
our bisection ends. */
|
||||
|
||||
long *next_serialno_list=NULL;
|
||||
int next_serialnos=0;
|
||||
vorbis_info vi;
|
||||
vorbis_comment vc;
|
||||
int testserial = serialno+1;
|
||||
|
||||
/* the below guards against garbage seperating the last and
|
||||
first pages of two links. */
|
||||
|
@ -534,10 +541,8 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
|
|||
bisect=(searched+endsearched)/2;
|
||||
}
|
||||
|
||||
if(bisect != vf->offset){
|
||||
ret=_seek_helper(vf,bisect);
|
||||
if(ret)return(ret);
|
||||
}
|
||||
ret=_seek_helper(vf,bisect);
|
||||
if(ret)return(ret);
|
||||
|
||||
last=_get_next_page(vf,&og,-1);
|
||||
if(last==OV_EREAD)return(OV_EREAD);
|
||||
|
@ -550,28 +555,22 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
|
|||
}
|
||||
|
||||
/* Bisection point found */
|
||||
|
||||
/* for the time being, fetch end PCM offset the simple way */
|
||||
{
|
||||
int testserial = serialno+1;
|
||||
vf->offset = next;
|
||||
while(testserial != serialno){
|
||||
testserial = serialno;
|
||||
vf->offset=_get_prev_page_serial(vf,currentno_list,currentnos,&testserial,&searchgran);
|
||||
}
|
||||
searched = next;
|
||||
while(testserial != serialno){
|
||||
testserial = serialno;
|
||||
searched = _get_prev_page_serial(vf,searched,currentno_list,currentnos,&testserial,&searchgran);
|
||||
}
|
||||
|
||||
if(vf->offset!=next){
|
||||
ret=_seek_helper(vf,next);
|
||||
if(ret)return(ret);
|
||||
}
|
||||
ret=_seek_helper(vf,next);
|
||||
if(ret)return(ret);
|
||||
|
||||
ret=_fetch_headers(vf,&vi,&vc,&next_serialno_list,&next_serialnos,NULL);
|
||||
if(ret)return(ret);
|
||||
serialno = vf->os.serialno;
|
||||
dataoffset = vf->offset;
|
||||
|
||||
/* this will consume a page, however the next bistection always
|
||||
/* this will consume a page, however the next bisection always
|
||||
starts with a raw seek */
|
||||
pcmoffset = _initial_pcmoffset(vf,&vi);
|
||||
|
||||
|
@ -638,11 +637,11 @@ static int _open_seekable2(OggVorbis_File *vf){
|
|||
/* Get the offset of the last page of the physical bitstream, or, if
|
||||
we're lucky the last vorbis page of this link as most OggVorbis
|
||||
files will contain a single logical bitstream */
|
||||
end=_get_prev_page_serial(vf,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran);
|
||||
end=_get_prev_page_serial(vf,vf->end,vf->serialnos+2,vf->serialnos[1],&endserial,&endgran);
|
||||
if(end<0)return(end);
|
||||
|
||||
/* now determine bitstream structure recursively */
|
||||
if(_bisect_forward_serialno(vf,0,dataoffset,vf->offset,endgran,endserial,
|
||||
if(_bisect_forward_serialno(vf,0,dataoffset,end,endgran,endserial,
|
||||
vf->serialnos+2,vf->serialnos[1],0)<0)return(OV_EREAD);
|
||||
|
||||
vf->offsets[0]=0;
|
||||
|
@ -1421,22 +1420,41 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
|
|||
if(pos>=total)break;
|
||||
}
|
||||
|
||||
/* search within the logical bitstream for the page with the highest
|
||||
pcm_pos preceding (or equal to) pos. There is a danger here;
|
||||
missing pages or incorrect frame number information in the
|
||||
bitstream could make our task impossible. Account for that (it
|
||||
would be an error condition) */
|
||||
/* Search within the logical bitstream for the page with the highest
|
||||
pcm_pos preceding pos. If we're looking for a position on the
|
||||
first page, bisection will halt without finding our position as
|
||||
it's before the first explicit granulepos fencepost. That case is
|
||||
handled separately below.
|
||||
|
||||
There is a danger here; missing pages or incorrect frame number
|
||||
information in the bitstream could make our task impossible.
|
||||
Account for that (it would be an error condition) */
|
||||
|
||||
/* new search algorithm originally by HB (Nicholas Vinen) */
|
||||
|
||||
/* new search algorithm by HB (Nicholas Vinen) */
|
||||
{
|
||||
ogg_int64_t end=vf->offsets[link+1];
|
||||
ogg_int64_t begin=vf->offsets[link];
|
||||
ogg_int64_t begin=vf->dataoffsets[link];
|
||||
ogg_int64_t begintime = vf->pcmlengths[link*2];
|
||||
ogg_int64_t endtime = vf->pcmlengths[link*2+1]+begintime;
|
||||
ogg_int64_t target=pos-total+begintime;
|
||||
ogg_int64_t best=begin;
|
||||
ogg_int64_t best=-1;
|
||||
int got_page=0;
|
||||
|
||||
ogg_page og;
|
||||
|
||||
/* if we have only one page, there will be no bisection. Grab the page here */
|
||||
if(begin==end){
|
||||
result=_seek_helper(vf,begin);
|
||||
if(result) goto seek_error;
|
||||
|
||||
result=_get_next_page(vf,&og,1);
|
||||
if(result<0) goto seek_error;
|
||||
|
||||
got_page=1;
|
||||
}
|
||||
|
||||
/* bisection loop */
|
||||
while(begin<end){
|
||||
ogg_int64_t bisect;
|
||||
|
||||
|
@ -1451,51 +1469,80 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
|
|||
bisect=begin;
|
||||
}
|
||||
|
||||
if(bisect!=vf->offset){
|
||||
result=_seek_helper(vf,bisect);
|
||||
if(result) goto seek_error;
|
||||
}
|
||||
result=_seek_helper(vf,bisect);
|
||||
if(result) goto seek_error;
|
||||
|
||||
/* read loop within the bisection loop */
|
||||
while(begin<end){
|
||||
result=_get_next_page(vf,&og,end-vf->offset);
|
||||
if(result==OV_EREAD) goto seek_error;
|
||||
if(result<0){
|
||||
/* there is no next page! */
|
||||
if(bisect<=begin+1)
|
||||
end=begin; /* found it */
|
||||
/* No bisection left to perform. We've either found the
|
||||
best candidate already or failed. Exit loop. */
|
||||
end=begin;
|
||||
else{
|
||||
/* We tried to load a fraction of the last page; back up a
|
||||
bit and try to get the whole last page */
|
||||
if(bisect==0) goto seek_error;
|
||||
bisect-=CHUNKSIZE;
|
||||
|
||||
/* don't repeat/loop on a read we've already performed */
|
||||
if(bisect<=begin)bisect=begin+1;
|
||||
|
||||
/* seek and cntinue bisection */
|
||||
result=_seek_helper(vf,bisect);
|
||||
if(result) goto seek_error;
|
||||
}
|
||||
}else{
|
||||
ogg_int64_t granulepos;
|
||||
got_page=1;
|
||||
|
||||
/* got a page. analyze it */
|
||||
/* only consider pages from primary vorbis stream */
|
||||
if(ogg_page_serialno(&og)!=vf->serialnos[link])
|
||||
continue;
|
||||
|
||||
/* only consider pages with the granulepos set */
|
||||
granulepos=ogg_page_granulepos(&og);
|
||||
if(granulepos==-1)continue;
|
||||
|
||||
if(granulepos<target){
|
||||
/* this page is a successful candidate! Set state */
|
||||
|
||||
best=result; /* raw offset of packet with granulepos */
|
||||
begin=vf->offset; /* raw offset of next page */
|
||||
begintime=granulepos;
|
||||
|
||||
/* if we're before our target but within a short distance,
|
||||
don't bisect; read forward */
|
||||
if(target-begintime>44100)break;
|
||||
bisect=begin; /* *not* begin + 1 */
|
||||
|
||||
bisect=begin; /* *not* begin + 1 as above */
|
||||
}else{
|
||||
if(bisect<=begin+1)
|
||||
end=begin; /* found it */
|
||||
else{
|
||||
if(end==vf->offset){ /* we're pretty close - we'd be stuck in */
|
||||
|
||||
/* This is one of our pages, but the granpos is
|
||||
post-target; it is not a bisection return
|
||||
candidate. (The only way we'd use it is if it's the
|
||||
first page in the stream; we handle that case later
|
||||
outside the bisection) */
|
||||
if(bisect<=begin+1){
|
||||
/* No bisection left to perform. We've either found the
|
||||
best candidate already or failed. Exit loop. */
|
||||
end=begin;
|
||||
}else{
|
||||
if(end==vf->offset){
|
||||
/* bisection read to the end; use the known page
|
||||
boundary (result) to update bisection, back up a
|
||||
little bit, and try again */
|
||||
end=result;
|
||||
bisect-=CHUNKSIZE; /* an endless loop otherwise. */
|
||||
bisect-=CHUNKSIZE;
|
||||
if(bisect<=begin)bisect=begin+1;
|
||||
result=_seek_helper(vf,bisect);
|
||||
if(result) goto seek_error;
|
||||
}else{
|
||||
/* Normal bisection */
|
||||
end=bisect;
|
||||
endtime=granulepos;
|
||||
break;
|
||||
|
@ -1506,9 +1553,46 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
|
|||
}
|
||||
}
|
||||
|
||||
/* found our page. seek to it, update pcm offset. Easier case than
|
||||
raw_seek, don't keep packets preceding granulepos. */
|
||||
{
|
||||
/* Out of bisection: did it 'fail?' */
|
||||
if(best == -1){
|
||||
|
||||
/* Check the 'looking for data in first page' special case;
|
||||
bisection would 'fail' because our search target was before the
|
||||
first PCM granule position fencepost. */
|
||||
|
||||
if(got_page &&
|
||||
begin == vf->dataoffsets[link] &&
|
||||
ogg_page_serialno(&og)==vf->serialnos[link]){
|
||||
|
||||
/* Yes, this is the beginning-of-stream case. We already have
|
||||
our page, right at the beginning of PCM data. Set state
|
||||
and return. */
|
||||
|
||||
vf->pcm_offset=total;
|
||||
|
||||
if(link!=vf->current_link){
|
||||
/* Different link; dump entire decode machine */
|
||||
_decode_clear(vf);
|
||||
|
||||
vf->current_link=link;
|
||||
vf->current_serialno=vf->serialnos[link];
|
||||
vf->ready_state=STREAMSET;
|
||||
|
||||
}else{
|
||||
vorbis_synthesis_restart(&vf->vd);
|
||||
}
|
||||
|
||||
ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
|
||||
ogg_stream_pagein(&vf->os,&og);
|
||||
|
||||
}else
|
||||
goto seek_error;
|
||||
|
||||
}else{
|
||||
|
||||
/* Bisection found our page. seek to it, update pcm offset. Easier case than
|
||||
raw_seek, don't keep packets preceding granulepos. */
|
||||
|
||||
ogg_page og;
|
||||
ogg_packet op;
|
||||
|
||||
|
@ -1538,23 +1622,23 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
|
|||
while(1){
|
||||
result=ogg_stream_packetpeek(&vf->os,&op);
|
||||
if(result==0){
|
||||
/* !!! the packet finishing this page originated on a
|
||||
preceding page. Keep fetching previous pages until we
|
||||
get one with a granulepos or without the 'continued' flag
|
||||
set. Then just use raw_seek for simplicity. */
|
||||
|
||||
result=_seek_helper(vf,best);
|
||||
if(result<0) goto seek_error;
|
||||
|
||||
while(1){
|
||||
result=_get_prev_page(vf,&og);
|
||||
/* No packet returned; we exited the bisection with 'best'
|
||||
pointing to a page with a granule position, so the packet
|
||||
finishing this page ('best') originated on a preceding
|
||||
page. Keep fetching previous pages until we get one with
|
||||
a granulepos or without the 'continued' flag set. Then
|
||||
just use raw_seek for simplicity. */
|
||||
/* Do not rewind past the beginning of link data; if we do,
|
||||
it's either a bug or a broken stream */
|
||||
result=best;
|
||||
while(result>vf->dataoffsets[link]){
|
||||
result=_get_prev_page(vf,result,&og);
|
||||
if(result<0) goto seek_error;
|
||||
if(ogg_page_serialno(&og)==vf->current_serialno &&
|
||||
(ogg_page_granulepos(&og)>-1 ||
|
||||
!ogg_page_continued(&og))){
|
||||
return ov_raw_seek(vf,result);
|
||||
}
|
||||
vf->offset=result;
|
||||
}
|
||||
}
|
||||
if(result<0){
|
||||
|
|
Loading…
Reference in a new issue