7 ポイント 投稿者 caromdreamer 2025-10-18 | まだコメントはありません。 | WhatsAppで共有

開発背景と実装アイデア

  • 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仕様の構造をそのまま表示
  • フレームデコード:
    1. 選択されたNAL Unitが属するGOP範囲を計算(前/次のIDRを探索)
    2. 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のライブラリをダウンロード

リンク

まだコメントはありません。

まだコメントはありません。