xref: /aosp_15_r20/external/libogg/doc/ogg-multiplex.html (revision 4d5d8b54cec1a9622d79143ad0e145ea73da2224)
1*4d5d8b54SAndroid Build Coastguard Worker<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
2*4d5d8b54SAndroid Build Coastguard Worker<html>
3*4d5d8b54SAndroid Build Coastguard Worker<head>
4*4d5d8b54SAndroid Build Coastguard Worker
5*4d5d8b54SAndroid Build Coastguard Worker<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15"/>
6*4d5d8b54SAndroid Build Coastguard Worker<title>Ogg Documentation</title>
7*4d5d8b54SAndroid Build Coastguard Worker
8*4d5d8b54SAndroid Build Coastguard Worker<style type="text/css">
9*4d5d8b54SAndroid Build Coastguard Workerbody {
10*4d5d8b54SAndroid Build Coastguard Worker  margin: 0 18px 0 18px;
11*4d5d8b54SAndroid Build Coastguard Worker  padding-bottom: 30px;
12*4d5d8b54SAndroid Build Coastguard Worker  font-family: Verdana, Arial, Helvetica, sans-serif;
13*4d5d8b54SAndroid Build Coastguard Worker  color: #333333;
14*4d5d8b54SAndroid Build Coastguard Worker  font-size: .8em;
15*4d5d8b54SAndroid Build Coastguard Worker}
16*4d5d8b54SAndroid Build Coastguard Worker
17*4d5d8b54SAndroid Build Coastguard Workera {
18*4d5d8b54SAndroid Build Coastguard Worker  color: #3366cc;
19*4d5d8b54SAndroid Build Coastguard Worker}
20*4d5d8b54SAndroid Build Coastguard Worker
21*4d5d8b54SAndroid Build Coastguard Workerimg {
22*4d5d8b54SAndroid Build Coastguard Worker  border: 0;
23*4d5d8b54SAndroid Build Coastguard Worker}
24*4d5d8b54SAndroid Build Coastguard Worker
25*4d5d8b54SAndroid Build Coastguard Worker#xiphlogo {
26*4d5d8b54SAndroid Build Coastguard Worker  margin: 30px 0 16px 0;
27*4d5d8b54SAndroid Build Coastguard Worker}
28*4d5d8b54SAndroid Build Coastguard Worker
29*4d5d8b54SAndroid Build Coastguard Worker#content p {
30*4d5d8b54SAndroid Build Coastguard Worker  line-height: 1.4;
31*4d5d8b54SAndroid Build Coastguard Worker}
32*4d5d8b54SAndroid Build Coastguard Worker
33*4d5d8b54SAndroid Build Coastguard Workerh1, h1 a, h2, h2 a, h3, h3 a, h4, h4 a {
34*4d5d8b54SAndroid Build Coastguard Worker  font-weight: bold;
35*4d5d8b54SAndroid Build Coastguard Worker  color: #ff9900;
36*4d5d8b54SAndroid Build Coastguard Worker  margin: 1.3em 0 8px 0;
37*4d5d8b54SAndroid Build Coastguard Worker}
38*4d5d8b54SAndroid Build Coastguard Worker
39*4d5d8b54SAndroid Build Coastguard Workerh1 {
40*4d5d8b54SAndroid Build Coastguard Worker  font-size: 1.3em;
41*4d5d8b54SAndroid Build Coastguard Worker}
42*4d5d8b54SAndroid Build Coastguard Worker
43*4d5d8b54SAndroid Build Coastguard Workerh2 {
44*4d5d8b54SAndroid Build Coastguard Worker  font-size: 1.2em;
45*4d5d8b54SAndroid Build Coastguard Worker}
46*4d5d8b54SAndroid Build Coastguard Worker
47*4d5d8b54SAndroid Build Coastguard Workerh3 {
48*4d5d8b54SAndroid Build Coastguard Worker  font-size: 1.1em;
49*4d5d8b54SAndroid Build Coastguard Worker}
50*4d5d8b54SAndroid Build Coastguard Worker
51*4d5d8b54SAndroid Build Coastguard Workerli {
52*4d5d8b54SAndroid Build Coastguard Worker  line-height: 1.4;
53*4d5d8b54SAndroid Build Coastguard Worker}
54*4d5d8b54SAndroid Build Coastguard Worker
55*4d5d8b54SAndroid Build Coastguard Worker#copyright {
56*4d5d8b54SAndroid Build Coastguard Worker  margin-top: 30px;
57*4d5d8b54SAndroid Build Coastguard Worker  line-height: 1.5em;
58*4d5d8b54SAndroid Build Coastguard Worker  text-align: center;
59*4d5d8b54SAndroid Build Coastguard Worker  font-size: .8em;
60*4d5d8b54SAndroid Build Coastguard Worker  color: #888888;
61*4d5d8b54SAndroid Build Coastguard Worker  clear: both;
62*4d5d8b54SAndroid Build Coastguard Worker}
63*4d5d8b54SAndroid Build Coastguard Worker</style>
64*4d5d8b54SAndroid Build Coastguard Worker
65*4d5d8b54SAndroid Build Coastguard Worker</head>
66*4d5d8b54SAndroid Build Coastguard Worker
67*4d5d8b54SAndroid Build Coastguard Worker<body>
68*4d5d8b54SAndroid Build Coastguard Worker
69*4d5d8b54SAndroid Build Coastguard Worker<div id="xiphlogo">
70*4d5d8b54SAndroid Build Coastguard Worker  <a href="http://www.xiph.org/"><img src="fish_xiph_org.png" alt="Fish Logo and Xiph.org"/></a>
71*4d5d8b54SAndroid Build Coastguard Worker</div>
72*4d5d8b54SAndroid Build Coastguard Worker
73*4d5d8b54SAndroid Build Coastguard Worker<h1>Page Multiplexing and Ordering in a Physical Ogg Stream</h1>
74*4d5d8b54SAndroid Build Coastguard Worker
75*4d5d8b54SAndroid Build Coastguard Worker<p>The low-level mechanisms of an Ogg stream (as described in the Ogg
76*4d5d8b54SAndroid Build Coastguard WorkerBitstream Overview) provide means for mixing multiple logical streams
77*4d5d8b54SAndroid Build Coastguard Workerand media types into a single linear-chronological stream. This
78*4d5d8b54SAndroid Build Coastguard Workerdocument specifies the high-level arrangement and use of page
79*4d5d8b54SAndroid Build Coastguard Workerstructure to multiplex multiple streams of mixed media type within a
80*4d5d8b54SAndroid Build Coastguard Workerphysical Ogg stream.</p>
81*4d5d8b54SAndroid Build Coastguard Worker
82*4d5d8b54SAndroid Build Coastguard Worker<h2>Design Elements</h2>
83*4d5d8b54SAndroid Build Coastguard Worker
84*4d5d8b54SAndroid Build Coastguard Worker<p>The design and arrangement of the Ogg container format is governed by
85*4d5d8b54SAndroid Build Coastguard Workerseveral high-level design decisions that form the reasoning behind
86*4d5d8b54SAndroid Build Coastguard Workerspecific low-level design decisions.</p>
87*4d5d8b54SAndroid Build Coastguard Worker
88*4d5d8b54SAndroid Build Coastguard Worker<h3>Linear media</h3>
89*4d5d8b54SAndroid Build Coastguard Worker
90*4d5d8b54SAndroid Build Coastguard Worker<p>The Ogg bitstream is intended to encapsulate chronological,
91*4d5d8b54SAndroid Build Coastguard Workertime-linear mixed media into a single delivery stream or file. The
92*4d5d8b54SAndroid Build Coastguard Workerdesign is such that an application can always encode and/or decode a
93*4d5d8b54SAndroid Build Coastguard Workerfull-featured bitstream in one pass with no seeking and minimal
94*4d5d8b54SAndroid Build Coastguard Workerbuffering. Seeking to provide optimized encoding (such as two-pass
95*4d5d8b54SAndroid Build Coastguard Workerencoding) or interactive decoding (such as scrubbing or instant
96*4d5d8b54SAndroid Build Coastguard Workerreplay) is not disallowed or discouraged, however no bitstream feature
97*4d5d8b54SAndroid Build Coastguard Workermust require nonlinear operation on the bitstream.</p>
98*4d5d8b54SAndroid Build Coastguard Worker
99*4d5d8b54SAndroid Build Coastguard Worker<h3>Multiplexing</h3>
100*4d5d8b54SAndroid Build Coastguard Worker
101*4d5d8b54SAndroid Build Coastguard Worker<p>Ogg bitstreams multiplex multiple logical streams into a single
102*4d5d8b54SAndroid Build Coastguard Workerphysical stream at the page level. Each page contains an abstract
103*4d5d8b54SAndroid Build Coastguard Workertime stamp (the Granule Position) that represents an absolute time
104*4d5d8b54SAndroid Build Coastguard Workerlandmark within the stream. After the pages representing stream
105*4d5d8b54SAndroid Build Coastguard Workerheaders (all logical stream headers occur at the beginning of a
106*4d5d8b54SAndroid Build Coastguard Workerphysical bitstream section before any logical stream data), logical
107*4d5d8b54SAndroid Build Coastguard Workerstream data pages are arranged in a physical bitstream in strict
108*4d5d8b54SAndroid Build Coastguard Workernon-decreasing order by chronological absolute time as
109*4d5d8b54SAndroid Build Coastguard Workerspecified by the granule position.</p>
110*4d5d8b54SAndroid Build Coastguard Worker
111*4d5d8b54SAndroid Build Coastguard Worker<p>The only exception to arranging pages in strictly ascending time order
112*4d5d8b54SAndroid Build Coastguard Workerby granule position is those pages that do not set the granule
113*4d5d8b54SAndroid Build Coastguard Workerposition value. This is a special case when exceptionally large
114*4d5d8b54SAndroid Build Coastguard Workerpackets span multiple pages; the specifics of handling this special
115*4d5d8b54SAndroid Build Coastguard Workercase are described later under 'Continuous and Discontinuous
116*4d5d8b54SAndroid Build Coastguard WorkerStreams'.</p>
117*4d5d8b54SAndroid Build Coastguard Worker
118*4d5d8b54SAndroid Build Coastguard Worker<h3>Seeking</h3>
119*4d5d8b54SAndroid Build Coastguard Worker
120*4d5d8b54SAndroid Build Coastguard Worker<p>Ogg is designed to use an interpolated bisection search to
121*4d5d8b54SAndroid Build Coastguard Workerimplement exact positional seeking.  Interpolated bisection search is
122*4d5d8b54SAndroid Build Coastguard Workera spec-mandated mechanism.</p>
123*4d5d8b54SAndroid Build Coastguard Worker
124*4d5d8b54SAndroid Build Coastguard Worker<p><i>An index may improve objective performance, but it seldom
125*4d5d8b54SAndroid Build Coastguard Workerimproves subjective performance outside of a few high-latency use
126*4d5d8b54SAndroid Build Coastguard Workercases and adds no additional functionality as bisection search
127*4d5d8b54SAndroid Build Coastguard Workerdelivers the same functionality for both one- and two-pass stream
128*4d5d8b54SAndroid Build Coastguard Workertypes.  For these reasons, use of indexes is discouraged, except in
129*4d5d8b54SAndroid Build Coastguard Workercases where an index provides demonstrable and noticeable performance
130*4d5d8b54SAndroid Build Coastguard Workerimprovement.</i></p>
131*4d5d8b54SAndroid Build Coastguard Worker
132*4d5d8b54SAndroid Build Coastguard Worker<p>Seek operations are by absolute time; a direct bisection search must
133*4d5d8b54SAndroid Build Coastguard Workerfind the exact time position requested. Information in the Ogg
134*4d5d8b54SAndroid Build Coastguard Workerbitstream is arranged such that all information to be presented for
135*4d5d8b54SAndroid Build Coastguard Workerplayback from the desired seek point will occur at or after the
136*4d5d8b54SAndroid Build Coastguard Workerdesired seek point. Seek operations are neither 'fuzzy' nor
137*4d5d8b54SAndroid Build Coastguard Workerheuristic.</p>
138*4d5d8b54SAndroid Build Coastguard Worker
139*4d5d8b54SAndroid Build Coastguard Worker<p><i>Although key frame handling in video appears to be an exception to
140*4d5d8b54SAndroid Build Coastguard Worker"all needed playback information lies ahead of a given seek",
141*4d5d8b54SAndroid Build Coastguard Workerkey frames can still be handled directly within this indexless
142*4d5d8b54SAndroid Build Coastguard Workerframework. Seeking to a key frame in video (as well as seeking in other
143*4d5d8b54SAndroid Build Coastguard Workermedia types with analogous restraints) is handled as two seeks; first
144*4d5d8b54SAndroid Build Coastguard Workera seek to the desired time which extracts state information that
145*4d5d8b54SAndroid Build Coastguard Workerdecodes to the time of the last key frame, followed by a second seek
146*4d5d8b54SAndroid Build Coastguard Workerdirectly to the key frame. The location of the previous key frame is
147*4d5d8b54SAndroid Build Coastguard Workerembedded as state information in the granulepos; this mechanism is
148*4d5d8b54SAndroid Build Coastguard Workerdescribed in more detail later.</i></p>
149*4d5d8b54SAndroid Build Coastguard Worker
150*4d5d8b54SAndroid Build Coastguard Worker<h3>Continuous and Discontinuous Streams</h3>
151*4d5d8b54SAndroid Build Coastguard Worker
152*4d5d8b54SAndroid Build Coastguard Worker<p>Logical streams within a physical Ogg stream belong to one of two
153*4d5d8b54SAndroid Build Coastguard Workercategories, "Continuous" streams and "Discontinuous" streams.
154*4d5d8b54SAndroid Build Coastguard WorkerAlthough these are discussed in more detail later, the distinction is
155*4d5d8b54SAndroid Build Coastguard Workerimportant to a high-level understanding of how to buffer an Ogg
156*4d5d8b54SAndroid Build Coastguard Workerstream.</p>
157*4d5d8b54SAndroid Build Coastguard Worker
158*4d5d8b54SAndroid Build Coastguard Worker<p>A stream that provides a gapless, time-continuous media type with a
159*4d5d8b54SAndroid Build Coastguard Workerfine-grained timebase is considered to be 'Continuous'. A continuous
160*4d5d8b54SAndroid Build Coastguard Workerstream should never be starved of data. Clear examples of continuous
161*4d5d8b54SAndroid Build Coastguard Workerdata types include broadcast audio and video.</p>
162*4d5d8b54SAndroid Build Coastguard Worker
163*4d5d8b54SAndroid Build Coastguard Worker<p>A stream that delivers data in a potentially irregular pattern or with
164*4d5d8b54SAndroid Build Coastguard Workerwidely spaced timing gaps is considered to be 'Discontinuous'. A
165*4d5d8b54SAndroid Build Coastguard Workerdiscontinuous stream may be best thought of as data representing
166*4d5d8b54SAndroid Build Coastguard Workerscattered events; although they happen in order, they are typically
167*4d5d8b54SAndroid Build Coastguard Workerunconnected data often located far apart. One possible example of a
168*4d5d8b54SAndroid Build Coastguard Workerdiscontinuous stream types would be captioning. Although it's
169*4d5d8b54SAndroid Build Coastguard Workerpossible to design captions as a continuous stream type, it's most
170*4d5d8b54SAndroid Build Coastguard Workernatural to think of captions as widely spaced pieces of text with
171*4d5d8b54SAndroid Build Coastguard Workerlittle happening between.</p>
172*4d5d8b54SAndroid Build Coastguard Worker
173*4d5d8b54SAndroid Build Coastguard Worker<p>The fundamental design distinction between continuous and
174*4d5d8b54SAndroid Build Coastguard Workerdiscontinuous streams concerns buffering.</p>
175*4d5d8b54SAndroid Build Coastguard Worker
176*4d5d8b54SAndroid Build Coastguard Worker<h3>Buffering</h3>
177*4d5d8b54SAndroid Build Coastguard Worker
178*4d5d8b54SAndroid Build Coastguard Worker<p>Because a continuous stream is, by definition, gapless, Ogg buffering
179*4d5d8b54SAndroid Build Coastguard Workeris based on the simple premise of never allowing any active continuous
180*4d5d8b54SAndroid Build Coastguard Workerstream to starve for data during decode; buffering proceeds ahead
181*4d5d8b54SAndroid Build Coastguard Workeruntil all continuous streams in a physical stream have data ready to
182*4d5d8b54SAndroid Build Coastguard Workerdecode on demand.</p>
183*4d5d8b54SAndroid Build Coastguard Worker
184*4d5d8b54SAndroid Build Coastguard Worker<p>Discontinuous stream data may occur on a fairly regular basis, but the
185*4d5d8b54SAndroid Build Coastguard Workertiming of, for example, a specific caption is impossible to predict
186*4d5d8b54SAndroid Build Coastguard Workerwith certainty in most captioning systems. Thus the buffering system
187*4d5d8b54SAndroid Build Coastguard Workershould take discontinuous data 'as it comes' rather than working ahead
188*4d5d8b54SAndroid Build Coastguard Worker(for a potentially unbounded period) to look for future discontinuous
189*4d5d8b54SAndroid Build Coastguard Workerdata. As such, discontinuous streams are ignored when managing
190*4d5d8b54SAndroid Build Coastguard Workerbuffering; their pages simply 'fall out' of the stream when continuous
191*4d5d8b54SAndroid Build Coastguard Workerstreams are handled properly.</p>
192*4d5d8b54SAndroid Build Coastguard Worker
193*4d5d8b54SAndroid Build Coastguard Worker<p>Buffering requirements need not be explicitly declared or managed for
194*4d5d8b54SAndroid Build Coastguard Workerthe encoded stream; the decoder simply reads as much data as is
195*4d5d8b54SAndroid Build Coastguard Workernecessary to keep all continuous stream types gapless (also ensuring
196*4d5d8b54SAndroid Build Coastguard Workerdiscontinuous data arrives in time) and no more, resulting in optimum
197*4d5d8b54SAndroid Build Coastguard Workerimplicit buffer usage for a given stream. Because all pages of all
198*4d5d8b54SAndroid Build Coastguard Workerdata types are stamped with absolute timing information within the
199*4d5d8b54SAndroid Build Coastguard Workerstream, inter-stream synchronization timing is always explicitly
200*4d5d8b54SAndroid Build Coastguard Workermaintained without the need for explicitly declared buffer-ahead
201*4d5d8b54SAndroid Build Coastguard Workerhinting.</p>
202*4d5d8b54SAndroid Build Coastguard Worker
203*4d5d8b54SAndroid Build Coastguard Worker<p>Further details, mechanisms and reasons for the differing arrangement
204*4d5d8b54SAndroid Build Coastguard Workerand behavior of continuous and discontinuous streams is discussed
205*4d5d8b54SAndroid Build Coastguard Workerlater.</p>
206*4d5d8b54SAndroid Build Coastguard Worker
207*4d5d8b54SAndroid Build Coastguard Worker<h3>Whole-stream navigation</h3>
208*4d5d8b54SAndroid Build Coastguard Worker
209*4d5d8b54SAndroid Build Coastguard Worker<p>Ogg is designed so that the simplest navigation operations treat the
210*4d5d8b54SAndroid Build Coastguard Workerphysical Ogg stream as a whole summary of its streams, rather than
211*4d5d8b54SAndroid Build Coastguard Workernavigating each interleaved stream as a separate entity.</p>
212*4d5d8b54SAndroid Build Coastguard Worker
213*4d5d8b54SAndroid Build Coastguard Worker<p>First Example: seeking to a desired time position in a multiplexed (or
214*4d5d8b54SAndroid Build Coastguard Workerunmultiplexed) Ogg stream can be accomplished through a bisection
215*4d5d8b54SAndroid Build Coastguard Workersearch on time position of all pages in the stream (as encoded in the
216*4d5d8b54SAndroid Build Coastguard Workergranule position). More powerful searches (such as a key frame-aware
217*4d5d8b54SAndroid Build Coastguard Workerseek within video) are also possible with additional search
218*4d5d8b54SAndroid Build Coastguard Workercomplexity, but similar computational complexity.</p>
219*4d5d8b54SAndroid Build Coastguard Worker
220*4d5d8b54SAndroid Build Coastguard Worker<p>Second Example: A bitstream section may consist of three multiplexed
221*4d5d8b54SAndroid Build Coastguard Workerstreams of differing lengths. The result of multiplexing these
222*4d5d8b54SAndroid Build Coastguard Workerstreams should be thought of as a single mixed stream with a length
223*4d5d8b54SAndroid Build Coastguard Workerequal to the longest of the three component streams. Although it is
224*4d5d8b54SAndroid Build Coastguard Workeralso possible to think of the multiplexed results as three concurrent
225*4d5d8b54SAndroid Build Coastguard Workerstreams of different lengths and it is possible to recover the three
226*4d5d8b54SAndroid Build Coastguard Workeroriginal streams, it will also become obvious that once multiplexed,
227*4d5d8b54SAndroid Build Coastguard Workerit isn't possible to find the internal lengths of the component
228*4d5d8b54SAndroid Build Coastguard Workerstreams without a linear search of the whole bitstream section.
229*4d5d8b54SAndroid Build Coastguard WorkerHowever, it is possible to find the length of the whole bitstream
230*4d5d8b54SAndroid Build Coastguard Workersection easily (in near-constant time per section) just as it is for a
231*4d5d8b54SAndroid Build Coastguard Workersingle-media unmultiplexed stream.</p>
232*4d5d8b54SAndroid Build Coastguard Worker
233*4d5d8b54SAndroid Build Coastguard Worker<h2>Granule Position</h2>
234*4d5d8b54SAndroid Build Coastguard Worker
235*4d5d8b54SAndroid Build Coastguard Worker<h3>Description</h3>
236*4d5d8b54SAndroid Build Coastguard Worker
237*4d5d8b54SAndroid Build Coastguard Worker<p>The Granule Position is a signed 64 bit field appearing in the header
238*4d5d8b54SAndroid Build Coastguard Workerof every Ogg page. Although the granule position represents absolute
239*4d5d8b54SAndroid Build Coastguard Workertime within a logical stream, its value does not necessarily directly
240*4d5d8b54SAndroid Build Coastguard Workerencode a simple timestamp. It may represent frames elapsed (as in
241*4d5d8b54SAndroid Build Coastguard WorkerVorbis), a simple timestamp, or a more complex bit-division encoding
242*4d5d8b54SAndroid Build Coastguard Worker(such as in Theora). The exact encoding of the granule position is up
243*4d5d8b54SAndroid Build Coastguard Workerto a specific codec.</p>
244*4d5d8b54SAndroid Build Coastguard Worker
245*4d5d8b54SAndroid Build Coastguard Worker<p>The granule position is governed by the following rules:</p>
246*4d5d8b54SAndroid Build Coastguard Worker
247*4d5d8b54SAndroid Build Coastguard Worker<ul>
248*4d5d8b54SAndroid Build Coastguard Worker
249*4d5d8b54SAndroid Build Coastguard Worker<li>Granule Position must always increase forward or remain equal from
250*4d5d8b54SAndroid Build Coastguard Workerpage to page, be unset, or be zero for a header page. The absolute
251*4d5d8b54SAndroid Build Coastguard Workertime to which any correct sequence of granule position maps must
252*4d5d8b54SAndroid Build Coastguard Workersimilarly always increase forward or remain equal. <i>(A codec may
253*4d5d8b54SAndroid Build Coastguard Workermake use of data, such as a control sequence, that only affects codec
254*4d5d8b54SAndroid Build Coastguard Workerworking state without producing data and thus advancing granule
255*4d5d8b54SAndroid Build Coastguard Workerposition and time. Although the packet sequence number increases in
256*4d5d8b54SAndroid Build Coastguard Workerthis case, the granule position, and thus the time position, do
257*4d5d8b54SAndroid Build Coastguard Workernot.)</i></li>
258*4d5d8b54SAndroid Build Coastguard Worker
259*4d5d8b54SAndroid Build Coastguard Worker<li>Granule position may only be unset if there no packet defining a
260*4d5d8b54SAndroid Build Coastguard Workertime boundary on the page (that is, if no packet in a continuous
261*4d5d8b54SAndroid Build Coastguard Workerstream ends on the page, or no packet in a discontinuous stream begins
262*4d5d8b54SAndroid Build Coastguard Workeron the page. This will be discussed in more detail under Continuous
263*4d5d8b54SAndroid Build Coastguard Workerand Discontinuous streams).</li>
264*4d5d8b54SAndroid Build Coastguard Worker
265*4d5d8b54SAndroid Build Coastguard Worker<li>A codec must be able to translate a given granule position value
266*4d5d8b54SAndroid Build Coastguard Workerto a unique, deterministic absolute time value through direct
267*4d5d8b54SAndroid Build Coastguard Workercalculation. A codec is not required to be able to translate an
268*4d5d8b54SAndroid Build Coastguard Workerabsolute time value into a unique granule position value.</li>
269*4d5d8b54SAndroid Build Coastguard Worker
270*4d5d8b54SAndroid Build Coastguard Worker<li>Codecs shall choose a granule position definition that allows that
271*4d5d8b54SAndroid Build Coastguard Workercodec means to seek as directly as possible to an immediately
272*4d5d8b54SAndroid Build Coastguard Workerdecodable point, such as the bit-divided granule position encoding of
273*4d5d8b54SAndroid Build Coastguard WorkerTheora allows the codec to seek efficiently to key frame without using
274*4d5d8b54SAndroid Build Coastguard Workeran index. That is, additional information other than absolute time
275*4d5d8b54SAndroid Build Coastguard Workermay be encoded into a granule position value so long as the granule
276*4d5d8b54SAndroid Build Coastguard Workerposition obeys the above points.</li>
277*4d5d8b54SAndroid Build Coastguard Worker
278*4d5d8b54SAndroid Build Coastguard Worker</ul>
279*4d5d8b54SAndroid Build Coastguard Worker
280*4d5d8b54SAndroid Build Coastguard Worker<h4>Example: timestamp</h4>
281*4d5d8b54SAndroid Build Coastguard Worker
282*4d5d8b54SAndroid Build Coastguard Worker<p>In general, a codec/stream type should choose the simplest granule
283*4d5d8b54SAndroid Build Coastguard Workerposition encoding that addresses its requirements. The examples here
284*4d5d8b54SAndroid Build Coastguard Workerare by no means exhaustive of the possibilities within Ogg.</p>
285*4d5d8b54SAndroid Build Coastguard Worker
286*4d5d8b54SAndroid Build Coastguard Worker<p>A simple granule position could encode a timestamp directly. For
287*4d5d8b54SAndroid Build Coastguard Workerexample, a granule position that encoded milliseconds from beginning
288*4d5d8b54SAndroid Build Coastguard Workerof stream would allow a logical stream length of over 100,000,000,000
289*4d5d8b54SAndroid Build Coastguard Workerdays before beginning a new logical stream (to avoid the granule
290*4d5d8b54SAndroid Build Coastguard Workerposition wrapping).</p>
291*4d5d8b54SAndroid Build Coastguard Worker
292*4d5d8b54SAndroid Build Coastguard Worker<h4>Example: framestamp</h4>
293*4d5d8b54SAndroid Build Coastguard Worker
294*4d5d8b54SAndroid Build Coastguard Worker<p>A simple millisecond timestamp granule encoding might suit many stream
295*4d5d8b54SAndroid Build Coastguard Workertypes, but a millisecond resolution is inappropriate to, eg, most
296*4d5d8b54SAndroid Build Coastguard Workeraudio encodings where exact single-sample resolution is generally a
297*4d5d8b54SAndroid Build Coastguard Workerrequirement. A millisecond is both too large a granule and often does
298*4d5d8b54SAndroid Build Coastguard Workernot represent an integer number of samples.</p>
299*4d5d8b54SAndroid Build Coastguard Worker
300*4d5d8b54SAndroid Build Coastguard Worker<p>In the event that audio frames are always encoded as the same number of
301*4d5d8b54SAndroid Build Coastguard Workersamples, the granule position could simply be a linear count of frames
302*4d5d8b54SAndroid Build Coastguard Workersince beginning of stream. This has the advantages of being exact and
303*4d5d8b54SAndroid Build Coastguard Workerefficient. Position in time would simply be <tt>[granule_position] *
304*4d5d8b54SAndroid Build Coastguard Worker[samples_per_frame] / [samples_per_second]</tt>.</p>
305*4d5d8b54SAndroid Build Coastguard Worker
306*4d5d8b54SAndroid Build Coastguard Worker<h4>Example: samplestamp (Vorbis)</h4>
307*4d5d8b54SAndroid Build Coastguard Worker
308*4d5d8b54SAndroid Build Coastguard Worker<p>Frame counting is insufficient in codecs such as Vorbis where an audio
309*4d5d8b54SAndroid Build Coastguard Workerframe [packet] encodes a variable number of samples. In Vorbis's
310*4d5d8b54SAndroid Build Coastguard Workercase, the granule position is a count of the number of raw samples
311*4d5d8b54SAndroid Build Coastguard Workerfrom the beginning of stream; the absolute time of
312*4d5d8b54SAndroid Build Coastguard Workera granule position is <tt>[granule_position] /
313*4d5d8b54SAndroid Build Coastguard Worker[samples_per_second]</tt>.</p>
314*4d5d8b54SAndroid Build Coastguard Worker
315*4d5d8b54SAndroid Build Coastguard Worker<h4>Example: bit-divided framestamp (Theora)</h4>
316*4d5d8b54SAndroid Build Coastguard Worker
317*4d5d8b54SAndroid Build Coastguard Worker<p>Some video codecs may be able to use the simple framestamp scheme for
318*4d5d8b54SAndroid Build Coastguard Workergranule position. However, most modern video codecs introduce at
319*4d5d8b54SAndroid Build Coastguard Workerleast the following complications:</p>
320*4d5d8b54SAndroid Build Coastguard Worker
321*4d5d8b54SAndroid Build Coastguard Worker<ul>
322*4d5d8b54SAndroid Build Coastguard Worker
323*4d5d8b54SAndroid Build Coastguard Worker<li>video frames are relatively far apart compared to audio samples;
324*4d5d8b54SAndroid Build Coastguard Workerfor this reason, the point at which a video frame changes to the next
325*4d5d8b54SAndroid Build Coastguard Workerframe is usually a strictly defined offset within the frame 'period'.
326*4d5d8b54SAndroid Build Coastguard WorkerThat is, video at 50fps could just as easily define frame transitions
327*4d5d8b54SAndroid Build Coastguard Worker&lt;.015, .035, .055...&gt; as at &lt;.00, .02, .04...&gt;.</li>
328*4d5d8b54SAndroid Build Coastguard Worker
329*4d5d8b54SAndroid Build Coastguard Worker<li>frame rates often include drop-frames, leap-frames or other
330*4d5d8b54SAndroid Build Coastguard Workerrational-but-non-integer timings.</li>
331*4d5d8b54SAndroid Build Coastguard Worker
332*4d5d8b54SAndroid Build Coastguard Worker<li>Decode must begin at a 'key frame' or 'I frame'. Keyframes usually
333*4d5d8b54SAndroid Build Coastguard Workeroccur relatively seldom.</li>
334*4d5d8b54SAndroid Build Coastguard Worker
335*4d5d8b54SAndroid Build Coastguard Worker</ul>
336*4d5d8b54SAndroid Build Coastguard Worker
337*4d5d8b54SAndroid Build Coastguard Worker<p>The first two points can be handled straightforwardly via the fact
338*4d5d8b54SAndroid Build Coastguard Workerthat the codec has complete control mapping granule position to
339*4d5d8b54SAndroid Build Coastguard Workerabsolute time; non-integer frame rates and offsets can be set in the
340*4d5d8b54SAndroid Build Coastguard Workercodec's initial header, and the rest is just arithmetic.</p>
341*4d5d8b54SAndroid Build Coastguard Worker
342*4d5d8b54SAndroid Build Coastguard Worker<p>The third point appears trickier at first glance, but it too can be
343*4d5d8b54SAndroid Build Coastguard Workerhandled through the granule position mapping mechanism. Here we
344*4d5d8b54SAndroid Build Coastguard Workerarrange the granule position in such a way that granule positions of
345*4d5d8b54SAndroid Build Coastguard Workerkey frames are easy to find. Divide the granule position into two
346*4d5d8b54SAndroid Build Coastguard Workerfields; the most-significant bits are an absolute frame counter, but
347*4d5d8b54SAndroid Build Coastguard Workerit's only updated at each key frame. The least significant bits encode
348*4d5d8b54SAndroid Build Coastguard Workerthe number of frames since the last key frame. In this way, each
349*4d5d8b54SAndroid Build Coastguard Workergranule position both encodes the absolute time of the current frame
350*4d5d8b54SAndroid Build Coastguard Workeras well as the absolute time of the last key frame.</p>
351*4d5d8b54SAndroid Build Coastguard Worker
352*4d5d8b54SAndroid Build Coastguard Worker<p>Seeking to a most recent preceding key frame is then accomplished by
353*4d5d8b54SAndroid Build Coastguard Workerfirst seeking to the original desired point, inspecting the granulepos
354*4d5d8b54SAndroid Build Coastguard Workerof the resulting video page, extracting from that granulepos the
355*4d5d8b54SAndroid Build Coastguard Workerabsolute time of the desired key frame, and then seeking directly to
356*4d5d8b54SAndroid Build Coastguard Workerthat key frame's page. Of course, it's still possible for an
357*4d5d8b54SAndroid Build Coastguard Workerapplication to ignore key frames and use a simpler seeking algorithm
358*4d5d8b54SAndroid Build Coastguard Worker(decode would be unable to present decoded video until the next
359*4d5d8b54SAndroid Build Coastguard Workerkey frame). Surprisingly many player applications do choose the
360*4d5d8b54SAndroid Build Coastguard Workersimpler approach.</p>
361*4d5d8b54SAndroid Build Coastguard Worker
362*4d5d8b54SAndroid Build Coastguard Worker<h3>granule position, packets and pages</h3>
363*4d5d8b54SAndroid Build Coastguard Worker
364*4d5d8b54SAndroid Build Coastguard Worker<p>Although each packet of data in a logical stream theoretically has a
365*4d5d8b54SAndroid Build Coastguard Workerspecific granule position, only one granule position is encoded
366*4d5d8b54SAndroid Build Coastguard Workerper page. It is possible to encode a logical stream such that each
367*4d5d8b54SAndroid Build Coastguard Workerpage contains only a single packet (so that granule positions are
368*4d5d8b54SAndroid Build Coastguard Workerpreserved for each packet), however a one-to-one packet/page mapping
369*4d5d8b54SAndroid Build Coastguard Workeris not intended to be the general case.</p>
370*4d5d8b54SAndroid Build Coastguard Worker
371*4d5d8b54SAndroid Build Coastguard Worker<p>Because Ogg functions at the page, not packet, level, this
372*4d5d8b54SAndroid Build Coastguard Workeronce-per-page time information provides Ogg with the finest-grained
373*4d5d8b54SAndroid Build Coastguard Workertime information is can use. Ogg passes this granule positioning data
374*4d5d8b54SAndroid Build Coastguard Workerto the codec (along with the packets extracted from a page); it is the
375*4d5d8b54SAndroid Build Coastguard Workerresponsibility of codecs to track timing information at granularities
376*4d5d8b54SAndroid Build Coastguard Workerfiner than a single page.</p>
377*4d5d8b54SAndroid Build Coastguard Worker
378*4d5d8b54SAndroid Build Coastguard Worker<h3>start-time and end-time positioning</h3>
379*4d5d8b54SAndroid Build Coastguard Worker
380*4d5d8b54SAndroid Build Coastguard Worker<p>A granule position represents the <em>instantaneous time location
381*4d5d8b54SAndroid Build Coastguard Workerbetween two pages</em>. However, continuous streams and discontinuous
382*4d5d8b54SAndroid Build Coastguard Workerstreams differ on whether the granulepos represents the end-time of
383*4d5d8b54SAndroid Build Coastguard Workerthe data on a page or the start-time. Continuous streams are
384*4d5d8b54SAndroid Build Coastguard Worker'end-time' encoded; the granulepos represents the point in time
385*4d5d8b54SAndroid Build Coastguard Workerimmediately after the last data decoded from a page. Discontinuous
386*4d5d8b54SAndroid Build Coastguard Workerstreams are 'start-time' encoded; the granulepos represents the point
387*4d5d8b54SAndroid Build Coastguard Workerin time of the first data decoded from the page.</p>
388*4d5d8b54SAndroid Build Coastguard Worker
389*4d5d8b54SAndroid Build Coastguard Worker<p>An Ogg stream type is declared continuous or discontinuous by its
390*4d5d8b54SAndroid Build Coastguard Workercodec. A given codec may support both continuous and discontinuous
391*4d5d8b54SAndroid Build Coastguard Workeroperation so long as any given logical stream is continuous or
392*4d5d8b54SAndroid Build Coastguard Workerdiscontinuous for its entirety and the codec is able to ascertain (and
393*4d5d8b54SAndroid Build Coastguard Workerinform the Ogg layer) as to which after decoding the initial stream
394*4d5d8b54SAndroid Build Coastguard Workerheader. The majority of codecs will always be continuous (such as
395*4d5d8b54SAndroid Build Coastguard WorkerVorbis) or discontinuous (such as Writ).</p>
396*4d5d8b54SAndroid Build Coastguard Worker
397*4d5d8b54SAndroid Build Coastguard Worker<p>Start- and end-time encoding do not affect multiplexing sort-order;
398*4d5d8b54SAndroid Build Coastguard Workerpages are still sorted by the absolute time a given granulepos maps to
399*4d5d8b54SAndroid Build Coastguard Workerregardless of whether that granulepos represents start- or
400*4d5d8b54SAndroid Build Coastguard Workerend-time.</p>
401*4d5d8b54SAndroid Build Coastguard Worker
402*4d5d8b54SAndroid Build Coastguard Worker<h2>Multiplex/Demultiplex Division of Labor</h2>
403*4d5d8b54SAndroid Build Coastguard Worker
404*4d5d8b54SAndroid Build Coastguard Worker<p>The Ogg multiplex/demultiplex layer provides mechanisms for encoding
405*4d5d8b54SAndroid Build Coastguard Workerraw packets into Ogg pages, decoding Ogg pages back into the original
406*4d5d8b54SAndroid Build Coastguard Workercodec packets, determining the logical structure of an Ogg stream, and
407*4d5d8b54SAndroid Build Coastguard Workernavigating through and synchronizing with an Ogg stream at a desired
408*4d5d8b54SAndroid Build Coastguard Workerstream location. Strict multiplex/demultiplex operations are entirely
409*4d5d8b54SAndroid Build Coastguard Workerin the Ogg domain and require no intervention from codecs.</p>
410*4d5d8b54SAndroid Build Coastguard Worker
411*4d5d8b54SAndroid Build Coastguard Worker<p>Implementation of more complex operations does require codec
412*4d5d8b54SAndroid Build Coastguard Workerknowledge, however. Unlike other framing systems, Ogg maintains
413*4d5d8b54SAndroid Build Coastguard Workerstrict separation between framing and the framed bitstream data; Ogg
414*4d5d8b54SAndroid Build Coastguard Workerdoes not replicate codec-specific information in the page/framing
415*4d5d8b54SAndroid Build Coastguard Workerdata, nor does Ogg blur the line between framing and stream
416*4d5d8b54SAndroid Build Coastguard Workerdata/metadata. Because Ogg is fully data-agnostic toward the data it
417*4d5d8b54SAndroid Build Coastguard Workerframes, operations which require specifics of bitstream data (such as
418*4d5d8b54SAndroid Build Coastguard Worker'seek to key frame') also require interaction with the codec layer
419*4d5d8b54SAndroid Build Coastguard Worker(because, in this example, the Ogg layer is not aware of the concept
420*4d5d8b54SAndroid Build Coastguard Workerof key frames). This is different from systems that blur the
421*4d5d8b54SAndroid Build Coastguard Workerseparation between framing and stream data in order to simplify the
422*4d5d8b54SAndroid Build Coastguard Workerseparation of code. The Ogg system purposely keeps the distinction in
423*4d5d8b54SAndroid Build Coastguard Workerdata simple so that later codec innovations are not constrained by
424*4d5d8b54SAndroid Build Coastguard Workerframing design.</p>
425*4d5d8b54SAndroid Build Coastguard Worker
426*4d5d8b54SAndroid Build Coastguard Worker<p>For this reason, however, complex seeking operations require
427*4d5d8b54SAndroid Build Coastguard Workerinteraction with the codecs in order to decode the granule position of
428*4d5d8b54SAndroid Build Coastguard Workera given stream type back to absolute time or in order to find
429*4d5d8b54SAndroid Build Coastguard Worker'decodable points' such as key frames in video.</p>
430*4d5d8b54SAndroid Build Coastguard Worker
431*4d5d8b54SAndroid Build Coastguard Worker<h2>Unsorted Discussion Points</h2>
432*4d5d8b54SAndroid Build Coastguard Worker
433*4d5d8b54SAndroid Build Coastguard Worker<p>flushes around key frames? RFC suggestion: repaginating or building a
434*4d5d8b54SAndroid Build Coastguard Workerstream this way is nice but not required</p>
435*4d5d8b54SAndroid Build Coastguard Worker
436*4d5d8b54SAndroid Build Coastguard Worker<h2>Appendix A: multiplexing examples</h2>
437*4d5d8b54SAndroid Build Coastguard Worker
438*4d5d8b54SAndroid Build Coastguard Worker<div id="copyright">
439*4d5d8b54SAndroid Build Coastguard Worker  The Xiph Fish Logo is a
440*4d5d8b54SAndroid Build Coastguard Worker  trademark (&trade;) of Xiph.Org.<br/>
441*4d5d8b54SAndroid Build Coastguard Worker
442*4d5d8b54SAndroid Build Coastguard Worker  These pages &copy; 1994 - 2005 Xiph.Org. All rights reserved.
443*4d5d8b54SAndroid Build Coastguard Worker</div>
444*4d5d8b54SAndroid Build Coastguard Worker
445*4d5d8b54SAndroid Build Coastguard Worker</body>
446*4d5d8b54SAndroid Build Coastguard Worker</html>
447