troyou
troyou

Reputation: 190

How to calculate sampleTime and sampleDuration with ogg file

I have create ogg decoder in media foundation.

I have read some packets as a sample (compress data), now I need to know the sample' time and sample's duration.

Now I know the AvgBytesPerSec and SamplesPerSec and so on, but this parameters are use for uncompress data.

so how can get IMFSample's time and duration by use compress data ?

Upvotes: 2

Views: 2474

Answers (1)

ioctlLR
ioctlLR

Reputation: 1232

I'll assume you know a few things before answering:

  • How to read the Vorbis setup packets (1st and 3rd in the stream):
    • Sample Rate
    • Decoding parameters (specifically the block sizes and modes)
  • How to read Vorbis audio packet headers:
    • Validation bit
    • Mode selection
  • How to calculate the current timestamp for uncompressed PCM data based on sample number.
  • How to calculate the duration of a buffer of uncompressed PCM data based on sample count.

The Vorbis Specification should help with the first two. Since you are not decoding the audio, you can safely discard the time, floor, residue, and mapping configuration after you've read it in (technically you can discard the codebooks as well, but only after you've read the floor configuration in).

Granule Position and Sample Position are interchangable terms in Vorbis.

To calculate the number of samples in a packet, add the current packet's block size to the previous packet's block size, then divide by 4. There are two exceptions to this: The first audio packet is empty (0 samples), and the last audio packet's size is calculated by subtracting the second last page's granule position from the last page's granule position.

To calculate the last sample position of a packet, use the following logic:

  1. The first audio packet in the stream is 0.
  2. The last full audio packet in a page is the page's granule position (including the last page)
  3. Packets in the middle of a page are calculated from the page's granule position. Start at the granule position of the last full audio packet in the page, then subtract the number of samples in each packet after the one you are calculating for.
  4. If you need the initial position of a packet, use the granule position of the previous packet.

If you need an example of how this is all done, you might try reading through this one (public domain, C). If that doesn't help, I have a from-scratch implementation in C# that I can link to.

Upvotes: 2

Related Questions