summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <xiphmont@xiph.org>2000-06-15 12:17:03 +0000
committerMonty <xiphmont@xiph.org>2000-06-15 12:17:03 +0000
commite5e1687f292195d06989943b04827fc3211f5480 (patch)
treed8faed01ec4066f097cb5b6d2db4d9dcb256b50a
parentc9b627e4442c3d487adb10c102f6a40c01fe43f8 (diff)
downloadlibvorbis-git-e5e1687f292195d06989943b04827fc3211f5480.tar.gz
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
-rw-r--r--include/vorbis/vorbisfile.h6
-rw-r--r--lib/block.c13
-rw-r--r--lib/vorbisfile.c40
-rw-r--r--todo.txt4
4 files changed, 47 insertions, 16 deletions
diff --git a/include/vorbis/vorbisfile.h b/include/vorbis/vorbisfile.h
index 06c3724d..983c1baa 100644
--- a/include/vorbis/vorbisfile.h
+++ b/include/vorbis/vorbisfile.h
@@ -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);
diff --git a/lib/block.c b/lib/block.c
index 546793b0..ba744589 100644
--- a/lib/block.c
+++ b/lib/block.c
@@ -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);
diff --git a/lib/vorbisfile.c b/lib/vorbisfile.c
index 09e6cfc3..82836f71 100644
--- a/lib/vorbisfile.c
+++ b/lib/vorbisfile.c
@@ -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;
}
}
diff --git a/todo.txt b/todo.txt
index bb90db94..dccd1d04 100644
--- a/todo.txt
+++ b/todo.txt
@@ -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