PSI/SI Tables, Descriptors & Identifiers
The Complete Signalling Reference
Everything that turns an opaque bitstream into navigable television, with the identifier values you need to read a hex dump. Every PSI and SI table with its table_id, reserved PID, purpose, producer and consumer; the full DVB descriptor tag registry; why the same descriptor means different things in different tables; and why the codec your audio uses is often not signalled by a stream type at all.
1. Scope and sources
A transport stream without signalling is a bag of packets. The tables described here are what let a receiver discover which services exist, what each is made of, what they are called, when programmes start, and what time it is.
Two specifications divide the work. ISO/IEC 13818-1 defines PSI — Program Specific Information — the tables describing the stream's own structure. ETSI EN 300 468 defines SI — Service Information — the tables describing the broadcast as a service offering. Every descriptor tag in section 6 is taken from EN 300 468 V1.19.1 (2025-02), the current edition, read directly rather than from secondary sources.
One deliberate omission. This sheet does not reproduce the stream_type registry. Those values live in ISO/IEC 13818-1, which is not freely published, and several widely circulated tables of them disagree with each other. Section 8 explains the mechanism and — more usefully — why for DVB audio the stream_type often is not the thing that identifies the codec. For the authoritative value list, consult ISO/IEC 13818-1 directly.
For the container these tables travel in — packets, PIDs, sections and PES — start with MPEG Transport Stream Explained. For monitoring these tables in production, see DVB Errors & Troubleshooting.
2. The signalling model
Three nested structures carry all of it, and confusing them is the source of most parsing bugs:
- A table is a logical structure identified by a
table_id. It is what you conceptually want — "the PAT", "the SDT". - A section is the transport unit, at most 4096 bytes. A table may span up to 256 sections when it uses the long syntax, and all of them must be collected before the table is complete. Long sections carry a version number and a CRC32; short sections carry neither.
- A descriptor is a self-describing sub-structure carried inside tables, identified by a tag byte and a length byte. Descriptors are where almost all the detail lives.
The consequence worth internalizing: a receiver does not read "the SDT". It collects sections on PID 0x0011 with table_id 0x42, checks each CRC, assembles them by section number, notices the version number, and then walks the descriptor loops inside. Every one of those steps is a place things go wrong, which is why the error indicators in the troubleshooting sheet are so granular.
3. Reserved PID map
Signalling lives at fixed PIDs so a receiver can start with no prior knowledge.
| PID | Dec | Carries |
|---|---|---|
0x0000 | 0 | PAT — and nothing else. A stray table here is itself an error. |
0x0001 | 1 | CAT |
0x0002 | 2 | TSDT |
0x0010 | 16 | NIT — actual and other network |
0x0011 | 17 | SDT — actual and other TS — and BAT |
0x0012 | 18 | EIT — present/following and schedule, actual and other TS |
0x0013 | 19 | RST |
0x0014 | 20 | TDT and TOT |
0x1FFF | 8191 | Null packets |
PMT PIDs are not reserved. Each service's PMT sits on a PID chosen by the multiplexer and announced in the PAT. Three PIDs therefore share a single value in a way that trips people up: SDT and BAT both live on 0x0011, and TDT and TOT both on 0x0014, distinguished only by table_id.
4. The table_id registry
Because PIDs are shared, table_id is what actually identifies a table. These are the values you filter on.
| table_id | Table | On PID | Defined by |
|---|---|---|---|
0x00 | PAT — Program Association Table | 0x0000 | MPEG |
0x01 | CAT — Conditional Access Table | 0x0001 | MPEG |
0x02 | PMT — Program Map Table | from PAT | MPEG |
0x03 | TSDT — Transport Stream Description Table | 0x0002 | MPEG |
0x40 | NIT — actual network | 0x0010 | DVB |
0x41 | NIT — other network | 0x0010 | DVB |
0x42 | SDT — actual TS | 0x0011 | DVB |
0x46 | SDT — other TS | 0x0011 | DVB |
0x4A | BAT — Bouquet Association Table | 0x0011 | DVB |
0x4E | EIT — present/following, actual TS | 0x0012 | DVB |
0x4F | EIT — present/following, other TS | 0x0012 | DVB |
0x50–0x6F | EIT — schedule. TR 101 290 treats 0x4E–0x6F as the valid EIT range on this PID. | 0x0012 | DVB |
0x70 | TDT — Time and Date Table | 0x0014 | DVB |
0x71 | RST — Running Status Table | 0x0013 | DVB |
0x72 | ST — Stuffing Table | various | DVB |
0x73 | TOT — Time Offset Table | 0x0014 | DVB |
DIT and SIT are defined by DVB for partial transport streams. Their table_id and PID values are omitted here because they could not be confirmed from the specification text during verification, and an unverified identifier in a reference table is worse than an absent one.
The EIT schedule range is worth noting: a whole block of table_id values, because a full multi-day schedule for every service does not fit into a single table. This is also why a complete seven-day EPG for a large operator consumes several megabits per second.
5. Table by table
5.1 PAT — Program Association Table
Produced by the multiplexer. Consumed by every receiver, first. Lists every service in the transport stream as a pair of service id and the PID carrying that service's PMT. Must recur at least every 0.5 s. Program number 0 is special: it points to the NIT rather than a PMT.
Without it nothing is decodable, which is why it is the highest-priority monitored item after synchronization itself.
5.2 PMT — Program Map Table
Produced by the multiplexer, one per service. Consumed by a receiver after the PAT. Describes exactly one service: the PCR PID, and for each elementary stream its PID, its stream type, and a descriptor loop carrying the detail — language, audio format, subtitle type, and CA information where the service is scrambled. Also recurs at least every 0.5 s.
The PMT is the single most useful table to read when diagnosing "why does this channel not play". Everything a decoder needs for one service is in it.
5.3 CAT — Conditional Access Table
Produced by the CA system's head-end components. Consumed by receivers holding a matching CA module. Lists the EMM streams present in this multiplex. Absent when nothing is scrambled — and its absence while scrambled packets are present is a monitored error, because a receiver then cannot obtain entitlement messages.
5.4 NIT — Network Information Table
Produced by the network operator. Consumed by receivers performing a scan. Technically describes the network: every transport stream in it, usually with complete tuning parameters, plus the services each carries and their logical channel numbers.
This is what makes fast scanning possible. A receiver tunes one transponder, reads the NIT, and learns where everything else is instead of sweeping the band. The delivery-system descriptors that carry those tuning parameters are tag 0x43 for satellite, 0x44 for cable, 0x5A for terrestrial and 0x79 for DVB-S2.
5.5 SDT — Service Description Table
Produced by the operator. Consumed by receivers building a channel list. Carries the human-facing description of each service: its name, its provider's name, whether it is scrambled, its running status. The service_descriptor (0x48) is where the name actually lives.
A stream with a valid PAT and PMT but no SDT plays perfectly and shows no channel name — a useful diagnostic signature.
5.6 BAT — Bouquet Association Table
Produced by a commercial operator. Groups services into a "bouquet" — a commercial package rather than a technical network. Several commercial operators may sell overlapping sets of the same services, which is precisely why bouquets are separate from networks. Shares PID 0x0011 with the SDT.
5.7 EIT — Event Information Table
Produced by the operator's schedule system. Consumed by the EPG. Comes in two flavours: present/following gives the current and next event per service and drives the now-and-next banner; schedule gives the full forward listing and drives the guide proper.
Schedule EIT is optional and expensive. It depends, as TSDuck's documentation puts it, on the operator's good will and available bandwidth — a complete seven-day EPG for a large operator uses several megabits per second, and sections are often sparse rather than complete.
5.8 TDT and TOT — time
Produced by the head-end. Consumed by receivers setting their clock. TDT carries UTC; TOT adds local offset per region, and uniquely among short-section tables it carries a CRC32. Typically broadcast only every 10 to 30 seconds, and monitored at a 30 s threshold.
5.9 RST, TSDT, DIT and SIT
RST signals that an event has started or finished early, letting a receiver update status faster than waiting for the next EIT cycle. TSDT describes the transport stream as a whole and is rarely used in practice. DIT and SIT belong to partial transport streams — recorded or spliced content rather than live broadcast.
6. The descriptor tag registry
Descriptors carry nearly all the substance of DVB signalling. Each is a tag byte, a length byte, and a payload whose structure the tag determines. The tags below are taken directly from Table 12 of EN 300 468 V1.19.1.
| Tag | Descriptor | What it carries |
|---|---|---|
0x40 | network_name | Human-readable network name. NIT only. |
0x41 | service_list | Service ids and types. NIT and BAT. |
0x42 | stuffing | Padding. Invalidates the descriptor it replaces. |
0x43 | satellite_delivery_system | Frequency, polarization, symbol rate, FEC, modulation. NIT only. |
0x44 | cable_delivery_system | Cable tuning parameters. NIT only. |
0x45 | VBI_data | Vertical blanking interval data. PMT. |
0x46 | VBI_teletext | Teletext carried in VBI. PMT. |
0x47 | bouquet_name | Bouquet name. BAT and SIT. |
0x48 | service | Service type, provider name, service name. SDT and SIT. The channel name comes from here. |
0x49 | country_availability | Countries where the service is available. |
0x4A | linkage | Points from one service or event to another. |
0x4B | NVOD_reference | Near-video-on-demand references. |
0x4C | time_shifted_service | Marks a service as a time shift of another. |
0x4D | short_event | Event name and short description. The EPG title. |
0x4E | extended_event | Long event description, split across items. |
0x4F | time_shifted_event | Event-level time shift reference. |
0x50 | component | Stream content and type, with a text description. |
0x51 | mosaic | Mosaic screen layout. |
0x52 | stream_identifier | Component tag, letting other tables reference a specific elementary stream. |
0x53 | CA_identifier | Which CA systems apply. |
0x54 | content | Genre classification. |
0x55 | parental_rating | Minimum age by country. |
0x56 | teletext | Teletext page and language. PMT. |
0x57 | telephone | Return-channel telephone number. |
0x58 | local_time_offset | Local offset and daylight-saving change. TOT. |
0x59 | subtitling | Subtitle language, type and page. PMT. |
0x5A | terrestrial_delivery_system | DVB-T tuning parameters. NIT only. |
0x5B | multilingual_network_name | Network name in several languages. |
0x5C | multilingual_bouquet_name | Bouquet name, several languages. |
0x5D | multilingual_service_name | Service name, several languages. |
0x5E | multilingual_component | Component description, several languages. |
0x5F | private_data_specifier | Scopes the private descriptors that follow. |
0x60 | service_move | Signals a service moving to another TS. |
0x61 | short_smoothing_buffer | Buffer model parameters. |
0x62 | frequency_list | Alternative frequencies for the same TS. |
0x63 | partial_transport_stream | Partial TS parameters. SIT. |
0x64 | data_broadcast | Data broadcast description. |
0x65 | scrambling | Which scrambling mode is in use. |
0x66 | data_broadcast_id | Data broadcast identifier. PMT. |
0x67 | transport_stream | Marks a stream as DVB-compliant. |
0x6A | AC-3 | Identifies AC-3 audio and its parameters. PMT. See section 8. |
0x6B | ancillary_data | Ancillary data identifier. |
0x6C | cell_list | Terrestrial cell geography. |
0x6D | cell_frequency_link | Cell to frequency mapping. |
0x6E | announcement_support | Announcement types supported. |
0x6F | application_signalling | Interactive application signalling. |
0x70 | adaptation_field_data | Adaptation field data identifier. |
0x71 | service_identifier | Textual service identifier. |
0x72 | service_availability | Cells where a service is available. |
0x73 | default_authority | Default CRID authority. |
0x74 | related_content | Related content signalling. |
0x75 | TVA_id | TV-Anytime identifier. |
0x76 | content_identifier | Content reference identifiers. |
0x77 | time_slice_fec_identifier | Time slicing and FEC. DVB-H heritage. |
0x78 | ECM_repetition_rate | Expected ECM repetition rate. |
0x79 | S2_satellite_delivery_system | DVB-S2 specific tuning parameters. NIT. |
0x7A | enhanced_AC-3 | Identifies E-AC-3 audio. PMT. |
0x7D | XAIT_location | Where to find the XAIT. |
0x7E | FTA_content_management | Free-to-air content management. |
0x7F | extension | Escape hatch. A second tag byte extends the space — this is how newer descriptors are added without exhausting the range. |
Tags 0x00–0x3F are the MPEG-defined range from ISO/IEC 13818-1, including CA_descriptor and ISO_639_language_descriptor. Tags 0x80 and above are user-private and only meaningful in the scope set by a preceding private_data_specifier_descriptor (0x5F). Four tags in the DVB range are omitted here rather than guessed, because they could not be extracted from the specification with confidence.
7. Placement — why the same tag means different things
EN 300 468 Table 12 does more than list tags: it specifies, for each descriptor, which tables it may appear in. A check mark means the descriptor may be carried in that table; a dash means it shall not be; an empty cell means the specification implies nothing either way.
This matters more than it first appears. Several descriptors are legal in exactly one table and meaningless elsewhere — network_name belongs only in the NIT, the delivery-system descriptors only in the NIT, service only in the SDT and SIT. A parser that reads descriptor loops without tracking which table it is inside will happily decode a descriptor that has no business being there, and produce confident nonsense.
Verified examples from Table 12: network_name (0x40) — NIT only, explicitly prohibited in BAT, SDT, EIT, TOT, PMT and SIT. service_list (0x41) — NIT and BAT only. stuffing (0x42) — permitted in NIT, BAT, SDT, EIT and SIT. VBI_data and VBI_teletext (0x45, 0x46) — PMT only. bouquet_name (0x47) — BAT and SIT. service (0x48) — SDT and SIT.
The standard also notes that the table is about descriptors declared or defined within EN 300 468, and that the placement guidance does not imply their use in other tables is restricted. In other words: treat it as authoritative for what is intended, not as an exhaustive prohibition.
8. Stream type versus descriptor — the audio trap
Each elementary stream in a PMT carries a stream_type byte. Intuitively that byte should tell you the codec, and for video it broadly does. For DVB audio it frequently does not, and this is one of the most common sources of "why does my parser think this is private data".
The mechanism is straightforward once seen. Codecs that predate a given edition of the MPEG registry, or that were standardized outside it, are carried as a private stream type, with the actual codec identified by a descriptor in the PMT's descriptor loop. AC-3 is the canonical case: its presence is signalled by the AC-3_descriptor at tag 0x6A, and enhanced AC-3 by enhanced_AC-3_descriptor at 0x7A. The stream type alone will not tell you.
Two practical consequences:
- Never identify a codec from
stream_typealone. Read the descriptor loop for that elementary stream as well. A parser that skips descriptors will mis-identify audio on a large fraction of real European transponders. - The descriptor is the authority when both are present. If the stream type says private data and an AC-3 descriptor is present, it is AC-3.
The same pattern recurs elsewhere: subtitles are identified by subtitling_descriptor (0x59) and teletext by teletext_descriptor (0x56) rather than by distinct stream types. The descriptor loop is not optional detail — it is where the stream is actually described.
The authoritative stream_type value list is in ISO/IEC 13818-1. It is deliberately not reproduced here, because the freely circulating versions of that table disagree with one another and a wrong value in a reference document is worse than an absent one.
9. Repetition rates and what breaks
Signalling is broadcast on a cycle, not served on demand. The intervals below are the monitored thresholds from ETSI TR 101 290 V1.4.1; the underlying maxima and minima come from EN 300 468 and TR 101 211.
| Table | Must appear within | Consequence if late or absent |
|---|---|---|
| PAT | 0.5 s | Nothing is decodable at all. |
| PMT | 0.5 s | That service is not decodable. |
| SDT (actual) | 2 s | Plays with no channel name. |
| EIT present/following | 2 s | No now-and-next banner. |
| NIT (actual) | 10 s | Scanning slows to a band sweep. |
| TDT | 30 s | Receiver clock cannot be set. |
The 0.5 s figures explain a behavior that looks like a bug and is not. Immediately after tuning, a receiver — or a server asked for a program by PMT — may not yet have the tables. SAT>IP Servers Pro rejects a PMT-based request in exactly that window rather than guessing, and expects the client to retry. Asking by explicit PID list needs no table knowledge and can be served immediately; asking by program requires the PMT first. That is a signalling consequence, not an implementation quirk.
10. Signalling as editable data
It is tempting to treat PSI/SI as fixed truth arriving from the broadcaster. In a processing chain it is neither fixed nor necessarily true, and understanding that is what separates working remultiplexing from mysterious failures.
Two concrete illustrations from SAT>IP Servers Pro:
- Deriving a single-program stream from a PMT. Given a PMT PID, the server reads the table, collects the PID set that service actually needs — PMT plus PCR plus audio and video plus PSI — and emits only those. That operation is nothing but reading section 5.2 correctly.
- Rewriting PSI after decryption. With
-t --cleanpsi, all CA information is stripped from the PSI so a successfully decrypted service presents to the client as clear. The video is no longer scrambled, so tables still advertising CA descriptors are now wrong, and correcting them is the right fix rather than a hack.
There is also a monitoring consequence worth stating plainly: you cannot audit table repetition on a filtered stream. Requesting a PID subset removes the very tables whose timing you wanted to measure. Monitoring feeds need the full multiplex.
11. Standards and sources
| Specification | Role here |
|---|---|
| ETSI EN 300 468 V1.19.1 (2025-02) | DVB Service Information. Source of every descriptor tag in section 6 and the placement rules in section 7, read directly from Table 12. |
| ISO/IEC 13818-1 / ITU-T H.222.0 | MPEG-2 Systems. Defines PSI — PAT, PMT, CAT, TSDT — the MPEG descriptor range, and the stream_type registry. |
| ETSI TR 101 290 V1.4.1 | Source of the monitored repetition thresholds in section 9. |
| ETSI TR 101 211 | Guidelines on SI repetition rates. |