NALU Explorer - Visualisierungstool für NAL Units in H.264-Videostreams
(nalu.funnify.org)Entwicklungshintergrund und Implementierungsidee
- Bei der Entwicklung/Fehlersuche von H.264-Videocodecs bestand der Wunsch, die Struktur der NAL Units visuell zu prüfen
- Eine Analyse über die FFmpeg-Kommandozeile ist zwar möglich, aber es sollte möglich sein, einzelne NAL Units anzuklicken und zusammen mit dem tatsächlichen Frame-Bild zu betrachten
- Benötigt wurde ein Annex-B-Parser, der direkt im Browser läuft; mit WebAssembly-basiertem FFmpeg ist zudem Frame-Decoding möglich
- Es wurde eine eigene Bibliothek
h264-parserentwickelt, die bis zu SPS/PPS/Slice Header parst (als NPM-Paket veröffentlicht) - Ausgabe auf Basis der H.264-Standard-Syntaxstruktur: Die Felder werden als hierarchische Struktur (Einrückung) angezeigt, exakt entlang des Parsing-Syntaxbaums der ITU-T-H.264-Spezifikation
Funktionsweise
- Annex-B-Parsing: Erkennung der Startcodes
00 00 00 01oder00 00 01 - Parameter-Parsing:
- SPS/PPS: Extraktion der Parameter per Parser
- Slice Header:
first_mb_in_slice,slice_type,pic_parameter_set_idusw. - Standardkonforme Syntax: Anzeige der H.264-Spezifikationsstruktur unverändert, etwa
nal_unit()→seq_parameter_set_rbsp()→vui_parameters()
- Frame-Decoding:
- Berechnung des GOP-Bereichs, zu dem die ausgewählte NAL Unit gehört (Suche nach vorherigem/nächstem IDR)
- Rekonstruktion von Annex B zusammen mit SPS/PPS-Headern
Hauptfunktionen
Parsing
- Trennung der NAL Units auf Basis von Annex-B-Startcodes
- Parsing nach NAL-Unit-Typ:
- Type 7 (SPS): Profil, Level, Auflösung, Bildrate usw.
- Type 8 (PPS): Entropy-Coding-Modus, Slice-Gruppen usw.
- Type 1/5 (Slice):
slice_type,first_mb_in_slice,frame_numusw. - Type 6 (SEI): Metadaten (Parsing eingeschränkt)
- Ausgabe des H.264-Standard-Syntaxbaums: Bedingtes Parsing (
if-Blöcke), Hierarchie und Reihenfolge des Bitstream-Lesens werden unverändert angezeigt - RBSP-Hexdump: Rohdaten können im Format Offset, Hex-Bytes und ASCII geprüft werden
Beispiel einer tatsächlichen SPS-Parsing-Ausgabe:
nal_unit()
forbidden_zero_bit: 0
nal_ref_idc: 3
nal_unit_type: 7
seq_parameter_set_rbsp()
profile_idc: 100
constraint_set0_flag: 0
constraint_set1_flag: 0
constraint_set2_flag: 0
constraint_set3_flag: 0
constraint_set4_flag: 0
constraint_set5_flag: 0
reserved_zero_2bits: 0
...
Frame-Decoding
- Automatische Bereichsberechnung pro GOP (Suche nach vorherigem/nächstem IDR)
- Automatische Suche nach SPS/PPS-Headern und vorgelagerte Einfügung
- Extraktion von BMP mit FFmpeg.wasm und Rendering auf Canvas
Datenextraktion
- Download einzelner NAL Units (Annex-B-Startcode + rawData)
- Download auf GOP-Basis (SPS/PPS + NAL Units des GOP-Bereichs)
- Visualisierung der NAL Units in Form einer Timeline (Farben nach Typ, proportional zur Größe)
Einschränkungen
- Slice Data nicht unterstützt: Es wird nur bis zum Slice Header geparst. Makroblock-Daten, MVD, Residualkoeffizienten usw. im Bereich
slice_datawerden nicht analysiert - AVC-Format nicht verifiziert: Code für length-basiertes Parsing ist implementiert, aber nicht getestet
- Initiales Laden von FFmpeg.wasm: Beim ersten Start werden Bibliotheken mit ~10–20 MB heruntergeladen
Links
- Live-Demo: https://nalu.funnify.org
- NPM-Bibliothek: https://www.npmjs.com/package/h264-parser
Noch keine Kommentare.