OGG File Documentation


Summary

An OGG (Ogg Vorbis Audio) file is lossy-compressed sound stored with the Vorbis codec inside the Ogg container, both from the Xiph.Org Foundation as free, patent-unencumbered alternatives to MP3. At the same bitrate Vorbis generally sounds better than MP3, which is why games and open-source software favour it. Its MIME type is audio/ogg and every file starts with the ASCII marker OggS. Play a .ogg free in VLC or foobar2000; convert to MP3 for devices, such as iPhones, that lack Vorbis support.

Technical details

FeatureValue
Full nameOgg Vorbis Audio File
File extension.ogg (audio), also .oga, .ogv (video)
MIME typeaudio/ogg
Format typeLossy compressed audio — Vorbis codec in an Ogg container
ContainerOgg (page-based multiplexing wrapper)
Audio codecVorbis (container can also carry Opus, FLAC, Speex, Theora)
DeveloperXiph.Org Foundation
IntroducedOgg container 2000; Vorbis 1.0 codec July 2002
Standard / specRFC 3533 (Ogg encapsulation); Xiph Vorbis I specification
Open standardYes — royalty-free, patent-unencumbered (BSD-licensed reference code)
Byte orderLittle-endian (Ogg page header integers)
Magic number4F 67 67 53 (“OggS”) at offset 0 of every page
Sample rateVorbis: 8 kHz–192 kHz
ChannelsUp to 255 (mono, stereo, 5.1 and beyond)
BitrateVariable (VBR), average or constant bitrate modes
MetadataVorbis comments (free-form UTF-8 tags)
Related extensions.oga, .ogv, .opus, .mp3, .flac, .spx
Specificationxiph.org/vorbis/doc/, datatracker.ietf.org/doc/html/rfc3533
File signature (magic bytes)
4F 67 67 53

Offset 0, 4 bytes. In ASCII this is OggS, the capture pattern that begins every Ogg page, not just the first. It identifies the Ogg container, not the codec inside it: a file starting with OggS may hold Vorbis, Opus (OpusHead), FLAC, Speex or Theora video. For Ogg Vorbis the ASCII string vorbis appears a few bytes into the first page’s identification header (around offset 29), right after a 0x01 packet-type byte.

What is an OGG file?

OGG names audio compressed with the Vorbis codec and wrapped in the Ogg container, both from the Xiph.Org Foundation. The Ogg container debuted in 2000 and the Vorbis codec reached version 1.0 in July 2002, designed together as free, patent-unencumbered alternatives to MP3 and AAC. The distinction between the two words matters technically: Ogg is the container, a streaming wrapper that frames and multiplexes data into pages; Vorbis is the audio codec whose compressed packets ride inside those pages. The same Ogg container also carries Opus, FLAC, Speex audio and Theora video, so “an Ogg file” is not necessarily Vorbis.

By convention plain audio is named .ogg (Vorbis) or .oga (any Ogg audio), Opus audio is .opus, and Ogg video is .ogv. Vorbis is lossy like MP3 but uses more modern transform and entropy coding, so at a given bitrate it generally sounds clearly better, especially below 128 kbit/s. Because it costs nothing to use, Vorbis became the default sound format for many games (Unity, the Source engine, RPG Maker and countless indie titles store effects and music as .ogg), for Wikimedia media, and across open-source software. The two enduring user questions — how to play a .ogg and how to convert one to MP3 — both come from Apple’s ecosystem not supporting Vorbis. Everything below is about how the bytes are actually arranged.

The Ogg page: the container’s framing unit

An Ogg bitstream is a sequence of pages. The page is the container’s atomic unit: every logical stream (an audio track, a video track) is chopped into pages, and pages from different logical streams can be interleaved into one physical file. Each page carries a fixed header of at least 27 bytes, defined by RFC 3533, followed by a segment table and then the packet data.

Ogg page header (little-endian, offsets from start of page)
  0   capture_pattern         4 bytes   "OggS" (0x4F 0x67 0x67 0x53)
  4   stream_structure_version 1 byte   0
  5   header_type_flag        1 byte    bit0 continued, bit1 BOS, bit2 EOS
  6   granule_position        8 bytes   codec time reference (see below)
 14   bitstream_serial_number 4 bytes   which logical stream this page belongs to
 18   page_sequence_number    4 bytes   increments per page; detects a lost page
 22   CRC_checksum            4 bytes   CRC-32 over the whole page (poly 0x04C11DB7)
 26   page_segments           1 byte    count N of entries in the segment table
 27   segment_table           N bytes   lacing values (packet lengths)
 27+N ... page body: the actual packet bytes ...

Three header fields do the container’s real work. The bitstream_serial_number tags every page with the logical stream it belongs to, so a demuxer can separate interleaved audio and video by serial number. The page_sequence_number increases by one per page within a stream; a gap tells the decoder a page was lost in transmission. The CRC_checksum is computed over the entire page with the checksum field zeroed, using the CRC-32 polynomial 0x04C11DB7, which lets a streaming client detect corruption without any container-level retransmission. The header_type_flag marks a page as the beginning-of-stream (BOS) or end-of-stream (EOS), and whether the first packet is continued from the previous page.

The segment table: lacing values and packet boundaries

Ogg does not store an explicit length for each packet. Instead the page_segments byte says how many lacing values follow, and each lacing value is a single byte in the range 0–255. A packet’s length is the sum of consecutive lacing values, and the rule for ending a packet is elegant: a lacing value of 255 means “this segment is full, the packet continues,” while any value less than 255 (including 0) marks the packet’s final segment.

