Although each packet of data in a logical stream theoretically has a
specific granule position, only one granule position is encoded
per page. It is possible to encode a logical stream such that each
page contains only a single packet (so that granule positions are
preserved for each packet), however a one-to-one packet/page mapping
is not intended to be the general case.<p>
Because Ogg functions at the page, not packet, level, this
once-per-page time information provides Ogg with the finest-grained
time information is can use. Ogg passes this granule positioning data
to the codec (along with the packets extracted from a page); it is
intended to be the responsibility of codecs to track timing
information at granularities finer than a single page.<p>
<h3>start-time and end-time positioning</h3>
A granule position represents the <em>instantaneous time location
between two pages</em>. In an "end-time" encoded page, the granulepos
represents the point in time immediately after the last data decoded
from a page. In a "start-time" encoded page, it represents the point
in time immediately before the first data decoded from the page.<p>
Start-time or end-time positioning is flagged in bit 3 of byte 5 in the
Ogg page header. A set bit indicates start-time positioning. Version 0
Ogg streams are restricted to using end-time positioning; version 1 may
use either or both start-time and end-time positioning. A single logical stream
within the multiplexed physical Ogg version 1 stream may also mix
start-time and end-time positioning.<p>
Start- and end-time do not affect multiplexing sort-order; pages are
still sorted by the absolute time a given granulepos maps to
regardless of whether that granulepos prepresents start- or
end-time.<p>
<h4>use of end-time positioning</h4>
End-time positioning is most useful in unmultiplexed streams. It allows
two useful features relatively more easily:
<ol>
<li>"short" beginning-of-stream and end-of-stream packets can be represented entirely using granulepos; the codec does not need to store auxiliary sizing information in the codec's data packets.<br>
<li>Retrieving the exact end-time of a stream is the trivial operation of inspecting the granule posiiton of the last page.<br>
</ol>
However, end-time coding results in sightly less efficient buffering
usage in a multiplexed stream.
<h4>use of start-time positioning</h4>
Multiplexed streams of start-time encoded pages yield optimal
buffering behavior; it requires the minimum theoretical buffer space
of any possible arrangement of pages. This is the primary benefit of
start-time positioning.<p>
The drawbacks of start-time positioning mirror the benefits attributed to
end-time positioning. Namely:<p>
<ol>
<li>
Codecs that generate short packets can no longer infer the presence of
a short packet from granulepos context; the 'shortness' of the packet
must be encoded in the packet itself. This drawback is minor, however
it does mean that codecs like Vorbis (which relies on granpos context
to detect sort packets) absolutely must use end-time positioning to
handle short packets.<br>
<li>
Determining ending time position of a stream requires slightly more
work than in an end-time encoded stream; the packets of the final
stream page must be counted forward to find ending time.
<br>
</ol>
Despite these minor drawbacks, the additional buffer efficiency of
start-time positioning strongly recommends its use in both multiplexed
and unmultiplexed streams. Use of end-time positioning should largely be
treated as a legacy means of supporting codecs that use
granulepos-context to determine short packets (such as Vorbis I).<p>
<h4>mixed start-time and end-time positioning</h4>
Mixed positioning may refer to either multiplexing two or more streams
that use different time positionings, or using more than one time
positioning within a logical stream. <p>
Mixed positioning mostly affects only buffer efficiency; although
end-time positioning is less efficient than start-time, mixed-time
positioning will often be less efficient than both. The inefficiency is
relative however; buffer efficiency can still be excellent in all
three cases.<p>
One possible use of mixed-time positioning is combine the benefits of
end-time and start-time positioning, for example, use start-time positioning
for all but the last page of a stream, which is then coded in end-time
format. This way, a short packet can be flagged using granulepos
context and the end-time position of the stream is immediately obvious
from inspecting the last granule position.<p>
[POINT OF DISCUSSION: the above suggestion looks like it may be worth
considering as the suggested way of positioning the stream, thus doing
away entirely with the need to 'count time forward through packets' on
the last page of a start-time encoded stream to find final steam
length. However, a truncated stream will be missing the end-time last
page.
1) We could say 'mixed time is the way to go' and just let a
damaged/truncated stream suffer.
2) We could say 'counting time forward through packets is just the way
it has to be done' and do away with the possibility of mixed coding