←Back
⚡ Quick Reference

MPEG Transport Stream

The container DVB broadcast delivery travels in — carrying today's H.264 and H.265 services, because "MPEG-2" names the container, not the codec. Fixed 188-byte packets, 13-bit PIDs, and the tables that turn an opaque bitstream into television.

188
Bytes per packet
0x47
Sync byte, always
8192
Possible PIDs
27 MHz
PCR system clock

First, the name is misleading

MPEG-2 Systems

ISO/IEC 13818-1. The transport stream — the container. Still universal in DVB broadcast.

MPEG-2 Video

ISO/IEC 13818-2. A 1990s codec, now largely legacy. Different standard, same family name.

So an H.265 UHD service is HEVC video inside an MPEG-2 Transport Stream. Both at once. Per ETSI TS 101 154 (V2.10.1), the container carries MPEG-2, AVC, HEVC and VC-1 video, and everything from MPEG-1 Layer II through E-AC-3, AC-4 and MPEG-H audio.
One exception: DVB's IP profiles — DVB-DASH and DVB-I — use ISOBMFF and CMAF segments, not transport stream. Broadcast feeds are TS; DASH/HLS feeds are not. Do not point a TS demux at a CMAF segment.

The packet in one picture

PartSizeNotes
Header4 bytesAlways present. Never scrambled.
Adaptation field0 – 183 bytesOptional. Carries PCR, stuffing, flags.
Payloadup to 184 bytesPES media, or table sections.
Why 188? An ATM AAL-1 cell payload is 47 bytes, and 4 × 47 = 188 — one packet fitted exactly into four cells. ATM never took over broadcast, but the packet size stayed. Align every buffer you write to a multiple of 188.

Header fields worth knowing

FieldBitsWhy you care
sync_byte80x47 every time. How the demux finds alignment.
transport_error_indicator1Upstream demod says this payload is damaged.
PUSI1This packet starts a new payload unit. Your resync anchor.
PID13Which elementary stream. 0x0000–0x1FFF.
scrambling_control2Scrambled? Even or odd key?
adaptation_field_control2Adaptation field present? Payload present?
continuity_counter4Loss detection, mod 16.

Reserved PID map — memorize this

PIDTableWhat it tells you
0x0000PATEvery service, and where its PMT lives. Start here.
0x0001CATEMM streams. Absent if nothing is scrambled.
0x0002TSDTRarely used.
0x0010NITEvery transport stream in the network, with tuning parameters.
0x0011SDT / BATService names; bouquet groupings.
0x0012EITNow/next banner and the full EPG.
0x0013RSTEvent started or ended early.
0x0014TDT / TOTUTC and local offset. Every 10–30 s only.
0x1FFFnullPadding to hold constant bitrate.
PMT PIDs are not fixed. Each service's PMT sits wherever the multiplexer put it, announced in the PAT. That is why you always read PID 0 first.

PSI vs SI — which spec to open

PSI — MPEG

ISO/IEC 13818-1. Structure of the stream itself: PAT, PMT, CAT, TSDT. Present in any conformant TS anywhere in the world.

SI — DVB

ETSI EN 300 468. The stream as a service offering: NIT, SDT, BAT, EIT, RST, TDT, TOT. Names, schedules, networks, time.

Rule of thumb: no PMT means it will not play. No SDT means it plays with no channel name. No EIT means no programme guide.

Five things that bite people

1
Buffers that are not multiples of 188
The classic "random glitch every few seconds"

A round decimal buffer size eventually splits a packet across a read boundary. Align everything to 188.

2
Continuity counter is blind to multiples of 16
4 bits, wraps at 16

Lose exactly 16, 32 or 48 packets and the counter lands where it would have anyway. A cheap check, not a guarantee.

3
CC errors with perfect RF are often software
Frontend polling competes with the demux

On some hardware, polling signal statistics itself causes continuity errors. Disabling frontend polling can clear them — at the cost of live signal reporting.

4
Asking for a program before the PMT arrives
Tables cycle; they are not on demand

Right after tuning, the PMT may not be known yet. Request by explicit PID list and you need no table knowledge; request by program and you must wait.

5
PCR jitter, not wrong PCR values
Irregular arrival breaks clock recovery

The decoder locks a PLL to PCR arrival. Remultiplexing and reinserting PCRs at the wrong instants breaks playback that was previously fine, even when every value is technically correct.

Timing in three lines

StampClockJob
PCR27 MHz — 33-bit base at 90 kHz + 9-bit extensionLets the decoder rebuild the encoder's clock. At least every 100 ms.
DTS90 kHzWhen to decode a frame.
PTS90 kHzWhen to present it. Differs from DTS whenever B-frames are used.
PCR = PCR_base × 300 + PCR_ext — because 27 MHz ÷ 90 kHz = 300.

Two payload types

PES — media

Video, audio, subtitles, teletext. Up to 65536 bytes per PES packet, spread over many TS packets. Start marked by PUSI.

Sections — tables

Signalling. Up to 4096 bytes per section. Long sections carry a version number and a CRC32; short ones carry neither.

Read more

About the author

Gleb Sazanov

Project Leader

Gleb Sazanov is an accomplished Chief Technology Officer (CTO) with over 20 years of experience in software development, system architecture, and cloud-based solutions. As the CTO of SATLINE, a leading provider of virtual and colocation services tailored to SATCOM businesses, Gleb drives the company’s technological strategy, fostering innovation and efficiency in data center services. His expertise spans various domains, including DevOps, system scaling, and high-performance infrastructure management. With a deep passion for cutting-edge technologies, Gleb plays a pivotal role in shaping the future of the SATCOM industry.