Show GN: 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 스펙의 파싱 신택스 트리를 그대로 따라 계층 구조(indent)로 필드 표시
작동 방식
-
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