Skip to content

Documentation

MPEG Transport Stream Explained

A working engineer's reference to the container that carries DVB broadcast delivery — including today's H.264 and H.265 services, because "MPEG-2" here names the container, not the video codec. Covers the 188-byte packet and where that number came from, the 4-byte header field by field, how PIDs identify elementary streams, the difference between PES and section payloads, the full PSI/SI table map, and how PCR, PTS and continuity counters keep a stream coherent — with the practical consequences visible in a real SAT>IP implementation throughout.

  • 2026-09-24 10:57
  • 2026-09-24 14:11

The numbers worth memorizing

1. Scope and audience

The MPEG-2 Transport Stream is the container DVB broadcast delivery travels in, whether the last hop is satellite, terrestrial or cable. Its structure is defined in ISO/IEC 13818-1, published jointly as ITU-T H.222.0; the signalling tables that make a broadcast navigable are defined by DVB in ETSI EN 300 468.

“MPEG-2” here means the container, not the codec. This is the single most common misreading of the name, and it matters because almost nothing broadcast today uses MPEG-2 video. Two different standards share the family name:

  • ISO/IEC 13818-1 — MPEG-2 Systems. The transport stream. This document.
  • ISO/IEC 13818-2 — MPEG-2 Video. A codec from the 1990s, now largely legacy.

A modern H.265/HEVC UHD service is HEVC video inside an MPEG-2 Transport Stream. Both statements are true simultaneously. The DVB codec specification is titled, in full, “Specification for the use of Video and Audio Coding in Broadcasting Applications based on the MPEG-2 Transport Stream” — which is DVB stating plainly that new codecs ride in this same container. Section 3 lists what is actually carried today.

This sheet is written for engineers who need to work with real streams rather than pass an exam: people debugging a feed that will not decode, sizing a link, writing software that demultiplexes, or trying to understand why a perfectly locked carrier still produces unwatchable output. Every structural claim here is traceable to the standards listed in section 20.

Throughout, the practical consequences are illustrated with SATLINE SAT>IP Servers Pro, our own SAT>IP server implementation. The point is not the product — it is that transport-stream theory has direct, visible consequences in production code, and it is easier to understand a 13-bit PID field when you can see what a server does with the value 8192.

Companion sheets: for constructing tuning requests and the full parameter list, see SAT>IP URL Builder & T2-MI Configuration. For choosing how signal reaches your platform in the first place, see the satellite ingest tier guide.

2. Why 188 bytes?

A transport stream is a continuous, synchronous sequence of fixed-length packets. Each is exactly 188 bytes: a 4-byte header followed by up to 184 bytes of payload. The number looks arbitrary and is not.

When MPEG-2 Systems was being specified, ATM was expected to carry broadcast video. The payload of an ATM Adaptation Layer 1 cell is 47 bytes, and 4 × 47 = 188, so one transport packet fits exactly into four AAL-1 cells with no padding and no straddling. ATM did not become the broadcast transport it was expected to be, but the packet size outlived the reason for it, and every DVB, ATSC and ISDB deployment in the world still carries 188-byte packets today.

Fixed length is the property that matters now. A demultiplexer never has to parse a length field to find the next packet; it steps forward 188 bytes and expects a sync byte. That makes recovery from corruption cheap, which is exactly what you want on a lossy medium.

2.1. Where 188 shows up in real code

The constant propagates into everything that touches a stream. In SAT>IP Servers Pro, both the application-level adapter buffer and the kernel DVB buffer must be exact multiples of 188 — the defaults are 376000 bytes (2000 packets) and 5775360 bytes (30720 packets), tunable with -b. A buffer that is not packet-aligned will eventually split a packet across a read boundary and force the demux to resynchronize for no reason.

Practical note: if you are writing anything that reads a transport stream, align every buffer, every socket read size and every file chunk to 188 bytes. Most “random glitches every few seconds” reports in home-grown ingest code trace back to a buffer size that is a round decimal number rather than a multiple of 188.

3. What DVB actually carries today

The container has not changed since the 1990s. Almost everything inside it has. The authoritative list is ETSI TS 101 154, currently at V2.10.1, whose scope covers satellite, cable and terrestrial broadcasting and IP-based networks, spanning SDTV, HDTV, stereoscopic 3DTV and both phases of UHDTV, plus DVB Next Generation Audio.

3.1. The container is not universal across all of DVB

One qualification the name invites people to miss. MPEG-2 TS is the container for DVB broadcast delivery. DVB’s IP-delivery specifications do not use it:

