1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *
9 * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: stdio-based convenience library for opening/seeking/decoding
15 author: Monty <xiphmont@mit.edu>
16 modifications by: Monty
17 last modification date: Nov 04 1999
19 ********************************************************************/
24 #include "vorbisfile.h"
26 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
27 one logical bitstream arranged end to end (the only form of Ogg
28 multiplexing allowed in a Vorbis bitstream; grouping [parallel
29 multiplexing] is not allowed in Vorbis) */
31 /* A Vorbis file can be played beginning to end (streamed) without
32 worrying ahead of time about chaining (see decoder_example.c). If
33 we have the whole file, however, and want random access
34 (seeking/scrubbing) or desire to know the total length/time of a
35 file, we need to account for the possibility of chaining. */
37 /* We can handle things a number of ways; we can determine the entire
38 bitstream structure right off the bat, or find pieces on demand.
39 This example determines and caches structure for the entire
40 bitstream, but builds a virtual decoder on the fly when moving
41 between links in the chain. */
43 /* There are also different ways to implement seeking. Enough
44 information exists in an Ogg bitstream to seek to
45 sample-granularity positions in the output. Or, one can seek by
46 picking some portion of the stream roughly in the desired area if
47 we only want course navigation through the stream. */
49 /*************************************************************************
50 * Many, many internal helpers. The intention is not to be confusing;
51 * rampant duplication and monolithic function implementation would be
52 * harder to understand anyway. The high level functions are last. Begin
53 * grokking near the end of the file */
55 /* read a little more data from the file/pipe into the ogg_sync framer */
56 #define CHUNKSIZE 4096
57 static long _get_data(OggVorbis_File *vf){
58 char *buffer=ogg_sync_buffer(&vf->oy,4096);
59 long bytes=fread(buffer,1,4096,vf->f);
60 ogg_sync_wrote(&vf->oy,bytes);
64 /* save a tiny smidge of verbosity to make the code more readable */
65 static void _seek_helper(OggVorbis_File *vf,long offset){
66 fseek(vf->f,offset,SEEK_SET);
68 ogg_sync_reset(&vf->oy);
71 /* The read/seek functions track absolute position within the stream */
73 /* from the head of the stream, get the next page. boundary specifies
74 if the function is allowed to fetch more data from the stream (and
75 how much) or only use internally buffered data.
77 boundary: -1) unbounded search
78 0) read no additional data; use cached only
79 n) search for a new page beginning for n bytes
81 return: -1) did not find a page
82 n) found a page at absolute offset n */
84 static long _get_next_page(OggVorbis_File *vf,ogg_page *og,int boundary){
85 if(boundary>0)boundary+=vf->offset;
89 if(boundary>0 && vf->offset>=boundary)return(-1);
90 more=ogg_sync_pageseek(&vf->oy,og);
97 /* send more paramedics */
98 if(!boundary)return(-1);
99 if(_get_data(vf)<=0)return(-1);
101 /* got a page. Return the offset at the page beginning,
102 advance the internal offset past the page end */
112 /* find the latest page beginning before the current stream cursor
113 position. Much dirtier than the above as Ogg doesn't have any
114 backward search linkage. no 'readp' as it will certainly have to
116 static long _get_prev_page(OggVorbis_File *vf,ogg_page *og){
117 long begin=vf->offset;
123 _seek_helper(vf,begin);
124 while(vf->offset<begin+CHUNKSIZE){
125 ret=_get_next_page(vf,og,begin+CHUNKSIZE-vf->offset);
134 /* we have the offset. Actually snork and hold the page now */
135 _seek_helper(vf,offset);
136 ret=_get_next_page(vf,og,CHUNKSIZE);
138 /* this shouldn't be possible */
139 fprintf(stderr,"Missed page fencepost at end of logical bitstream. "
146 /* finds each bitstream link one at a time using a bisection search
147 (has to begin by knowing the offset of the lb's initial page).
148 Recurses for each link so it can alloc the link storage after
149 finding them all, then unroll and fill the cache at the same time */
150 static void _bisect_forward_serialno(OggVorbis_File *vf,
156 long endsearched=end;
160 /* the below guards against garbage seperating the last and
161 first pages of two links. */
162 while(searched<endsearched){
166 if(endsearched-searched<CHUNKSIZE){
169 bisect=(searched+endsearched)/2;
172 _seek_helper(vf,bisect);
173 ret=_get_next_page(vf,&og,-1);
174 if(ret<0 || ogg_page_serialno(&og)!=currentno){
178 searched=ret+og.header_len+og.body_len;
183 vf->offsets=malloc((m+2)*sizeof(long));
184 vf->offsets[m+1]=searched;
186 _bisect_forward_serialno(vf,next,next,
187 end,ogg_page_serialno(&og),m+1);
190 vf->offsets[m]=begin;
193 /* uses the local ogg_stream storage in vf; this is important for
194 non-streaming input sources */
195 static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,long *serialno){
200 ret=_get_next_page(vf,&og,CHUNKSIZE);
202 fprintf(stderr,"Did not find initial header for bitstream.\n");
206 if(serialno)*serialno=ogg_page_serialno(&og);
207 ogg_stream_init(&vf->os,ogg_page_serialno(&og));
209 /* extract the initial header from the first page and verify that the
210 Ogg bitstream is in fact Vorbis data */
212 vorbis_info_init(vi);
216 ogg_stream_pagein(&vf->os,&og);
218 int result=ogg_stream_packetout(&vf->os,&op);
221 fprintf(stderr,"Corrupt header in logical bitstream. "
225 if(vorbis_info_headerin(vi,&op)){
226 fprintf(stderr,"Illegal header in logical bitstream. "
233 if(_get_next_page(vf,&og,1)<0){
234 fprintf(stderr,"Missing header in logical bitstream. "
242 vorbis_info_clear(vi);
243 ogg_stream_clear(&vf->os);
247 /* last step of the OggVorbis_File initialization; get all the
248 vorbis_info structs and PCM positions. Only called by the seekable
249 initialization (local stream storage is hacked slightly; pay
250 attention to how that's done) */
251 static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first){
255 vf->vi=malloc(vf->links*sizeof(vorbis_info));
256 vf->pcmlengths=malloc(vf->links*sizeof(size64));
257 vf->serialnos=malloc(vf->links*sizeof(long));
259 for(i=0;i<vf->links;i++){
261 /* we already grabbed the initial header earlier. This just
262 saves the waste of grabbing it again */
263 memcpy(vf->vi+i,first,sizeof(vorbis_info));
264 memset(first,0,sizeof(vorbis_info));
267 /* seek to the location of the initial header */
269 _seek_helper(vf,vf->offsets[i]);
270 if(_fetch_headers(vf,vf->vi+i,NULL)==-1){
271 vorbis_info_clear(vf->vi+i);
272 fprintf(stderr,"Error opening logical bitstream #%d.\n\n",i+1);
274 ogg_stream_clear(&vf->os); /* clear local storage. This is not
275 done in _fetch_headers, as that may
276 be called in a non-seekable stream
277 (in which case, we need to preserve
278 the stream local storage) */
282 /* get the serial number and PCM length of this link. To do this,
283 get the last page of the stream */
285 long end=vf->offsets[i+1];
286 _seek_helper(vf,end);
289 ret=_get_prev_page(vf,&og);
291 /* this should not be possible */
292 fprintf(stderr,"Could not find last page of logical "
293 "bitstream #%d\n\n",i);
294 vorbis_info_clear(vf->vi+i);
297 if(ogg_page_frameno(&og)!=-1){
298 vf->serialnos[i]=ogg_page_serialno(&og);
299 vf->pcmlengths[i]=ogg_page_frameno(&og);
307 static int _open_seekable(OggVorbis_File *vf){
313 /* is this even vorbis...? */
314 ret=_fetch_headers(vf,&initial,&serialno);
315 ogg_stream_clear(&vf->os);
316 if(ret==-1)return(-1);
318 /* we can seek, so set out learning all about this file */
320 fseek(vf->f,0,SEEK_END); /* Yes, I know I used lseek earlier. */
321 vf->offset=vf->end=ftell(vf->f);
323 /* We get the offset for the last page of the physical bitstream.
324 Most OggVorbis files will contain a single logical bitstream */
325 end=_get_prev_page(vf,&og);
327 /* moer than one logical bitstream? */
328 if(ogg_page_serialno(&og)!=serialno){
330 /* Chained bitstream. Bisect-search each logical bitstream
331 section. Do so based on serial number only */
332 _bisect_forward_serialno(vf,0,0,end+1,serialno,0);
336 /* Only one logical bitstream */
337 _bisect_forward_serialno(vf,0,end,end+1,serialno,0);
341 _prefetch_all_headers(vf,&initial);
346 static int _open_nonseekable(OggVorbis_File *vf){
347 /* we cannot seek. Set up a 'single' (current) logical bitstream entry */
349 vf->vi=malloc(sizeof(vorbis_info));
351 /* Try to fetch the headers, maintaining all the storage */
352 if(_fetch_headers(vf,vf->vi,&vf->current_serialno)==-1)return(-1);
357 /* clear out the current logical bitstream decoder */
358 static void _decode_clear(OggVorbis_File *vf){
359 ogg_stream_clear(&vf->os);
360 vorbis_dsp_clear(&vf->vd);
361 vorbis_block_clear(&vf->vb);
366 /* fetch and process a packet. Handles the case where we're at a
367 bitstream boundary and dumps the decoding machine. If the decoding
368 machine is unloaded, it loads it. It also keeps pcm_offset up to
369 date (seek and read both use this. seek uses a special hack with
372 return: -1) hole in the data (lost packet)
373 0) need more date (only if readp==0)/eof
377 static int _process_packet(OggVorbis_File *vf,int readp){
380 /* handle one packet. Try to fetch it from current stream state */
381 /* extract packets from page */
384 /* process a packet if we can. If the machine isn't loaded,
386 if(vf->decode_ready){
388 int result=ogg_stream_packetout(&vf->os,&op);
391 if(result==-1)return(-1); /* hole in the data. alert the toplevel */
393 /* got a packet. process it */
395 vorbis_synthesis(&vf->vb,&op);
396 vorbis_synthesis_blockin(&vf->vd,&vf->vb);
398 /* update the pcm offset. */
400 int link=(vf->seekable?vf->current_link:0);
404 /* this packet has a pcm_offset on it (the last packet
405 completed on a page carries the offset) After processing
406 (above), we know the pcm position of the *last* sample
407 ready to be returned. Find the offset of the *first* */
409 samples=vorbis_synthesis_pcmout(&vf->vd,&dummy);
413 frameno+=vf->pcmlengths[i];
414 vf->pcm_offset=frameno;
421 if(_get_next_page(vf,&og,-1)<0)return(0); /* eof. leave unitialized */
423 /* has our decoding just traversed a bitstream boundary? */
424 if(vf->decode_ready){
425 if(vf->current_serialno!=ogg_page_serialno(&og)){
430 /* Do we need to load a new machine before submitting the page? */
431 /* This is different in the seekable and non-seekable cases.
433 In the seekable case, we already have all the header
434 information loaded and cached; we just initialize the machine
435 with it and continue on our merry way.
437 In the non-seekable (streaming) case, we'll only be at a
438 boundary if we just left the previous logical bitstream and
439 we're now nominally at the header of the next bitstream
442 if(!vf->decode_ready){
445 vf->current_serialno=ogg_page_serialno(&og);
447 /* match the serialno to bitstream section. We use this rather than
448 offset positions to avoid problems near logical bitstream
450 for(link=0;link<vf->links;link++)
451 if(vf->serialnos[link]==vf->current_serialno)break;
452 if(link==vf->links)return(-1); /* sign of a bogus stream. error out,
453 leave machine uninitialized */
455 vf->current_link=link;
457 /* we're streaming */
458 /* fetch the three header packets, build the info struct */
460 _fetch_headers(vf,vf->vi,&vf->current_serialno);
466 ogg_stream_init(&vf->os,vf->current_serialno);
467 vorbis_synthesis_init(&vf->vd,vf->vi+link);
468 vorbis_block_init(&vf->vd,&vf->vb);
471 ogg_stream_pagein(&vf->os,&og);
475 /**********************************************************************
476 * The helpers are over; it's all toplevel interface from here on out */
478 /* clear out the OggVorbis_File struct */
479 int ov_clear(OggVorbis_File *vf){
481 vorbis_block_clear(&vf->vb);
482 vorbis_dsp_clear(&vf->vd);
483 ogg_stream_clear(&vf->os);
485 if(vf->vi && vf->links){
487 for(i=0;i<vf->links;i++)
488 vorbis_info_clear(vf->vi+i);
491 if(vf->pcmlengths)free(vf->pcmlengths);
492 if(vf->serialnos)free(vf->serialnos);
493 if(vf->offsets)free(vf->offsets);
494 ogg_sync_clear(&vf->oy);
495 if(vf->f)fclose(vf->f);
496 memset(vf,0,sizeof(OggVorbis_File));
501 /* inspects the OggVorbis file and finds/documents all the logical
502 bitstreams contained in it. Tries to be tolerant of logical
503 bitstream sections that are truncated/woogie.
509 int ov_open(FILE *f,OggVorbis_File *vf,char *initial,long ibytes){
510 long offset=lseek(fileno(f),0,SEEK_CUR);
513 memset(vf,0,sizeof(OggVorbis_File));
516 /* init the framing state */
517 ogg_sync_init(&vf->oy);
519 /* perhaps some data was previously read into a buffer for testing
520 against other stream types. Allow initialization from this
521 previously read data (as we may be reading from a non-seekable
524 char *buffer=ogg_sync_buffer(&vf->oy,ibytes);
525 memcpy(buffer,initial,ibytes);
526 ogg_sync_wrote(&vf->oy,ibytes);
529 /* can we seek? Stevens suggests the seek test was portable */
531 ret=_open_seekable(vf);
533 ret=_open_nonseekable(vf);
539 ogg_stream_init(&vf->os,vf->current_serialno);
540 vorbis_synthesis_init(&vf->vd,vf->vi);
541 vorbis_block_init(&vf->vd,&vf->vb);
547 /* How many logical bitstreams in this physical bitstream? */
548 long ov_streams(OggVorbis_File *vf){
552 /* Is the FILE * associated with vf seekable? */
553 long ov_seekable(OggVorbis_File *vf){
557 /* returns: total raw (compressed) length of content if i==-1
558 raw (compressed) length of that logical bitstream for i==0 to n
559 -1 if the stream is not seekable (we can't know the length)
561 long ov_raw_total(OggVorbis_File *vf,int i){
562 if(!vf->seekable)return(-1);
563 if(i<0 || i>=vf->links){
566 for(i=0;i<vf->links;i++)
567 acc+=ov_raw_total(vf,i);
570 return(vf->offsets[i+1]-vf->offsets[i]);
574 /* returns: total PCM length (samples) of content if i==-1
575 PCM length (samples) of that logical bitstream for i==0 to n
576 -1 if the stream is not seekable (we can't know the length)
578 size64 ov_pcm_total(OggVorbis_File *vf,int i){
579 if(!vf->seekable)return(-1);
580 if(i<0 || i>=vf->links){
583 for(i=0;i<vf->links;i++)
584 acc+=ov_pcm_total(vf,i);
587 return(vf->pcmlengths[i]);
591 /* returns: total seconds of content if i==-1
592 seconds in that logical bitstream for i==0 to n
593 -1 if the stream is not seekable (we can't know the length)
595 double ov_time_total(OggVorbis_File *vf,int i){
596 if(!vf->seekable)return(-1);
597 if(i<0 || i>=vf->links){
600 for(i=0;i<vf->links;i++)
601 acc+=ov_time_total(vf,i);
604 return((float)(vf->pcmlengths[i])/vf->vi[i].rate);
608 /* seek to an offset relative to the *compressed* data. This also
609 immediately sucks in and decodes pages to update the PCM cursor. It
610 will cross a logical bitstream boundary, but only if it can't get
611 any packets out of the tail of the bitstream we seek to (so no
614 returns zero on success, nonzero on failure */
616 int ov_raw_seek(OggVorbis_File *vf,long pos){
619 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
620 if(pos<0 || pos>vf->offsets[vf->links])goto seek_error;
622 /* clear out decoding machine state */
626 _seek_helper(vf,pos);
628 /* we need to make sure the pcm_offset is set. We use the
629 _fetch_packet helper to process one packet with readp set, then
630 call it until it returns '0' with readp not set (the last packet
631 from a page has the 'frameno' field set, and that's how the
632 helper updates the offset */
634 switch(_process_packet(vf,1)){
636 /* oh, eof. There are no packets remaining. Set the pcm offset to
638 vf->pcm_offset=ov_pcm_total(vf,-1);
641 /* error! missing data or invalid bitstream structure */
649 switch(_process_packet(vf,0)){
651 /* the offset is set. If it's a bogus bitstream with no offset
652 information, it's not but that's not our fault. We still run
653 gracefully, we're just missing the offset */
656 /* error! missing data or invalid bitstream structure */
659 /* continue processing packets */
665 /* dump the machine so we're in a known state */
670 /* seek to a sample offset relative to the decompressed pcm stream
672 returns zero on success, nonzero on failure */
674 int ov_pcm_seek(OggVorbis_File *vf,size64 pos){
676 size64 total=ov_pcm_total(vf,-1);
678 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
679 if(pos<0 || pos>total)goto seek_error;
681 /* which bitstream section does this pcm offset occur in? */
682 for(link=vf->links-1;link>=0;link--){
683 total-=vf->pcmlengths[link];
687 /* seach within the logical bitstream for the page with the highest
688 pcm_pos preceeding (or equal to) pos. There is a danger here;
689 missing pages or incorrect frame number information in the
690 bitstream could make our task impossible. Account for that (it
691 would be an error condition) */
693 size64 target=pos-total;
694 long end=vf->offsets[link+1];
695 long begin=vf->offsets[link];
703 if(end-begin<CHUNKSIZE){
706 bisect=(end+begin)/2;
709 _seek_helper(vf,bisect);
713 ret=_get_next_page(vf,&og,-1);
718 size64 frameno=ogg_page_frameno(&og);
720 if(frameno==-1)continue;
722 best=bisect+acc; /* raw offset of packet with frameno */
723 begin=vf->offset; /* raw offset of next packet */
732 /* found our page. seek to it (call raw_seek). */
734 if(ov_raw_seek(vf,best))goto seek_error;
738 if(vf->pcm_offset>=pos)goto seek_error;
739 if(pos>ov_pcm_total(vf,-1))goto seek_error;
741 /* discard samples until we reach the desired position. Crossing a
742 logical bitstream boundary with abandon is OK. */
743 while(vf->pcm_offset<pos){
745 long target=pos-vf->pcm_offset;
746 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
748 if(samples>target)samples=target;
749 vorbis_synthesis_read(&vf->vd,samples);
750 vf->pcm_offset+=samples;
753 if(_process_packet(vf,1)==0)
754 vf->pcm_offset=ov_pcm_total(vf,-1); /* eof */
759 /* dump machine so we're in a known state */
764 /* seek to a playback time relative to the decompressed pcm stream
765 returns zero on success, nonzero on failure */
766 int ov_time_seek(OggVorbis_File *vf,double seconds){
767 /* translate time to PCM position and call ov_pcm_seek */
770 size64 pcm_total=ov_pcm_total(vf,-1);
771 double time_total=ov_time_total(vf,-1);
773 if(!vf->seekable)return(-1); /* don't dump machine if we can't seek */
774 if(seconds<0 || seconds>time_total)goto seek_error;
776 /* which bitstream section does this time offset occur in? */
777 for(link=vf->links-1;link>=0;link--){
778 pcm_total-=vf->pcmlengths[link];
779 time_total-=ov_time_total(vf,link);
780 if(seconds>=time_total)break;
783 /* enough information to convert time offset to pcm offset */
785 size64 target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
786 return(ov_pcm_seek(vf,target));
790 /* dump machine so we're in a known state */
795 /* tell the current stream offset cursor. Note that seek followed by
796 tell will likely not give the set offset due to caching */
797 long ov_raw_tell(OggVorbis_File *vf){
801 /* return PCM offset (sample) of next PCM sample to be read */
802 size64 ov_pcm_tell(OggVorbis_File *vf){
803 return(vf->pcm_offset);
806 /* return time offset (seconds) of next PCM sample to be read */
807 double ov_time_tell(OggVorbis_File *vf){
808 /* translate time to PCM position and call ov_pcm_seek */
812 double time_total=0.;
815 pcm_total=ov_pcm_total(vf,-1);
816 time_total=ov_time_total(vf,-1);
818 /* which bitstream section does this time offset occur in? */
819 for(link=vf->links-1;link>=0;link--){
820 pcm_total-=vf->pcmlengths[link];
821 time_total-=ov_time_total(vf,link);
822 if(vf->pcm_offset>pcm_total)break;
826 return(time_total+(vf->pcm_offset-pcm_total)/vf->vi[link].rate);
829 /* link: -1) return the vorbis_info struct for the bitstream section
830 currently being decoded
831 0-n) to request information for a specific bitstream section
833 In the case of a non-seekable bitstream, any call returns the
834 current bitstream. NULL in the case that the machine is not
837 vorbis_info *ov_info(OggVorbis_File *vf,int link){
841 return vf->vi+vf->current_link;
857 /* up to this point, everything could more or less hide the multiple
858 logical bitstream nature of chaining from the toplevel application
859 if the toplevel application didn't particularly care. However, at
860 the point that we actually read audio back, the multiple-section
861 nature must surface: Multiple bitstream sections do not necessarily
862 have to have the same number of channels or sampling rate.
864 ov_read returns the sequential logical bitstream number currently
865 being decoded along with the PCM data in order that the toplevel
866 application can take action on channel/sample rate changes. This
867 number will be incremented even for streamed (non-seekable) streams
868 (for seekable streams, it represents the actual logical bitstream
869 index within the physical bitstream. Note that the accessor
870 functions above are aware of this dichotomy).
872 input values: buffer) a buffer to hold packed PCM data for return
873 length) the byte length requested to be placed into buffer
874 bigendianp) should the data be packed LSB first (0) or
876 word) word size for output. currently 1 (byte) or
879 return values: -1) error/hole in data
881 n) number of bytes of PCM actually returned. The
882 below works on a packet-by-packet basis, so the
883 return length is not related to the 'length' passed
884 in, just guaranteed to fit.
886 *section) set to the logical bitstream number */
888 long ov_read(OggVorbis_File *vf,char *buffer,int length,
889 int bigendianp,int word,int sgned,int *bitstream){
893 if(vf->decode_ready){
895 long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
897 /* yay! proceed to pack data into the byte buffer */
899 long channels=ov_info(vf,-1)->channels;
900 long bytespersample=word * channels;
901 if(samples>length/bytespersample)samples=length/bytespersample;
903 /* a tight loop to pack each size */
906 int off=(sgned?0:128);
907 for(j=0;j<samples;j++)
908 for(i=0;i<channels;i++){
909 int val=rint(pcm[i][j]*128.);
911 if(val<-128)val=-128;
915 int off=(sgned?0:32768);
918 for(j=0;j<samples;j++)
919 for(i=0;i<channels;i++){
920 int val=rint(pcm[i][j]*32768.);
921 if(val>32767)val=32767;
922 if(val<-32768)val=-32768;
925 *buffer++=(val&0xff);
928 for(j=0;j<samples;j++)
929 for(i=0;i<channels;i++){
930 int val=rint(pcm[i][j]*32768.);
931 if(val>32767)val=32767;
932 if(val<-32768)val=-32768;
934 *buffer++=(val&0xff);
942 vorbis_synthesis_read(&vf->vd,samples);
943 vf->pcm_offset+=samples;
944 *bitstream=vf->current_link;
945 return(samples*bytespersample);
949 /* suck in another packet */
950 switch(_process_packet(vf,1)){