[theora] oggz reading & seeking

Chris Pearce chris at pearce.org.nz
Fri Aug 28 06:12:34 PDT 2009

On 8/27/2009 9:43 AM, Manolache Adrian wrote:
 > I'm wondering if i am missing something obvious.

I'd guess you're missing something non-obvious!

However, your code after oggz_seek_units() is non-optimal. It's reading 
whatever packet is 1/4 of the way behind the read cursor, and if the 
first packet at that point isn't a keyframe, it jumps back 1/4 of the 
way to the original byteOffset. You need a more reasoned approach - 
you'll likely skip past previous keyframe packets with this appraoch.

Also oggz_tell_granulepos() returns the gp of the last page read, which 
is the gp of the last packet on that page. If there's an interframe 
packet on the page after the keyframe, that page's gp won't have a 0 
offset, despite containing a keyframe. So you could be pass over a 
keyframe packet without knowing it. The page with offset-0 gp is also 
where the keyframe ends, it may start on a previous page!

You should use th_packet_iskeyframe() to determine if a theora *packet* 
is a keyframe. You also don't need to decode the packets (using 
th_decode_packetin()) until you find the keyframe.

Chris P.

On 8/27/2009 9:43 AM, Manolache Adrian wrote:
> Thanks a lot you guys! I am using liboggz and i need this for playback
> from disk. I tried patching my liboggz with the patches mentioned by
> Chris but haven't had any luck(tried skipping the files that we're not
> there but always got a malformed patch file error when no more skipping
> could be done).
> So after reading the URL's you posted i tried using the not so fast
> method described here
> http://lists.xiph.org/pipermail/theora/2009-July/002544.html. I've been
> successuful in eliminating the artefacts but it is rather slow.
> I tried implementing the following approach then:
> 1.0 seek to time t, retrieve current byteOffset (with oggz_tell) and
> currentFrame
> 2.0 repeat until the offset of the current frame is not 0(beginning of
> the frame)
> -> read data until a full packet is formed
> -> extract frame and offset from this packet, if frame=currentFrame and
> offset is 0
> then stop, else decide in which direction to seek(forward if
> frame<currentFrame, or backward if offset>0 and frame=currentFrame)
> Every time curretByteOffset is incremented(with a value that gets halfed
> now, if we seeked before currentFrame and/) or decremented so this
> process is reasonably fast.
> I do get some artefacts though, even if this method is faster. I'm
> wondering if i am missing something obvious. Here is some code if that
> would help better understand the approach i am using:
> The seek routine(the numbers are just for testing).
> http://pastebin.com/m25e13603
> and everytime a video packet arrives i call this function:
> http://pastebin.com/m1ac79d2b
> --- On *Mon, 8/24/09, Chris Pearce /<chris at pearce.org.nz>/* wrote:
>     From: Chris Pearce <chris at pearce.org.nz>
>     Subject: Re: [theora] oggz reading & seeking
>     To: "Manolache Adrian" <prog_ady at yahoo.com>
>     Cc: theora at xiph.org
>     Date: Monday, August 24, 2009, 6:23 PM
>     Your decode will be encountering only interframes after the seek. It
>     will return garbage until it encounters a keyframe. As ogg.k.ogg.k
>     says, you need to seek back to the previous keyframe and decode
>     forwards from there.
>     I fixed this in Firefox's HTML video element implementation. There's
>     a patch in this bug: https://bugzilla.mozilla.org/show_bug.cgi?id=463358
>     which you may find useful. This uses the double-bisect method ogg.k
>     mentioned. It still fails in some cases, due to these reasons:
>     http://lists.xiph.org/pipermail/theora/2009-July/002549.html
>     Seeking is hard.
>     Another solution is here, but it's not as fast on local files:
>     http://lists.xiph.org/pipermail/theora/2009-July/002544.html
>     Chris P.
>     On 8/24/2009 7:06 AM, Manolache Adrian wrote:
>      > I've rewritten my theora player using liboggz. I've stumbled upon a
>      > few issues though. First of all liboggz exposes oggz_read and
>     oggz_run,
>      > but how can i read only sound data, or only video data using liboggz,
>      > say something like this: oggz_read_sound(1024),
>     oggz_read_video(1024).
>      > Second of all i tried using liboggz's seek function. Immediately
>     after
>      > the seek i get some "garbage" frames: how can i address this issue?
>      >
>      >
>      >
>      >
>     ------------------------------------------------------------------------
>      >
>      > _______________________________________________
>      > theora mailing list
>      > theora at xiph.org </mc/compose?to=theora at xiph.org>
>      > http://lists.xiph.org/mailman/listinfo/theora
> start: 0000-00-00 end: 0000-00-00

More information about the theora mailing list