The engineering reason is structural rather than fashion: transport stream was designed for a continuous synchronous broadcast and is a poor fit for segmented delivery and mid-stream representation switching, where it carries a worse overhead-to-payload ratio than fragmented MP4. Note also that the DVB specification itself has been retitled from “based on the MPEG-2 Transport Stream” to “in Broadcast and Broadband Applications” — the standards body making the same distinction.

Practical consequence for ingest. If your feed arrives from satellite, terrestrial or cable, it is a transport stream and everything in this document applies. If it arrives as DASH or HLS segments, you are in ISOBMFF and this document describes the wrong layer. A hybrid platform routinely handles both, and conflating them is a real source of pipeline bugs — a TS demux will make no sense of a CMAF segment.

4. The 4-byte packet header, field by field

Every packet opens with the same four bytes. The fields are small, and each one earns its place.

Four bytes of overhead on 188 is roughly 2.1%, which is the price of being able to multiplex thousands of independent streams into one bitstream and demultiplex any of them without state.

5. The adaptation field

When the adaptation-field control bits say so, an optional variable-length field sits between the header and the payload. It is effectively an extended header, and it carries three things worth knowing about:

The adaptation field is why payload is described as “up to 184 bytes” rather than “184 bytes”. A packet with a large adaptation field may carry very little actual content, and a stream whose adaptation fields are consistently large is wasting capacity.

6. PIDs and elementary streams

A transport stream is a multiplex of elementary streams. An elementary stream is nothing more mysterious than the concatenation of the payloads of every packet sharing a PID value. Video is one elementary stream, each audio language is another, each subtitle track another, and the signalling tables occupy their own.

Thirteen bits means up to 8192 elementary streams can coexist in one multiplex — 0x0000 through 0x1FFF. In practice a satellite transponder carries a few dozen. The address space is generous because it costs nothing to be generous with it.

Demultiplexing is trivial: filter on a PID value and concatenate payloads. Multiplexing is the hard direction, because packets from every stream have to be interleaved smoothly enough that no decoder buffer starves or overflows.

6.1. The 8192 sentinel — a worked example

Because valid PIDs stop at 8191, the value 8192 is unusable as a real PID — which makes it a natural sentinel for “everything”. SAT>IP Servers Pro uses exactly that: a request for pids=all is mapped internally to PID 8192, meaning pass the entire transponder rather than filter. A request for pids=0,1,17,18,1500,1501 instead builds a filtered single-program stream containing only those PIDs.

This is worth pausing on, because it explains a real behavior. A full multiplex and a filtered selection are the same code path with a different PID set; the sentinel is what distinguishes them. It is also why the choice is a per-request parameter rather than a provisioning decision — the client states which PIDs it wants each time it connects.

6.2. Reserved PID values

Two ends of the range are special. 0x0000 to 0x001F are reserved for signalling, mapped in section 11. At the top, 0x1FFF carries null packets: padding with no content, inserted to hold a constant bitrate when the real streams do not fill it. A transponder running well below capacity is mostly null packets, and a rising null-packet ratio is a useful signal that a multiplexer is under-filled.

7. Two kinds of payload: PES and sections

Every elementary stream carries one of two payload structures, and knowing which is which determines how you parse it.

One useful exception to the one-thing-per-stream rule: a teletext elementary stream is itself a multiplex of many text “pages”, so a single PID can carry a whole teletext service.

8. How PES data is packetized

A typical PES packet spans three phases across the transport layer:

That last detail is the reason stuffing exists. Transport packets are fixed length and PES packets are not, so something has to absorb the remainder.

Why this matters for loss: packet loss inside audio and video is survivable. The visible result is a macroblock smear or an audio glitch, and how gracefully it recovers depends on the decoder. Codec bitstreams contain their own synchronization patterns — NAL unit boundaries in AVC, for instance — so a decoder can often resynchronize inside a PES packet without waiting for the next PUSI.

9. Sections, tables and versioning

A table is split into one or more sections, and sections are the unit that actually travels. The distinction matters because the two section syntaxes behave very differently.

9.1. Short sections

One section per table — section and table are equivalent. Used for CA messages (ECM and EMM) and for time and date information (TDT and TOT). There is no standard integrity check beyond the section length field; some table types add their own, such as cryptographic integrity inside ECM and EMM, or a CRC32 in the TOT.

9.2. Long sections

Up to 256 sections per table, all of which must be received to rebuild the complete table. Long sections add two mechanisms that make broadcast signalling workable:

Because sections are packed back to back inside a PID, a packet carrying PUSI also carries a pointer field giving the offset to the first section start in that packet — the bytes before it are the tail of the previous section. Parsers that ignore the pointer field work most of the time and then fail confusingly.

10. PSI versus SI — who defines what

