Muxer — Statistical Multiplex

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

MPTS Multiplekser i adaptacyjny hybrydowy statmux

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.

1. Warstwa enkodera (FFmpeg per strumień)

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.

2. Warstwa mux (potok TSDuck tsp)

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.

3. Warstwa wyjściowa (UDP)

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).

Rekomendowane wymiary (Σ min / średnia / maks vs mux.bitrate)

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%.

Przykład: 4 kanały HD w muksie DVB-T 19 Mbps

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%.

Diagnostyka i alarmy

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.

Usterki i ich przyczyny

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.

Parametry potoku tsp (mux_worker.ex)

--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).

Empiryczne obliczenie pojemności (CLT)

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)

Zalecane wartości per kanał (HD H.264)

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

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ść — jak szybkość transmisji jest dzielona

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 VBR

Praktyczny zysk (10 strumieni × 3 Mbps średnia, 4 Mbps maks)

Bez 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

Wyłączność URL ↔ Statmux

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.

Potok (enkoder → zbalansowany transkoder → mux ffmpeg → tsp)

┌─────────────────────────┐
          │  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:1234

Rozmiarowanie VBR core min/avg/max dla statmux

Zysk 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)

Wskazówki i rozwiązywanie problemów

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

Procedura operatora

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

StatMux — natywny statystyczny multipleks

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.

Architektura i przepływ danych

Architecture diagram

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.

Mózg: sprzężenie zwrotne + wyprzedzenie C1

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.

Mierzony drut (sprzężenie zwrotne)

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.

Zdolność dostarczania

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.

Wyrównana jakość

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).

Predykcyjna redystrybucja

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.

Drut CBR: bufor + wypełnianie null + taktowanie

Wyjście jest dokładnym strumieniem CBR na skonfigurowanym cap. Trzy warstwy to gwarantują:

Stały bufor ~1 s

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ęć.

Wypełnianie null

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.

Dokładne taktowanie

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 wyjścia (rzeka)

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.

Kolorowe pasy

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.

Linia cap / max

Przerywana linia na górze = skonfigurowany cap (sufit drutu). Treść + wypełnianie null zawsze leżą pod nim.

Pasmo null

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.

Znaczniki dropów

Czerwone znaczniki na osi czasu = przepełnienie kolejki wysyłania (drop). Zero w stanie ustalonym; skoki tylko przy starcie/zalewaniu.

Zakres (30s–30m)

Przyciski natychmiastowo przełączają okno czasu (po stronie klienta), aktywny ma szare tło. Wykres akumuluje 30 min w przeglądarce.

Podpowiedź

Najazd myszy pokazuje bitrate per kanał, QP i indeks jakości w danym momencie (wartość historyczna, nie na żywo).

cap %

Aktualny poziom regulacji puli (pool/(pool−trim)). >100% = nadciśnienie (wypełnianie bufora), <100% = przycinanie.

Rezerwa (suwak)

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.

Bufor (dropi)

Nagłówek pokazuje utilization % kolejki wysyłania i skumulowane dropi. Przycisk "wyczyść dropi" resetuje licznik.

GOP

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.

VBV

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ń.

Karty strumieni i stany

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.

Tabele PSI/SI (pełny zestaw DVB)

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 ↔ EPG: pełna integracja

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ń.

Rozmiar / rekomendacje

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.

Relacja do broadcast statmuxów

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).

Co mamy

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.

Gdzie się różnimy

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.

Rozwiązywanie problemów

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.

Architektura (od końca do końca)

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 OVF0

Czerwona 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.

Harmonogram

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.

Miernik różnicy (powyżej wykresu)

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)

Suwak headroom (78–90%, domyślnie 85)

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.

Utrata sygnału / awaria kanału (izolacja)

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 / taktowanie

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).

TSDuck Plugins Used

merge
regulate
pat
pmt
sdt
nit
eitinject
timeref
bitrate_monitor
continuity
psimerge
count