×

⊳ Muxer

MPTS · TSDuck · PSI/SI

MPTS-multiplexer en adaptieve hybride Statmux

Stream Manager mux assembleert meerdere SPTS-streams tot één CBR MPTS-uitvoer (DVB/IPTV). Adaptieve hybride statmux combineert een CBR-kernvulling met VBR-gebalanceerde encoders voor constante mux-uitvoer.

1. Encoderlaag (FFmpeg per stream)

Wanneer de bovenliggende mux statmux heeft ingeschakeld, draait elke FFmpeg-encoder capped-VBR: -b:v <avg> -minrate <min> -maxrate <max> -bufsize <max×2>. VBV-buffer = 2× max geeft ~2 s piekruimte. Statmux-streams krijgen ook een deterministische GOP-offset (-force_key_frames) per stream_id zodat I-framepieken niet samenvallen.

2. Mux-laag (TSDuck tsp-pipeline)

tsp -I null (∞ NULL-pakketten @ lijnsnelheid) → -P merge tsp -I ip <stream> (overlayt echte pakketten) → -P continuity (drop-alarm) → -P pcradjust --bitrate X (herschrijft PCR's) → -P pcrverify --jitter-max 500µs → -P bitrate_monitor (snelheidsalarm ±5%) → -P regulate --bitrate X --packet-burst 32 → -O ip <out> --packet-burst 7 --enforce-burst.

3. Uitvoerlaag (UDP)

regulate-plugin zendt exact mux.bitrate bps op de draad. Achterblijvende invoer → NULL-pakketten vullen het gat. Piekende invoer → interne FIFO-buffer (4096 pakketten ≈ 0,3 s @ 19 Mbps) absorbeert. --enforce-burst dwingt 7 TS-pakketten per UDP-datagram (1316 B, IPTV-standaard).

Aanbevolen maatvoering (Σ min / gem / max vs mux.bitrate)

Mux-topbalk toont 3 sommen met kleurstatus. Regels:

Σ gem ≤ 85 % mux.bitrate — gemiddeld doelsom over alle kanalen plus audio. Dat is het mux-'budget'. De 15 % statistische reserve beschermt tegen pieksamenvallen. Groen ≤ 85 %, amber ≤ 100 %, rood > 100 %.

Σ max ≤ 160 % mux.bitrate — piekplafondssom. Mag de capaciteit overschrijden (dat is het punt van statmux). Groen ≤ 160 %, amber ≤ 200 %, rood > 200 %.

Σ min ≤ 50 % mux.bitrate — encoderbodenssom. Een veilige bodem zorgt dat de encoder bij stilstaande scènes niet onnodig laag daalt. Groen ≤ 50 %, amber ≤ 90 %, rood > 90 %.

Voorbeeld: 4 HD-kanalen in een 19 Mbps DVB-T mux

Beschikbaar budget na PSI/SI/EIT: ~18,5 Mbps. Σ gem = 4 × 4,0 = 16 Mbps (86 % — amber, iets verlagen). Σ max = 4 × 6,0 = 24 Mbps (130 % — groen, OK). Σ min = 4 × 3,0 = 12 Mbps (65 % — amber, OK).

Diagnostiek en alarmen

Bij ≥ 10 alarmen in 60s verschijnt een flash-melding in de Mux UI met aanbeveling de bitsnelheid te verlagen. Auto-back-off is NIET actief — de operator beslist.

-P bitrate_monitor --periodic 60 --min/max ±5% — alarm als werkelijke snelheid meer dan ±5 % van doel afwijkt.

-P continuity — bijhouden van TS-continuiteitstellers. Logt een waarschuwing bij elke drop.

-P pcrverify --jitter-max 500000 — DVB staat PCR-jitter ≤ 500 µs toe. Alarm = pcradjust kan niet bijhouden.

Storingen en oorzaken

GOP-samenvallen — alle encoders zenden tegelijk I-frames uit. Fix: GOP-offset (al actief voor statmux).

Invoersignaalverlies — één kanaal wordt zwart, mux gaat door (dankzij -I null basis). Duur ~3-8 s voor FFmpeg-herstart.

Over-inschrijving (aanhoudende pieken > capaciteit) — blokken/audio stutter ~50-200 ms. Fix: verlaag stream avg met 5-10 % of verwijder een kanaal.

PCR-drift — STB stutter elke paar seconden. Fix: pcradjust in de pipeline (al aanwezig), bekijk pcrverify-alarmen.

STB VBV-underrun — STB verliest sync en hersynct (~2-3 s). Fix: encoder bufsize = 2 × maxrate (al ingesteld), verlaag maxrate.

tsp-pipelineparameters (mux_worker.ex)

--max-input-packets 4096 / --max-flushed-packets 4096 (interne FIFO ≈ 0,3 s @ 19 Mbps). --receive-buffer-size 16777216 (16 MB UDP-ontvangstbuffer per invoer). --packet-burst 32 (regulate) / 7 (uitvoer, IPTV-standaard). --enforce-burst (elk UDP-datagram is exact 7 pakketten).

Empirische capaciteitsberekening (CLT)

Topbalkbadge `📐 aanbev X.XM` toont de aanbevolen mux-capaciteit afgeleid van de centrale limietstelling.

Badge-kleur: 🟢 groen = cap ≥ 99,7% aanbev · 🟡 amber = tussen 99% en 99,7% · 🔴 rood = cap < 99% · 🔵 blauw = cap niet ingesteld.

z-score per dekkingsdoel: 90% z=1,28 · 95% z=1,65 · 99% z=2,33 · 99,7% z=3,00 (standaard) · 99,99% z=3,72 (broadcast-kwaliteit).

σ_eff = σ_total × statmux_factor (statmux_factor = 0,7 bij Statmux AAN, anders 1,0)

Aanbevolen waarden per kanaal (HD H.264)

1080p25 HD-kanaal: gem = 4000-5000 kbps, min = gem × 0,75, max = gem × 1,5. UI vult min/max automatisch in vanuit gem.

Adaptieve hybride Statmux

Adaptieve hybride statmux is een runtimemechanisme dat ongebruikte capaciteit verschuift van core-streams (beschermd, volledig VBR) naar gebalanceerde streams (opofferbaar).

Capaciteit — hoe bitsnelheid wordt verdeeld

Mux-capaciteit 38 Mbps
  ┌──────────────────────────────────────────────────────────────────┐
  │█████████████████████████████████████████████████████░░░░░░░░░░░░│
  └──────────────────────────────────────────────────────────────────┘
   ◀────── core_max (voorspeld uit 6 HLS-segmenten) ─▶◀── gebalanceerd ──▶

Praktisch voordeel (10 streams × 3 Mbps gem, 4 Mbps max)

Zonder adaptieve hybride statmux moet u de mux dimensioneren voor het worst-case Σ max. Met statmux dimensioneert u rond Σ gem + een statistisch buffer. Reëel voordeel ~5 Mbps op een 38 Mbps mux.

Puur CBR (encoder vast)

VBR zonder Statmux

Adaptieve hybride Statmux AAN

URL ↔ Statmux exclusiviteit

Aangepaste URL-invoer en Statmux zijn wederzijds exclusief. Met Statmux aan vertrouwt de gebalanceerde transcoder op de lokale encoder HLS om bitsnelheid te regelen.

Pipeline (encoder → gebalanceerde transcoder → mux ffmpeg → tsp)

┌─────────────────────────┐
          │  Encoder (NVDEC→NVENC)  │ ← UDP satelliet
          └────────────┬────────────┘
                       │
              ┌────────┴────────┐
        rol="core"        rol="gebalanceerd"
              │                 │
              ▼                 ▼
          ┌─────────────────────────┐
          │  ffmpeg-als-mux         │
          └────────────┬────────────┘
                       │
                       ▼ UDP multicast
                  239.x.x.x:1234

Core VBR min/gem/max dimensioneren voor statmux

Statistisch voordeel treedt alleen op wanneer encoders een brede VBR-range hebben — wanneer max ≈ gem is de encoder effectief CBR en heeft de router niets te herverdelen.

Uitgewerkt voorbeeld — 38 Mbps mux, 10 HD core + 2 gebalanceerd: aanbevolen brede VBR: min=1500 gem=3000 max=6000.

Aanbevolen bereik per core-stream:

• min ≈ gem × 0,5

• gem = nominaal doel op resolutie

• max ≈ gem × 2,0

Tips en probleemoplossing

Minstens 1 gebalanceerde stream — zonder één heeft de adaptieve router niets om te comprimeren tijdens pieken, dus winst = 0

Muziek- en informatiekanalen zijn de beste kandidaten — 90%+ tolerantie voor snelheidsvermindering

Volg via `[balance-router]` logvermeldingen — toont `core_max`, `remaining`, tierovergangen per 1 s tick

Als `core_max > capaciteit` (CORE OVERPEAK-waarschuwing in log), verlaag het aantal core-streams of verlaag encoder maxrate

Operatorworkflow

Voeg streams toe aan de mux (kanaaltoewijzing blijft handmatig)

Schakel Statmux in op de mux-koptekst (gele chip). Bij inschakelen schakelen alle encoders over naar VBR en worden ze herstart

Markeer opofferbare streams via het oranje selectievakje rechts — doorgaans muziek-/informatiekanalen waar snelheidsvermindering onzichtbaar is

Klaar. De adaptieve router leest een 6-segment HLS-voorspelling van core-streams elke 1 s en wisselt atomair de gebalanceerde symlink tussen HIGH/MED/MIN-tiers

StatMux — native statistische multiplex

Meerdere variabele-bitsnelheidskanalen delen één vaste transportstroom (MPTS). Bits worden dynamisch herverdeeld door inhoudscompexiteit — een veeleisende scène krijgt meer, een statische minder.

Klasse: gesloten-lus feedbackstatmux met C1 look-ahead (feedforward) over VBR-encoders — broadcast statmux-principe, aangedreven door broncompexiteit.

Architectuur en gegevensstroom

Architecture diagram

UDP-multicast SSM, per kanaal

Encoder

broncompexiteit

Lus

eigen lijn / stream

allocatore (Σ ≤ pool)

buffer

null-opvulling → CBR

CBR-draad op cap

anticipeer complexe scène voor de dip

gemeten draad — kalibratie

doelbitsnelheid

Elk kanaal draait op zijn eigen lijn tot de mux (aparte encoder + loopback-verbinding), waar alle samenvoegen tot één MPTS-multicastlijn op een exact vaste bitsnelheid.

Brein: feedback + C1 look-ahead

De allocator combineert twee signalen — een voorspelling uit broncompexiteit (voorwaarts) en de gemeten draad (achterwaarts).

C1 meet inhoudscompelxiteit bij de decoder — wat de encoderuitvoer voorgaat op de pipelinelatentie. De relatieve complexiteitsverandering wordt toegepast op de doelbitsnelheid in BEIDE richtingen VOOR de encoder het produceert.

Gemeten draad (feedback)

Exacte per-stream bits uitgestoten door de mux kalibreren de complexiteit→bitsnelheid-mapping en houden de som exact op de pool.

Leverbaarheid

De claim van een stream wordt gedekt door wat de encoder daadwerkelijk produceert. Een gemakkelijk kanaal kan bandbreedte die het niet kan besteden niet hamsteren — het geeft die vrij aan de hongerige.

Geëgaliseerde kwaliteit

Het doel is niet gelijke bitsnelheid maar gelijke kwaliteit — continue druk verplaatst bits van hoge-kwaliteitskanalen (lage QP) naar lage-kwaliteitskanalen (hoge QP).

Voorspellende herverdeling

Wanneer C1 signaleert dat een kanaal daalt, wordt zijn bandbreedte in dezelfde tick aan de andere gegeven — ze rampen omhoog voor de daling de draad bereikt.

Pool = cap N − overhead (PSI/EIT) − audio − reserve (schuifregelaar). Gemeten van de draad, gewenst maximum tegen bursts.

Per-stream vraag = leverbare draad × C1 look-ahead (relatieve complexiteitsverandering) + kwaliteitsegaliserende druk.

Proportionele pooltoewijzing per vraag, begrensd tot [min, max] uit het videoprofiel; vrije bandbreedte gaat naar de hongerige.

Encoderdoel = toewijzing / kalibratie (per-stream EMA gemeten/doel); verzonden met een drempelwaarde en begrenzing tegen oscillatie.

Buffer-hold servo houdt het wachtrijniveau op ~1 s (band), noodstop bij overbelasting; null-opvulling vult de rest aan tot CBR.

CBR-draad: buffer + null-opvulling + pacing

De uitvoer is een exacte CBR-stream op de geconfigureerde cap. Drie lagen garanderen dit:

Staande buffer ~1 s

De verzendwachtrij houdt een staand niveau van ~1 s draad bij dat sub-seconde GOP-dips absorbeert.

Null-opvulling

Wanneer inhoud onder cap is, wordt het verschil gevuld met MPEG-TS null-pakketten (PID 0x1FFF). De draad haalt dus ALTIJD de cap — DVB-conform.

Exacte pacing

Uitvoer wordt gepaced naar de exacte cap (busy-spin ABSTIME); een 12 ms schuldbegrenzing voorkomt inhaalbursts.

Uitvoergrafiek (rivier)

Een live gestapelde grafiek van de echte draad — elke band is één kanaal, vloeiend van rechts. Data gemeten op de draad (tsp-probe + NIF-tellers), niet geschat.

Gekleurde banden

Elk kanaal heeft een stabiele kleur; dikte = zijn instantane bitsnelheid. Overhead (PSI/EIT) is grijs onderaan, null-opvulling is getextureerd wit bovenaan.

Cap / Max-lijn

De gestippelde lijn bovenaan = geconfigureerde cap (draadplafond). Inhoud + null-opvulling zitten altijd eronder.

Null-band

De gestippelde witte band bovenaan = null-opvulling (vrije capaciteit). Hoe dunner, hoe voller de draad.

Drop-markeringen

Rode markeringen op de tijdlijn = verzendwachtrij-overflow (drop). Nul in stabiele staat; bursts alleen bij opstarten/vloed.

Bereik (30s–30m)

Knoppen schakelen het tijdvenster direct (client-zijde), de actieve heeft een grijze achtergrond.

Tooltip

Hover toont per-kanaal bitsnelheid, QP en kwaliteitsindex op dat moment (historische waarde, niet live).

cap %

Huidig poolregulatieniveau (pool/(pool−trim)). >100% = overdruk (buffer vullen), <100% = trimmen.

Reserve (schuifregelaar)

Tolerantieband boven cap — hoeveel als null-reserve te bewaren. 0 = vul exact N; positief = grotere reserve (veiliger); negatief = licht overvullen.

Buffer (drop)

De koptekst toont wachtrij-gebruik % en cumulatieve drops. De 'drops wissen'-knop reset de teller.

GOP

Gemeenschappelijke GOP-lengte voor alle kanalen in de mux. Wall-stagger spreidt I-frames in de tijd zodat ze niet samenvallen.

VBV

Encoder VBV-buffergrootte (ms). Kleiner vlakt I-frames af (goed voor bewegingskanalen), groter geeft een gedetailleerder I-frame.

Streamkaarten en standen

Elk kanaal in de mux heeft een kaart met naam, PNR, huidige en doelbitsnelheid en staat:

Actief — kanaal codeert en stroomt naar de draad.

Starten — encoder start op / stabiliseert.

Uit — kanaal is in de mux maar actief niet (0 kbps).

Fout — invoer verloren / encoder gecrasht.

PSI/SI-tabellen (complete DVB-set)

StatMux genereert de volledige set verplichte MPEG-TS / DVB-tabellen direct in de NIF-mux — geen externe SI-inserter.

Tabel

PID

Intervallo

Doel / bron

EIT ↔ EPG: volledige integratie

EIT (Event Information Table, PID 0x12) is niet statisch — het is volledig gekoppeld aan het EPG-systeem van de applicatie.

Kanaalmaatvoering (min / gem / max)

min = ondergrens (statische scène). Aanbevolen gem × 0,5–0,75. Stel laag genoeg in om te besparen op rustige inhoud voor anderen.

gem = doelniveau. Σ gem van alle kanalen ≈ videopool (cap − overhead − audio).

max = plafond (VBR-ruimte voor pieken). Aanbevolen gem × 1,5. Beperk niet hard tot gem — VBR heeft ruimte voor pieken nodig.

Voorbeelden (gem): SD 1,5–2,5M · HD 2,5–4M · FHD 4–6M · UHD 12–18M.

Relatie tot broadcast statmuxes

We doen echte statistische multiplexing — dynamische bitverdeling over VBR-kanalen die een vaste draad delen, met kwaliteitsegalisering.

Wat we hebben

CBR-draad op cap · 1 s buffer · per-stream proportionele toewijzing · C1 look-ahead feedforward · kwaliteitsegalisering · voorspellende herverdeling · null-opvulling · exacte pacing.

Waar we verschillen

Een broadcast statmux gebruikt de rate-distortion-schatting van de encoder. Wij gebruiken C1 broncompexiteit (r≈0,92) + een VBR-encoder die zijn eigen QP kiest — een hardwarebeperking, geen ontwerpbeperking.

Probleemoplossing

Symptoom

Oorzaak / oplossing

Gaten / null-pieken (5–7M) in de grafiek

Inhoudsdips — ofwel GOP tussen I-frames (geabsorbeerd door de 1 s buffer) of een collectieve inhoudsstall (behandeld door herverdeling).

Drops > 0 stijgen

Verzendwachtrij overloopt — inhoud boven cap. Controleer de reserve (schuifregelaar), util en of de allocator niet vastloopt.

Eén kanaal blijft laag in bitsnelheid / hoge QP

Ofwel statische inhoud (correct — het geeft bandbreedte vrij) of te laag max in het profiel. Controleer min/gem/max en de werkelijke broncompexiteit.

Grafiek stottert / linkerkant wist

Client-zijde — harde vernieuwing (Ctrl+Shift+R) voor de nieuwe JS-bundel.

cap % / buffer verandert niet na bewerking

LiveView re-render — harde vernieuwing. Waarden worden eens per seconde bijgewerkt.

Architectuur (end-to-end)

SAT UDP SSM ─┐
             ├─ gst_encoder.py(K1)  CBR ─ TCP127 ─┐
   (per      └─ gst_encoder.py(Kn)  CBR ─ TCP127 ─┤
   kanaal)                                        ▼
                                   ┌─────── NIF StatMux ───────┐
                                   │ NULL pad -> draad cap CBR  │
                                   └────────────┬──────────────┘
                                                ▼
                                   MPTS  UDP multicast (CBR cap)

gst_encoder.py per stream: SAT UDP SSM invoer → nvh264enc rc-mode=cbr. Bitsnelheid aangestuurd door BalanceRouter via set_bitrate.

Per-invoerring (TCP loopback van encoder), 2-pass drain (audioprioriteit, volledige video), proportionele allocator, NULL-opvulling exact tot draadcap (CBR), PCR pass-through van encoder.

Één MPTS (PAT/PMT/SDT gegenereerd door NIF) → UDP-multicast op de uitvoer-VLAN. Draad is strikt CBR op mux.bitrate (NULL-stuffing).

Rij 1: ⚠ (validatieproblemen) · PNR · naam in een kader (kleur = stand).

Rij 2+: min·gem·max kbps · voorspelde complexiteit Δ laag/gem/hoog/piek · INVOER VERLOREN · ⚙URL · encoder Mbps · SID · service_type.

Naamkleur = streamstand:

Mbps
 37 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌  <= cap 37,0 Mbit (rood)
    ▓▓▓▓ JOJ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
    ▒▒▒▒ Markíza ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  0 └──────────────────────────────────
        tijd ->           10m │ 1h │ 24h

Rode 'cap'-lijn: draad CBR-plafond (mux.bitrate) — NULL vult tot hier.

Oranje 'headroom N%'-lijn: = cap × headroom-schuifregelaar / 100. Encoderdoelen mikken hier. Beweegt met de schuifregelaar.

Grijs gebied met zwarte stippen tussen inhoud en cap = NULL-opvulling (ongebruikte reserve).

Klik op de kleurband van een kanaal → vouwt automatisch de kaart van dat kanaal eronder open.

Planning

MuxEitAdapter leest gebeurtenissen uit het EPG-systeem per service, bouwt DVB EIT-secties en packetiseert ze op PID 0x12.

EIT wordt direct in de NIF-mux geïnjecteerd, gelijkmatig IN de null-ruimte — vervangt de burstige externe tsp-cascade.

Tabel 0x4E — de huidige + volgende gebeurtenis. Geïnjecteerd elke ≤2 s voor directe 'nu/volgende' actualiteit op de STB.

De mux regenereert periodiek de EIT .bin vanuit EPG (~15 s) — een EPG-planningswijziging bereikt de draad zonder herstart.

Tabellen 0x50/0x51 — de volledige planning uren/dagen vooruit. Gelijkmatig in de stream verspreid.

Verschilmeter (boven de grafiek)

Indicator van werkelijke stroom vs cap. Midden = cap (0). Markering links (groen) = reserve; rechts (rood) = overflow. Live, beweegt elke tick.

-5 Mbps CAP 37000 kbps +5 Mbps

[#### groen = reserve ####│::: rood = boven cap :::]

^ -3200k

(Σ inhoud ~3,2 Mbps onder cap = gezonde reserve)

Headroom-schuifregelaar (78–90 %, standaard 85)

Lager (→78): meer NULL-reserve, veiliger, minder strak capgebruik.

Hoger (→90): strakker capgebruik, minder NULL.

⚠ ≥88 %: schuifregelaar wordt geel — dicht bij het ringoverloop-bevriezingsplafond. Hard begrensd op 78–90.

Asymmetrie: verlagen voegt betrouwbaar reserve toe; verhogen is begrensd door per-stream max_bps-begrenzing.

Beheert hoeveel van de cap de encoders targeten: encoderdoel = budget × headroom% / 100 (oranje lijn in grafiek). Wijzigingen zijn live, opgeslagen in SystemConfig.

Signaalverlies / kanaalstoringen (isolatie)

Één kanaal faalt (encoder crash / signaalverlies) ⇒ de mux blijft draaien, andere kanalen onaangetast, draad houdt de cap (NULL absorbeert de uitval), CC=0 op overlevenden.

PCR / temporizzazione

PCR en PES PTS/DTS zijn pass-through van de encoder (enkelvoudig klokdomein ⇒ coherent, geen drift). Resterende PCR-jitter ~tientallen ms is inherent.

CAT — conditional access (alleen bij scrambling / ECM).

EIT — gebeurtenisinformatie (EPG) — uit het EPG-systeem, zie hieronder.

NIT — netwerkinformatie (netwerk-ID, naam, transportstroom).

PAT — programmalijst (koppelt PNR → PMT PID).

PMT — per programma: video/audio/PCR PID's, codecs, descriptors.

SDT — servicenamen en aanbieders (wat de STB toont in de lijst).

TDT/TOT — tijd en datum + lokale offset (STB-klok).