cleanup docs
svn path=/trunk/ogg/; revision=9956
This commit is contained in:
parent
a80448d530
commit
9c524d53c8
BIN
doc/fish_xiph_org.png
Normal file
BIN
doc/fish_xiph_org.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
322
doc/framing.html
322
doc/framing.html
@ -1,23 +1,87 @@
|
||||
<HTML><HEAD><TITLE>xiph.org: Ogg Vorbis documentation</TITLE>
|
||||
<BODY bgcolor="#ffffff" text="#202020" link="#006666" vlink="#000000">
|
||||
<nobr><a href="http://www.xiph.org/ogg/index.html"><img src="white-ogg.png" border=0><img
|
||||
src="vorbisword2.png" border=0></a></nobr><p>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<h1><font color=#000070>
|
||||
Ogg logical bitstream framing
|
||||
</font></h1>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15"/>
|
||||
<title>Ogg Documentation</title>
|
||||
|
||||
<em>Last update to this document: July 14, 2002</em><br>
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin: 0 18px 0 18px;
|
||||
padding-bottom: 30px;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
color: #333333;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #3366cc;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#xiphlogo {
|
||||
margin: 30px 0 16px 0;
|
||||
}
|
||||
|
||||
#content p {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h1, h1 a, h2, h2 a, h3, h3 a, h4, h4 a {
|
||||
font-weight: bold;
|
||||
color: #ff9900;
|
||||
margin: 1.3em 0 8px 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
#copyright {
|
||||
margin-top: 30px;
|
||||
line-height: 1.5em;
|
||||
text-align: center;
|
||||
font-size: .8em;
|
||||
color: #888888;
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="xiphlogo">
|
||||
<a href="http://www.xiph.org/"><img src="fish_xiph_org.png" alt="Fish Logo and Xiph.org"/></a>
|
||||
</div>
|
||||
|
||||
<h1>Ogg logical bitstream framing</h1>
|
||||
|
||||
<h2>Ogg bitstreams</h2>
|
||||
|
||||
The Ogg transport bitstream is designed to provide framing, error
|
||||
<p>The Ogg transport bitstream is designed to provide framing, error
|
||||
protection and seeking structure for higher-level codec streams that
|
||||
consist of raw, unencapsulated data packets, such as the Vorbis audio
|
||||
codec or Tarkin video codec.
|
||||
codec or Tarkin video codec.</p>
|
||||
|
||||
<h2>Application example: Vorbis</h2>
|
||||
Vorbis encodes short-time blocks of PCM data into raw packets of
|
||||
|
||||
<p>Vorbis encodes short-time blocks of PCM data into raw packets of
|
||||
bit-packed data. These raw packets may be used directly by transport
|
||||
mechanisms that provide their own framing and packet-separation
|
||||
mechanisms (such as UDP datagrams). For stream based storage (such as
|
||||
@ -25,29 +89,24 @@ files) and transport (such as TCP streams or pipes), Vorbis uses the
|
||||
Ogg bitstream format to provide framing/sync, sync recapture
|
||||
after error, landmarks during seeking, and enough information to
|
||||
properly separate data back into packets at the original packet
|
||||
boundaries without relying on decoding to find packet boundaries.<p>
|
||||
boundaries without relying on decoding to find packet boundaries.</p>
|
||||
|
||||
<h2>Design constraints for Ogg bitstreams</h2>
|
||||
|
||||
<ol><li>True streaming; we must not need to seek to build a 100%
|
||||
complete bitstream.
|
||||
|
||||
<li> Use no more than approximately 1-2% of bitstream bandwidth for
|
||||
packet boundary marking, high-level framing, sync and seeking.
|
||||
|
||||
<li> Specification of absolute position within the original sample
|
||||
stream.
|
||||
|
||||
<li> Simple mechanism to ease limited editing, such as a simplified
|
||||
concatenation mechanism.
|
||||
|
||||
<li> Detection of corruption, recapture after error and direct, random
|
||||
access to data at arbitrary positions in the bitstream.
|
||||
<ol>
|
||||
<li>True streaming; we must not need to seek to build a 100% complete bitstream.</li>
|
||||
<li>Use no more than approximately 1-2% of bitstream bandwidth for packet
|
||||
boundary marking, high-level framing, sync and seeking.</li>
|
||||
<li>Specification of absolute position within the original sample stream.</li>
|
||||
<li>Simple mechanism to ease limited editing, such as a simplified concatenation
|
||||
mechanism.</li>
|
||||
<li>Detection of corruption, recapture after error and direct, random
|
||||
access to data at arbitrary positions in the bitstream.</li>
|
||||
</ol>
|
||||
|
||||
<h2>Logical and Physical Bitstreams</h2>
|
||||
|
||||
A <em>logical</em> Ogg bitstream is a contiguous stream of
|
||||
<p>A <em>logical</em> Ogg bitstream is a contiguous stream of
|
||||
sequential pages belonging only to the logical bitstream. A
|
||||
<em>physical</em> Ogg bitstream is constructed from one or more
|
||||
than one logical Ogg bitstream (the simplest physical bitstream
|
||||
@ -57,38 +116,38 @@ bitstreams into more complex physical bitstreams is described in the
|
||||
<a href="oggstream.html">Ogg bitstream overview</a>. The exact
|
||||
mapping of raw Vorbis packets into a valid Ogg Vorbis physical
|
||||
bitstream is described in <a href="vorbis-stream.html">Vorbis
|
||||
bitstream mapping</a>.
|
||||
bitstream mapping</a>.</p>
|
||||
|
||||
<h2>Bitstream structure</h2>
|
||||
|
||||
An Ogg stream is structured by dividing incoming packets into
|
||||
<p>An Ogg stream is structured by dividing incoming packets into
|
||||
segments of up to 255 bytes and then wrapping a group of contiguous
|
||||
packet segments into a variable length page preceded by a page
|
||||
header. Both the header size and page size are variable; the page
|
||||
header contains sizing information and checksum data to determine
|
||||
header/page size and data integrity.<p>
|
||||
header/page size and data integrity.</p>
|
||||
|
||||
The bitstream is captured (or recaptured) by looking for the beginning
|
||||
<p>The bitstream is captured (or recaptured) by looking for the beginning
|
||||
of a page, specifically the capture pattern. Once the capture pattern
|
||||
is found, the decoder verifies page sync and integrity by computing
|
||||
and comparing the checksum. At that point, the decoder can extract the
|
||||
packets themselves.<p>
|
||||
packets themselves.</p>
|
||||
|
||||
<h3>Packet segmentation</h3>
|
||||
|
||||
Packets are logically divided into multiple segments before encoding
|
||||
<p>Packets are logically divided into multiple segments before encoding
|
||||
into a page. Note that the segmentation and fragmentation process is a
|
||||
logical one; it's used to compute page header values and the original
|
||||
page data need not be disturbed, even when a packet spans page
|
||||
boundaries.<p>
|
||||
boundaries.</p>
|
||||
|
||||
The raw packet is logically divided into [n] 255 byte segments and a
|
||||
last fractional segment of < 255 bytes. A packet size may well
|
||||
<p>The raw packet is logically divided into [n] 255 byte segments and a
|
||||
last fractional segment of < 255 bytes. A packet size may well
|
||||
consist only of the trailing fractional segment, and a fractional
|
||||
segment may be zero length. These values, called "lacing values" are
|
||||
then saved and placed into the header segment table.<p>
|
||||
then saved and placed into the header segment table.</p>
|
||||
|
||||
An example should make the basic concept clear:<p>
|
||||
<p>An example should make the basic concept clear:</p>
|
||||
|
||||
<pre>
|
||||
<tt>
|
||||
@ -100,21 +159,21 @@ lacing values for page header segment table: 255,255,243
|
||||
</tt>
|
||||
</pre>
|
||||
|
||||
We simply add the lacing values for the total size; the last lacing
|
||||
<p>We simply add the lacing values for the total size; the last lacing
|
||||
value for a packet is always the value that is less than 255. Note
|
||||
that this encoding both avoids imposing a maximum packet size as well
|
||||
as imposing minimum overhead on small packets (as opposed to, eg,
|
||||
simply using two bytes at the head of every packet and having a max
|
||||
packet size of 32k. Small packets (<255, the typical case) are
|
||||
packet size of 32k. Small packets (<255, the typical case) are
|
||||
penalized with twice the segmentation overhead). Using the lacing
|
||||
values as suggested, small packets see the minimum possible
|
||||
byte-aligned overheade (1 byte) and large packets, over 512 bytes or
|
||||
so, see a fairly constant ~.5% overhead on encoding space.<p>
|
||||
so, see a fairly constant ~.5% overhead on encoding space.</p>
|
||||
|
||||
Note that a lacing value of 255 implies that a second lacing value
|
||||
follows in the packet, and a value of < 255 marks the end of the
|
||||
<p>Note that a lacing value of 255 implies that a second lacing value
|
||||
follows in the packet, and a value of < 255 marks the end of the
|
||||
packet after that many additional bytes. A packet of 255 bytes (or a
|
||||
multiple of 255 bytes) is terminated by a lacing value of 0:<p>
|
||||
multiple of 255 bytes) is terminated by a lacing value of 0:</p>
|
||||
|
||||
<pre><tt>
|
||||
raw packet:
|
||||
@ -124,20 +183,20 @@ raw packet:
|
||||
lacing values: 255, 0
|
||||
</tt></pre>
|
||||
|
||||
Note also that a 'nil' (zero length) packet is not an error; it
|
||||
consists of nothing more than a lacing value of zero in the header.<p>
|
||||
<p>Note also that a 'nil' (zero length) packet is not an error; it
|
||||
consists of nothing more than a lacing value of zero in the header.</p>
|
||||
|
||||
<h3>Packets spanning pages</h3>
|
||||
|
||||
Packets are not restricted to beginning and ending within a page,
|
||||
<p>Packets are not restricted to beginning and ending within a page,
|
||||
although individual segments are, by definition, required to do so.
|
||||
Packets are not restricted to a maximum size, although excessively
|
||||
large packets in the data stream are discouraged; the Ogg
|
||||
bitstream specification strongly recommends nominal page size of
|
||||
approximately 4-8kB (large packets are foreseen as being useful for
|
||||
initialization data at the beginning of a logical bitstream).<p>
|
||||
initialization data at the beginning of a logical bitstream).</p>
|
||||
|
||||
After segmenting a packet, the encoder may decide not to place all the
|
||||
<p>After segmenting a packet, the encoder may decide not to place all the
|
||||
resulting segments into the current page; to do so, the encoder places
|
||||
the lacing values of the segments it wishes to belong to the current
|
||||
page into the current segment table, then finishes the page. The next
|
||||
@ -147,9 +206,9 @@ packet body must also correspond properly to the lacing values in the
|
||||
spanned pages. The segment data in the first packet corresponding to
|
||||
the lacing values of the first page belong in that page; packet
|
||||
segments listed in the segment table of the following page must begin
|
||||
the page body of the subsequent page).<p>
|
||||
the page body of the subsequent page).</p>
|
||||
|
||||
The last mechanic to spanning a page boundary is to set the header
|
||||
<p>The last mechanic to spanning a page boundary is to set the header
|
||||
flag in the new page to indicate that the first lacing value in the
|
||||
segment table continues rather than begins a packet; a header flag of
|
||||
0x01 is set to indicate a continued packet. Although mandatory, it
|
||||
@ -160,45 +219,45 @@ simpler design (with no overhead) that needs only inspect the current
|
||||
page header after frame capture. This also allows faster error
|
||||
recovery in the event that the packet originates in a corrupt
|
||||
preceding page, implying that the previous page's segment table
|
||||
cannot be trusted.<p>
|
||||
cannot be trusted.</p>
|
||||
|
||||
Note that a packet can span an arbitrary number of pages; the above
|
||||
<p>Note that a packet can span an arbitrary number of pages; the above
|
||||
spanning process is repeated for each spanned page boundary. Also a
|
||||
'zero termination' on a packet size that is an even multiple of 255
|
||||
must appear even if the lacing value appears in the next page as a
|
||||
zero-length continuation of the current packet. The header flag
|
||||
should be set to 0x01 to indicate that the packet spanned, even though
|
||||
the span is a nil case as far as data is concerned.<p>
|
||||
the span is a nil case as far as data is concerned.</p>
|
||||
|
||||
The encoding looks odd, but is properly optimized for speed and the
|
||||
<p>The encoding looks odd, but is properly optimized for speed and the
|
||||
expected case of the majority of packets being between 50 and 200
|
||||
bytes (note that it is designed such that packets of wildly different
|
||||
sizes can be handled within the model; placing packet size
|
||||
restrictions on the encoder would have only slightly simplified design
|
||||
in page generation and increased overall encoder complexity).<p>
|
||||
in page generation and increased overall encoder complexity).</p>
|
||||
|
||||
The main point behind tracking individual packets (and packet
|
||||
<p>The main point behind tracking individual packets (and packet
|
||||
segments) is to allow more flexible encoding tricks that requiring
|
||||
explicit knowledge of packet size. An example is simple bandwidth
|
||||
limiting, implemented by simply truncating packets in the nominal case
|
||||
if the packet is arranged so that the least sensitive portion of the
|
||||
data comes last.<p>
|
||||
data comes last.</p>
|
||||
|
||||
<h3>Page header</h3>
|
||||
|
||||
The headering mechanism is designed to avoid copying and re-assembly
|
||||
<p>The headering mechanism is designed to avoid copying and re-assembly
|
||||
of the packet data (ie, making the packet segmentation process a
|
||||
logical one); the header can be generated directly from incoming
|
||||
packet data. The encoder buffers packet data until it finishes a
|
||||
complete page at which point it writes the header followed by the
|
||||
buffered packet segments.<p>
|
||||
buffered packet segments.</p>
|
||||
|
||||
<h4>capture_pattern</h4>
|
||||
|
||||
A header begins with a capture pattern that simplifies identifying
|
||||
pages; once the decoder has found the capture pattern it can do a more
|
||||
intensive job of verifying that it has in fact found a page boundary
|
||||
(as opposed to an inadvertent coincidence in the byte stream).<p>
|
||||
<p>A header begins with a capture pattern that simplifies identifying
|
||||
pages; once the decoder has found the capture pattern it can do a more
|
||||
intensive job of verifying that it has in fact found a page boundary
|
||||
(as opposed to an inadvertent coincidence in the byte stream).</p>
|
||||
|
||||
<pre><tt>
|
||||
byte value
|
||||
@ -211,7 +270,7 @@ buffered packet segments.<p>
|
||||
|
||||
<h4>stream_structure_version</h4>
|
||||
|
||||
The capture pattern is followed by the stream structure revision:
|
||||
<p>The capture pattern is followed by the stream structure revision:</p>
|
||||
|
||||
<pre><tt>
|
||||
byte value
|
||||
@ -221,7 +280,7 @@ buffered packet segments.<p>
|
||||
|
||||
<h4>header_type_flag</h4>
|
||||
|
||||
The header type flag identifies this page's context in the bitstream:
|
||||
<p>The header type flag identifies this page's context in the bitstream:</p>
|
||||
|
||||
<pre><tt>
|
||||
byte value
|
||||
@ -236,21 +295,21 @@ buffered packet segments.<p>
|
||||
|
||||
<h4>absolute granule position</h4>
|
||||
|
||||
(This is packed in the same way the rest of Ogg data is packed; LSb
|
||||
of LSB first. Note that the 'position' data specifies a 'sample'
|
||||
number (eg, in a CD quality sample is four octets, 16 bits for left
|
||||
and 16 bits for right; in video it would likely be the frame number.
|
||||
It is up to the specific codec in use to define the semantic meaning
|
||||
of the granule position value). The position specified is the total
|
||||
samples encoded after including all packets finished on this page
|
||||
(packets begun on this page but continuing on to the next page do not
|
||||
count). The rationale here is that the position specified in the
|
||||
frame header of the last page tells how long the data coded by the
|
||||
bitstream is. A truncated stream will still return the proper number
|
||||
of samples that can be decoded fully.
|
||||
<p>
|
||||
A special value of '-1' (in two's complement) indicates that no packets
|
||||
finish on this page.
|
||||
<p>(This is packed in the same way the rest of Ogg data is packed; LSb
|
||||
of LSB first. Note that the 'position' data specifies a 'sample'
|
||||
number (eg, in a CD quality sample is four octets, 16 bits for left
|
||||
and 16 bits for right; in video it would likely be the frame number.
|
||||
It is up to the specific codec in use to define the semantic meaning
|
||||
of the granule position value). The position specified is the total
|
||||
samples encoded after including all packets finished on this page
|
||||
(packets begun on this page but continuing on to the next page do not
|
||||
count). The rationale here is that the position specified in the
|
||||
frame header of the last page tells how long the data coded by the
|
||||
bitstream is. A truncated stream will still return the proper number
|
||||
of samples that can be decoded fully.</p>
|
||||
|
||||
<p>A special value of '-1' (in two's complement) indicates that no packets
|
||||
finish on this page.</p>
|
||||
|
||||
<pre><tt>
|
||||
byte value
|
||||
@ -267,13 +326,13 @@ buffered packet segments.<p>
|
||||
|
||||
<h4>stream serial number</h4>
|
||||
|
||||
Ogg allows for separate logical bitstreams to be mixed at page
|
||||
granularity in a physical bitstream. The most common case would be
|
||||
sequential arrangement, but it is possible to interleave pages for
|
||||
two separate bitstreams to be decoded concurrently. The serial
|
||||
number is the means by which pages physical pages are associated with
|
||||
a particular logical stream. Each logical stream must have a unique
|
||||
serial number within a physical stream:
|
||||
<p>Ogg allows for separate logical bitstreams to be mixed at page
|
||||
granularity in a physical bitstream. The most common case would be
|
||||
sequential arrangement, but it is possible to interleave pages for
|
||||
two separate bitstreams to be decoded concurrently. The serial
|
||||
number is the means by which pages physical pages are associated with
|
||||
a particular logical stream. Each logical stream must have a unique
|
||||
serial number within a physical stream:</p>
|
||||
|
||||
<pre><tt>
|
||||
byte value
|
||||
@ -286,8 +345,8 @@ buffered packet segments.<p>
|
||||
|
||||
<h4>page sequence no</h4>
|
||||
|
||||
Page counter; lets us know if a page is lost (useful where packets
|
||||
span page boundaries).
|
||||
<p>Page counter; lets us know if a page is lost (useful where packets
|
||||
span page boundaries).</p>
|
||||
|
||||
<pre><tt>
|
||||
byte value
|
||||
@ -300,17 +359,17 @@ buffered packet segments.<p>
|
||||
|
||||
<h4>page checksum</h4>
|
||||
|
||||
32 bit CRC value (direct algorithm, initial val and final XOR = 0,
|
||||
generator polynomial=0x04c11db7). The value is computed over the
|
||||
entire header (with the CRC field in the header set to zero) and then
|
||||
continued over the page. The CRC field is then filled with the
|
||||
computed value.<p>
|
||||
<p>32 bit CRC value (direct algorithm, initial val and final XOR = 0,
|
||||
generator polynomial=0x04c11db7). The value is computed over the
|
||||
entire header (with the CRC field in the header set to zero) and then
|
||||
continued over the page. The CRC field is then filled with the
|
||||
computed value.</p>
|
||||
|
||||
(A thorough discussion of CRC algorithms can be found in <a
|
||||
href="ftp://ftp.rocksoft.com/papers/crc_v3.txt">"A
|
||||
Painless Guide to CRC Error Detection Algorithms"</a> by Ross
|
||||
Williams <a
|
||||
href="mailto:ross@guest.adelaide.edu.au">ross@guest.adelaide.edu.au</a>.)
|
||||
<p>(A thorough discussion of CRC algorithms can be found in <a
|
||||
href="ftp://ftp.rocksoft.com/papers/crc_v3.txt">"A
|
||||
Painless Guide to CRC Error Detection Algorithms"</a> by Ross
|
||||
Williams <a
|
||||
href="mailto:ross@guest.adelaide.edu.au">ross@guest.adelaide.edu.au</a>.)</p>
|
||||
|
||||
<pre><tt>
|
||||
byte value
|
||||
@ -323,14 +382,14 @@ buffered packet segments.<p>
|
||||
|
||||
<h4>page_segments</h4>
|
||||
|
||||
The number of segment entries to appear in the segment table. The
|
||||
maximum number of 255 segments (255 bytes each) sets the maximum
|
||||
possible physical page size at 65307 bytes or just under 64kB (thus
|
||||
we know that a header corrupted so as destroy sizing/alignment
|
||||
information will not cause a runaway bitstream. We'll read in the
|
||||
page according to the corrupted size information that's guaranteed to
|
||||
be a reasonable size regardless, notice the checksum mismatch, drop
|
||||
sync and then look for recapture).<p>
|
||||
<p>The number of segment entries to appear in the segment table. The
|
||||
maximum number of 255 segments (255 bytes each) sets the maximum
|
||||
possible physical page size at 65307 bytes or just under 64kB (thus
|
||||
we know that a header corrupted so as destroy sizing/alignment
|
||||
information will not cause a runaway bitstream. We'll read in the
|
||||
page according to the corrupted size information that's guaranteed to
|
||||
be a reasonable size regardless, notice the checksum mismatch, drop
|
||||
sync and then look for recapture).</p>
|
||||
|
||||
<pre><tt>
|
||||
byte value
|
||||
@ -340,8 +399,8 @@ buffered packet segments.<p>
|
||||
|
||||
<h4>segment_table (containing packet lacing values)</h4>
|
||||
|
||||
The lacing values for each packet segment physically appearing in
|
||||
this page are listed in contiguous order.
|
||||
<p>The lacing values for each packet segment physically appearing in
|
||||
this page are listed in contiguous order.</p>
|
||||
|
||||
<pre><tt>
|
||||
byte value
|
||||
@ -351,45 +410,22 @@ buffered packet segments.<p>
|
||||
n 0x00-0xff (0-255, n=page_segments+26)
|
||||
</tt></pre>
|
||||
|
||||
Total page size is calculated directly from the known header size and
|
||||
<p>Total page size is calculated directly from the known header size and
|
||||
lacing values in the segment table. Packet data segments follow
|
||||
immediately after the header.<p>
|
||||
immediately after the header.</p>
|
||||
|
||||
Page headers typically impose a flat .25-.5% space overhead assuming
|
||||
<p>Page headers typically impose a flat .25-.5% space overhead assuming
|
||||
nominal ~8k page sizes. The segmentation table needed for exact
|
||||
packet recovery in the streaming layer adds approximately .5-1%
|
||||
nominal assuming expected encoder behavior in the 44.1kHz, 128kbps
|
||||
stereo encodings.<p>
|
||||
stereo encodings.</p>
|
||||
|
||||
<hr>
|
||||
<a href="http://www.xiph.org/">
|
||||
<img src="white-xifish.png" align=left border=0>
|
||||
</a>
|
||||
<font size=-2 color=#505050>
|
||||
<div id="copyright">
|
||||
The Xiph Fish Logo is a
|
||||
trademark (™) of Xiph.Org.<br/>
|
||||
|
||||
Ogg is a <a href="http://www.xiph.org">Xiph.org Foundation</a> effort
|
||||
to protect essential tenets of Internet multimedia from corporate
|
||||
hostage-taking; Open Source is the net's greatest tool to keep
|
||||
everyone honest. See <a href="http://www.xiph.org/about.html">About
|
||||
the Xiph.org Foundation</a> for details.
|
||||
<p>
|
||||
|
||||
Ogg Vorbis is the first Ogg audio CODEC. Anyone may freely use and
|
||||
distribute the Ogg and Vorbis specification, whether in a private,
|
||||
public or corporate capacity. However, the Xiph.org Foundation and
|
||||
the Ogg project (xiph.org) reserve the right to set the Ogg Vorbis
|
||||
specification and certify specification compliance.<p>
|
||||
|
||||
Xiph.org's Vorbis software CODEC implementation is distributed under a
|
||||
BSD-like license. This does not restrict third parties from
|
||||
distributing independent implementations of Vorbis software under
|
||||
other licenses.<p>
|
||||
|
||||
Ogg, Vorbis, Xiph.org Foundation and their logos are trademarks (tm)
|
||||
of the <a href="http://www.xiph.org/">Xiph.org Foundation</a>. These
|
||||
pages are copyright (C) 1994-2002 Xiph.org Foundation. All rights
|
||||
reserved.<p>
|
||||
These pages © 1994 - 2005 Xiph.Org. All rights reserved.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
</html>
|
||||
|
@ -1,4 +1,92 @@
|
||||
<a href="oggstream.html">Ogg logical and physical bitstream overview</a><br>
|
||||
<a href="framing.html">Ogg logical bitstream framing</a><br>
|
||||
<a href="ogg-multiplex.html">Ogg multi-stream multiplexing</a><br>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15"/>
|
||||
<title>Ogg Documentation</title>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin: 0 18px 0 18px;
|
||||
padding-bottom: 30px;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
color: #333333;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #3366cc;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#xiphlogo {
|
||||
margin: 30px 0 16px 0;
|
||||
}
|
||||
|
||||
#content p {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h1, h1 a, h2, h2 a, h3, h3 a {
|
||||
font-weight: bold;
|
||||
color: #ff9900;
|
||||
margin: 1.3em 0 8px 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
#copyright {
|
||||
margin-top: 30px;
|
||||
line-height: 1.5em;
|
||||
text-align: center;
|
||||
font-size: .8em;
|
||||
color: #888888;
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="xiphlogo">
|
||||
<a href="http://www.xiph.org/"><img src="fish_xiph_org.png" alt="Fish Logo and Xiph.org"/></a>
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
<li><a href="oggstream.html">Ogg logical and physical bitstream overview</a></li>
|
||||
<li><a href="framing.html">Ogg logical bitstream framing</a></li>
|
||||
<li><a href="ogg-multiplex.html">Ogg multi-stream multiplexing</a></li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li><a href="rfc3533.txt">rfc3533: The Ogg Encapsulation Format Version 0</a></li>
|
||||
<li><a href="rfc3534.txt">rfc3534: The application/ogg Media Type</a></li>
|
||||
</ul>
|
||||
|
||||
<div id="copyright">
|
||||
The Xiph Fish Logo is a
|
||||
trademark (™) of Xiph.Org.<br/>
|
||||
|
||||
These pages © 1994 - 2005 Xiph.Org. All rights reserved.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,162 +1,225 @@
|
||||
<HTML><HEAD><TITLE>xiph.org: Ogg documentation</TITLE>
|
||||
<BODY bgcolor="#ffffff" text="#202020" link="#006666" vlink="#000000">
|
||||
<nobr><a href="http://www.xiph.org/ogg/index.html"><img src="white-ogg.png" border=0><img src="vorbisword2.png" border=0></a></nobr><p>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<h1><font color=#000070>
|
||||
Page Multiplexing and Ordering in a Physical Ogg Stream
|
||||
</font></h1>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15"/>
|
||||
<title>Ogg Documentation</title>
|
||||
|
||||
<em>Last update to this document: May 17, 2004</em><br>
|
||||
<p>
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin: 0 18px 0 18px;
|
||||
padding-bottom: 30px;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
color: #333333;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
The low-level mechanisms of an Ogg stream (as described in the Ogg
|
||||
a {
|
||||
color: #3366cc;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#xiphlogo {
|
||||
margin: 30px 0 16px 0;
|
||||
}
|
||||
|
||||
#content p {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h1, h1 a, h2, h2 a, h3, h3 a {
|
||||
font-weight: bold;
|
||||
color: #ff9900;
|
||||
margin: 1.3em 0 8px 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
#copyright {
|
||||
margin-top: 30px;
|
||||
line-height: 1.5em;
|
||||
text-align: center;
|
||||
font-size: .8em;
|
||||
color: #888888;
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="xiphlogo">
|
||||
<a href="http://www.xiph.org/"><img src="fish_xiph_org.png" alt="Fish Logo and Xiph.org"/></a>
|
||||
</div>
|
||||
|
||||
<h1>Page Multiplexing and Ordering in a Physical Ogg Stream</h1>
|
||||
|
||||
<p>The low-level mechanisms of an Ogg stream (as described in the Ogg
|
||||
Bitstream Overview) provide means for mixing multiple logical streams
|
||||
and media types into a single linear-chronological stream. This
|
||||
and media types into a single linear-chronological stream. This
|
||||
document specifies the high-level arrangement and use of page
|
||||
structure to multiplex multiple streams of mixed media type within a
|
||||
physical Ogg stream.
|
||||
physical Ogg stream.</p>
|
||||
|
||||
<h2>Design Elements</h2>
|
||||
|
||||
The design and arrangement of the Ogg container format is governed by
|
||||
<p>The design and arrangement of the Ogg container format is governed by
|
||||
several high-level design decisions that form the reasoning behind
|
||||
specific low-level design decisions.
|
||||
specific low-level design decisions.</p>
|
||||
|
||||
<h3>Linear media</h3>
|
||||
|
||||
The Ogg bitstream is intended to encapsulate chronological,
|
||||
time-linear mixed media into a single delivery stream or file. The
|
||||
<p>The Ogg bitstream is intended to encapsulate chronological,
|
||||
time-linear mixed media into a single delivery stream or file. The
|
||||
design is such that an application can always encode and/or decode a
|
||||
full-featured bitstream in one pass with no seeking and minimal
|
||||
buffering. Seeking to provide optimized encoding (such as two-pass
|
||||
buffering. Seeking to provide optimized encoding (such as two-pass
|
||||
encoding) or interactive decoding (such as scrubbing or instant
|
||||
replay) is not disallowed or discouraged, however no bitstream feature
|
||||
must require nonlinear operation on the bitstream.<p>
|
||||
must require nonlinear operation on the bitstream.</p>
|
||||
|
||||
<h3>Multiplexing</h3>
|
||||
|
||||
Ogg bitstreams multiplex multiple logical streams into a single
|
||||
physical stream at the page level. Each page contains an abstract
|
||||
<p>Ogg bitstreams multiplex multiple logical streams into a single
|
||||
physical stream at the page level. Each page contains an abstract
|
||||
time stamp (the Granule Position) that represents an absolute time
|
||||
landmark within the stream. After the pages representing stream
|
||||
landmark within the stream. After the pages representing stream
|
||||
headers (all logical stream headers occur at the beginning of a
|
||||
physical bitstream section before any logical stream data), logical
|
||||
stream data pages are arranged in strict, monotonically increasing
|
||||
order of chronological absolute time as specified by the granule
|
||||
position. <p>
|
||||
position.</p>
|
||||
|
||||
The only exception to arranging pages in strictly ascending time order
|
||||
<p>The only exception to arranging pages in strictly ascending time order
|
||||
by granule position is those pages that do not set the granule
|
||||
position value. This is a special case when exceptionally large
|
||||
position value. This is a special case when exceptionally large
|
||||
packets span multiple pages; the specifics of handling this special
|
||||
case are described later under 'Continuous and Discontinuous
|
||||
Streams'.<p>
|
||||
Streams'.</p>
|
||||
|
||||
<h3>Seeking</h3>
|
||||
|
||||
Ogg is designed to use a bisection search to implement exact
|
||||
<p>Ogg is designed to use a bisection search to implement exact
|
||||
positional seeking rather than building an index; an index requires
|
||||
two-pass encoding and as such is not acceptable given the requirement
|
||||
for full-featured linear encoding.<p>
|
||||
for full-featured linear encoding.</p>
|
||||
|
||||
<i>Even making an index optional then requires an
|
||||
<p><i>Even making an index optional then requires an
|
||||
application to support multiple methods (bisection search for a
|
||||
one-pass stream, indexing for a two-pass stream), which adds no
|
||||
additional functionality as bisection search delivers the same
|
||||
functionality for both stream types.</i><p>
|
||||
functionality for both stream types.</i></p>
|
||||
|
||||
Seek operations are by absolute time; a direct bisection search must
|
||||
find the exact time position requested. Information in the Ogg
|
||||
<p>Seek operations are by absolute time; a direct bisection search must
|
||||
find the exact time position requested. Information in the Ogg
|
||||
bitstream is arranged such that all information to be presented for
|
||||
playback from the desired seek point will occur at or after the
|
||||
desired seek point. Seek operations are neither 'fuzzy' nor
|
||||
heuristic.<p>
|
||||
desired seek point. Seek operations are neither 'fuzzy' nor
|
||||
heuristic.</p>
|
||||
|
||||
<i>Although key frame handling in video appears to be an exception to
|
||||
<p><i>Although key frame handling in video appears to be an exception to
|
||||
"all needed playback information lies ahead of a given seek",
|
||||
key frames can still be handled directly within this indexless
|
||||
framework. Seeking to a key frame in video (as well as seeking in other
|
||||
media types with analogous restraints) is handled as two seeks; first
|
||||
a seek to the desired time which extracts state information that
|
||||
decodes to the time of the last key frame, followed by a second seek
|
||||
directly to the key frame. The location of the previous key frame is
|
||||
directly to the key frame. The location of the previous key frame is
|
||||
embedded as state information in the granulepos; this mechanism is
|
||||
described in more detail later.</i>
|
||||
described in more detail later.</i></p>
|
||||
|
||||
<h3>Continuous and Discontinuous Streams</h3>
|
||||
|
||||
Logical streams within a physical Ogg stream belong to one of two
|
||||
<p>Logical streams within a physical Ogg stream belong to one of two
|
||||
categories, "Continuous" streams and "Discontinuous" streams.
|
||||
Although these are discussed in more detail later, the distinction is
|
||||
important to a high-level understanding of how to buffer an Ogg
|
||||
stream.<p>
|
||||
stream.</p>
|
||||
|
||||
A stream that provides a gapless, time-continuous media type with a
|
||||
fine-grained timebase is considered to be 'Continuous'. A continuous
|
||||
stream should never be starved of data. Clear examples of continuous
|
||||
data types include broadcast audio and video.<p>
|
||||
<p>A stream that provides a gapless, time-continuous media type with a
|
||||
fine-grained timebase is considered to be 'Continuous'. A continuous
|
||||
stream should never be starved of data. Clear examples of continuous
|
||||
data types include broadcast audio and video.</p>
|
||||
|
||||
A stream that delivers data in a potentially irregular pattern or with
|
||||
widely spaced timing gaps is considered to be 'Discontinuous'. A
|
||||
<p>A stream that delivers data in a potentially irregular pattern or with
|
||||
widely spaced timing gaps is considered to be 'Discontinuous'. A
|
||||
discontinuous stream may be best thought of as data representing
|
||||
scattered events; although they happen in order, they are typically
|
||||
unconnected data often located far apart. One possible example of a
|
||||
discontinuous stream types would be captioning. Although it's
|
||||
discontinuous stream types would be captioning. Although it's
|
||||
possible to design captions as a continuous stream type, it's most
|
||||
natural to think of captions as widely spaced pieces of text with
|
||||
little happening between.<p>
|
||||
little happening between.</p>
|
||||
|
||||
The fundamental design distinction between continuous and
|
||||
discontinuous streams concerns buffering.<p>
|
||||
<p>The fundamental design distinction between continuous and
|
||||
discontinuous streams concerns buffering.</p>
|
||||
|
||||
<h3>Buffering</h3>
|
||||
|
||||
Because a continuous stream is, by definition, gapless, Ogg buffering
|
||||
<p>Because a continuous stream is, by definition, gapless, Ogg buffering
|
||||
is based on the simple premise of never allowing any active continuous
|
||||
stream to starve for data during decode; buffering proceeds ahead
|
||||
until all continuous streams in a physical stream have data ready to
|
||||
decode on demand. <p>
|
||||
decode on demand.</p>
|
||||
|
||||
Discontinuous stream data may occur on a fairly regular basis, but the
|
||||
<p>Discontinuous stream data may occur on a fairly regular basis, but the
|
||||
timing of, for example, a specific caption is impossible to predict
|
||||
with certainty in most captioning systems. Thus the buffering system
|
||||
should take discontinuous data 'as it comes' rather than working ahead
|
||||
(for a potentially unbounded period) to look for future discontinuous
|
||||
data. As such, discontinuous streams are ignored when managing
|
||||
data. As such, discontinuous streams are ignored when managing
|
||||
buffering; their pages simply 'fall out' of the stream when continuous
|
||||
streams are handled properly.<p>
|
||||
streams are handled properly.</p>
|
||||
|
||||
Buffering requirements need not be explicitly declared or managed for
|
||||
<p>Buffering requirements need not be explicitly declared or managed for
|
||||
the encoded stream; the decoder simply reads as much data as is
|
||||
necessary to keep all continuous stream types gapless (also ensuring
|
||||
discontinuous data arrives in time) and no more, resulting in optimum
|
||||
implicit buffer usage for a given stream. Because all pages of all
|
||||
implicit buffer usage for a given stream. Because all pages of all
|
||||
data types are stamped with absolute timing information within the
|
||||
stream, inter-stream synchronization timing is always explicitly
|
||||
maintained without the need for explicitly declared buffer-ahead
|
||||
hinting.<p>
|
||||
hinting.</p>
|
||||
|
||||
Further details, mechanisms and reasons for the differing arrangement
|
||||
<p>Further details, mechanisms and reasons for the differing arrangement
|
||||
and behavior of continuous and discontinuous streams is discussed
|
||||
later.<p>
|
||||
later.</p>
|
||||
|
||||
<h3>Whole-stream navigation</h3>
|
||||
|
||||
Ogg is designed so that the simplest navigation operations treat the
|
||||
<p>Ogg is designed so that the simplest navigation operations treat the
|
||||
physical Ogg stream as a whole summary of its streams, rather than
|
||||
navigating each interleaved stream as a separate entity. <p>
|
||||
navigating each interleaved stream as a separate entity.</p>
|
||||
|
||||
First Example: seeking to a desired time position in a multiplexed (or
|
||||
<p>First Example: seeking to a desired time position in a multiplexed (or
|
||||
unmultiplexed) Ogg stream can be accomplished through a bisection
|
||||
search on time position of all pages in the stream (as encoded in the
|
||||
granule position). More powerful searches (such as a key frame-aware
|
||||
seek within video) are also possible with additional search
|
||||
complexity, but similar computational complexity.<p>
|
||||
complexity, but similar computational complexity.</p>
|
||||
|
||||
Second Example: A bitstream section may consist of three multiplexed
|
||||
streams of differing lengths. The result of multiplexing these
|
||||
<p>Second Example: A bitstream section may consist of three multiplexed
|
||||
streams of differing lengths. The result of multiplexing these
|
||||
streams should be thought of as a single mixed stream with a length
|
||||
equal to the longest of the three component streams. Although it is
|
||||
equal to the longest of the three component streams. Although it is
|
||||
also possible to think of the multiplexed results as three concurrent
|
||||
streams of different lengths and it is possible to recover the three
|
||||
original streams, it will also become obvious that once multiplexed,
|
||||
@ -164,21 +227,22 @@ it isn't possible to find the internal lengths of the component
|
||||
streams without a linear search of the whole bitstream section.
|
||||
However, it is possible to find the length of the whole bitstream
|
||||
section easily (in near-constant time per section) just as it is for a
|
||||
single-media unmultiplexed stream.<p>
|
||||
single-media unmultiplexed stream.</p>
|
||||
|
||||
<h2>Granule Position</h2>
|
||||
|
||||
<h3>Description</h3>
|
||||
|
||||
The Granule Position is a signed 64 bit field appearing in the header
|
||||
of every Ogg page. Although the granule position represents absolute
|
||||
<p>The Granule Position is a signed 64 bit field appearing in the header
|
||||
of every Ogg page. Although the granule position represents absolute
|
||||
time within a logical stream, its value does not necessarily directly
|
||||
encode a simple timestamp. It may represent frames elapsed (as in
|
||||
encode a simple timestamp. It may represent frames elapsed (as in
|
||||
Vorbis), a simple timestamp, or a more complex bit-division encoding
|
||||
(such as in Theora). The exact encoding of the granule position is up
|
||||
to a specific codec.<p>
|
||||
(such as in Theora). The exact encoding of the granule position is up
|
||||
to a specific codec.</p>
|
||||
|
||||
<p>The granule position is governed by the following rules:</p>
|
||||
|
||||
The granule position is governed by the following rules:
|
||||
<ul>
|
||||
|
||||
<li>Granule Position must always increase forward or remain equal from
|
||||
@ -187,183 +251,195 @@ time to which any correct sequence of granule position maps must
|
||||
similarly always increase forward or remain equal. <i>(A codec may
|
||||
make use of data, such as a control sequence, that only affects codec
|
||||
working state without producing data and thus advancing granule
|
||||
position and time. Although the packet sequence number increases in
|
||||
position and time. Although the packet sequence number increases in
|
||||
this case, the granule position, and thus the time position, do
|
||||
not.)</i><br>
|
||||
not.)</i></li>
|
||||
|
||||
<li>Granule position may only be unset if there no packet defining a
|
||||
time boundary on the page (that is, if no packet in a continuous
|
||||
stream ends on the page, or no packet in a discontinuous stream begins
|
||||
on the page. This will be discussed in more detail under Continuous
|
||||
and Discontinuous streams).<br>
|
||||
on the page. This will be discussed in more detail under Continuous
|
||||
and Discontinuous streams).</li>
|
||||
|
||||
<li>A codec must be able to translate a given granule position value
|
||||
to a unique, deterministic absolute time value through direct
|
||||
calculation. A codec is not required to be able to translate an
|
||||
absolute time value into a unique granule position value.<br>
|
||||
calculation. A codec is not required to be able to translate an
|
||||
absolute time value into a unique granule position value.</li>
|
||||
|
||||
<li>Codecs shall choose a granule position definition that allows that
|
||||
codec means to seek as directly as possible to an immediately
|
||||
decodable point, such as the bit-divided granule position encoding of
|
||||
Theora allows the codec to seek efficiently to key frame without using
|
||||
an index. That is, additional information other than absolute time
|
||||
an index. That is, additional information other than absolute time
|
||||
may be encoded into a granule position value so long as the granule
|
||||
position obeys the above points.
|
||||
position obeys the above points.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h4>Example: timestamp</h4>
|
||||
|
||||
In general, a codec/stream type should choose the simplest granule
|
||||
position encoding that addresses its requirements. The examples here
|
||||
are by no means exhaustive of the possibilities within Ogg.<p>
|
||||
<p>In general, a codec/stream type should choose the simplest granule
|
||||
position encoding that addresses its requirements. The examples here
|
||||
are by no means exhaustive of the possibilities within Ogg.</p>
|
||||
|
||||
A simple granule position could encode a timestamp directly. For
|
||||
<p>A simple granule position could encode a timestamp directly. For
|
||||
example, a granule position that encoded milliseconds from beginning
|
||||
of stream would allow a logical stream length of over 100,000,000,000
|
||||
days before beginning a new logical stream (to avoid the granule
|
||||
position wrapping).<p>
|
||||
position wrapping).</p>
|
||||
|
||||
<h4>Example: framestamp</h4>
|
||||
|
||||
A simple millisecond timestamp granule encoding might suit many stream
|
||||
<p>A simple millisecond timestamp granule encoding might suit many stream
|
||||
types, but a millisecond resolution is inappropriate to, eg, most
|
||||
audio encodings where exact single-sample resolution is generally a
|
||||
requirement. A millisecond is both too large a granule and often does
|
||||
not represent an integer number of samples.<p>
|
||||
requirement. A millisecond is both too large a granule and often does
|
||||
not represent an integer number of samples.</p>
|
||||
|
||||
In the event that audio frames are always encoded as the same number of
|
||||
<p>In the event that audio frames are always encoded as the same number of
|
||||
samples, the granule position could simply be a linear count of frames
|
||||
since beginning of stream. This has the advantages of being exact and
|
||||
efficient. Position in time would simply be <tt>[granule_position] *
|
||||
[samples_per_frame] / [samples_per_second]</tt>.
|
||||
efficient. Position in time would simply be <tt>[granule_position] *
|
||||
[samples_per_frame] / [samples_per_second]</tt>.</p>
|
||||
|
||||
<h4>Example: samplestamp (Vorbis)</h4>
|
||||
|
||||
Frame counting is insufficient in codecs such as Vorbis where an audio
|
||||
frame [packet] encodes a variable number of samples. In Vorbis's
|
||||
<p>Frame counting is insufficient in codecs such as Vorbis where an audio
|
||||
frame [packet] encodes a variable number of samples. In Vorbis's
|
||||
case, the granule position is a count of the number of raw samples
|
||||
from the beginning of stream; the absolute time of
|
||||
a granule position is <tt>[granule_position] /
|
||||
[samples_per_second]</tt>.
|
||||
[samples_per_second]</tt>.</p>
|
||||
|
||||
<h4>Example: bit-divided framestamp (Theora)</h4>
|
||||
|
||||
Some video codecs may be able to use the simple framestamp scheme for
|
||||
granule position. However, most modern video codecs introduce at
|
||||
least the following complications:<p>
|
||||
<p>Some video codecs may be able to use the simple framestamp scheme for
|
||||
granule position. However, most modern video codecs introduce at
|
||||
least the following complications:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>video frames are relatively far apart compared to audio samples;
|
||||
for this reason, the point at which a video frame changes to the next
|
||||
frame is usually a strictly defined offset within the frame 'period'.
|
||||
That is, video at 50fps could just as easily define frame transitions
|
||||
<.015, .035, .055...> as at <.00, .02, .04...>.
|
||||
<.015, .035, .055...> as at <.00, .02, .04...>.</li>
|
||||
|
||||
<li>frame rates often include drop-frames, leap-frames or other
|
||||
rational-but-non-integer timings.
|
||||
rational-but-non-integer timings.</li>
|
||||
|
||||
<li>Decode must begin at a 'key frame' or 'I frame'. Keyframes usually
|
||||
occur relatively seldom.</li>
|
||||
|
||||
<li>Decode must begin at a 'key frame' or 'I frame'. Keyframes usually
|
||||
occur relatively seldom.
|
||||
</ul>
|
||||
|
||||
The first two points can be handled straightforwardly via the fact
|
||||
<p>The first two points can be handled straightforwardly via the fact
|
||||
that the codec has complete control mapping granule position to
|
||||
absolute time; non-integer frame rates and offsets can be set in the
|
||||
codec's initial header, and the rest is just arithmetic.<p>
|
||||
codec's initial header, and the rest is just arithmetic.</p>
|
||||
|
||||
The third point appears trickier at first glance, but it too can be
|
||||
handled through the granule position mapping mechanism. Here we
|
||||
<p>The third point appears trickier at first glance, but it too can be
|
||||
handled through the granule position mapping mechanism. Here we
|
||||
arrange the granule position in such a way that granule positions of
|
||||
key frames are easy to find. Divide the granule position into two
|
||||
key frames are easy to find. Divide the granule position into two
|
||||
fields; the most-significant bits are an absolute frame counter, but
|
||||
it's only updated at each key frame. The least significant bits encode
|
||||
the number of frames since the last key frame. In this way, each
|
||||
it's only updated at each key frame. The least significant bits encode
|
||||
the number of frames since the last key frame. In this way, each
|
||||
granule position both encodes the absolute time of the current frame
|
||||
as well as the absolute time of the last key frame.<p>
|
||||
as well as the absolute time of the last key frame.</p>
|
||||
|
||||
Seeking to a most recent preceding key frame is then accomplished by
|
||||
<p>Seeking to a most recent preceding key frame is then accomplished by
|
||||
first seeking to the original desired point, inspecting the granulepos
|
||||
of the resulting video page, extracting from that granulepos the
|
||||
absolute time of the desired key frame, and then seeking directly to
|
||||
that key frame's page. Of course, it's still possible for an
|
||||
that key frame's page. Of course, it's still possible for an
|
||||
application to ignore key frames and use a simpler seeking algorithm
|
||||
(decode would be unable to present decoded video until the next
|
||||
key frame). Surprisingly many player applications do choose the
|
||||
simpler approach.<p>
|
||||
key frame). Surprisingly many player applications do choose the
|
||||
simpler approach.</p>
|
||||
|
||||
<h3>granule position, packets and pages</h3>
|
||||
|
||||
Although each packet of data in a logical stream theoretically has a
|
||||
<p>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
|
||||
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>
|
||||
is not intended to be the general case.</p>
|
||||
|
||||
Because Ogg functions at the page, not packet, level, this
|
||||
<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
|
||||
time information is can use. Ogg passes this granule positioning data
|
||||
to the codec (along with the packets extracted from a page); it is the
|
||||
responsibility of codecs to track timing information at granularities
|
||||
finer than a single page.<p>
|
||||
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>. However, continuous streams and discontinuous
|
||||
<p>A granule position represents the <em>instantaneous time location
|
||||
between two pages</em>. However, continuous streams and discontinuous
|
||||
streams differ on whether the granulepos represents the end-time of
|
||||
the data on a page or the start-time. Continuous streams are
|
||||
the data on a page or the start-time. Continuous streams are
|
||||
'end-time' encoded; the granulepos represents the point in time
|
||||
immediately after the last data decoded from a page. Discontinuous
|
||||
immediately after the last data decoded from a page. Discontinuous
|
||||
streams are 'start-time' encoded; the granulepos represents the point
|
||||
in time of the first data decoded from the page.<p>
|
||||
in time of the first data decoded from the page.</p>
|
||||
|
||||
An Ogg stream type is declared continuous or discontinuous by its
|
||||
codec. A given codec may support both continuous and discontinuous
|
||||
<p>An Ogg stream type is declared continuous or discontinuous by its
|
||||
codec. A given codec may support both continuous and discontinuous
|
||||
operation so long as any given logical stream is continuous or
|
||||
discontinuous for its entirety and the codec is able to ascertain (and
|
||||
inform the Ogg layer) as to which after decoding the initial stream
|
||||
header. The majority of codecs will always be continuous (such as
|
||||
Vorbis) or discontinuous (such as Writ).<p>
|
||||
header. The majority of codecs will always be continuous (such as
|
||||
Vorbis) or discontinuous (such as Writ).</p>
|
||||
|
||||
Start- and end-time encoding do not affect multiplexing sort-order;
|
||||
<p>Start- and end-time encoding do not affect multiplexing sort-order;
|
||||
pages are still sorted by the absolute time a given granulepos maps to
|
||||
regardless of whether that granulepos represents start- or
|
||||
end-time.<p>
|
||||
end-time.</p>
|
||||
|
||||
<h2>Multiplex/Demultiplex Division of Labor</h2>
|
||||
|
||||
The Ogg multiplex/demultiplex layer provides mechanisms for encoding
|
||||
<p>The Ogg multiplex/demultiplex layer provides mechanisms for encoding
|
||||
raw packets into Ogg pages, decoding Ogg pages back into the original
|
||||
codec packets, determining the logical structure of an Ogg stream, and
|
||||
navigating through and synchronizing with an Ogg stream at a desired
|
||||
stream location. Strict multiplex/demultiplex operations are entirely
|
||||
in the Ogg domain and require no intervention from codecs.<p>
|
||||
stream location. Strict multiplex/demultiplex operations are entirely
|
||||
in the Ogg domain and require no intervention from codecs.</p>
|
||||
|
||||
Implementation of more complex operations does require codec
|
||||
knowledge, however. Unlike other framing systems, Ogg maintains
|
||||
<p>Implementation of more complex operations does require codec
|
||||
knowledge, however. Unlike other framing systems, Ogg maintains
|
||||
strict separation between framing and the framed bitstream data; Ogg
|
||||
does not replicate codec-specific information in the page/framing
|
||||
data, nor does Ogg blur the line between framing and stream
|
||||
data/metadata. Because Ogg is fully data-agnostic toward the data it
|
||||
data/metadata. Because Ogg is fully data-agnostic toward the data it
|
||||
frames, operations which require specifics of bitstream data (such as
|
||||
'seek to key frame') also require interaction with the codec layer
|
||||
(because, in this example, the Ogg layer is not aware of the concept
|
||||
of key frames). This is different from systems that blur the
|
||||
of key frames). This is different from systems that blur the
|
||||
separation between framing and stream data in order to simplify the
|
||||
separation of code. The Ogg system purposely keeps the distinction in
|
||||
separation of code. The Ogg system purposely keeps the distinction in
|
||||
data simple so that later codec innovations are not constrained by
|
||||
framing design.<p>
|
||||
framing design.</p>
|
||||
|
||||
For this reason, however, complex seeking operations require
|
||||
<p>For this reason, however, complex seeking operations require
|
||||
interaction with the codecs in order to decode the granule position of
|
||||
a given stream type back to absolute time or in order to find
|
||||
'decodable points' such as key frames in video.
|
||||
'decodable points' such as key frames in video.</p>
|
||||
|
||||
<h2>Unsorted Discussion Points</h2>
|
||||
|
||||
flushes around key frames? RFC suggestion: repaginating or building a
|
||||
stream this way is nice but not required
|
||||
|
||||
<p>flushes around key frames? RFC suggestion: repaginating or building a
|
||||
stream this way is nice but not required</p>
|
||||
|
||||
<h2>Appendix A: multiplexing examples</h2>
|
||||
|
||||
<div id="copyright">
|
||||
The Xiph Fish Logo is a
|
||||
trademark (™) of Xiph.Org.<br/>
|
||||
|
||||
These pages © 1994 - 2005 Xiph.Org. All rights reserved.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,43 +1,105 @@
|
||||
<HTML><HEAD><TITLE>xiph.org: Ogg Vorbis documentation</TITLE>
|
||||
<BODY bgcolor="#ffffff" text="#202020" link="#006666" vlink="#000000">
|
||||
<nobr><a href="http://www.xiph.org/ogg/index.html"><img src="white-ogg.png" border=0><img
|
||||
src="vorbisword2.png" border=0></a></nobr><p>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15"/>
|
||||
<title>Ogg Documentation</title>
|
||||
|
||||
<h1><font color=#000070>
|
||||
Ogg logical and physical bitstream overview
|
||||
</font></h1>
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin: 0 18px 0 18px;
|
||||
padding-bottom: 30px;
|
||||
font-family: Verdana, Arial, Helvetica, sans-serif;
|
||||
color: #333333;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
<em>Last update to this document: July 14, 2002</em><br>
|
||||
a {
|
||||
color: #3366cc;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#xiphlogo {
|
||||
margin: 30px 0 16px 0;
|
||||
}
|
||||
|
||||
#content p {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
h1, h1 a, h2, h2 a, h3, h3 a {
|
||||
font-weight: bold;
|
||||
color: #ff9900;
|
||||
margin: 1.3em 0 8px 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
#copyright {
|
||||
margin-top: 30px;
|
||||
line-height: 1.5em;
|
||||
text-align: center;
|
||||
font-size: .8em;
|
||||
color: #888888;
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="xiphlogo">
|
||||
<a href="http://www.xiph.org/"><img src="fish_xiph_org.png" alt="Fish Logo and Xiph.org"/></a>
|
||||
</div>
|
||||
|
||||
<h1>Ogg logical and physical bitstream overview</h1>
|
||||
|
||||
<h2>Ogg bitstreams</h2>
|
||||
|
||||
Ogg codecs use octet vectors of raw, compressed data
|
||||
<p>Ogg codecs use octet vectors of raw, compressed data
|
||||
(<em>packets</em>). These compressed packets do not have any
|
||||
high-level structure or boundary information; strung together, they
|
||||
appear to be streams of random bytes with no landmarks.<p>
|
||||
appear to be streams of random bytes with no landmarks.</p>
|
||||
|
||||
Raw packets may be used directly by transport mechanisms that provide
|
||||
<p>Raw packets may be used directly by transport mechanisms that provide
|
||||
their own framing and packet-separation mechanisms (such as UDP
|
||||
datagrams). For stream based storage (such as files) and transport
|
||||
datagrams). For stream based storage (such as files) and transport
|
||||
(such as TCP streams or pipes), Vorbis and other future Ogg codecs use
|
||||
the Ogg bitstream format to provide framing/sync, sync recapture
|
||||
after error, landmarks during seeking, and enough information to
|
||||
properly separate data back into packets at the original packet
|
||||
boundaries without relying on decoding to find packet boundaries.<p>
|
||||
boundaries without relying on decoding to find packet boundaries.</p>
|
||||
|
||||
<h2>Logical and physical bitstreams</h2>
|
||||
|
||||
Raw packets are grouped and encoded into contiguous pages of
|
||||
structured bitstream data called <em>logical bitstreams</em>. A
|
||||
<p>Raw packets are grouped and encoded into contiguous pages of
|
||||
structured bitstream data called <em>logical bitstreams</em>. A
|
||||
logical bitstream consists of pages, in order, belonging to a single
|
||||
codec instance. Each page is a self contained entity (although it is
|
||||
codec instance. Each page is a self contained entity (although it is
|
||||
possible that a packet may be split and encoded across one or more
|
||||
pages); that is, the page decode mechanism is designed to recognize,
|
||||
verify and handle single pages at a time from the overall bitstream.<p>
|
||||
verify and handle single pages at a time from the overall bitstream.</p>
|
||||
|
||||
Multiple logical bitstreams can be combined (with restrictions) into a
|
||||
single <em>physical bitstream</em>. A physical bitstream consists of
|
||||
<p>Multiple logical bitstreams can be combined (with restrictions) into a
|
||||
single <em>physical bitstream</em>. A physical bitstream consists of
|
||||
multiple logical bitstreams multiplexed at the page level and may
|
||||
include a 'meta-header' at the beginning of the multiplexed logical
|
||||
stream that serves as identification magic. Whole pages are taken in
|
||||
@ -47,150 +109,126 @@ logical bitstreams from the physical bitstream by taking the pages in
|
||||
order from the physical bitstream and redirecting them into the
|
||||
appropriate logical decoding entity. The simplest physical bitstream
|
||||
is a single, unmultiplexed logical bitstream with no meta-header; this
|
||||
is referred to as a 'degenerate stream'. <p>
|
||||
is referred to as a 'degenerate stream'.</p>
|
||||
|
||||
<a href=framing.html>Ogg Logical Bitstream Framing</a> discusses
|
||||
<p><a href="framing.html">Ogg Logical Bitstream Framing</a> discusses
|
||||
the page format of an Ogg bitstream, the packet coding process
|
||||
and logical bitstreams in detail. The remainder of this document
|
||||
and logical bitstreams in detail. The remainder of this document
|
||||
specifies requirements for constructing finished, physical Ogg
|
||||
bitstreams.<p>
|
||||
bitstreams.</p>
|
||||
|
||||
<h2>Mapping Restrictions</h2>
|
||||
|
||||
Logical bitstreams may not be mapped/multiplexed into physical
|
||||
bitstreams without restriction. Here we discuss design restrictions
|
||||
<p>Logical bitstreams may not be mapped/multiplexed into physical
|
||||
bitstreams without restriction. Here we discuss design restrictions
|
||||
on Ogg physical bitstreams in general, mostly to introduce
|
||||
design rationale. Each 'media' format defines its own (generally more
|
||||
restrictive) mapping. An '<a href="vorbis-ogg.html">Ogg Vorbis
|
||||
Audio Bitstream</a>', for example, has a <a
|
||||
href="vorbis-ogg.html">specific physical bitstream structure</a>.
|
||||
restrictive) mapping. An 'Ogg Vorbis Audio Bitstream', for example, has a
|
||||
specific physical bitstream structure.
|
||||
An 'Ogg A/V' bitstream (not currently specified) will also mandate a
|
||||
specific, restricted physical bitstream format.<p>
|
||||
specific, restricted physical bitstream format.</p>
|
||||
|
||||
<h3>additional end-to-end structure</h3>
|
||||
|
||||
The <a href="framing.html">framing specification</a> defines
|
||||
<p>The <a href="framing.html">framing specification</a> defines
|
||||
'beginning of stream' and 'end of stream' page markers via a header
|
||||
flag (it is possible for a stream to consist of a single page). A
|
||||
flag (it is possible for a stream to consist of a single page). A
|
||||
stream always consists of an integer number of pages, an easy
|
||||
requirement given the variable size nature of pages.<p>
|
||||
requirement given the variable size nature of pages.</p>
|
||||
|
||||
In addition to the header flag marking the first and last pages of a
|
||||
<p>In addition to the header flag marking the first and last pages of a
|
||||
logical bitstream, the first page of an Ogg bitstream obeys
|
||||
additional restrictions. Each individual media mapping specifies its
|
||||
own implementation details regarding these restrictions.<p>
|
||||
additional restrictions. Each individual media mapping specifies its
|
||||
own implementation details regarding these restrictions.</p>
|
||||
|
||||
The first page of a logical Ogg bitstream consists of a single,
|
||||
<p>The first page of a logical Ogg bitstream consists of a single,
|
||||
small 'initial header' packet that includes sufficient information to
|
||||
identify the exact CODEC type and media requirements of the logical
|
||||
bitstream. The intent of this restriction is to simplify identifying
|
||||
bitstream. The intent of this restriction is to simplify identifying
|
||||
the bitstream type and content; for a given media type (or across all
|
||||
Ogg media types) we can know that we only need a small, fixed
|
||||
amount of data to uniquely identify the bitstream type.<p>
|
||||
amount of data to uniquely identify the bitstream type.</p>
|
||||
|
||||
As an example, Ogg Vorbis places the name and revision of the Vorbis
|
||||
<p>As an example, Ogg Vorbis places the name and revision of the Vorbis
|
||||
CODEC, the audio rate and the audio quality into this initial header,
|
||||
thus simplifying vastly the certain identification of an Ogg Vorbis
|
||||
audio bitstream.<p>
|
||||
audio bitstream.</p>
|
||||
|
||||
<h3>sequential multiplexing (chaining)</h3>
|
||||
|
||||
The simplest form of logical bitstream multiplexing is concatenation
|
||||
(<em>chaining</em>). Complete logical bitstreams are strung
|
||||
one-after-another in order. The bitstreams do not overlap; the final
|
||||
<p>The simplest form of logical bitstream multiplexing is concatenation
|
||||
(<em>chaining</em>). Complete logical bitstreams are strung
|
||||
one-after-another in order. The bitstreams do not overlap; the final
|
||||
page of a given logical bitstream is immediately followed by the
|
||||
initial page of the next. Chaining is the only logical->physical
|
||||
mapping allowed by Ogg Vorbis.<p>
|
||||
initial page of the next. Chaining is the only logical->physical
|
||||
mapping allowed by Ogg Vorbis.</p>
|
||||
|
||||
Each chained logical bitstream must have a unique serial number within
|
||||
the scope of the physical bitstream.<p>
|
||||
<p>Each chained logical bitstream must have a unique serial number within
|
||||
the scope of the physical bitstream.</p>
|
||||
|
||||
<h3>concurrent multiplexing (grouping)</h3>
|
||||
|
||||
Logical bitstreams may also be multiplexed 'in parallel'
|
||||
(<em>grouped</em>). An example of grouping would be to allow
|
||||
<p>Logical bitstreams may also be multiplexed 'in parallel'
|
||||
(<em>grouped</em>). An example of grouping would be to allow
|
||||
streaming of separate audio and video streams, using different codecs
|
||||
and different logical bitstreams, in the same physical bitstream.
|
||||
Whole pages from multiple logical bitstreams are mixed together.<p>
|
||||
Whole pages from multiple logical bitstreams are mixed together.</p>
|
||||
|
||||
The initial pages of each logical bitstream must appear first; the
|
||||
media mapping specifies the order of the initial pages. For example,
|
||||
<p>The initial pages of each logical bitstream must appear first; the
|
||||
media mapping specifies the order of the initial pages. For example,
|
||||
Ogg A/V will eventually specify an Ogg video bitstream with
|
||||
audio. The mapping may specify that the physical bitstream must begin
|
||||
audio. The mapping may specify that the physical bitstream must begin
|
||||
with the initial page of a logical video bitstream, followed by the
|
||||
initial page of an audio stream. Unlike initial pages, terminal pages
|
||||
initial page of an audio stream. Unlike initial pages, terminal pages
|
||||
for the logical bitstreams need not all occur contiguously (although a
|
||||
specific media mapping may require this; it is not mandated by the
|
||||
generic Ogg stream spec). Terminal pages may be 'nil' pages,
|
||||
generic Ogg stream spec). Terminal pages may be 'nil' pages,
|
||||
that is, pages containing no content but simply a page header with
|
||||
position information and the 'last page of bitstream' flag set in the
|
||||
page header.<p>
|
||||
page header.</p>
|
||||
|
||||
Each grouped bitstream must have a unique serial number within the
|
||||
scope of the physical bitstream.<p>
|
||||
<p>Each grouped bitstream must have a unique serial number within the
|
||||
scope of the physical bitstream.</p>
|
||||
|
||||
<h3>sequential and concurrent multiplexing</h3>
|
||||
|
||||
Groups of concurrently multiplexed bitstreams may be chained
|
||||
consecutively. Such a physical bitstream obeys all the rules of both
|
||||
<p>Groups of concurrently multiplexed bitstreams may be chained
|
||||
consecutively. Such a physical bitstream obeys all the rules of both
|
||||
grouped and chained multiplexed streams; the groups, when unchained ,
|
||||
must stand on their own as a valid concurrently multiplexed
|
||||
bitstream.<p>
|
||||
bitstream.</p>
|
||||
|
||||
<h3>multiplexing example</h3>
|
||||
|
||||
Below, we present an example of a grouped and chained bitstream:<p>
|
||||
<p>Below, we present an example of a grouped and chained bitstream:</p>
|
||||
|
||||
<img src=stream.png><p>
|
||||
<p><img src="stream.png" alt="stream"/></p>
|
||||
|
||||
In this example, we see pages from five total logical bitstreams
|
||||
multiplexed into a physical bitstream. Note the following
|
||||
characteristics:
|
||||
<p>In this example, we see pages from five total logical bitstreams
|
||||
multiplexed into a physical bitstream. Note the following
|
||||
characteristics:</p>
|
||||
|
||||
<ol><li>Grouped bitstreams begin together; all of the initial pages
|
||||
must appear before any data pages. When concurrently multiplexed
|
||||
<ol>
|
||||
<li>Grouped bitstreams begin together; all of the initial pages
|
||||
must appear before any data pages. When concurrently multiplexed
|
||||
groups are chained, the new group does not begin until all the
|
||||
bitstreams in the previous group have terminated.<p>
|
||||
bitstreams in the previous group have terminated.</li>
|
||||
|
||||
<li>The pages of concurrently multiplexed bitstreams need not conform
|
||||
to a regular order; the only requirement is that page <tt>n</tt> of a
|
||||
logical bitstream follow page <tt>n-1</tt> in the physical bitstream.
|
||||
There are no restrictions on intervening pages belonging to other
|
||||
logical bitstreams. (Tying page appearance to bitrate demands is one
|
||||
logical bitstreams. (Tying page appearance to bitrate demands is one
|
||||
logical strategy, ie, the page appears at the chronological point
|
||||
where decode requires more information).
|
||||
|
||||
where decode requires more information).</li>
|
||||
</ol>
|
||||
|
||||
<hr>
|
||||
<a href="http://www.xiph.org/">
|
||||
<img src="white-xifish.png" align=left border=0>
|
||||
</a>
|
||||
<font size=-2 color=#505050>
|
||||
<div id="copyright">
|
||||
The Xiph Fish Logo is a
|
||||
trademark (™) of Xiph.Org.<br/>
|
||||
|
||||
Ogg is a <a href="http://www.xiph.org">Xiph.org Foundation</a> effort
|
||||
to protect essential tenets of Internet multimedia from corporate
|
||||
hostage-taking; Open Source is the net's greatest tool to keep
|
||||
everyone honest. See <a href="http://www.xiph.org/about.html">About
|
||||
the Xiph.org Foundation</a> for details.
|
||||
<p>
|
||||
|
||||
Ogg Vorbis is the first Ogg audio CODEC. Anyone may freely use and
|
||||
distribute the Ogg and Vorbis specification, whether in a private,
|
||||
public or corporate capacity. However, the Xiph.org Foundation and
|
||||
the Ogg project (xiph.org) reserve the right to set the Ogg Vorbis
|
||||
specification and certify specification compliance.<p>
|
||||
|
||||
Xiph.org's Vorbis software CODEC implementation is distributed under a
|
||||
BSD-like license. This does not restrict third parties from
|
||||
distributing independent implementations of Vorbis software under
|
||||
other licenses.<p>
|
||||
|
||||
Ogg, Vorbis, Xiph.org Foundation and their logos are trademarks (tm)
|
||||
of the <a href="http://www.xiph.org/">Xiph.org Foundation</a>. These
|
||||
pages are copyright (C) 1994-2002 Xiph.org Foundation. All rights
|
||||
reserved.<p>
|
||||
These pages © 1994 - 2005 Xiph.Org. All rights reserved.
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user