Two different bodies define signalling, and the distinction is not pedantic — it tells you which specification to open when something is missing.

A stream can be structurally valid MPEG and useless as television. If the PAT and PMT are correct but the SDT is absent, a decoder can extract and play the video while showing no channel name; if the EIT is absent, there is no programme guide. Conversely, no amount of SI compensates for a missing PMT.

11. The well-known PID map

Signalling lives at fixed, reserved PIDs so that a receiver knows where to start with no prior knowledge. These values are worth committing to memory.

PMT PIDs are not fixed. Each service’s PMT sits on a PID chosen by the multiplexer and announced in the PAT — which is why the PAT must be read first.

Note also that both NIT and SDT and EIT exist in “actual” and “other” variants: a stream can describe itself, and it can describe other transport streams and networks. That is how a receiver builds a full channel list from a single tuned transponder.

12. Walking PAT to PMT to elementary streams

Finding the video and audio for one channel is a three-step traversal, and every DVB receiver in existence performs it on every channel change:

12.1. What a real implementation does with this

SAT>IP Servers Pro exposes this traversal directly. Ask it for a program by PMT PID — streamid=pmt=1500, or just the number 1500 — and it locates the PMT, derives the per-program PID list (PMT + PCR + audio/video + PSI) and emits a single-program transport stream containing exactly that.

The failure mode is instructive. If the PMT is not yet known — which is normal in the moments right after tuning, because tables are broadcast on a cycle rather than being available on demand — the request is rejected with a log line to that effect, and the client is expected to retry. That is not a defect; it is the honest response to being asked for something the stream has not yet described. Any ingest software that appears to “sometimes fail on startup” is usually racing PSI acquisition in exactly this way.

Design consequence: a request expressed as an explicit PID list needs no table knowledge and can be served immediately. A request expressed as a program needs the PMT first. If startup latency matters to you, name your PIDs.

13. Timing: PCR, PTS and DTS

A transport stream carries no inherent notion of time. Timing is reconstructed from timestamps, and getting it wrong produces the failures that are hardest to diagnose: drifting lip sync, periodic stutter, decoders that run dry after twenty minutes.

13.1. PCR — Program Clock Reference

The PCR is a sample of the encoder’s 27 MHz system clock, carried in the adaptation field of the PID nominated as the PCR PID in the PMT. Its job is to let the decoder regenerate that clock.

It is encoded as 42 data bits in two parts: a 33-bit base counting at 90 kHz — the same units as PTS and DTS — and a 9-bit extension counting the remaining 27 MHz ticks. The full value is PCR_base × 300 + PCR_ext, since 27 MHz ÷ 90 kHz = 300. Those 42 bits sit inside a 48-bit field, the remaining 6 being reserved.

ISO/IEC 13818-1 requires a PCR at least every 100 ms. Individual broadcast profiles may demand tighter intervals. A decoder recovers the clock with a phase-locked loop driven by the difference between arriving PCR values and its own count, so PCR jitter — irregular arrival rather than wrong values — degrades recovery even when every timestamp is technically correct. This is why naively remultiplexing a stream and reinserting PCRs at the wrong instants breaks playback that was previously fine.

13.2. PTS and DTS

Presentation and Decoding Time Stamps live in PES headers and count at 90 kHz. PTS says when to present a frame; DTS says when to decode it. They differ whenever coding order differs from display order — which is whenever B-frames are used, since a frame that displays later must be decoded earlier to serve as a reference.

Both are interpreted against the clock the PCR reconstructs. That is the whole architecture: one clock per program, recovered from PCR, with PTS and DTS as offsets against it.

14. The continuity counter and detecting loss

The 4-bit continuity counter increments for each packet carrying payload on a PID, modulo 16. A receiver that sees a gap knows packets were lost, and this is the primary loss-detection mechanism in the entire container.

Its blind spot is worth knowing: because the counter is 4 bits, the loss of an exact multiple of 16 packets is undetectable — the counter lands precisely where it would have anyway. Continuity counting is an excellent cheap check, not a guarantee.

Continuity errors are usually reported as a rate, and interpreting them correctly saves a lot of wasted effort:

14.1. A real-world cause that is not signal

That last case is common enough to be worth a concrete example. Polling a DVB frontend for signal statistics competes with the demux for driver attention, and on some hardware and driver combinations the polling itself induces continuity errors. SAT>IP Servers Pro exposes -M *:0-0, which disables frontend polling entirely and, as its own documentation notes, “may solve CC errors with some hardware/drivers”.

The trade-off is explicit: you lose live signal-quality reporting and gain a clean stream. Being able to make that trade deliberately, rather than discovering it by accident, is the difference between understanding the container and guessing at it.

