TSDuck-based MPEG Transport Stream multiplexer with full PSI/SI support


Mux správce streamů kombinuje více SPTS streamů do jednoho CBR MPTS výstupu (DVB/IPTV). Adaptivní hybridní Statmux kombinuje CBR jádro s VBR vyváženými kodéry pro konstantní výstup muxu.
Pokud má nadřazený mux povolen statmux, každý FFmpeg kodér běží s capped-VBR: -b:v <avg> -minrate <min> -maxrate <max> -bufsize <max×2>. VBV buffer = 2× max dává ~2 s peak headroom. Statmux streamy také dostanou deterministický GOP offset (-force_key_frames) per stream_id, takže I-frame peaks se necoincidují napříč kanály.
tsp -I null (∞ NULL paketů @ line rate) → -P merge tsp -I ip <stream> (překrývá skutečné pakety) → -P continuity (drop alarm) → -P pcradjust --bitrate X (přepisuje PCR) → -P pcrverify --jitter-max 500µs → -P bitrate_monitor (rate alarm ±5%) → -P regulate --bitrate X --packet-burst 32 → -O ip <out> --packet-burst 7 --enforce-burst.
plugin regulate vydává přesně mux.bitrate bps na drátě. Vstupy zpoždění → NULL pakety vyplňují mezeru. Vstupy vrcholící → interní FIFO buffer (4096 paketů ≈ 0,3 s @ 19 Mbps) absorbuje. --enforce-burst vynutí 7 TS paketů na UDP datagram (1316 B, IPTV standard).
Horní lista muxu zobrazuje 3 součty se stavem barvy. Pravidla:
Σ avg ≤ 85 % mux.bitrate — součet cílových průměrů všech kanálů plus zvuk. To je mux 'rozpočet'. 15 % statistické rezervy chrání před shodou vrcholů. Zelená ≤ 85 %, jantarová ≤ 100 %, červená > 100 %.
Σ max ≤ 160 % mux.bitrate — součet stropů vrcholů. Povoleno překročit kapacitu (to je smyslem statmuxu — vrcholy se zřídka shodují). Zelená ≤ 160 %, amber ≤ 200 %, červená > 200 % (dropy při trvalém vrcholu).
Σ min ≤ 50 % mux.bitrate — součet podlah encoderů. Bezpečná podlaha zajišťuje, že encoder při statických scénách neklesne na zbytečně nízkou kvalitu. Zelená ≤ 50 %, amber ≤ 90 %, červená > 90 %.
Dostupný budget po PSI/SI/EIT: ~18,5 Mbps. Σ avg = 4 × 4,0 = 16 Mbps (86 % — amber hraniční, snižte dále). Σ max = 4 × 6,0 = 24 Mbps (130 % — zelená, OK). Σ min = 4 × 3,0 = 12 Mbps (65 % — amber, OK). Cíl: avg ~85 % budgetu, max ≤ 160 %.
Na ≥ 10 alarmech za 60s se ve Mux UI objeví flash notifikace doporučující snížení bitrate. Auto-back-off NENÍ aktivní — operátor rozhoduje.
-P bitrate_monitor --periodic 60 --min/max ±5% — alarm pokud skutečná rychlost vybočí o ±5 % od cíle. Znamená to, že regulate hladoví (vstup zemřel).
-P continuity — sleduje TS continuity countery. Logguje varování na každý drop (over-subscription, FFmpeg crash, NIC jitter).
-P pcrverify --jitter-max 500000 — DVB umožňuje PCR jitter ≤ 500 µs. Alarm = pcradjust nemůže držet krok nebo zdroj má selhané PCR.
Shoda GOP — všechny encodery vysílají I-snímky současně, shoda vrcholů. Oprava: offset GOP (již zapnuto pro statmux, hash(stream_id) mod gop_size).
Ztráta vstupního signálu — jeden kanál zčerna, mux pokračuje (díky -I null base). Trvání ~3-8 s pro restart FFmpeg.
Přetížení (trvalé vrcholy > kapacita) — bloky/výpadky audia ~50-200 ms. Oprava: snižte průměrný avg streamů o 5-10 % nebo odeberte kanál.
PCR drift — STB zaseknutí každých pár sekund. Oprava: pcradjust v pipeline (už tam), sledujte pcrverify alarmy.
STB VBV underrun — STB ztratí synchronizaci a znovu ji získá (~2-3 s). Oprava: encoder bufsize = 2 × maxrate (již nastaveno), snižte maxrate.
--max-input-packets 4096 / --max-flushed-packets 4096 (interní FIFO ≈ 0,3 s @ 19 Mbps). --receive-buffer-size 16777216 (16 MB UDP rcv buffer per vstup). --packet-burst 32 (regulate) / 7 (výstup, IPTV standard). --enforce-burst (každý UDP datagram je přesně 7 paketů).
Top-bar badge `📐 rec X.XM` ukazuje doporučenou kapacitu muxu odvozenou z centrální limitní věty. Součet nezávislých VBR streamů se blíží normálnímu rozdělení, takže Mux = μ_total + z·σ_total + margin. σ_i se odhaduje z VBR rozsahu každého vstupu jako (max−min)/4 (za předpokladu, že rozsah pokrývá ±2σ). Margin = 10% μ_total kompenzuje PSI/SI overhead, encoder rate-control jitter a stream korelaci, kterou čistá CLT podceňuje.
Barva odznaku: zelená = cap ≥ 99,7% rec (konzervativní) · amber = mezi 99% a 99,7% · červená = cap < 99% (nedostatečné, riziko dropů) · modrá = cap nenastaveno.
z-skóre pro cíle pokrytí: 90% z=1,28 · 95% z=1,65 · 99% z=2,33 · 99,7% z=3,00 (výchozí) · 99,99% z=3,72 (broadcast úroveň). Kliknutím aplikujete doporučení 99,7% na mux.bitrate (vyžaduje restart muxu).
σ_eff = σ_total × statmux_factor (statmux_factor = 0,7 když je Statmux ZAPNUT, jinak 1,0)
Kanál HD 1080p25: avg = 4000-5000 kbps, min = avg × 0,75 (~3000-3750), max = avg × 1,5 (~6000-7500). UI automaticky vyplní min/max z avg. Kanál SD: avg = 2000-2500 kbps. UHD: avg = 12000-18000 kbps.
Adaptivní hybridní Statmux je runtime mechanismus, který přesouvá nevyužitou kapacitu z core streamů (chráněné, plné VBR) na balanced streamy (obětní). 'Hybridní' protože dvě odlišné režimy řízení rychlosti běží souběžně (CBR core fill + VBR balanced); 'adaptivní' protože router přehodnocuje jednou za sekundu z HLS-lookahead predikce.
Kapacita muxu 38 Mbps
┌──────────────────────────────────────────────────────────────────┐
│█████████████████████████████████████████████████████░░░░░░░░░░░░│
└──────────────────────────────────────────────────────────────────┘
◀────── core_max (předpovězeno z 6 HLS segmentů) ─▶◀── vyváženě ──▶
per_balanced
= (kap − core_max
− SI overhead
− audio) / N
Příklad: kap=38000 core_max=29000 SI=200 audio_total=1280 N_balanced=2
zbývající = 38000 − 29000 − 200 − 1280 = 7520 kbps
per_balanced_max = 7520 / 2 = 3760 kbps
clamp(3760, 500, 3000) = 3000 kbps ← strop pro vyvážený VBRBez adaptivního hybridního statmuxu musíte dimenzovat mux pro worst-case Σ max. S adaptivním hybridním statmuxem dimenzujete kolem Σ avg + statistické vyrovnávací paměti (broadcast korelace ρ=0,15). Skutečný zisk ~5 Mbps na 38 Mbps muxu, nebo +1 stream za stejný cap.
Čisté CBR (encoder fixní)
VBR bez Statmuxu
Adaptivní hybridní Statmux ZAP
Vlastní URL vstup a Statmux se vzájemně vylučují. Se Statmuxem zapnutým tsp pipeline získává bitrate z alokátoru, nikoliv z URL vstupu.
┌─────────────────────────┐
│ Kódovač (NVDEC→NVENC) │ ← UDP satelitní
STREAM │ /dev/shm/stream_X/h264/│
│ → muxed.m3u8 + segmenty│
└────────────┬────────────┘
│
┌────────┴────────┐
│ │
role="core" role="vyváženě"
(chráněno) (obětní)
│ │
│ ▼
│ ┌───────────────────────────┐
│ │ BalancedTranscoder │
│ │ ffmpeg p1 NVENC VBR │
│ │ -maxrate dynamické │ ← Adaptivní hybridní router
│ │ /dev/shm/stream_X_ │ 1s tick (předpovídá z
│ │ balanced/h264/...m3u8 │ 6 HLS segmentů, atomický
│ └───────────┬───────────────┘ symlink swap HIGH/MED/MIN)
│ │
▼ ▼
┌─────────────────────────┐
│ ffmpeg jako mux │ ← /dev/shm/mux_X/pipe.sh
│ -f mpegts pipe:1 │
│ -muxrate <kap> │
└────────────┬────────────┘
│ shell pipe
▼
┌─────────────────────────┐
│ tsp -I file - │
│ kontinuita → regulace │
│ → pcradjust → bitrate_ │
│ monitor │
│ -P nit -P sdt -P inject│
│ (DVB SI tabulky) │
└────────────┬────────────┘
│
▼ UDP multicast
239.x.x.x:1234Statistický zisk nastane pouze tehdy, když mají encodery široký VBR rozsah — když max ≈ avg nebo min ≈ avg, router nemůže přesunovat bity.
Příklad výpočtu — mux 38 Mbps, 10 HD core + 2 vyvážené:
Staré (CBR-zamknuté): min=2000 avg=3000 max=4000
Σmax = 10×4000 + 2×7600 = 55200 kbps (1,45× kap — malý zisk)
σ_per_stream = (4000−2000)/4 = 500 kbps (zanedbatelné — ploché)
Σ statistická rezerva ≈ 1,5 Mbps
Doporučené (široký VBR): min=1500 avg=3000 max=6000
Σmax = 10×6000 + 2×7600 = 75200 kbps (1,98× kap — zdravý zisk)
Σavg = 10×3000 + 2×3000 = 36000 kbps (95 % kap — pohodlné)
Σmin = 10×1500 + 2×500 = 16000 kbps (42 % kap — pohodlná spodní hranice)
σ_per_stream = (6000−1500)/4 = 1125 kbps (významné)
Σ statistická rezerva ≈ 4 Mbps
Skutečný přínos: při akčních scénách jádro dosahuje špiček 5–6 Mbps (HD detail),
router sníží vyvážené na MIN úroveň, celkový tok zůstane na 38 Mbps.Doporučený rozsah pro core stream: min ≈ avg × 0,5 (encoder může klesnout na klidné scény); max ≈ avg × 1,5 (VBR headroom pro vrcholy).
Alespoň 1 vyváženou stream — bez nějaké adaptivní hybridní router nemá nic, co by mohl srazit během vrcholů, takže zisk = 0
Hudební a informační kanály jsou nejlepší kandidáti — tolerují 90 %+ snížení rychlosti
Sledujte přes záznamy `[balance-router]` — zobrazuje `core_max`, `remaining`, přechody tier.
Pokud `core_max > capacity` (varování CORE OVERPEAK v logu), snižte počet core streamů nebo jejich max.
Přidejte streamy do muxu (přiřazení kanálů zůstává manuální)
Přepněte Statmux na hlavičce muxu (žlutý čip). Pokud je povolen, všechny kodéry přepnou na VBR a restartují
Označte obětní streamy přes oranžové zaškrtávací políčko na pravé straně — typicky hudba/infozábava
Hotovo. Adaptivní hybridní router čte 6-segmentovou HLS predikci z core streamů a přiděluje zbývající kapacitu balanced streamům.
Více kanálů s proměnným bitrate sdílí jeden pevný transportní proud (MPTS). Bity jsou dynamicky přerozdělovány dle komplexity obsahu — náročná scéna dostane více, statická méně — takže kvalita zůstává vyrovnaná a součet nikdy nepřekročí kapacitu drátu.
Třída: statmux s uzavřenou zpětnou vazbou s C1 look-ahead (dopředná vazba) nad VBR encodery.
UDP multicast SSM, per kanál
Encodery
komplexita zdroje
Loopback — re-encode mux output pre feedback.
vlastní linka / stream
alokátor (Σ ≤ pool)
Stream buffer — drží dekodované snímky pred muxing.
Null packet — filler pre rate matching.
CBR drát na cap
anticipovat komplexní scénu před poklesem
měřený drát — kalibrace
cílový bitrate
Každý kanál běží na vlastní lince až do muxu (separátní encoder + loopback připojení).
Alokátor kombinuje dva signály — predikci z komplexity zdroje (dopředná vazba) a zpětnou vazbu ze skutečného drátu.
C1 měří komplexitu obsahu na dekodéru — předchází výstupu encoderu o ~1 s GOP latencí.
Přesné bity per-stream emitované muxem (čítače na straně odesílatele) kalibrují řídicí smyčku.
Nárok streamu je podložen tím, co encoder skutečně produkuje (× peak headroom).
Cílem není stejný bitrate, ale stejná kvalita — nepřetržitý tlak přesouvá bity.
Když C1 signalizuje pokles kanálu, jeho šířka pásma je předána ostatním ihned.
Váha na kanál = complexity_q12 × max_bps (scéna akce + vyšší max ⇒ více bitů).
Rozpočet na stream = globální rozpočet × váha / Σváhy, clamp [min_bps, max_bps], přepočítáno každých 10 ms.
Proporcionální přidělení poolu dle poptávky, omezeno na [min, max] z video profilu.
Cílový bitrate encoderu = alloc / kalibrace (EMA per-stream měřeno/cíl); odesláno každý tick.
Servo pro udržení bufferu udržuje úroveň fronty na ~1 s (pásmo), nouzový backstop při přetečení.
Výstup je přesný CBR proud na nakonfigurovaném cap. Tři vrstvy to garantují: přesné pacování, null padding a standing buffer.
Odesílací fronta drží stálou úroveň ~1 s drátu, která absorbuje sub-sekundové GOP vrcholy.
Když je obsah pod cap, rozdíl je vyplněn MPEG-TS null pakety (PID 0x1FFF) — standardní broadcast praxe.
Egress je pacován na přesný cap (busy-spin ABSTIME); svorka 12 ms dluhu zabraňuje kumulaci debt.
Živý skládaný graf skutečného drátu — každé pásmo je jeden kanál, proudící hladce v čase.
Každý kanál má stabilní barvu; tloušťka = jeho okamžitý bitrate. Overhead PSI/SI/EIT je zahrnut.
Čárkovaná čára nahoře = nakonfigurovaný cap (strop drátu). Obsah + null padding = přesně cap.
Tečkované bílé pásmo nahoře = null padding (volná kapacita). Čím tenčí, tím více kapacity je využito.
Červené značky na časové ose = přetečení odesílací fronty (drop). Nula v ustáleném stavu; normální při startu.
Tlačítka přepínají časové okno okamžitě (na straně klienta), aktivní má zelené pozadí.
Přejetí myší zobrazí per-kanálový bitrate, QP a index kvality v daný okamžik (historická data).
Aktuální úroveň regulace poolu (pool/(pool−trim)). >100% = přetlak (plní frontu).
Toleranční pásmo nad cap — kolik zachovat jako null rezervu. 0 = plnit přesně N; vyšší = méně tlak.
Záhlaví zobrazuje % využití odesílací fronty a kumulativní dropy. Tlačítko 'clear drops' resetuje čítač.
Délka GOP společná pro všechny kanály v muxu (uzamčena do video profilů při startu).
Velikost VBV bufferu encoderu (ms). Menší vyrovnává I-snímky (dobré pro pohybové kanály).
Hlavička sekce má přepínač 'Sbalit / Rozbalit vše'. Rozbalte kartu kliknutím na ni nebo kliknutím na její barevný pás v grafu. Levý barevný pás se zaškrtávacím polem = členství kanálu v muxu.
Běží — kanál kóduje a proudí na drát.
Spouštění — encoder se rozbíhá / stabilizuje.
šedá + tlumená = vypnuto/chyba a zaškrtávací pole VYPNUTO (záměrně zakázáno — bez alarmu)
Chyba — vstup ztracen / encoder selhal.
StatMux generuje kompletní sadu povinných tabulek MPEG-TS / DVB přímo v NIF muxeru — žádný externí SI inserter.
Tabulka
PID mapping pre PSI/SI deskriptory.
H.264/HEVC PSI/SI info (PAT, PMT, SDT, SIT).
Účel / zdroj
EIT (Event Information Table, PID 0x12) není statická — je plně propojena se systémem EPG.
min = spodní podlaha (statická scéna). Doporučeno avg × 0,5–0,75. Nastavte dostatečně nízko, aby se ušetřilo na klidném obsahu pro ostatní.
avg = cílová úroveň. Σ avg všech kanálů ≈ video pool (cap − overhead − audio).
max = strop (VBR headroom pro vrcholy/střihy). Doporučeno avg × 1,5. Nepevně omezujte na avg — VBR potřebuje prostor pro vrcholy.
Příklady (avg): SD 1,5–2,5M · HD 2,5–4M · FHD 4–6M · UHD 12–18M. Pro statmux udržujte rozumný rozsah, aby mohl pool redistribuovat.
Provádíme skutečné statistické multiplexování — dynamickou redistribuci bitů napříč VBR kanály.
CBR drát na cap · 1 s buffer · per-stream proporcionální přidělení · C1 look-ahead · zpětnovazební kalibrace.
Broadcast statmux používá odhad rate-distortion encoderu (přesné náklady na snímek). Naše C1 je aproximace přes komplexitu zdroje (SSE).
TS symbol rate — transport stream bitrate.
Příčina / oprava
Mezery / null vrcholy (5–7M) v grafu
Poklesy obsahu — buď GOP mezi I-snímky (absorbováno 1 s bufferem) nebo kolektivní zastavení obsahu (řešeno redistribucí).
Dropy > 0 stoupají
Přetečení odesílací fronty — obsah nad cap. Zkontrolujte rezervu (slider), util a že alokátor není zaseknutý (tick běží). Bootovací bursting je normální.
Jeden kanál zůstává na nízkém bitrate / vysokém QP
Buď statický obsah (správně — uvolňuje šířku pásma) nebo příliš nízký max v profilu. Zvyšte max nebo snižte min.
Graf drhne / levý okraj se maže
Na straně klienta — tvrdé obnovení (Ctrl+Shift+R) pro nový JS bundle. Data proudí přes WebSocket push.
cap % / buffer se po úpravě nemění
Žádné živé vzorky (mux zastaven nebo kodéry neběží) — zkontrolujte stav muxu i streamů.
Prehľad dátového toku — ako statmux pipeline spracováva streamy
gst_encoder.py per stream: SAT UDP SSM vstup → nvh264enc rc-mode=cbr. Bitrate je řízen alokátorem přes ZMQ příkazy.
Ring per-vstup (TCP loopback z kodéru), 2-pass drain (audio priorita, video full), proporcionální alokátor, NULL pad přesně k wire cap (CBR), PCR pass-through z kodéru.
Jeden MPTS (PAT/PMT/SDT generováno NIF) → UDP multicast na výstupní VLAN. Drát je přesné CBR na cap.
Řádek 1: ⚠ (problémy s validací) · PNR · název v rámečku (barva = stav).
Řádek 2+: min·avg·max kbps · predikovaná komplexita Δ nízká/střední/vysoká/peak · INPUT LOST odznak.
Barva názvu = stav streamu:
Mbps
37 ───────────────────────────── <= cap 37.0 Mbit (red, wire CBR ceiling)
· · · · · · · · · · · · · · · <= free space = NULL padding
·· grey · black dots · reserve ·· (unused capacity)
31 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ <= headroom 85% · 31.5 Mbit (orange,
▓▓▓▓ JOJ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ encoder targets aim here)
▒▒▒▒ Markíza ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
░░░░ TA3 ░░░░░░░░░░░░░░░░░░░░░░░░ <= click band -> expand card
0 └────────────────────────────────
time -> 10m │ 1h │ 24h CC0 PCR0 BR0 OVF0Červená linka 'cap': wire CBR ceiling (mux.bitrate) — NULL vyplňuje až sem.
Oranžová linka 'headroom N%': = cap × headroom slider / 100. Kodér vychází z cíle sem. Pohybuje se s posuvníkem.
Šedá oblast s černými tečkami mezi obsahem a maximem = NULL padding (nepoužitá rezerva). Více teček = více rezervy.
Klikněte na barevný pás kanálu → automaticky rozbalí kartu tohoto kanálu níže.
MuxEitAdapter čte události ze systému EPG per služba, buduje DVB EIT sekce a předává do NIF muxeru.
EIT je injektováno přímo do NIF muxeru, rovnoměrně DO null prostoru (1 paket / tick) — bez burstů.
Tabulka 0x4E — aktuálně běžící + další událost. Injektováno každé ≤2 s pro okamžité zobrazení v STB.
Mux pravidelně regeneruje EIT .bin z EPG (~15 s) — aktualizace EPG plánovače se projeví živě.
Tabulky 0x50/0x51 — úplný rozvrh hodin/dní dopředu (segmenty). Rovnoměrně rozloženo v cyklu.
Indikátor skutečného toku vs. cap. Střed = cap (0). Značka vlevo (zelená) = rezerva (Σ obsahu pod cap); vpravo (červená) = přetečení.
Bitrate gauge
Nižší (→78): více NULL rezervy, bezpečnější, méně těsné využití cap.
Vyšší (→90): těsnější využití cap, méně NULL.
⚠ ≥88 %: slider se zbarvuje žlutě — blízko stropu zmrazení ring-overflow. Pevné omezení 78–90 (nelze dosáhnout 100 — ochrana před zmrazeným videem).
Asymetrie: nižší spolehlivě přidá rezervu; vyšší je omezeno per-stream max_bps clamp (alokátor nebude tlačit kanál nad jeho max → bezpečné).
Řídí, kolik z cap kodéry cílují: kodér target = budget × headroom% / 100 (oranžová linka v grafu). Změny live (efekt od příštího 10 ms ticku), perzistované v SystemConfig.
Jeden kanál selže (pád encoderu / ztráta signálu) ⇒ mux dál běží, ostatní kanály nejsou ovlivněny, drát drží cap (NULL absorbuje výpadek), CC=0 na přeživších. Vláknění per-vstup jsou nezávislá. Kanál se zobrazí s červeným blikajícím názvem + odznák INPUT LOST; encoder je supervisorem restartován a kanál se sám obnoví.
PCR a PES PTS/DTS jsou pass-through z kodéru (single clock domain ⇒ coherent, bez driftu). Zbytková PCR jitter ~desítky ms je inherentní (10 ms output tick + UDP) — STB/VLC PLL ji toleruje, CC=0. Hard DVB-S2 modulator compliance je mimo rozsah pro aktuální IPTV use case.
CAT — podmíněný přístup (pouze při šifrování / ECM).
EIT — informace o událostech (EPG) — ze systému EPG, viz níže.
NIT — síťové info (ID sítě, název, transportní proud).
PAT — seznam programů (mapuje PNR → PMT PID).
PMT — per program: video/audio/PCR PID, kodeky, deskriptory.
SDT — názvy a provideři služeb (co STB zobrazí v seznamu).
TDT/TOT — čas a datum + místní offset (hodiny STB).