[theora] Indexing Ogg files for faster seeking

Chris Pearce chris at pearce.org.nz
Tue Oct 20 13:42:47 PDT 2009


Back by popular demand, a new version of OggIndex, which encapsulates 
the keyframe index in the skeleton track. Available here: 
http://github.com/cpearce/OggIndex/tree/skeleton-index-per-stream

I added a few fields to the skeleton ident header, and added "index" 
packets after the "fisbone" packets. I increased the skeleton version 
field to 3.1. Below is the skeleton track specification I used.


Skeleton 3.1 Spec - Includes one "index" packet per stream.
Skeleton header packet:
1. Identifier: 8 bytes, "fishead\0".
2. Version major: 2 Byte unsigned integer signifying the major (3)
3. Version minor: 2 Byte unsigned integer signifying the minor (1)
4. Presentationtime numerator: 8 Byte signed integer
5. Presentationtime denominator: 8 Byte signed integer
6. Basetime numerator: 8 Byte signed integer
7. Basetime denominator: 8 Byte signed integer
8. UTC [ISO8601]: a 20 Byte string containing a UTC time
9. [NEW] Start time, the presentation time in milliseconds of the
     first sample in the media. 8 byte signed integer, -1 if unknown.
     Note that samples between the Start time and the Presentationtime
     are not supposed to be shown.
10. [NEW] End time, the end time of the last sample in the media.
     8 byte signed integer, -1 if unknown.
11. [NEW] The length of the segment, in bytes: 8 byte signed integer,
     -1 if unknown.
Skeleton 'fisbone\0' packets as per skeleton track 3.0, one per stream.
[NEW] Skeleton index packets. There should be one per content stream, 
coming after the fisbone packets, before the skeleton eos packet:
1. Identifier 6 bytes: "index\0"
2. The serialno of the stream as a 4 byte field.
3. The number of keypoints in the index packet, 'n' as a 4 byte
    unsigned integer. This can be 0.
4. 'n' key points, each of which contain, in the following order:
     - the page's byte offset as an 8 byte unsigned integer, followed by
     - the checksum of the page found at the offset, as a 4 byte field,
       followed by
     - the presentation time in milliseconds of the key point, as an 8
       byte unsigned integer.

Existing player compatibility with index-in-skeleton and 
index-in-index-track files:

    * Firefox 3.5.3 plays the index-in-skeleton files, purely by luck,
      whereas it can't get the duration of index-in-index-track files
      due to a bug in liboggz. Firefox3.5 uses liboggplay, which assumes
      any skeleton packet which doesn't have "fishead" magic bytes is a
      "fisbone" packet. It's possible that a skeleton index packet would
      break FF3.5 due to being parsed as a fisbone packet. So regardless
      of which approach we took, we'd have to patch Firefox 3.5.x.
    * The ogg DirectShow codecs work ok with index-in-skeleton files,
      but seeks in index-in-index-track files result in a seek to 0.
    * VLC - plays both index-in-skeleton and index-in-index-track
      files,  but seeks to 0 in index-in-skeleton files result in the
      video window disappearing, but the media can still be played again
      after this happens.
    * XiphQT - plays and seeks (inside buffered ranges) with both types
      of files
    * Totem/gstreamer - with both index-in-skeleton and
      index-in-index-track files, Totem/gstreamer prompts for a missing
      plugin on load, but will still play the file. All seeks just reset
      playback position to 0. I assume gstreamer must be checking the
      skeleton version field, and/or prompting when it reads the
      packets/tracks with unrecognized magic bytes.

Firefox index-in-skeleton capable builds available for download here:
http://build.mozilla.org/tryserver-builds/cpearce@mozilla.com-try-b7b626658548

Indexed videos for testing available here:
http://pearce.org.nz/video/


Chris P.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.xiph.org/pipermail/theora/attachments/20091021/62b2b58d/attachment.htm 


More information about the theora mailing list