diff options
author | Monty <xiphmont@xiph.org> | 2000-06-15 12:17:03 +0000 |
---|---|---|
committer | Monty <xiphmont@xiph.org> | 2000-06-15 12:17:03 +0000 |
commit | e5e1687f292195d06989943b04827fc3211f5480 (patch) | |
tree | d8faed01ec4066f097cb5b6d2db4d9dcb256b50a | |
parent | c9b627e4442c3d487adb10c102f6a40c01fe43f8 (diff) | |
download | libvorbis-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.h | 6 | ||||
-rw-r--r-- | lib/block.c | 13 | ||||
-rw-r--r-- | lib/vorbisfile.c | 40 | ||||
-rw-r--r-- | todo.txt | 4 |
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; } } @@ -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 |