PES Packet Encapsulation in DVD VOB Packs
DVD Video Object (VOB) files rely on the MPEG-2 Program Stream specification, dividing multimedia data into fixed-size 2048-byte blocks known as packs. Within each pack, raw audio, video, or subpicture elementary streams are wrapped into Packetized Elementary Stream (PES) packets. This article explains how these elementary streams are formatted, addressed, and encapsulated within an individual VOB pack, detailing the role of pack headers, stream identifiers, synchronization timestamps, and padding mechanisms to ensure DVD hardware compliance.
The Fixed 2048-Byte Pack Structure
A VOB file is a sequence of continuous packs, each exactly 2048 bytes (2 KB) to match the physical sector size of a standard DVD-ROM. Unlike generic MPEG-2 Program Streams that allow variable-length packs, DVD authoring rules mandate this strict 2048-byte boundary.
An individual VOB pack typically encapsulates a single PES packet. The total byte budget of the pack is divided into:
- Pack Header (14 bytes)
- System Header (Optional, typically 24 bytes when present in navigation or initial packs)
- PES Packet (Variable length, consuming the bulk of the remaining bytes)
- Padding Packet or Stuffing Bytes (Variable length, added when the PES payload does not fill the 2048-byte limit)
Step 1: The Pack Header
Every VOB pack begins with a 14-byte Pack Header containing synchronization and multiplexing metadata:
- Pack Start Code (
0x000001BA): A 4-byte prefix identifying the start of a pack. - System Clock Reference (SCR): A 42-bit timestamp encoded across 6 bytes that synchronizes the decoder’s system time clock (STC) with the multiplexer's reference clock.
- MPEG Multiplex Rate: A 22-bit integer indicating the maximum transmission rate of the stream.
- Stuffing Length: Indicates any following pack stuffing bytes (typically set to 0 in standard VOBs).
Step 2: PES Packet Encapsulation
Directly following the Pack Header (or an optional System Header), the elementary stream data is framed by a PES header. The PES packet structure comprises the following fields:
- Packet Start Code Prefix (
0x000001): A 3-byte sequence marking the start of a PES packet. - Stream ID (1 byte): Defines the type and nature of
the encapsulated elementary data:
0xE0–0xEF: MPEG-2 Video streams.0xBD: Private Stream 1 (used for non-MPEG audio like AC-3, DTS, and LPCM, as well as subpicture subtitles).0xBF: Private Stream 2 (used for DVD Navigation Packs, such as PCI and DSI data).0xC0–0xDF: MPEG-1/2 Audio streams.
- PES Packet Length (2 bytes): Specifies the number of bytes remaining in the PES packet, including any PES header extensions and the elementary payload.
Step 3: PES Header Extensions and Timing Data
Following the length field, the PES header includes optional flags and timing mechanisms essential for playback:
- Scrambling and Priority Flags: Indicate encryption states and decoding priority.
- PTS/DTS Flags: Indicate the presence of Presentation Time Stamps (PTS) and Decoding Time Stamps (DTS). PTS dictates when a video frame or audio sample must be displayed, while DTS dictates when compressed data must be extracted and decoded.
- PES Header Data Length (1 byte): Specifies the length of the remaining header fields.
- Sub-stream ID (Private Stream 1 only): For audio
and subtitles wrapped in Stream ID
0xBD, the first byte of the PES payload area is an internal sub-stream identifier (e.g.,0x80–0x87for AC-3,0x20–0x3Ffor subpictures) to route the data to the correct sub-decoder.
Step 4: Payload Insertion and Sector Alignment
The raw elementary stream (compressed video frames, audio frames, or run-length-encoded subtitle data) is placed into the PES payload.
Because elementary stream frames rarely divide evenly into the remaining space of a 2048-byte sector:
- If the payload completes a frame and leaves unused space, a
Padding Packet (Stream ID
0xBE) is appended to the end of the pack. The padding packet consists of the0x000001BEstart code, a 2-byte length field, and stuffing bytes (usually0xFF). - Alternatively, standard PES header stuffing bytes (up to 32 bytes of
0xFF) can be inserted into the PES extension header itself to fill smaller gaps.
Once the payload and necessary padding bytes are assembled, the total block size equals precisely 2048 bytes, completing the encapsulation of the elementary stream into the VOB pack.