15. Null packets, stuffing and constant bitrate

Broadcast links run at a fixed bitrate whether or not there is content to fill them. When the real streams fall short, the multiplexer inserts null packets on PID 0x1FFF. They are discarded on arrival and exist purely to hold the rate constant.

This has two practical consequences. First, the useful bitrate of a transponder is always below its gross bitrate, and the gap is null packets. Second, null-packet ratio is a free diagnostic: a multiplex that is 40% null is either deliberately under-filled or has lost a service.

Stuffing appears again in conditional access. SAT>IP Servers Pro’s -E flag passes encrypted packets through to the client even when decryption failed; doubling it (-E -E) sends the undecrypted packets as stuffing packets instead, which keeps ordinary players from choking on data they cannot interpret. It is a small option that only makes sense once you know that stuffing is a first-class concept in the container rather than a hack.

16. Scrambling and conditional access in the container

Conditional access is a large subject; what matters here is the small part of it the transport stream itself defines.

DVB SimulCrypt exists so that several conditional-access systems can protect the same content simultaneously — one broadcast operator serving multiple commercial operators, or a transition between CA generations. The broadcast side stays simple: common scrambling, plus multiple ECM and EMM streams with standard signalling. The head-end side is where the complexity lives.

16.1. Implementation touchpoints

SAT>IP Servers Pro shows how these structures surface in an implementation: it supports the dvbapi protocol for software decryption with an official subscription, and DVB-CI/DDCI for cards with CA hardware. Options exist to control CAT propagation to a DDCI device (-5), to limit PMT scanning to what a client actually asked for (-9, which improves reliability for channels carried by several providers), and to strip all CA descriptors from the PSI so a successfully decrypted service presents as clear to the client (-t --cleanpsi).

That last one is a neat illustration of PSI being editable data rather than fixed truth. The video is now unscrambled, so the tables that still advertise it as scrambled are wrong, and rewriting them is the correct fix.

17. T2-MI — a transport stream inside a transport stream

Several broadcasters distribute a complete DVB-T2 multiplex over satellite by encapsulating it in T2-MI, the DVB-T2 Modulator Interface. What you receive is an outer transport stream whose payload on one PID is not video but an entire inner transport stream, wrapped in baseband frames and L1 signalling, potentially carrying several PLPs (Physical Layer Pipes).

Point a normal demux at it and you get nothing useful. The outer PSI describes a T2-MI stream, not channels. Something has to decapsulate and select a PLP before the inner tables become readable.

17.1. The T2-MI packet, field by field

T2-MI is specified in ETSI TS 102 773, currently V1.4.1 (2016-03), as the interface between a DVB-T2 gateway and a modulator. Its packets are embedded in the outer transport stream by data piping — the outer PID carries T2-MI packets rather than PES or sections, which is exactly why a conventional demux finds nothing usable in it.

Each T2-MI packet is a 6-byte header, a variable-length payload, optional padding, and a 32-bit CRC tail:

That CRC covering the whole packet is why the failure described in section 18 presents the way it does: lose a fraction of the encapsulated bytes and essentially every T2-MI CRC fails, while the outer carrier still measures perfectly.

17.2. T2-MI packet types

Twelve types are defined; everything else is reserved for future use.

For practical work only three of these usually matter. Baseband frames (0x00) carry the payload you want. L1-current (0x10) tells you the PLP layout, so it is what you read to discover which PLPs exist rather than guessing. Timestamps (0x20) matter only if you are driving transmitters.

Reference implementation. If you are writing a decapsulator, the dvb-t2mi Rust crate is a readable parser and builder for all twelve packet types against TS 102 773 V1.4.1, with typed accessors for L1-pre and L1-post, decoded FFT and guard-interval enums, UTC-decoded timestamps, and both multi-PLP passthrough and single-PLP filtering. Useful as a cross-check even if you are implementing in another language.

17.3. Extracting the inner stream in practice

SAT>IP Servers Pro performs this in the streaming pipeline for HTTP, RTSP and SRT outputs alike, controlled by three parameters:

Handled conventionally this requires a discrete decapsulator or gateway between demodulator and streamer — a device whose entire purpose is removing a layer of packaging. Doing it in the pipeline removes that box from the architecture.

18. When the hardware loses packets: raw BBFrame reconstruction

This section describes a failure that looks impossible and a fix that only makes sense if you understand the layers below the transport stream. It is the best argument we can offer that container knowledge is not academic.

