NALU Explorer - H.264ビデオストリーム NAL Unit 可視化ツール
(nalu.funnify.org)開発背景と実装アイデア
- H.264ビデオコーデックの開発/デバッグ時に、NAL Unit構造を視覚的に確認したかった
- FFmpegのコマンドラインで分析は可能だが、各NAL Unitをクリックしながら実際のフレーム画像と一緒に見たかった
- ブラウザ上でそのまま動作するAnnex Bパーサーが必要で、WebAssemblyベースのFFmpegを活用すればフレームのデコードも可能
- 独自の
h264-parserライブラリを開発し、SPS/PPS/Slice Headerまでパース(NPMパッケージとして公開) - H.264標準シンタックス構造ベースの出力: ITU-T H.264仕様のパースシンタックスツリーをそのままたどる階層構造(インデント)でフィールドを表示
動作方式
- Annex Bパース:
00 00 00 01または00 00 01のstart codeを検出 - パラメータパース:
- SPS/PPS: パーサーでパラメータを抽出
- Slice Header:
first_mb_in_slice,slice_type,pic_parameter_set_idなど - 標準シンタックス準拠:
nal_unit()→seq_parameter_set_rbsp()→vui_parameters()など、H.264仕様の構造をそのまま表示
- フレームデコード:
- 選択されたNAL Unitが属するGOP範囲を計算(前/次のIDRを探索)
- SPS/PPSヘッダーとともにAnnex Bを再構成
主な機能
パース
- Annex B Start CodeベースでNAL Unitを分離
- NAL Unitタイプ別パース:
- Type 7 (SPS): profile, level, resolution, frame rate など
- Type 8 (PPS): entropy coding mode, slice groups など
- Type 1/5 (Slice): slice_type, first_mb_in_slice, frame_num など
- Type 6 (SEI): メタデータ(パースは限定的)
- H.264標準シンタックスツリー出力: 条件付きパース(
ifブロック)、階層構造、ビットストリーム読み取り順序をそのまま表示 - RBSP Hexダンプ: offset, hex bytes, ASCII形式でrawデータを確認可能
実際のSPSパース出力例:
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
...
フレームデコード
- GOP単位で自動範囲計算(前/次のIDRを探索)
- SPS/PPSヘッダーを自動検索して先頭に挿入
- FFmpeg.wasmでBMPを抽出後、Canvasにレンダリング
データ抽出
- 個別のNAL Unitをダウンロード(Annex B Start Code + rawData)
- GOP単位でダウンロード(SPS/PPS + GOP範囲のNAL Units)
- タイムライン形式でNAL Unitを可視化(タイプ別の色、サイズ比例)
制限事項
- Slice Data未対応: Slice Headerまでのみパース。マクロブロックデータ、MVD、残差係数などの
slice_data領域は分析しない - AVCフォーマット未検証: Length-basedパースコードは実装済みだがテストされていない
- FFmpeg.wasmの初回読み込み: 初回実行時に約10〜20MBのライブラリをダウンロード
リンク
- ライブデモ: https://nalu.funnify.org
- NPMライブラリ: https://www.npmjs.com/package/h264-parser
まだコメントはありません。