MPEG-2: Understanding the Transport Stream Structure

Amitdogra
7 min readJun 8, 2024

--

Transport Stream

A transport stream consists of packets of fixed length, consisting of 4 bytes of header(including a 13-bit packet identifier (PID)) followed by 184 bytes of data obtained by chopping up the data in the PES packets.

Packets make up a transport stream.

The Header

Header takes up exactly 4-bytes.

Sync byte

The sync byte is actually a full byte! It’s the only one, and it was purposeful. It’s intended purpose is to make seeking and finding the start of TS packets easy. You simply read the file until you find that byte, and then you can parse the following bytes, which allows you to “make the call” if it’s a TS packet, and then look for the next sync byte to find the start of the next packet.

Packet Identifiers (PID)

Packet identifiers, or PID for short, are used to identify packets that are related to the same “packetized” data. Some PIDs are reserved, this is intended so that you know what PID to look for specific pieces of data such as the Program Specific Information* *tables.

Payload Unit Start Indicator (PUSI)

Payload Unit Start Indicator or PUSI for short, will be set to true when specific payloads are starting. For example, when the PSI is in the payload, this flag will be set to 1. Another important example is PES packets (Packetized Elementary Stream).

Continuity Counter

An increasing number per PID, incremented when the payload flag is set in the Adaptation Field Control bits. Can be used to order the packets before passing to decoder and identify gaps. (What do you do when there is one? confirm?!)

When a file is being encoded, you can identify what PID should be used if your downstream system cares. We identify the PID currently in the analyzer tool by the “stream_type” value that is associated so we can detect what PID was used by FFmpeg out of the reserved set.

The Payload

Program Specific Information (PSI)

Program Specific Information or PSI, is a collection of “tables”. Each table begins with a header, which is defined below, and these are included in the payload of a packet. The PSI tables are one type of packet that can trigger the Payload Unit Start Indicator to be set.

Program-specific information (PSI) is metadata about a program (channel) and part of an MPEG transport stream.

The PSI data includes four tables:

  • PAT (Program Association Table)
  • CAT (Conditional Access Table)
  • PMT (Program Mapping Table)
  • NIT (Network Information Table)

Program Association Table (PAT)

The program association table (PAT) lists all programs available in the transport stream. Each of the listed programs is identified by a 16-bit value called program_number. Each of the programs listed in PAT has an associated value of PID for its PMT.

The value 0x0000 for program_number is reserved to specify the PID where to look for network information table. If such a program is not present in PAT the default PID value (0x0010) shall be used for NIT.

TS packets containing PAT information always have PID 0x0000, and table id 0x00.

As noted above in the diagram, all the tables end with a checksum, so you can always guarantee that the data came over the wire correctly. This is part of the error detection properties of MPEGTS.

Program Map Table (PMT)

PMTs contain information about programs. For each program, there is one PMT. While the MPEG-2 standard permits more than one PMT section to be transmitted on a single PID (Single Transport stream PID contains PMT information of more than one program), most MPEG-2 “users” such as ATSC and SCTE require each PMT to be transmitted on a separate PID that is not used for any other packets.

The PMTs provide information on each program present in the transport stream, including the program_number, and list the elementary streams that comprise the described MPEG-2 program

The Program Map Table or PMT describes the contents of each PID, so combined with the Program Association Table, you can produce the expected content of the stream of data, and if we were in a multi-program environment, of that particular program.

Inside the PMT is a PID reference for the Program Clock Reference (PCR), which is what the decoder can use to synchronize the playback of the multiple streams. The packet identified by this PID will contain a timestamp in the adaptation field of that packet, this timestamp can be used to generate a clock in the decoder. The Presentation timestamps are relative to this value.

Another concept that is introduced here is the Elementary Stream (ES), this is finally, the ACTUAL data that you are trying to deliver. The rest of what has been described so far is the mechanism to get it to the end-user, and able to be reassembled into something for playback!

