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
188-byte packets
13-bit PIDs · 8192 streams
PSI/SI tables
PCR · PTS · DTS
T2-MI & BBFrame
The numbers worth memorizing
Packet
188 bytes = 4-byte header + up to 184 payload
Sync byte
0x47 — every packet, no exceptions
PID
13 bits → 8192 possible streams
Section
up to 4096 bytes
PES packet
up to 65536 bytes
Continuity counter
4 bitswraps every 16 packets
System clock
27 MHzPCR reference
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.
| Layer | Covered by TS 101 154 | In practice |
|---|---|---|
| Video | MPEG-2, H.264/AVC, SVC, MVC Stereo, H.265/HEVC, VC-1 | AVC dominates HD; HEVC is the UHD workhorse. MPEG-2 video survives mainly on legacy SD services. |
| Audio | MPEG-1 Layer I and II, MPEG-2 Layer II, Dolby AC-3, Enhanced AC-3, AC-4, DTS, DTS-HD, MPEG-4 HE-AAC, HE-AAC v2, MPEG-H LC | MPEG-1 Layer II persists on older services; HE-AAC and E-AC-3 are the modern mainstream; AC-4 and MPEG-H carry Next Generation Audio. |
| HDR | UHDTV phase 2 with HDR, including dynamic mapping metadata | Delivered as part of the HEVC UHD profile rather than as a separate stream type. |
| Emerging | VVC (H.266) and AVS3 test content published | Test content exists; treat production readiness as a question for your platform vendors rather than an assumption. |
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:
- DVB-DASH(ETSI TS 103 285) profiles MPEG-DASH for DVB services using ISOBMFF segments, not transport stream.
- CMAF,built on ISOBMFF, is the common segmented container behind both DASH and HLS delivery.
- DVB-Ipresents services over IP with DASH delivery, alongside or instead of broadcast.
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.
| Field | Width | What it does |
|---|---|---|
| sync_byte | 8 bits | Always 0x47. The demux uses it to find and verify packet alignment. (It is the ASCII letter G, which is why hex dumps of transport streams are speckled with G characters.) |
| transport_error_indicator | 1 bit | Set by an upstream demodulator to mark a packet that arrived with uncorrectable errors. Once set it must not be cleared — it is a warning that the payload is untrustworthy. |
| payload_unit_start_indicator | 1 bit | PUSI. Marks a packet that begins a new payload unit — the first byte of a PES packet, or a pointer to the start of a section. This is the resynchronization anchor after loss. |
| transport_priority | 1 bit | Advisory hint that this packet matters more than others on the same PID. Rarely acted upon. |
| PID | 13 bits | Identifies which elementary stream the packet belongs to. Thirteen bits gives 8192 distinct values, 0x0000 to 0x1FFF. |
| transport_scrambling_control | 2 bits | Whether the payload is scrambled, and with which of the two control words (even or odd). Header and adaptation field are never scrambled. |
| adaptation_field_control | 2 bits | Whether an adaptation field is present, whether a payload is present, or both. |
| continuity_counter | 4 bits | Increments per packet carrying payload on that PID, modulo 16. The primary loss-detection mechanism — see section 14. |
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:
- PCR and OPCR— the Program Clock Reference, covered in section 13. This is the single most important thing the adaptation field does.
- Stuffing— padding used to make a payload end exactly on a packet boundary. When a PES packet’s final fragment does not fill 184 bytes, the encoder grows the adaptation field to absorb the difference rather than leaving a partial packet.
- Private data and flags— discontinuity indicator, random-access indicator, splice countdown, and transport-private data.
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.
PES — Packetized Elementary Stream
Continuous media: video, audio, subtitles, teletext. A PES packet may be up to 65536 bytes and is spread across many transport packets. Its start is flagged by PUSI.
Video may be MPEG-2 (H.262), AVC (H.264) or HEVC (H.265). Audio may be MPEG-2 Layer 2, AAC, HE-AAC, AC-3, DTS and others. One elementary stream carries exactly one thing — one video, or one audio language, or one subtitle track. Multi-channel audio such as 5.1 stays inside a single PID.
Sections — signalling data
Structured tables describing the stream. A section is at most 4096 bytes, identified by a table_id in its header, and comes in two syntaxes — “short” and “long” — distinguished by a single bit.
Sections are what turn an opaque bitstream into something navigable. Without them you have packets and no idea which ones constitute a channel.
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:
- First packet— PUSI set to 1, usually with an adaptation field carrying a PCR, then the PES start-code prefix
00 00 01and PES header. Payload is under 184 bytes because the adaptation field consumed some. - Intermediate packets— PUSI 0, no adaptation field, a full 184 bytes of payload each, interleaved with packets from other PIDs.
- Final packet— PUSI 0, with an adaptation field grown by stuffing so that the end of the PES packet lands exactly on the end of the transport packet.
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:
- A version numberin the section header. The same table is broadcast repeatedly with the same version; when its content changes, the version changes. A receiver sets a demux filter to be woken only for tables it has not already seen, instead of re-parsing the same PAT every few hundred milliseconds forever.
- A CRC32 per section.Corrupt sections are rejected at the demux level rather than being acted on. Resynchronization happens on the next packet with PUSI set.
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.
PSI — Program Specific Information
MPEG-defined, in ISO/IEC 13818-1. Describes the structure of the transport stream itself: which programs exist (PAT), what each is made of (PMT), and where conditional-access data lives (CAT). Present in any conformant transport stream regardless of broadcast region.
SI — Service Information
DVB-defined, in ETSI EN 300 468. Describes the broadcast as a service offering: names, networks, bouquets, programme schedules, time. In MPEG terms these are private sections — MPEG makes room for them without specifying them.
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.
| PID | Dec | Table | Defined by | Purpose |
|---|---|---|---|---|
0x0000 | 0 | PAT | MPEG | Program Association Table — lists every service in the stream with its service id and the PID of its PMT. The entry point for everything. |
0x0001 | 1 | CAT | MPEG | Conditional Access Table — lists EMM streams present in this multiplex. Absent when nothing is scrambled. |
0x0002 | 2 | TSDT | MPEG | Transport Stream Description Table. Rarely used in practice. |
0x0010 | 16 | NIT | DVB | Network Information Table — technical description of the network, listing every transport stream in it, usually with full tuning parameters. This is what makes fast network scanning possible. |
0x0011 | 17 | SDT / BAT | DVB | Service Description Table (service names and metadata) and Bouquet Association Table (commercial operator groupings) share this PID. |
0x0012 | 18 | EIT | DVB | Event Information Table — present/following for the now-and-next banner, and schedule for the full EPG. |
0x0013 | 19 | RST | DVB | Running Status Table — signals that an event has started or ended early. |
0x0014 | 20 | TDT / TOT | DVB | Time and Date Table (UTC) and Time Offset Table (local offset per region). Typically broadcast only every 10 to 30 seconds. |
0x1FFF | 8191 | null packets | MPEG | Stuffing to maintain constant bitrate. Carries nothing. |
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:
- Read the PATon PID 0. It gives a list of service ids and, for each, the PID where that service’s PMT lives.
- Read that PMT.It describes one service: the PID and stream type of every elementary stream in it, the PCR PID, descriptors carrying language and format detail, and the ECM streams if the service is scrambled.
- Filter those PIDs.You now have the minimum viable set for that channel.
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:
- Errors on every PID at oncepoint upstream — RF, demodulator or the link — because nothing selective is happening.
- Errors on one PID onlypoint at the multiplexer, a filter, or something in your own processing chain.
- Errors correlated with a clean RF picturepoint at software or driver behavior rather than signal.
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.
- transport_scrambling_controlin the packet header says whether the payload is scrambled and which of two control words applies. Keys alternate between even and odd so that the next key can be distributed while the current one is still in use.
- The header and adaptation field are never scrambled.PIDs, continuity counters and PCRs stay readable, which is what allows a scrambled stream to still be multiplexed, routed and analyzed by equipment holding no keys.
- ECM— Entitlement Control Messages — are CA-specific messages controlling access to a scrambled service, sent to everyone. Their PIDs are announced in the PMT.
- EMM— Entitlement Management Messages — manage subscriber rights and smartcards, addressed to a specific set of subscribers. Their PIDs are announced in the CAT on PID 1.
- CW— the Control Word is the actual content key. ECMs carry it in protected form.
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:
| Field | Width | Purpose |
|---|---|---|
| packet_type | 8 bits | What the payload is. Values in the table below. |
| packet_count | 8 bits | Increments per packet regardless of payload, wrapping 0xFF to 0x00. No requirement on the first value. |
| superframe_idx | 4 bits | Constant across all packets carrying one T2 super-frame; incremented per super-frame. |
| rfu | 9 bits | Reserved, all set to 0. |
| t2mi_stream_id | 3 bits | Identifies the T2-MI stream when a composite signal carries several. Set to 000 when only one is used; must be unique within the set presented to a single modulator. |
| payload_len | 16 bits | Length in bits, not bytes. A detail that catches implementers. |
| payload | variable | Type-dependent content. |
| pad | 0–7 bits | Padding so the packet is a whole number of bytes. |
| crc32 | 32 bits | Computed across every other bit — header, payload and padding. |
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.
| packet_type | Description | Why it matters |
|---|---|---|
0x00 | Baseband Frame | The actual DVB-T2 user data. This is what a decapsulator reassembles the inner transport stream from. |
0x01 | Auxiliary stream I/Q data | Auxiliary stream sample values. |
0x02 | Arbitrary cell insertion | Direct insertion of specified cell values. |
0x10 | L1-current | Layer-1 signalling for the current T2 frame — FFT mode, guard interval, MIMO, PLP configuration. |
0x11 | L1-future | Layer-1 signalling for a forthcoming frame, enabling advance reconfiguration. |
0x12 | P2 bias balancing cells | Bias balancing in the P2 symbols. |
0x20 | DVB-T2 timestamp | Emission timing. This is what makes single-frequency-network synchronization possible across transmitters. |
0x21 | Individual addressing | Addresses a specific modulator in the set. |
0x30 | FEF part: Null | Future Extension Frame, null content. |
0x31 | FEF part: I/Q data | FEF carried as I/Q samples. |
0x32 | FEF part: composite | FEF as a composite signal. |
0x33 | FEF sub-part | Sub-division of an FEF part. |
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:
| Parameter | Values | Meaning |
|---|---|---|
t2mi_pid | auto, or a PID | The outer PID carrying T2-MI packets. auto tries 4096 first, then 4095 — the two values used in practice. |
t2mi_plp | 0, auto, all | Which PLP to extract. auto picks the first that carries data; all merges every PLP, which is what you want when a common PSI PLP is separate from the data PLPs. |
t2mi_pids | all or a list | PID selection on the inner stream. Note that the outer pids= list does not filter inner PIDs — once decapsulation is active, the inner stream is the stream. |
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
| Specification | Defines |
|---|---|
| ISO/IEC 13818-1 / ITU-T H.222.0 | MPEG-2 Systems: transport stream packet structure, adaptation field, PES, PSI (PAT, PMT, CAT, TSDT), PCR/PTS/DTS timing |
| ETSI EN 300 468 | DVB Service Information: NIT, SDT, BAT, EIT, RST, TDT, TOT, descriptors, and their reserved PID assignments |
| SAT>IP Protocol Specification v1.2.2 | RTSP-based tuner access over IP, including the query parameters used throughout this sheet |
| ETSI EN 302 755 | DVB-T2, including the PLP concept referenced in section 17 |
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.