On some DVB-S2 multistream (MIS) transponders carrying a bursty T2-MI feed, the demodulator’s hardware MIS-to-TS de-encapsulation drops packets — typically around 9%. The RF is perfect. Signal strength is fine, the carrier is locked, and the inner DVB-T2 multiplex is nonetheless undecodable, with near-total T2-MI CRC failure. Every instinct says signal problem, and every signal measurement says otherwise.

The cause is that the hardware de-encapsulation step is lossy for this traffic pattern. The fix is to stop asking the hardware to do it. On STiD135-based tuners with the raw-bbframe driver patch, bbframe=1 tunes the adapter so the demodulator emits raw DVB-S2 baseband frames, and SAT>IP Servers Pro reconstructs the outer transport stream losslessly in software before handing it to the normal T2-MI demux.

The implementation detail worth admiring: it sets a reserved DTV_STREAM_ID bit (0x40000000) per tune, so the same card continues serving conventional transport-stream transponders concurrently. It is not a card-wide mode switch.

Worked example — RAI 4K at 5°W, 12606 V, DVB-S2 8PSK 2/3, ISI 5, T2-MI:

?src=1&freq=12606&pol=v&msys=dvbs2&mtype=8psk&sr=35300&fec=23&ro=0.35&isi=5&plsm=gold&plsc=131070&bbframe=1&pids=all&t2mi_pid=4096&t2mi_plp=0

Note plsm=gold is a name, not a number — a numeric value is parsed as root mode and re-derives the code, which is a different thing.

Diagnosing this without understanding baseband frames, multistream input selection and T2-MI encapsulation as distinct layers would be close to impossible. You would spend the time on the dish.

19. Multiplexing in practice: one tuner, many clients

Because demultiplexing is a filter operation, one tuned transponder can serve many consumers who each want different parts of it. SAT>IP Servers Pro is built around this: a single DVB card streams to multiple clients simultaneously, each opening a different PID set.

This is a direct consequence of the container’s design. The transponder arrives once; each client’s request is a PID filter applied to it. A client wanting one radio station receives a handful of PIDs; a client wanting the full multiplex receives the 8192 sentinel; a client wanting one television service receives PMT plus PCR plus audio/video plus PSI. No retuning, no duplication of reception.

The same logic extends to output transports. The identical PID selection can be delivered over HTTP, RTSP, or SRT — for example streamid=pids=0,1,17,18,1500,1501,1502,1508 maps exactly onto the HTTP pids= list. The container is transport-agnostic; only the wrapper changes.

SAT>IP Servers Pro implements SAT>IP protocol specification v1.2.2 and has been tested against DVB-S, DVB-S2, DVB-T, DVB-T2, DVB-C, DVB-C2, ATSC and ISDB-T, on x86-64, x86, ARM and MIPS, requiring DVB API 5. Because the interface is the published standard rather than something proprietary, existing clients work unmodified — Tvheadend, DVBViewer, VDR, VLC and mobile applications among them.

Try it: a single radio service from Hotbird 13°E is three PIDs — ?msys=dvbs&freq=11623&pol=v&sr=27500&pids=0,10750,254. PID 0 is the PAT, and the other two are the PMT and audio. That URL is the whole of this document in one line.

20. Standards

Structural facts in this document were verified against ISO/IEC 13818-1 and ETSI EN 300 468 as summarized in TSDuck’s An introduction to MPEG-TS by Thierry Lelégard, the author of TSDuck. Implementation behavior is drawn from the SAT>IP Servers Pro documentation and source.

21. Sources

[1] TSDuck, “An introduction to MPEG-TS” by Thierry Lelégard, tsduck.io. Verified September 2026. Source for the transport stream structural facts in this document, as summarized from ISO/IEC 13818-1 (MPEG-2 Systems) and ETSI EN 300 468 (DVB Service Information).

[2] ETSI Standards portal, etsi.org/standards. Verified September 2026. Reference for ETSI EN 300 468 and the related DVB specifications.

[3] SATLINE.TV Virtual SAT>IP Servers page, satline.tv/virtual-sat-ip-servers. Verified September 2026. Source for the SAT>IP Servers Pro implementation behavior described in this document.

[4] SATLINE.TV tools page, satline.tv/tools. Verified September 2026. Source for the Astra and TVHeadend deployment scripts.

Two things to check before publishing. ISO/IEC 13818-1 is published by ISO, not ETSI, so [2] only covers EN 300 468. If you want a direct reference for 13818-1, add an iso.org entry. Also, your original intro mentions the SAT>IP Servers Pro “source.” If that means source code hosted somewhere other than satline.tv/tools, it needs its own entry.

Gleb Sazanov

Chief Technology Officer

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.

Table of contents

Gleb Sazanov
Chief Technology Officer