The elementary stream type is an 8-bit value.

Some examples values for stream types are:

  • 27 == H.264
  • 15 == AAC audio

Also inside the PMT are additional descriptors, some things of interest are part of this, but many are defined as optional and many decoders don’t use the data included as the DVB standard says that many values should be ignored.

Packetized Elementary Stream (PES)

The payload of a TS packet can be a PES packet. It begins with a start code to identify them easily when parsing payloads, and a stream id which identifies the type of data that is being delivered.

In the world of MPEGTS this is where things start to become very individualized to the type of data that is being transferred.

Network Information Table (NIT)

The NIT (Network Information Table) is a section of the MPEG transport stream that carries information about the network to which the receiver is connected.

The NIT provides essential information about the network, including details about the transport streams available within the network. NIT has a Table ID value of `0x40`, which identifies it as the Network Information Table.

The NIT consists of various fields and descriptors, including the network ID, descriptors for the network, transport stream information, and descriptors for each transport stream.

Network ID: This field indicates the unique identifier for the network.

Descriptors: Descriptors provide additional information about the network or transport streams, such as the network name, provider information, and other network-related details.

To parse the NIT, one needs to read the section header and extract information such as the network ID, descriptors, and information about the transport streams.

private static void parseNITPacket(byte[] packetData) {
// Section length
int sectionLength = ((packetData[6] & 0x0F) << 8) | (packetData[7] & 0xFF);

// Network ID
int networkId = ((packetData[8] & 0xFF) << 8) | (packetData[9] & 0xFF);

// Descriptors
int descriptorsLength = sectionLength - 5; // 5 bytes for fixed fields
int currentIndex = 10; // Start index of descriptors
while (currentIndex < packetData.length && descriptorsLength > 0) {
// Descriptor Tag
int descriptorTag = packetData[currentIndex] & 0xFF;

// Descriptor Length
int descriptorLength = packetData[currentIndex + 1] & 0xFF;

// Descriptor Data
byte[] descriptorData = Arrays.copyOfRange(packetData, currentIndex + 2, currentIndex + 2 + descriptorLength);

// Process the descriptor data according to its tag

// Move to the next descriptor
currentIndex += 2 + descriptorLength;
descriptorsLength -= 2 + descriptorLength;
}

System.out.println("Network ID: " + networkId);
System.out.println("Parsing NIT packet completed.");
}

MpegTs — Short Explanation

The Sync Byte (0x47) marks the beginning of each MPEG-2 transport stream (TS) packet, serving as a synchronization indicator for packet boundaries.

The PID (Packet Identifier) field within each TS packet identifies the type of payload contained in the packet. Different PID values correspond to various components of the transport stream:

  • PID 0x0000 points to the Program Association Table (PAT), which lists all programs and their corresponding Program Map Table (PMT) PIDs.
  • PID 0x0010 points to the Network Information Table (NIT), providing network-related information and descriptors.
  • PIDs obtained from the PAT point to the PMT, which lists all elementary streams (audio, video, etc.) for a specific program.
  • PIDs obtained from the PMT point to the actual elementary streams carrying audio, video, or other data.

The Program Association Table (PAT) is a vital component of the MPEG-2 transport stream. It lists all programs available in the stream along with the PID of their respective Program Map Tables (PMTs).

The Program Map Table (PMT) contains detailed information about the elementary streams associated with a specific program. It lists all elementary streams, such as audio and video streams, along with their corresponding PIDs.

The Network Information Table (NIT) provides network-related information and descriptors within the MPEG-2 transport stream. It includes details about the network structure, service providers, and other relevant information.

Elementary Streams within the MPEG-2 transport stream contain the actual audio, video, or other data transmitted over the network. These streams are identified by their PIDs and are crucial for decoding and playback of multimedia content.

--

--

Amitdogra

Passionate Roku developer with a love for web technologies and backend wizardry. 🚀 ✨ #Android #Streaming #Roku #Web #Nodejs