Example segment table:  FF FF 5A 20
  packet A = 255 + 255 + 90  = 600 bytes  (two 255s then a value < 255)
  packet B = 32 bytes                       (single value < 255)

A packet larger than one page runs off the end: its last lacing value on this page is 255, and it resumes on the next page, whose header_type_flag has the “continued” bit set. This scheme lets Ogg frame variable-length codec packets with a single byte of overhead per 255 bytes and no separate index, which is what makes it cheap to generate on the fly for live streaming.

Granule position: how Ogg encodes time

The container itself is codec-agnostic about time. It carries an 8-byte granule_position on each page whose meaning is defined by the codec, not by Ogg. For Vorbis the granule position is the count of PCM audio samples decodable up to and including the last packet that finishes on that page. Because Vorbis runs at a known sample rate, dividing the granule position by that rate gives the playback time in seconds, which is exactly how a player seeks: it binary-searches pages by granule position to land near a target time.

A granule position of -1 (all bits set) means no packet completes on the page, so the field carries no new timing information. Different codecs interpret the same field differently: Opus counts 48 kHz samples regardless of the actual audio rate, Theora packs a frame number and a keyframe offset into two bit-fields. That per-codec meaning is why the container can time any stream without knowing the codec’s internals.

The three Vorbis headers: identification, comment and setup

Inside the pages, a Vorbis logical stream always begins with three mandatory header packets before any audio. They are the first packets of the stream and define everything a decoder needs.

Each Vorbis header packet starts with:  packet_type  "vorbis"
  0x01 vorbis   Identification header
  0x03 vorbis   Comment header (metadata)
  0x05 vorbis   Setup header (codebooks)

The identification header (packet type 0x01) carries the Vorbis version, the audio channel count, the sample rate in Hz, and three bitrate hints (maximum, nominal, minimum). It also encodes the two block sizes as powers of two: Vorbis uses a short window and a long window and switches between them so transients stay sharp while steady tones compress efficiently. The comment header (type 0x03) holds the Vorbis comments: free-form UTF-8 TAG=value pairs such as ARTIST=, TITLE= and ALBUM=, with no fixed length limit, which is why Ogg tagging is more flexible than MP3’s fixed ID3v1 fields. The setup header (type 0x05) is the largest and most important: it contains the codebooks, the Huffman-style entropy tables and the floor and residue configurations the decoder uses to reconstruct every audio packet. Without the setup header the audio packets are undecodable, which is why all three headers must be present and are placed at the very start of the stream.

How a Vorbis audio packet is decoded

Vorbis is a transform codec built on the modified discrete cosine transform (MDCT). Each audio packet decodes one window of samples through a fixed pipeline. The decoder first reads a mode that selects the block size (short or long window). It then reconstructs the spectral envelope, the floor, as a low-resolution curve, and separately decodes the residue, the fine spectral detail, using the codebooks from the setup header. Multiplying floor by residue gives the full spectrum, an inverse MDCT converts it back to time-domain samples, and overlapping windows are added to produce continuous PCM output.

Two design choices explain Vorbis’s quality edge over MP3. The floor/residue split codes the coarse loudness shape and the fine texture with separate, well-matched codebooks, and the adaptive window keeps pre-echo low on percussive sounds. Because the codebooks live once in the setup header rather than in every frame, Vorbis spends its per-packet bits almost entirely on audio, which is part of why it holds up so well at low bitrates. The codec is inherently variable-bitrate: quality-based encoding lets each packet use as many bits as its content needs.

Playing OGG and the codec-versus-container catch

Firefox, Chrome, Edge and Android decode Ogg Vorbis natively; the notable holdouts are Apple’s apps (QuickTime, Apple Music, default iOS players) and some stock Windows setups without an add-on. VLC plays any Ogg codec out of the box on every platform, foobar2000 and Audacity play and re-encode on Windows, and on Windows 10/11 Microsoft’s free Web Media Extensions add Vorbis to the built-in player. When conversion is unavoidable, ffmpeg -i in.ogg -q:a 2 out.mp3 transcodes to MP3 for universal device support; use 192 kbit/s or higher because lossy-to-lossy re-encoding adds a little loss.

The container-versus-codec split has a real diagnostic payoff. A .ogg that a player refuses often is not corrupt: the pages parse (they start with OggS), but the packet inside is a codec the player lacks, most often Opus or FLAC in an Ogg wrapper rather than Vorbis. Checking the first page’s codec signature (vorbis versus OpusHead versus fLaC) tells you which decoder you actually need. That is also why remuxing between Ogg audio types can be lossless when the codec matches, but a Vorbis-to-Opus change is a true re-encode, not a rewrap.

Frequently asked questions

Why does the same “OggS” signature appear many times in one file?

Because OggS is the capture pattern that begins every page, not just the file. Ogg is a paged container, so a long track contains thousands of pages, each starting with OggS, each with its own CRC and sequence number so a streaming client can detect a lost or corrupted page mid-stream.

Why must an Ogg Vorbis file start with three header packets?

The identification, comment and setup headers must precede any audio because the setup header carries the codebooks that decode every audio packet. A stream missing its setup header is unplayable; placing all three at the start lets a decoder initialise fully before the first sample arrives.

What is the difference between OGG, OGA, OGV and OPUS?

Ogg is the container. .ogg and .oga hold audio (usually Vorbis), .ogv holds Theora video, and .opus holds the newer Opus codec, which is also an Ogg stream. They are all Ogg files distinguished by the codec inside.

References