[vorbis-dev] Calculating vorbis packet durations...

Michael Smith msmith at xiph.org
Tue May 18 18:02:31 PDT 2004



On Tuesday 18 May 2004 22:40, illiminable wrote:
> ----- Original Message -----
> From: "Adriano Almeida" <adriano at continuum.com.br>
> To: <vorbis-dev at xiph.org>
> Sent: Tuesday, May 18, 2004 8:15 PM
> Subject: Re: [vorbis-dev] Calculating vorbis packet durations...
>
> > I had this problem and after a "few"searches I came to this method:
> >
> > first decode and setup the ogg file until the point u find the modes
> > configuration.
> >
> > If u have the previous page, save the granule postition.
>
> That's what i'm currently doing, but it's a problem after a seek
> particularly in multi-stream files, as you need to find a previous page of
> all streams which is not practical.

You can do without this stage, so that's ok. 

>
> > while( !endOfPackets)
> >     {
> >     getPacket;
> >     check if this is and audio packet;
> >     read window configurations;
>
> What is this window configurations... i'm not very familiar with the vorbis
> packet structure, as i use a wrapper to libvorbis. Could you perhaps tell
> me what the field names (or their byte positions ) in the packet are for
> this ?

These are the block sizes. You don't need to directly access this if you're 
using libvorbis, as there's a convenience function: 
vorbis_packet_blocksize(). You still need the previous packet blocksize to 
use this for granulepos calculations, though. 

>
> >     thisPacketSize = previousPacketWindowSize/4+ thisPacketWindowSize/4;
>
> So this means that you still can't get an accurate result without the
> previous page ?

You need the previous _packet_ to get an accurate value (actually, that's not 
strictly true - you need the previous packet block size, but that's given by 
a flag in the current packet - so you can figure it out if you need to. I 
don't think libvorbis has a function to do this). 

But you also need that previous packet to be able to decode this packet 
usefully, so that's not a problem. (Specifically: you can decode the packet 
anyway, but unless you've also decoded the previous packet, you can't get any 
audio output from it). So: if you needed to actually start playback from this 
(current) packet, you would have seeked to the previous packet (if it was on 
a different page), and so you wouldn't have this problem.

Here's what I would do to calculate granulepos for each vorbis packet in a 
page:

For each packet in the page:
  Calculate granulepos increment (prevWindowSize/4 + thisWindowSize/4). Store 
in a temp array.

Now, add all the values in your temp array: this is the total granulepos 
increment for this page. Call that pageIncrement.

If it's an EOS page, things are more complex: I think for this single case, 
you'll need the previous page granulepos as well.

If it isn't: Calculate the initial page granulepos (this is roughly equivalent 
to the granulepos of the previous page, except in corner cases (like the 
first page, which has no previous page)) as pageGranulepos - pageIncrement. 
This _can_ be negative or zero for the first page.

Then, the granulepos for each packet is trivially calculated from the 
granulepos increments in your temp array, and the initial page granulepos.

This just leaves the nasty EOS page case. In this case, you do need the 
previous page granulepos. You should use this previous page granulepos as 
your initial page granulepos in this case (this will NOT be the same as the 
granulepos calculated for the normal case). Then, you must clamp granulepos 
values for the packets on this page to the page granulepos values (this 
should result in only clamping the final packet on the page).

Most of the complexity here is in the EOS handling, which is neccesary because 
of how vorbis handles 'short packets'. 

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'vorbis-dev-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the Vorbis-dev mailing list