Commit e5e1687f authored by Monty's avatar Monty
Browse files

Fixed a link-crossing bug in libvorbis (total time was reset to -1
at the link boundary until the next packet with a frame number arrived)

Implemented instantaneous bitrate capability in libvorbis; added
ov_bitrate_instant() to interface

Added instantaneous bitrate display to xmms

Monty

svn path=/trunk/vorbis/; revision=451
parent c9b627e4
......@@ -12,7 +12,7 @@
********************************************************************
function: stdio-based convenience library for opening/seeking/decoding
last mod: $Id: vorbisfile.h,v 1.5 2000/06/14 10:13:35 xiphmont Exp $
last mod: $Id: vorbisfile.h,v 1.6 2000/06/15 12:17:03 xiphmont Exp $
********************************************************************/
......@@ -68,6 +68,9 @@ typedef struct {
long current_serialno;
int current_link;
double bittrack;
double samptrack;
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 */
......@@ -83,6 +86,7 @@ extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf,
char *initial, long ibytes, ov_callbacks callbacks);
extern long ov_bitrate(OggVorbis_File *vf,int i);
extern long ov_bitrate_instant(OggVorbis_File *vf);
extern long ov_streams(OggVorbis_File *vf);
extern long ov_seekable(OggVorbis_File *vf);
extern long ov_serialnumber(OggVorbis_File *vf,int i);
......
......@@ -12,7 +12,7 @@
********************************************************************
function: PCM data vector blocking, windowing and dis/reassembly
last mod: $Id: block.c,v 1.31 2000/06/14 10:13:35 xiphmont Exp $
last mod: $Id: block.c,v 1.32 2000/06/15 12:17:03 xiphmont Exp $
Handle windowing, overlap-add, etc of the PCM vectors. This is made
more amusing by Vorbis' current two allowed block sizes.
......@@ -689,13 +689,16 @@ int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb){
return(0);
}
/* pcm==NULL indicates we just want the pending samples, no more */
int vorbis_synthesis_pcmout(vorbis_dsp_state *v,double ***pcm){
vorbis_info *vi=v->vi;
if(v->pcm_returned<v->centerW){
int i;
for(i=0;i<vi->channels;i++)
v->pcmret[i]=v->pcm[i]+v->pcm_returned;
*pcm=v->pcmret;
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(0);
......
......@@ -12,7 +12,7 @@
********************************************************************
function: stdio-based convenience library for opening/seeking/decoding
last mod: $Id: vorbisfile.c,v 1.24 2000/06/14 10:13:35 xiphmont Exp $
last mod: $Id: vorbisfile.c,v 1.25 2000/06/15 12:17:03 xiphmont Exp $
********************************************************************/
......@@ -385,8 +385,10 @@ static void _decode_clear(OggVorbis_File *vf){
ogg_stream_clear(&vf->os);
vorbis_dsp_clear(&vf->vd);
vorbis_block_clear(&vf->vb);
vf->pcm_offset=-1;
vf->decode_ready=0;
vf->bittrack=0.;
vf->samptrack=0.;
}
/* fetch and process a packet. Handles the case where we're at a
......@@ -425,12 +427,18 @@ static int _process_packet(OggVorbis_File *vf,int readp){
submit them,
vorbis_synthesis will
reject them */
vorbis_synthesis_blockin(&vf->vd,&vf->vb);
/* suck in the synthesis data and track bitrate */
{
int oldsamples=vorbis_synthesis_pcmout(&vf->vd,NULL);
vorbis_synthesis_blockin(&vf->vd,&vf->vb);
vf->samptrack+=vorbis_synthesis_pcmout(&vf->vd,NULL)-oldsamples;
vf->bittrack+=op.bytes*8;
}
/* update the pcm offset. */
if(frameno!=-1 && !op.e_o_s){
int link=(vf->seekable?vf->current_link:0);
double **dummy;
int i,samples;
/* this packet has a pcm_offset on it (the last packet
......@@ -446,7 +454,7 @@ static int _process_packet(OggVorbis_File *vf,int readp){
to have a reference point. Thus the !op.e_o_s clause
above */
samples=vorbis_synthesis_pcmout(&vf->vd,&dummy);
samples=vorbis_synthesis_pcmout(&vf->vd,NULL);
frameno-=samples;
for(i=0;i<link;i++)
......@@ -461,6 +469,10 @@ static int _process_packet(OggVorbis_File *vf,int readp){
if(!readp)return(0);
if(_get_next_page(vf,&og,-1)<0)return(0); /* eof. leave unitialized */
/* bitrate tracking; add the header's bytes here, the body bytes
are done by packet above */
vf->bittrack+=og.header_len*8;
/* has our decoding just traversed a bitstream boundary? */
if(vf->decode_ready){
if(vf->current_serialno!=ogg_page_serialno(&og)){
......@@ -656,6 +668,18 @@ long ov_bitrate(OggVorbis_File *vf,int i){
}
}
/* returns the actual bitrate since last call. returns -1 if no
additional data to offer since last call (or at beginning of stream) */
long ov_bitrate_instant(OggVorbis_File *vf){
int link=(vf->seekable?vf->current_link:0);
long ret;
if(vf->samptrack==0)return(-1);
ret=vf->bittrack/vf->samptrack*vf->vi[link].rate+.5;
vf->bittrack=0.;
vf->samptrack=0.;
return(ret);
}
/* Guess */
long ov_serialnumber(OggVorbis_File *vf,int i){
if(i>=vf->links)return(-1);
......@@ -732,6 +756,7 @@ int ov_raw_seek(OggVorbis_File *vf,long pos){
if(pos<0 || pos>vf->offsets[vf->links])goto seek_error;
/* clear out decoding machine state */
vf->pcm_offset=-1;
_decode_clear(vf);
/* seek */
......@@ -775,6 +800,7 @@ int ov_raw_seek(OggVorbis_File *vf,long pos){
seek_error:
/* dump the machine so we're in a known state */
vf->pcm_offset=-1;
_decode_clear(vf);
return -1;
}
......@@ -862,6 +888,7 @@ int ov_pcm_seek(OggVorbis_File *vf,int64_t pos){
seek_error:
/* dump machine so we're in a known state */
vf->pcm_offset=-1;
_decode_clear(vf);
return -1;
}
......@@ -893,6 +920,7 @@ int ov_time_seek(OggVorbis_File *vf,double seconds){
seek_error:
/* dump machine so we're in a known state */
vf->pcm_offset=-1;
_decode_clear(vf);
return -1;
}
......@@ -924,7 +952,7 @@ double ov_time_tell(OggVorbis_File *vf){
for(link=vf->links-1;link>=0;link--){
pcm_total-=vf->pcmlengths[link];
time_total-=ov_time_total(vf,link);
if(vf->pcm_offset>pcm_total)break;
if(vf->pcm_offset>=pcm_total)break;
}
}
......
......@@ -2,10 +2,6 @@ Development hit list for 1.0:
libvorbis:
Implement correct truncated packet handling; this is mostly a case of
'intiialize vectors and check return values' in res0.c:inverse (but
not entirely)
Meaningful error code returns
Option for brute-forcing vq search on maptype 2 (helps on undertrained
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment