Hi Zen,
For starters, if you want to get proper a/v sync from an exact timepoint,
you need to have decoded a few packets preceeding that timepoint. For
vorbis, you need to roll back 2 packets to accomodate the overlap-add.
For theora, you need to roll back to the preceeding keyframe. Once you've
done that, you must feed the encoded data into your decoder. You can throw
away the frames of audio and video generated prior to the target timepoint,
but you have to pass the packet data through the decoder in order for the
decode state to get set up properly.
The reason I mention that first is that what you *don't* want is to somehow
byte-seek to the exact packet that "contains" the target timepoint,
and
then start reading and expect the a/v to decode perfectly and in sync.
And, before someone else jumps in with the idea of making the granulepos
indicate the start-time of the packet, no, that doesn't help at all and
would only make seeking more inefficient :)
So, the right thing to do is:
0. ensure that your decoders always tell your a/v engine whatever
timestamps they see while reading, as well as adding on the
number of generated frames
1. seek to about where you want to be, by granulepos markers.
2. scan back by a bit. Either just seek back some random amount,
(you're close enough already that you might as well just
resync a few K back or so :) or scan back through the packets.
3. start reading and decoding, throwing away the generated frames.
a few timestamps will pass by, you'll passed a keyframe and at
least 2 vorbis frames ...
4. once you figure you're at the correct playback time, start
actually sending the frames onwards.
You *need* to do that to actually get the right a/v data. The two streams
aren't frame clocked, they have different granulerates, and they have
different prebuffering requirements. But all you should need to do is
give the a/v engine the decoded data with timestamps -- it's its job to
actually render the decoded streams synchronously.
good luck :)
Conrad.
On Wed, May 05, 2004 at 04:32:28PM +0800, illiminable
wrote:> OK... i've come across a problem trying to get the granule pos of the
start
> of the page... it's not so crucial with single stream ogg files... but
now
> that i have theora+vorbis in a file, i'm finding that when i seek to a
> position, i have no way to determine the relative offsets of the different
> streams at the new seek point and hence the av is out of sync.
>
> So given a page, is it possible to determine the start time... or do i have
> to code this separately for each codec and decode the page determine the
> quantity of data and then subtract it ? Or else scan backwards looking for
> each of the other streams and use a previous page endpoint as a start point
> for the page i actaully want to know about.
>
> The problem with using previous pages is that if the page you want to know
> about has a part of a packet from the previous page... then it's
actually
> the last packet on the previous page that starts at that time.
>
> Is there an easy solution for this ?
>
> Cheers,
>
> Zen
>
>
> --- >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
'theora-dev-request@xiph.org'
> containing only the word 'unsubscribe' in the body. No subject is
needed.
> Unsubscribe messages sent to the list will be ignored/filtered.
--- >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
'theora-dev-request@xiph.org'
containing only the word 'unsubscribe' in the body. No subject is
needed.
Unsubscribe messages sent to the list will be ignored/filtered.