08 · H.264 / AVC — 22년의 지배자
이 문서가 답하는 질문: H.264는 어떻게 동작하고, 왜 22년 동안 표준이 됐나? 선행:
07-codecs-overview.md
한 줄 답
H.264는 “프레임을 시간(I/P/B)·공간(매크로블록)·주파수(DCT)·엔트로피(CABAC) 4축으로 동시에 압축”하는 코덱이다. 2003년 표준화 이후 22년간 표준이 된 이유는 압축 효율 + HW 가속 보급 + MPEG LA 라이선스 명료성 의 3박자.
Why — 왜 H.264가 그토록 중요한가
H.264 발표 시점(2003) 인터넷 비디오는 RealVideo·WMV·MPEG-4 Part 2(DivX)가 난립. H.264는 이전 세대(MPEG-2)보다 같은 품질에서 비트레이트 50% 절감 — 4 Mbps DVD를 2 Mbps로 SD 동급, 8 Mbps로 720p, 5 Mbps로 1080p.
이게 의미하는 바:
- YouTube가 처음으로 1080p를 송출 가능 → 2008년 YouTube HD launch
- iPhone(2007)이 비디오 재생 → HW 디코더 탑재
- Blu-ray가 4시간을 한 디스크에 → 영화 산업 채택
- Skype·FaceTime 영상통화 가능 → 화상회의 시장
→ “충분히 좋은 압축 + 모든 디바이스 HW 가속 + 라이선스 명료” — 이 셋이 동시에 충족된 첫 코덱.
How — 4축 압축 메커니즘
1) 시간 축 — I / P / B 프레임 (GOP)
| 프레임 타입 | 풀이 | 데이터 양 | 의존성 |
|---|---|---|---|
| I-frame (Intra) | 자기 자신만으로 디코드 가능 (사진 한 장) | 가장 큼 ( | 없음 |
| P-frame (Predictive) | 이전 프레임에서 변화량만 저장 | 작음 | 이전 I/P에 의존 |
| B-frame (Bi-directional) | 이전 + 다음 프레임에서 변화량 양방향 예측 | 가장 작음 | 양쪽 I/P에 의존 |
표시 순서: I B B P B B P B B P B B I
디코딩 순서: I P B B P B B P B B I B B
↑ B는 P가 먼저 디코드되어야 가능 → DTS ≠ PTSGOP (Group of Pictures): 한 I-frame부터 다음 I-frame 직전까지의 프레임 묶음.
| GOP 길이 | 사용처 | 특징 |
|---|---|---|
| 짧음 (1초 = 24~60 프레임) | 라이브·스트리밍 | seek 빠름·비트레이트 ↑ |
| 김 (10초+ ) | 다운로드·아카이브 | 효율 ↑ ·seek 느림 |
→ HLS는 보통 2~6초 GOP (세그먼트 경계 = key frame). 라이브는 1~2초.
2) 공간 축 — 매크로블록 (Macroblock, 16×16)
H.264는 프레임을 16×16 픽셀 매크로블록으로 쪼갠다. 각 매크로블록을 다시 16×16 / 16×8 / 8×16 / 8×8 / 8×4 / 4×8 / 4×4 서브블록으로 분할 — 움직임이 복잡한 영역에 더 작은 블록.
한 프레임:
┌─────┬─────┬─────┬─────┐
│ MB │ MB │ MB │ MB │ ← 매크로블록 (16×16)
├─────┼─────┼─────┼─────┤
│ MB │ MB │ MB │ MB │
└─────┴─────┴─────┴─────┘
각 매크로블록 안:
- Intra prediction (I-frame): 주변 픽셀로 추측
- Motion compensation (P/B): 참조 프레임의 어디서 왔는지 *모션벡터*3) 주파수 축 — DCT (Discrete Cosine Transform)
각 매크로블록 안의 픽셀 차이값을 DCT로 주파수 영역으로 변환:
- 저주파(부드러운 영역) → 큰 계수 — 보존
- 고주파(디테일·노이즈) → 작은 계수 — 양자화로 0에 가깝게 (lossy 발생)
→ DCT 자체는 lossless, 양자화(quantization) 단계가 진짜 손실. QP(Quantization Parameter)가 클수록 더 압축.
4) 엔트로피 축 — CAVLC vs CABAC
| 엔트로피 코딩 | 효율 | 비용 |
|---|---|---|
| CAVLC (Context-Adaptive Variable Length Coding) | 표준 | 빠름·간단 |
| CABAC (Context-Adaptive Binary Arithmetic Coding) | 10~15% 더 효율 | 느림·복잡 |
→ High profile은 CABAC 사용. Baseline은 CAVLC.
디블록킹 필터 (Deblocking Filter)
H.264는 디코딩 후 블록 경계의 인공적 줄무늬를 부드럽게 하는 필터 가 표준에 포함 — 같은 비트레이트에서 시각 품질 향상.
What — 사양 표
Profile (지원 기능 묶음)
| Profile | 주요 도구 | 사용처 |
|---|---|---|
| Baseline (BP) | I·P, CAVLC, no B-frames | 화상통화 (FaceTime), 모바일 구식 |
| Constrained Baseline (CBP) | BP의 부분집합 (FMO·ASO·RS 제외) | iOS 호환 폴백 |
| Main (MP) | + B-frames, CABAC | SD 방송 |
| Extended (XP) | BP + 스트리밍 도구 | 거의 안 씀 |
| High (HiP) | + 8×8 변환, 8×8 prediction | HD 표준 ★ |
| High 10 (Hi10P) | High + 10-bit | HDR/마스터링 |
| High 4:2:2 (Hi422P) | High + 4:2:2 chroma | 방송 마스터링 |
| High 4:4:4 Predictive (Hi444PP) | + 4:4:4 + lossless | VFX·아카이브 |
Level (해상도·비트레이트 제한)
| Level | 최대 해상도@fps | 최대 비트레이트 (Main) |
|---|---|---|
| 1 | QCIF@15 | 64 kbps |
| 2 | CIF@30 | 2 Mbps |
| 3 | SD@30 | 10 Mbps |
| 3.1 | 720p@30 | 14 Mbps |
| 4 | 1080p@30 | 20 Mbps |
| 4.1 | 1080p@30 | 50 Mbps (Blu-ray) |
| 4.2 | 1080p@60 | 50 Mbps |
| 5 | 4K@30 | 135 Mbps |
| 5.1 | 4K@30 | 240 Mbps |
| 5.2 | 4K@60 / 8K@30 | 240 Mbps |
| 6 / 6.1 / 6.2 | 8K@60 | 800 Mbps |
→ avc1.640028 = avc1.[profile_idc][constraint][level] = High@4.0
NAL Unit (Network Abstraction Layer)
H.264 비트스트림은 NAL unit의 시퀀스:
[NAL][NAL][NAL][NAL]...
↑ 각 NAL unit의 1바이트 헤더에 type 표시:
type 1: P/B slice
type 5: IDR (I-frame, key frame)
type 7: SPS (Sequence Parameter Set — 해상도·profile·level)
type 8: PPS (Picture Parameter Set — 엔트로피·QP)
type 9: AUD (Access Unit Delimiter)→ MP4 컨테이너에 들어갈 때는 length-prefixed (avcC config).
→ MPEG-TS·Annex B 스트리밍에는 **start code (0x00000001)**로 분리.
ABR Ladder 예시 (H.264 단독)
| 레이블 | 해상도 | fps | 비트레이트 | profile |
|---|---|---|---|---|
| 240p | 426×240 | 30 | 400 kbps | Baseline 1.3 |
| 360p | 640×360 | 30 | 800 kbps | Baseline 3.0 |
| 480p | 854×480 | 30 | 1.5 Mbps | Main 3.1 |
| 720p | 1280×720 | 30 | 2.5 Mbps | High 3.1 |
| 720p60 | 1280×720 | 60 | 4 Mbps | High 4.0 |
| 1080p | 1920×1080 | 30 | 5 Mbps | High 4.0 |
| 1080p60 | 1920×1080 | 60 | 8 Mbps | High 4.2 |
| 1440p | 2560×1440 | 30 | 9 Mbps | High 5.0 |
| 4K | 3840×2160 | 30 | 16 Mbps | High 5.1 |
| 4K60 | 3840×2160 | 60 | 25 Mbps | High 5.2 |
→ HLS master.m3u8 가 이 ladder를 가리키며, 플레이어가 대역폭 측정해서 자동 전환 (ABR).
ffmpeg H.264 명령어
# 표준 1080p 인코딩 (CRF 모드, 화질 우선)
ffmpeg -i in.mov \
-c:v libx264 -preset slow -crf 18 \
-profile:v high -level 4.0 \
-pix_fmt yuv420p \
-c:a aac -b:a 128k \
-movflags +faststart \
out.mp4
# 라이브 스트리밍용 (CBR + 짧은 GOP)
ffmpeg -i input.mov \
-c:v libx264 -preset veryfast -tune zerolatency \
-b:v 4M -maxrate 4M -bufsize 8M \
-g 60 -keyint_min 60 -sc_threshold 0 \
-c:a aac -b:a 128k \
-f flv rtmp://server/live/stream
# 2-pass VBR (배포용 정확한 사이즈)
ffmpeg -y -i in.mov -c:v libx264 -b:v 5M -pass 1 -an -f null /dev/null
ffmpeg -i in.mov -c:v libx264 -b:v 5M -pass 2 -c:a aac -b:a 128k out.mp4
# HLS 세그먼트 출력
ffmpeg -i in.mp4 \
-c:v libx264 -preset fast -crf 22 \
-c:a aac -b:a 128k \
-hls_time 6 -hls_list_size 0 \
-hls_segment_filename "seg_%03d.ts" \
out.m3u8x264 preset과 tune
ultrafast superfast veryfast faster fast medium slow slower veryslow placebo
← 빠름·낮은 효율 느림·높은 효율 →| tune | 용도 |
|---|---|
film | 영화 (grain 보존) |
animation | 애니 (큰 평면 영역 + 깔끔한 라인) |
grain | 노이즈 보존 우선 |
zerolatency | 라이브 (B-frame off, lookahead off) |
stillimage | 정지화면 슬라이드 |
What-if — 잘못 다루면 어떻게 깨지는가
❌ 함정 1 — Baseline을 모든 디바이스 폴백이라 가정
iOS 6 이전 = Baseline 강제. 하지만 2026 시점 모든 디바이스가 High Profile 지원. Baseline은 압축 효율이 15~20% 나쁨 — 굳이 폴백으로 둘 이유 없음.
❌ 함정 2 — Level을 너무 높게
-level 6.2로 1080p 인코딩하면 일부 HW 디코더 (오래된 Smart TV, 콘솔)가 거부.
필요한 만큼만 Level 설정 — 1080p30이면 Level 4.0이 표준.
❌ 함정 3 — sc_threshold 미설정 → key frame 위치 변동
ABR/HLS는 모든 ladder의 key frame 위치가 일치해야 끊김 없이 전환된다.
# 잘못 — scene change 감지로 key frame이 가변
-g 60
# 올바름 — 정확히 60프레임마다 강제 key frame
-g 60 -keyint_min 60 -sc_threshold 0 -force_key_frames "expr:gte(t,n_forced*2)"❌ 함정 4 — CRF 18 이하
CRF 18은 시각적 lossless에 가깝지만, 4K 60p 라면 비트레이트 30+ Mbps. 모바일 무리. CRF 21~24가 일반적인 sweet spot (고품질 OTT는 18~22).
❌ 함정 5 — Constrained Baseline ≠ Baseline
iOS Safari는 Constrained Baseline 만 폴백 호환 (FMO·ASO·RS 빠짐).
# constrained baseline로 인코딩
-profile:v baseline -level 3.0 -x264opts "no-cabac:no-deblock"❌ 함정 6 — -tune film 을 게임 영상에 적용
film tune은 grain(노이즈)을 보존하려 비트를 쓴다. 게임은 grain이 거의 없는 평면 영역 → 비트 낭비.
게임은 default 또는 -tune animation.
Insight — 흥미로운 이야기
“x264가 표준 reference보다 더 좋은 인코더가 됐다”
ITU-T가 발표하는 H.264 reference encoder(JM)는 연구용. 실제 압축 효율은 형편없음. 2004년 Loren Merritt이 x264 라는 오픈소스 인코더를 시작 — 표준의 모든 도구를 영리하게 조합. 결과: x264가 JM보다 30% 더 압축 효율 좋음. 이후 Apple·MS·Adobe·YouTube 모두 x264 또는 그 변종 사용. → 표준은 “어떤 비트스트림이 valid한가”만 정의하고, 어떻게 만들지 는 인코더의 자유 — 산업이 표준보다 빨리 뛴 사례.
“Baseline의 트라우마”
2007년 iPhone 1세대 출시 때 H.264 디코더는 Baseline만 가속 가능했다. 그래서 모바일 첫 시대 = Baseline 시대. 그 뒤 10년간 iOS 호환을 위해 Baseline으로 인코딩하는 관행이 남아있고, 지금은 모든 디바이스가 High까지 가속인데도 “iOS 폴백은 Baseline” 이라는 misconception이 여전히 존재.
“H.264의 진짜 비밀무기는 deblocking filter”
같은 비트레이트에서 MPEG-2 vs H.264 비교를 해보면, 가장 눈에 띄는 차이가 디블록킹. 매크로블록 경계의 인공 줄무늬가 사라져 더 자연스럽게 보인다. 디블록킹은 표준에 포함된 디코더 필수 단계 — 인코더에서 빠뜨릴 수 없는 후처리.
“x264 preset ‘placebo’의 유래”
placebo preset은 medium 대비 30% 더 시간 들고 효율은 0.1% 좋음. 이름 그대로 위약 효과. 현실에서는 veryslow가 합리적 한계 — placebo는 농담 같은 옵션.
“NTSC drop-frame의 그림자가 H.264에도”
H.264 SEI(Supplemental Enhancement Information)에 timecode metadata 가 들어간다. 방송에서 23.976/29.97 timecode를 전달하는 데 쓰는데, drop-frame flag도 그대로 — NTSC의 0.1% 그림자.
요약 + Mermaid
H.264는 시간(I/P/B)·공간(매크로블록)·주파수(DCT)·엔트로피(CABAC) 4축으로 압축한다. Profile=기능, Level=리소스, GOP=세그먼트 경계. ABR ladder는 모든 변형의 key frame 위치를 일치시켜야 한다. 22년의 표준이지만 현재는 폴백 — 신규는 HEVC/AV1, H.264는 모든 디바이스가 받는 안전망.