Detecting PES Packet Boundaries in VOB Streams

This article explains the technical process decoders use to locate and delineate Packetized Elementary Stream (PES) packet boundaries within an arbitrary DVD Video Object (VOB) file. Because a VOB file is fundamentally an implementation of the MPEG-2 Program Stream (PS) standard, decoders rely on unique 32-bit start code prefixes, the 16-bit PES packet length field, and DVD-specific 2,048-byte sector alignments to reliably isolate packets even when starting playback from an arbitrary byte position.

The Underlying VOB Structure

A VOB stream is a specialized MPEG-2 Program Stream structured into discrete 2,048-byte (2 KB) packs, matching the physical sector size of DVD media. Each pack starts with a Pack Header and contains one or more PES packets, which wrap the raw elementary stream data (such as MPEG-2 video, AC-3, DTS, or LPCM audio) alongside presentation timestamps (PTS) and decoding timestamps (DTS).

To extract audio, video, and sub-picture data, the decoder must continuously identify where a PES packet starts and where it terminates.

Step 1: Scanning for the 32-bit Start Code Prefix

When reading an arbitrary stream, the decoder maintains a sliding 4-byte buffer to identify synchronization markers. Every PES packet begins with a standard 32-bit start code:

  1. Prefix (24 bits): 0x00 0x00 0x01
  2. Stream ID (8 bits): A single byte identifying the payload type.

Valid PES stream IDs generally range from 0xBC to 0xFF. Common stream IDs found in VOB files include:

Pack headers (0x00 0x00 0x01 0xBA) and System headers (0x00 0x00 0x01 0xBB) share the same 24-bit prefix, allowing the decoder's parser to distinguish PES packets from higher-level stream structures based solely on the fourth byte.

Step 2: Reading the PES Packet Length

Immediately following the 1-byte stream_id, the MPEG-2 specification defines a 16-bit unsigned integer: PES_packet_length.

+-----------------------------+-----------+-------------------+
| Start Code Prefix (24 bits) | Stream ID | PES Packet Length |
|         0x00 0x00 0x01      |  (8 bits) |     (16 bits)     |
+-----------------------------+-----------+-------------------+

The boundary detection mechanism depends directly on this value:

Step 3: Utilizing Fixed 2,048-Byte Pack Alignment

VOB streams follow strict sector constraints that simplify boundary detection compared to generic MPEG-2 Program Streams:

Because of this rigid geometry, the end of a PES packet inside a VOB invariably coincides with either the end of the 2,048-byte sector or the beginning of a stuffing/padding sequence within that same sector.

Resynchronization on Corrupt or Arbitrary Streams

If a decoder begins reading at an arbitrary point within a VOB stream (such as during seeking or after packet loss), it executes a state-machine resynchronization:

  1. Byte Scan: The parser steps forward byte-by-byte until it locates 0x00 0x00 0x01.
  2. Start Code Evaluation: It checks if the succeeding byte is a valid VOB stream ID or a Pack Header (0xBA).
  3. Length Validation: If a PES start code is identified, the decoder reads the 16-bit length. It then validates whether the end offset calculated from that length aligns with either the next valid start code prefix or the next 2,048-byte pack boundary.
  4. Acceptance: Once the calculated boundary correlates with the start of a new valid header, the decoder locks synchronization and begins routing payload data to the elementary decoders.