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


Mux menedżera strumieni łączy wiele strumieni SPTS w jeden wyjściowy MPTS CBR (DVB/IPTV). Adaptacyjny hybrydowy statmux łączy wypełnienie rdzenia CBR z enkoderem zbalansowanym VBR na wyjściu muxu o stałej szybkości transmisji.
Gdy główny mux ma włączony statmux, każdy koder FFmpeg działa w trybie capped-VBR: -b:v <średnia> -minrate <min> -maxrate <maks> -bufsize <maks×2>. Bufor VBV = 2× maks daje ~2 s hojności szczytu. Strumienie statmux również otrzymują deterministyczne przesunięcie GOP (-force_key_frames) na strumień_id, aby szczyty I-frame nie zbiegały się między kanałami.
tsp -I null (∞ pakiety NULL @ szybkość linii) → -P merge tsp -I ip <strumień> (nakłada rzeczywiste pakiety) → -P continuity (alarm upuszczenia) → -P pcradjust --bitrate X (przepisuje PCR) → -P pcrverify --jitter-max 500µs → -P bitrate_monitor (alarm szybkości ±5%) → -P regulate --bitrate X --packet-burst 32 → -O ip <wyjście> --packet-burst 7 --enforce-burst.
Plugin regulate emituje dokładnie mux.bitrate bps na druciku. Wejścia opóźnione → pakiety NULL wypełniają lukę. Wejścia piczne → wewnętrzny bufor FIFO (4096 pakietów ≈ 0,3 s @ 19 Mbps) absorb. --enforce-burst zmusza do 7 pakietów TS na datagram UDP (1316 B, standard IPTV).
Pasek górny muxu pokazuje 3 sumy ze statusem koloru. Reguły:
Σ średnia ≤ 85% mux.bitrate — średnia docelowa suma we wszystkich kanałach plus audio. To jest budżet muxu. 15% rezerwa statystyczna chroni przed zbieżnością szczytu. Zielony ≤ 85%, bursztynowy ≤ 100%, czerwony > 100%.
Σ max ≤ 160% mux.bitrate — suma sufitu szczytowego. Może przekraczać pojemność (to właśnie sens statmux — szczyty rzadko zbiegają się). Zielony ≤ 160%, żółty ≤ 200%, czerwony > 200% (dropy przy trwałym szczycie).
Σ min ≤ 50% mux.bitrate — suma podłogi enkodera. Bezpieczna podłoga zapewnia, że na spokojnych scenach enkoder nie spada do niepotrzebnie niskiej jakości. Zielony ≤ 50%, żółty ≤ 90%, czerwony > 90%.
Dostępny budżet po PSI/SI/EIT: ~18,5 Mbps. Σ avg = 4 × 4,0 = 16 Mbps (86% — żółty pogranicze, obniż). Σ max = 4 × 6,0 = 24 Mbps (130% — zielony, OK). Σ min = 4 × 3,0 = 12 Mbps (65% — żółty, OK). Cel: avg ~85% budżetu, max ≤ 160%.
Na ≥ 10 alarmów w 60 s pojawia się powiadomienie z migającą błyskawicą w interfejsie Mux rekomendujące zmniejszenie szybkości transmisji. Automatyczne wycofanie się NIE jest aktywne — operator decyduje.
-P bitrate_monitor --periodic 60 --min/max ±5% — alarm jeśli rzeczywista szybkość odbiega o ponad ±5% od celu. Oznacza, że regulate jest zagłodzony (wejście umarło).
-P continuity — śledzi liczniki ciągłości TS. Rejestruje ostrzeżenie przy każdym upuszczeniu (nadsubskrypcja, awaria FFmpeg, jitter NIC).
-P pcrverify --jitter-max 500000 — DVB zezwala na jitter PCR ≤ 500 µs. Alarm = pcradjust nie nadąża lub źródło ma uszkodzone PCR.
Zbieg GOP — wszystkie enkodery emitują I-klatki jednocześnie, zbieg szczytu. Rozwiązanie: przesunięcie GOP (już włączone dla statmux, hash(stream_id) mod gop_size).
Utrata sygnału wejściowego — pojedynczy kanał ucieka, mux kontynuuje (dzięki bazie -I null). Czas trwania ~3-8 s dla restartowania FFmpeg.
Nadsubskrypcja (trwałe szczyty > pojemności) — zakłócenia/zacinanie audio ~50-200 ms. Rozwiązanie: obniż avg strumienia o 5-10% lub usuń kanał.
Dryfowanie PCR — skoków STB co kilka sekund. Naprawa: pcradjust w potoku (już tam), obserwuj alarmy pcrverify.
Niedomiar VBV dekodera STB — STB traci synchronizację i ponownie ją nabywa (~2-3 s). Rozwiązanie: bufsize enkodera = 2 × maxrate (już ustawione), obniż maxrate.
--max-input-packets 4096 / --max-flushed-packets 4096 (wewnętrzne FIFO ≈ 0,3 s @ 19 Mbps). --receive-buffer-size 16777216 (16 MB bufor rcv UDP per wejście). --packet-burst 32 (regulate) / 7 (wyjście, standard IPTV). --enforce-burst (każdy datagram UDP zawiera dokładnie 7 pakietów).
Odznaka paska górnego "📐 rec X.XM" pokazuje zalecaną pojemność muxu pochodzącą z centralnego twierdzenia granicy. Suma niezależnych strumieni VBR zbliża się do rozkładu normalnego, więc Mux = μ_total + z·σ_total + marża. σ_i jest szacowana z zakresu VBR każdego wejścia jako (maks−min)/4 (zakładając zakres obejmuje ±2σ). Marża = 10% μ_total kompensuje narzut PSI/SI, jitter kontroli szybkości kodera i korelację strumienia, którą czyste CLT nie docenia.
Kolor oznaczenia: 🟢 zielony = cap ≥ 99,7% rekomendacji (konserwatywny) · 🟡 żółty = między 99% a 99,7% · 🔴 czerwony = cap < 99% (niewystarczający, ryzyko dropów) · 🔵 niebieski = cap nieustawiony.
z-score per cel pokrycia: 90% z=1,28 · 95% z=1,65 · 99% z=2,33 · 99,7% z=3,00 (domyślny) · 99,99% z=3,72 (klasa broadcast). Podpowiedź oznaczenia wyświetla wszystkie poziomy; kliknięcie stosuje rekomendację 99,7% do mux.bitrate (wymagany restart muxu).
σ_eff = σ_total × statmux_factor (statmux_factor = 0,7 gdy Statmux jest WŁ., w przeciwnym razie 1,0)
Kanał HD 1080p25: avg = 4000-5000 kbps, min = avg × 0,75 (~3000-3750), max = avg × 1,5 (~6000-7500). Interfejs automatycznie uzupełnia min/max na podstawie avg. Interfejs Statmux automatycznie uzupełnia avg z profilu transkodera strumienia. Kanał SD: avg = 2000-2500 kbps. UHD: avg = 12000-18000 kbps.
Adaptacyjny Hybrydowy Statmux to mechanizm działający w czasie wykonania, który przenosi niewykorzystaną pojemność ze strumieni core (chronionych, pełne VBR) do strumieni zbalansowanych (poświęcalnych). "Hybrydowy", ponieważ dwa odrębne reżimy kontroli szybkości działają równolegle (wypełnienie CBR core + VBR zbalansowany); "adaptacyjny", ponieważ router ponownie ocenia co sekundę na podstawie predykcji z wyprzedzeniem HLS. Operator oznacza strumienie jako zbalansowane przez prawe pole wyboru; system pre-enkoduje je na trzy poziomy (HIGH/MED/MIN) i router atomowo zamienia dowiązanie symboliczne na podstawie pozostałej przepustowości po przewidzeniu szczytów core.
Pojemność muxu 38 Mbps
┌──────────────────────────────────────────────────────────────────┐
│█████████████████████████████████████████████████████░░░░░░░░░░░░│
└──────────────────────────────────────────────────────────────────┘
◀────── core_max (przewidywane z 6 segmentów HLS) ─▶◀── zbalansowane ──▶
per_balanced
= (cap − core_max
− narzut SI
− audio) / N
Przykład: cap=38000 core_max=29000 SI=200 audio_total=1280 N_balanced=2
remaining = 38000 − 29000 − 200 − 1280 = 7520 kbps
per_balanced_max = 7520 / 2 = 3760 kbps
clamp(3760, 500, 3000) = 3000 kbps ← sufit dla zbalansowanego VBRBez adaptacyjnego hybrydowego statmuxu musisz rozmieścić mux dla najgorszego przypadku Σ maks. Z adaptacyjnym hybrydowym statmuxem rozmieścić około Σ średnia + bufor statystyczny (korelacja transmisji ρ=0,15). Rzeczywisty zysk ~5 Mbps na muxie 38 Mbps lub +1 strumień z tym samym limitem.
Czyste CBR (enkoder stały)
VBR bez Statmux
Adaptacyjny Hybrydowy Statmux WŁĄCZONY
Własne nadpisanie URL wejścia i Statmux wzajemnie się wykluczają. Przy włączonym Statmux zbalansowany transkoder polega na lokalnym HLS enkodera do kontroli szybkości. Zewnętrzny URL obejdzie tę pętlę kontrolną. Interfejs egzekwuje to obustronne — pole wyboru blokuje się przy kolidującej kombinacji, a podpowiedź pokazuje, który strumień blokuje.
┌─────────────────────────┐
│ Enkoder (NVDEC→NVENC) │ ← UDP satellite
STRUMIEŃ│ /dev/shm/stream_X/h264/│
│ → muxed.m3u8 + segmenty│
└────────────┬────────────┘
│
┌────────┴────────┐
│ │
rola="core" rola="balanced"
(chroniony) (poświęcalny)
│ │
│ ▼
│ ┌───────────────────────────┐
│ │ BalancedTranscoder │
│ │ ffmpeg p1 NVENC VBR │
│ │ -maxrate dynamiczny │ ← Adaptacyjny router hybrydowy
│ │ /dev/shm/stream_X_ │ takt 1 s (przewiduje z 6
│ │ balanced/h264/...m3u8 │ segmentów HLS, atomowe
│ └───────────┬───────────────┘ przełączenie symlinku HIGH/MED/MIN)
│ │
▼ ▼
┌─────────────────────────┐
│ ffmpeg-as-mux │ ← /dev/shm/mux_X/pipe.sh
│ -f mpegts pipe:1 │
│ -muxrate <cap> │
└────────────┬────────────┘
│ potok powłoki
▼
┌─────────────────────────┐
│ tsp -I file - │
│ continuity → regulate │
│ → pcradjust → bitrate_ │
│ monitor │
│ -P nit -P sdt -P inject│
│ (tabele DVB SI) │
└────────────┬────────────┘
│
▼ multicast UDP
239.x.x.x:1234Zysk statystyczny pojawia się tylko wtedy, gdy enkodery mają szeroki zakres VBR — gdy max ≈ avg enkoder jest efektywnie CBR i router nie ma nic do redystrybucji. Skonfiguruj min/avg/max per strumień tak, aby Σmax znacznie przekraczał cap muxu (nadsubskrypcja = przestrzeń dla zysku statystycznego), a Σavg leżał wygodnie poniżej.
Przykład — mux 38 Mbps, 10 HD core + 2 zbalansowane:
Stary (zablokowany CBR): min=2000 avg=3000 max=4000
Σmax = 10×4000 + 2×7600 = 55200 kbps (1,45× cap — mały zysk)
σ_per_stream = (4000−2000)/4 = 500 kbps (trywialny — płaski)
Σ rezerwa statystyczna ≈ 1,5 Mbps
Zalecany (szeroki VBR): min=1500 avg=3000 max=6000
Σmax = 10×6000 + 2×7600 = 75200 kbps (1,98× cap — zdrowy zysk)
Σavg = 10×3000 + 2×3000 = 36000 kbps (95% cap — wygodny)
Σmin = 10×1500 + 2×500 = 16000 kbps (42% cap — wygodna podłoga)
σ_per_stream = (6000−1500)/4 = 1125 kbps (znaczący)
Σ rezerwa statystyczna ≈ 4 Mbps
Rzeczywista korzyść: na scenach akcji core szczytuje na 5−6 Mbps (detal HD),
router redukuje zbalansowane do poziomu MIN, całkowity drut pozostaje na 38 Mbps.Zalecany zakres per strumień core: • min ≈ avg × 0,5 (enkoder może obniżyć na spokojnych scenach) • avg = nominalny cel wg rozdzielczości (HD ≈ 3 Mbps, FHD ≈ 5 Mbps, UHD ≈ 12 Mbps) • max ≈ avg × 2,0 (enkoder może szczytować na akcji — sport, film akcji) Guardy pojemności muxu (muszą być spełnione): • Σ avg core + Σ avg balanced ≤ mux.bitrate × 0,85 (cel wygodny) • Σ max core + Σ max balanced ≤ mux.bitrate × 2,0 (zysk z nadsubskrypcji) • Σ min core + Σ min balanced ≤ mux.bitrate × 0,6 (podłoga w najgorszym przypadku) σ_per_stream = (max − min) / 4 (zakłada zakres ±2σ) σ_total = √((1−ρ) · Σσ²ᵢ + ρ · (Σσᵢ)²) ρ = 0,15 typowo dla broadcast σ_eff = σ_total × 0,7 (współczynnik statmux gdy WŁĄCZONY) Mux_99,7% = μ_total + 3 · σ_eff (pokazywany w górnym pasku 📐 rekomendacja)
Co najmniej 1 zbalansowany strumień — bez niego router adaptacyjny hybrydowy nie ma nic do zmniejszenia podczas szczytów, więc zysk = 0
Kanały muzyki i informacji to najlepsi kandydaci — tolerancja redukcji szybkości ponad 90%
Śledź przez wpisy dziennika `[balance-router]` — pokazuje `core_max`, `remaining`, przejścia poziomów dla każdego taktu 1 s
Jeśli `core_max > capacity` (ostrzeżenie CORE OVERPEAK w dzienniku), zmniejsz liczbę strumieni core lub obniż maxrate enkodera
Dodaj strumienie do muxu (przypisanie kanałów pozostaje ręczne)
Włącz/wyłącz Statmux na nagłówku muxu (żółty chip). Gdy włączony, wszystkie kodery przełączają się na VBR i restartują
Oznacz strumienie poświęcalne pomarańczowym polem wyboru po prawej — zazwyczaj kanały muzyczne/informacyjne, gdzie zmniejszenie szybkości jest niezauważalne
Gotowe. Adaptacyjny router hybrydowy odczytuje predykcję z 6 segmentów HLS ze strumieni core co 1 s i atomowo zamienia dowiązanie symboliczne zbalansowanego między poziomami HIGH/MED/MIN
Wiele kanałów o zmiennym bitrate współdzieli jeden stały strumień transportowy (MPTS). Bity są dynamicznie realokowane według złożoności treści — wymagająca scena dostaje więcej, statyczna mniej — dzięki czemu jakość pozostaje wyrównana, a suma nigdy nie przekracza pojemności drutu.
Klasa: statmux ze sprzężeniem zwrotnym i wyprzedzeniem C1 (feedforward) na enkoderach VBR — zasada statmux broadcast, sterowana ze złożoności źródła.
UDP multicast SSM, per kanał
Enkodery
złożoność źródła
Loopback
własna linia / strumień
alokator (Σ ≤ pula)
bufor
wypełnianie null → CBR
Drut CBR na cap
antycypuj złożoną scenę przed zapadnięciem
mierzony drut — kalibracja
docelowy bitrate
Każdy kanał biegnie własną linią do muxu (osobny enkoder + połączenie loopback), gdzie wszystkie łączą się w jeden strumień MPTS multicast o dokładnie stałej szybkości. Alokator jest centralnym mózgiem (1 GenServer per mux), takt ~0,85 s.
Alokator łączy dwa sygnały — predykcję ze złożoności źródła (wyprzedzenie) i mierzony drut (sprzężenie zwrotne). To przybliża profesjonalne statmuxy, które znają koszt klatki przed enkodowaniem.
C1 mierzy złożoność treści na dekoderze — co wyprzedza wyjście enkodera o opóźnienie potoku. Względna zmiana złożoności (korelacja r≈0,92 z bitami) jest stosowana do docelowego bitrate w OBIE strony PRZED produkcją przez enkoder: rosnąca scena jest pre-alokowana (bez zapadnięcia), opadająca zwalnia bity wcześnie dla innych.
Dokładne bity per strumień emitowane przez mux (liczniki po stronie nadawcy) kalibrują mapowanie złożoność→bitrate i utrzymują sumę dokładnie na poziomie puli. Kotwica ground-truth — predykcja C1 nie jest idealna (r 0,92), śledzenie drutu ją koryguje.
Roszczenie strumienia jest poparte tym, co enkoder faktycznie produkuje (× zapas szczytowy). Łatwy kanał nie może przetrzymywać przepustowości, której nie może wykorzystać — zwalnia ją dla głodnych.
Celem nie jest równy bitrate ale równa jakość — ciągłe ciśnienie przenosi bity z kanałów wysokiej jakości (niskie QP) do kanałów niskiej jakości (wysokie QP).
Gdy C1 sygnalizuje opadanie kanału, jego przepustowość jest przekazywana innym w tym samym takcie — rampują w górę zanim spadek faktycznie dotrze do drutu.
Waga na kanał = complexity_q12 × max_bps (scena akcji + wyższy max ⇒ więcej bitów).
Budżet na strumień = budżet globalny × waga / Σwagi, zaciśnij [min_bps, max_bps], przeliczany co 10 ms.
Proporcjonalna alokacja puli według zapotrzebowania, ograniczona do [min, max] z profilu wideo; wolna przepustowość trafia do głodnych strumieni.
Cel enkodera = alokacja / kalibracja (EMA mierzona/docelowa per strumień); wysyłana z progiem (Δ≥3%/1s) i limitem zmiany przeciw oscylacjom.
Serwomechanizm buffer-hold utrzymuje poziom kolejki ~1 s (pas), awaryjny backstop przy przeciążeniu; wypełnianie null-padem uzupełnia resztę do CBR.
Wyjście jest dokładnym strumieniem CBR na skonfigurowanym cap. Trzy warstwy to gwarantują:
Kolejka wysyłania utrzymuje stały poziom ~1 s drutu absorbujący sub-sekundowe zapadnięcia GOP (między I-klatkami). Zweryfikowane z nagrania: 0,5–1 s absorbuje 88–91% zapadnięć.
Gdy treść jest poniżej cap, różnica jest wypełniana pakietami null MPEG-TS (PID 0x1FFF). Drut zawsze OSIĄGA cap — zgodny z DVB.
Egress jest taktowany na dokładny cap (busy-spin ABSTIME); zacisk długu 12 ms zapobiega catch-up burstom po krótkim zatrzymaniu → brak jittera PCR, brak skoków powyżej cap.
Wykres stosu na żywo rzeczywistego drutu — każdy pas to jeden kanał, płynący od prawej. Dane są mierzone na drucie (sonda tsp + liczniki NIF), nie szacowane.
Każdy kanał ma stabilny kolor; grubość = jego chwilowy bitrate. Narzut (PSI/EIT) jest szary na dole, wypełnianie null ma teksturę białą na górze.
Przerywana linia na górze = skonfigurowany cap (sufit drutu). Treść + wypełnianie null zawsze leżą pod nim.
Białe kropkowane pasmo na górze = wypełnianie null (wolna pojemność). Im cieńsze, tym pełniejszy drut; znika przy wymagającej treści.
Czerwone znaczniki na osi czasu = przepełnienie kolejki wysyłania (drop). Zero w stanie ustalonym; skoki tylko przy starcie/zalewaniu.
Przyciski natychmiastowo przełączają okno czasu (po stronie klienta), aktywny ma szare tło. Wykres akumuluje 30 min w przeglądarce.
Najazd myszy pokazuje bitrate per kanał, QP i indeks jakości w danym momencie (wartość historyczna, nie na żywo).
Aktualny poziom regulacji puli (pool/(pool−trim)). >100% = nadciśnienie (wypełnianie bufora), <100% = przycinanie.
Pas tolerancji powyżej cap — ile zachować jako rezerwę null. 0 = wypełnij dokładnie N; dodatni = większa rezerwa (bezpieczniejszy); ujemny = lekkie przepełnienie.
Nagłówek pokazuje utilization % kolejki wysyłania i skumulowane dropi. Przycisk "wyczyść dropi" resetuje licznik.
Wspólna długość GOP dla wszystkich kanałów w muxie (zablokowana w profilach wideo przy starcie). Rozłożenie ścienne rozkłada I-klatki w czasie, aby nie kolidowały.
Rozmiar bufora VBV enkodera (ms). Mniejszy wygładza I-klatki (dobry dla kanałów z ruchem), większy daje bardziej szczegółową I-klatkę. Domyślnie 850; możliwe nadpisanie per strumień.
Nagłówek sekcji ma przełącznik "Zwiń / Rozwiń wszystko". Rozwiń kartę, klikając ją lub klikając jej pasek koloru na wykresie. Lewy kolorowy pasek z polem wyboru = członkostwo kanału w muxie.
Działa — kanał enkoduje i przepływa do drutu.
Uruchamianie — enkoder startuje / stabilizuje się.
szary + przyciemniony = wyłączone/błąd i pole wyboru WYŁĄCZONE (celowo wyłączone — brak alarmu)
Błąd — utrata wejścia / awaria enkodera.
StatMux generuje pełny zestaw obowiązkowych tabel MPEG-TS / DVB bezpośrednio w muxie NIF — bez zewnętrznego insertera SI. Tabele są równomiernie rozłożone w czasie w strumieniu, aby STB zawsze szybko nabył PSI/SI po przestrojeniu.
Tabela
PID
Interwał
Cel / źródło
EIT (Event Information Table, PID 0x12) nie jest statyczny — jest w pełni połączony z systemem EPG aplikacji. Operator przypisuje każdemu kanałowi w muxie usługę EPG (eit_epg_service_id), a mux generuje na żywo EIT z zaplanowanych zdarzeń.
min = dolna podłoga (scena statyczna). Zalecane avg × 0,5–0,75. Ustaw wystarczająco nisko, aby oszczędzać na spokojnej treści dla innych.
avg = poziom docelowy. Σ avg wszystkich kanałów ≈ pula wideo (cap − narzut − audio).
max = sufit (zapas VBR dla szczytów/cięć). Zalecane avg × 1,5. Nie ograniczaj twardo do avg — VBR potrzebuje miejsca na szczyty.
Przykłady (avg): SD 1,5–2,5M · HD 2,5–4M · FHD 4–6M · UHD 12–18M. Dla statmux utrzymuj rozsądny rozrzut, aby pula mogła być redystrybuowana.
Robimy prawdziwy statystyczny multipleks — dynamiczną redystrybucję bitów między kanałami VBR współdzielącymi stały drut, z wyrównywaniem jakości. Mechanicznie jesteśmy blisko profesjonalnych headend statmuxów (wyrównanie cap, bufor 1 s, wypełnianie null, GOP/B-klatki, nadpisanie podłogi).
Drut CBR na cap · bufor 1 s · proporcjonalna alokacja per strumień · wyprzedzenie C1 feedforward · wyrównywanie jakości · predykcyjna redystrybucja · wypełnianie null · dokładne taktowanie.
Broadcast statmux używa oszacowania rate-distortion enkodera (dokładny koszt klatki, enkoder jest podrzędny alokatora). Używamy złożoności źródła C1 (r≈0,92) + enkodera VBR, który sam wybiera QP — ograniczenie sprzętowe, nie projektowe. Klasa: sprzężenie zwrotne + wyprzedzenie zamiast czystego feedforward.
Objaw
Przyczyna / rozwiązanie
Przerwy / skoki null (5–7M) na wykresie
Zapadnięcia treści — albo GOP między I-klatkami (absorbowany przez bufor 1 s) albo kolektywne zatrzymanie treści (obsługiwane przez redystrybucję). Wyprzedzenie C1 znacznie je zmniejszyło.
Dropi > 0 rosnące
Przepełnienie kolejki wysyłania — treść powyżej cap. Sprawdź rezerwę (suwak), utilization i czy alokator nie jest zablokowany (takt działa). Bursts przy starcie są normalne.
Jeden kanał pozostaje przy niskim bitrate / wysokim QP
Albo statyczna treść (poprawnie — zwalnia przepustowość) lub zbyt niski max w profilu. Sprawdź min/avg/max i rzeczywistą złożoność źródła.
Wykres zacina się / lewy brzeg się wymazuje
Po stronie klienta — twarde odświeżenie (Ctrl+Shift+R) dla nowego pakietu JS. Dane przepływają przez przyrostowe push, oś = wybrany zakres.
cap % / bufor nie zmienia się po edycji
Brak próbek na żywo (mux zatrzymany lub kodery nie działają) — sprawdź zarówno mux, jak i status strumienia.
SAT UDP SSM ─┐
├─ gst_encoder.py(K1) CBR ─ TCP127 ─┐ Złożoność ZMQ
(na ├─ gst_encoder.py(K2) CBR ─ TCP127 ─┤ ▲ │
kanał) └─ gst_encoder.py(Kn) CBR ─ TCP127 ─┤ │ ▼
▼ BalanceRouter
┌─────── NIF StatMux ───────┐ │ set_bitrate
│ pierścień na wejście (upuść-stary) │◄─┘
│ dwuetapowe opróżnianie (priorytet A, V) │
│ alokator: w=cmplx×max │
│ ×headroom% (suwak 78-90) │
│ wyłączenie na podstawie przeterminowania (>2s) │
│ NULL pad -> limit drut CBR │
│ PCR pass-through │
└────────────┬──────────────┘
▼
MPTS multicast UDP (limit CBR)gst_encoder.py per strumień: wejście UDP SSM SAT → nvh264enc rc-mode=cbr. Szybkość jest sterowana przez BalanceRouter przez set_bitrate. Złożoność sceny (SAD/px) raportowana przez ZMQ do alokatora.
Pierścień na wejście (TCP pętla zwrotna z kodera), dwuetapowe opróżnianie (priorytet audio, pełne wideo), alokator proporcjonalny, NULL pad dokładnie do limitu druciku (CBR), PCR pass-through z kodera.
Jeden MPTS (PAT/PMT/SDT generowany przez NIF) → multicast UDP na wyjściowym VLAN. Drut jest ściśle CBR na mux.bitrate (wypełnianie NULL).
Wiersz 1: ⚠ (problemy walidacji) · PNR · nazwa w ramce (kolor = stan).
Wiersz 2+: min·avg·max kbps · przewidywana złożoność Δ niski/średni/wysoki/szczyt · UTRATA WEJŚCIA · ⚙URL · Mbps enkodera · SID · service_type.
Kolor nazwy = stan strumienia:
Mbps
37 ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ <= cap 37,0 Mbit (czerwony, sufit CBR drutu)
· · · · · · · · · · · · · · · · · <= wolna przestrzeń = wypełnianie NULL
·· szare · czarne kropki · rezerwa ·· (niewykorzystana pojemność)
31 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ <= headroom 85% · 31,5 Mbit (pomarańczowy,
▓▓▓▓ JOJ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ cele enkoderów celują tutaj)
▒▒▒▒ Markíza ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
░░░░ TA3 ░░░░░░░░░░░░░░░░░░░░░░░░░░ <= kliknij pas -> rozwiń kartę
0 └──────────────────────────────────
czas -> 10m │ 1h │ 24h CC0 PCR0 BR0 OVF0Czerwona linia "limit": limit CBR druciku (mux.bitrate) — NULL wypełnia się tutaj.
Pomarańczowa linia 'rezerwa N%': = limit × suwak rezerwy / 100. Encoder set_bitrate celuje tutaj. Porusza się wraz z suwakiem.
Szary obszar z czarnymi punktkami między zawartością a limitem = wypełnienie NULL (niewykorzystana rezerwa). Więcej punktków = więcej rezerwy.
Kliknij pasek koloru kanału → automatycznie rozwinąć kartę tego kanału poniżej.
MuxEitAdapter odczytuje zdarzenia z systemu EPG per usługę, buduje sekcje DVB EIT (nazwa, czas, czas trwania, opis, gatunek) i pakietyzuje je na PID 0x12. Wersje sekcji rosną przy zmianie EPG — dekoder STB odbiera aktualizację.
EIT jest wstrzykiwany bezpośrednio w muxie NIF, równomiernie W przestrzeń null (1 pakiet / N wyjść + p/f okresowo) — zastępując bursty zewnętrznej kaskady tsp. Szczyt/avg ≈ 1,1, bez eksmisji treści, cap utrzymany.
Tabela 0x4E — aktualnie nadawane + następne zdarzenie. Wstrzykiwane co ≤2 s dla aktualności "teraz/następne" na STB.
Mux okresowo regeneruje EIT .bin z EPG (~15 s) — zmiana harmonogramu EPG dociera do drutu bez restartu. Nagłówek muxu pokazuje "EIT ✓" gdy aktywny.
Tabele 0x50/0x51 — pełny harmonogram godziny/dni naprzód (segmenty). Rozkładane równomiernie do strumienia.
Wskaźnik rzeczywistego przepływu vs cap. Środek = cap (0). Znacznik w lewo (zielony) = rezerwa (Σ treści poniżej cap); w prawo (czerwony) = przepełnienie. Na żywo, zmienia się co takt.
-5 Mbps CAP 37000 kbps +5 Mbps
[#### zielony = rezerwa ####│::: czerwony = powyżej cap :::]
^ -3200k
(Σ treści ~3,2 Mbps poniżej cap = zdrowa rezerwa)
Niższy (→78): więcej rezerwy NULL, bezpieczniejszy, mniejsze wykorzystanie cap.
Wyższe (→90): ściślejsze wykorzystanie limitu, mniej NULL.
⚠ ≥88%: suwak staje się żółty — blisko sufitu zamrożenia przepełnienia pierścienia. Twarde ograniczenie 78–90 (nie można osiągnąć 100 — zabezpieczenie przed zamrożonym wideo).
Asymetria: obniżenie niezawodnie dodaje rezerwę; podniesienie jest ograniczone max_bps zaciskiem na strumień (alokator nie pchnię kanału poza jego max → bezpieczne).
Kontroluje, ile limitu kodery celują: cel kodera = budżet × headroom% / 100 (pomarańczowa linia na wykresie). Zmiany na żywo (efekt od następnego znacznika 10 ms), utrwalone w SystemConfig.
Jeden kanał pada (awaria enkodera / utrata sygnału) ⇒ mux działa dalej, inne kanały niezmienione, drut utrzymuje cap (NULL absoruje awarię), CC=0 u ocalałych. Wątki pierścieni per wejście są niezależne. Uszkodzony kanał pokazuje czerwoną migającą nazwę + oznaczenie UTRATA WEJŚCIA; enkoder jest restartowany pod nadzorem i kanał sam się odtwarza.
PCR i PES PTS/DTS są pass-through z kodera (domena pojedynczego zegara ⇒ spójne, brak dryftu). Rezydualny jitter PCR ~dziesiątki ms jest nieodłączne (wyjście 10 ms + UDP) — STB/VLC PLL toleruje to, CC=0. Twardą zgodność modula-ra DVB-S2 jest poza zakresem dla bieżącego przypadku użycia IPTV.
CAT — dostęp warunkowy (tylko przy scramblowaniu / ECM).
EIT — informacje o zdarzeniach (EPG) — z systemu EPG, patrz poniżej.
NIT — informacje o sieci (ID sieci, nazwa, strumień transportowy).
PAT — lista programów (mapuje PNR → PID PMT).
PMT — per program: PIDy wideo/audio/PCR, kodeki, deskryptory.
SDT — nazwy i dostawcy usług (co STB pokazuje na liście).
TDT/TOT — czas i data + lokalny offset (zegar STB).