H.264 (AVC) — The Universal Codec
H.264 — 모든 곳에 있는 코덱
2003년 이후 모든 인터넷·모바일·BD의 사실상 표준. 압도적 호환성과 합리적 라이센스로 "안전한 선택"의 대명사. 2026년에도 여전히 가장 많이 쓰인다.
Overview
H.264는 2003년에 등장해 2026년에도 가장 많이 쓰이는 비디오 코덱이다. 등장 후 23년이 지났지만 압도적 호환성과 충분한 압축률로 여전히 '안전한 선택'.
이번 장은 H.264의 핵심 기술과 그것이 만들어낸 "코덱 표준이란 무엇인가"의 본보기를 본다. H.265·AV1은 모두 H.264의 후속이고, H.264를 모르면 그 후속들을 이해 못 한다.
- H.264의 등장 배경과 시대적 의미를 안다
- Macroblock 단위 처리와 sub-블록 분할을 이해한다
- 9방향 인트라 예측의 직관과 한계를 안다
- CABAC와 CAVLC의 차이·trade-off를 안다
- Profile/Level의 의미와 호환성 영향을 안다
Sections
7.1 등장 배경 — MPEG-2의 한계와 인터넷 시대
1995년 MPEG-2가 DVD·디지털 방송의 표준이 됐다. 비트레이트 8~10Mbps에서 SD(720×480) 화질. 당시엔 충분했지만 인터넷·HD 시대로 가면서 한계가 보였다.
1080p HD를 MPEG-2로 인코딩하면 20Mbps 필요. 당시 인터넷 평균 속도가 1Mbps 수준이라 비현실적. "같은 화질에 절반 비트레이트"가 절실했다.
ITU-T VCEG(H.26x 시리즈)와 ISO/IEC MPEG(MPEG-x 시리즈)가 "이번엔 같이 만들자"고 합의 — Joint Video Team(JVT) 결성. 결과물이 H.264 = MPEG-4 Part 10 = AVC(Advanced Video Coding). 2003년 표준화.
한 줄 요약: MPEG-2 대비 같은 화질에 절반 비트레이트. 1080p HD를 10Mbps에 가능 → DVD에서 BD로, 위성에서 IPTV로, PC에서 인터넷·모바일로의 거대한 이행을 가능하게 한 결정적 기술.
7.2 Macroblock 16×16과 sub-블록 분할
H.264의 기본 처리 단위는 16×16 픽셀의 매크로블록(macroblock). 한 프레임을 16×16 격자로 나눠 각 매크로블록을 독립적으로 압축.
하지만 16×16이 항상 최적은 아니다. 디테일이 많은 영역은 더 작게, 단조로운 영역은 더 크게 처리해야 효율적. 그래서 매크로블록을 더 작은 sub-블록으로 분할 가능:
- 16×16 → 16×8 → 8×16 → 8×8 - 8×8 → 8×4 → 4×8 → 4×4
인코더는 각 매크로블록마다 "어떻게 분할하면 최적인가"를 탐색. 분할이 정밀할수록 압축은 좋지만 시그널링 오버헤드도 늘어남.
H.264 vs H.265 비교 지점: H.265는 16×16 매크로블록 대신 CTU(Coding Tree Unit, 최대 64×64) 를 쓴다. 더 큰 블록으로 단조 영역을 효율적 처리. 이게 H.265 압축 효율의 큰 부분.
7.3 9방향 인트라 예측 — 같은 프레임 안에서의 추측
I-프레임의 압축 핵심은 인트라 예측. H.264는 4×4 블록 단위로 9방향 예측:
- DC (블록 평균) - Vertical (수직) - Horizontal (수평) - Diagonal Down-Left - Diagonal Down-Right - Vertical-Right - Horizontal-Down - Vertical-Left - Horizontal-Up
각 방향은 "왼쪽 + 위쪽 블록의 픽셀을 어떻게 외삽(extrapolate)해 현재 4×4를 채울까"의 규칙. 예: Vertical은 위쪽 행 픽셀을 그대로 아래로 복사.
인코더가 9방향 다 시도해 가장 잘 맞는 걸 선택. 잘 맞는 방향이 있으면 잔차가 매우 작아짐 → 압축 폭증.
16×16 매크로블록은 별도로 4방향 예측(DC·Vertical·Horizontal·Planar)도 가능. 큰 단조 영역에 효율적.
H.265는 이걸 35방향으로, AV1은 56방향으로 확장. 자세한 건 다음 장.
7.4 CABAC vs CAVLC — 엔트로피 부호화 두 갈래
H.264의 마지막 압축 단계 엔트로피 부호화는 두 가지를 제공한다.
CAVLC (Context-Adaptive Variable Length Coding): - Huffman 류의 가변 길이 부호화 - 컨텍스트(주변 블록 상태)에 따라 코드 테이블 변경 - 빠름·구현 간단 - Baseline profile에서 강제
CABAC (Context-Adaptive Binary Arithmetic Coding): - 산술 부호화. Shannon 한계에 더 가까움 - 같은 데이터에 10% 더 적은 비트 (압축 효율 향상) - 그러나 계산 비용 큼 (디코더 부담) - Main·High profile에서 사용
실무 트레이드오프: 모바일(특히 옛 기기)·라이브 인코딩엔 CAVLC, VOD·고화질엔 CABAC. ffmpeg -x264-params no-cabac로 끌 수 있음.
H.265는 CABAC만 사용. CAVLC 제거. 디코더가 강해진 시대라 가능한 선택. AV1은 SBAC(Symbol-Based Arithmetic Coding) 으로 발전 — 더 효율적이지만 또 더 무거움.
7.5 Profile과 Level — 호환성의 미디엄
H.264 표준은 거대하다. 모든 디바이스가 모든 기능을 지원할 수는 없음. 그래서 Profile과 Level로 부분집합 정의.
Profile = 기능 집합: - Baseline: 가장 단순. B-프레임 없음, CAVLC만. 화상회의·옛 모바일. - Main: B-프레임 + CABAC. 일반 TV·SD. - High: 8×8 변환, 4:2:0 외, 무손실 모드. BD·HD 스트리밍. - High 10/4:4:4: 10bit, 4:4:4 컬러. 전문 영역.
Level = 처리 능력: - Level 3.0: SD 30fps - Level 4.0: 1080p 30fps - Level 4.2: 1080p 60fps - Level 5.1: 4K 30fps - Level 5.2: 4K 60fps
호환성의 의미: "이 영상은 H.264 High@L4.0" 이면 "Main 디코더는 못 풀 수도 있고, L4.0 미만 디코더도 못 풀 수도". 옛 아이폰이 어떤 영상을 못 보는 게 보통 이 Profile/Level 미스매치.
실무 팁: 모든 디바이스 호환을 원하면 Baseline 또는 Main @ L3.1 이하 사용. 화질을 양보하지만 안 깨짐.
초등학교 미술시간에 모눈종이를 받았다고 치자. "풍경화를 그려야 하는데, 한 칸 한 칸 채워야 한다." 16×16 모눈종이 블록을 받았는데, 푸른 하늘 영역은 그냥 "이 16×16 다 같은 파란색"이라고 하면 된다. 디테일이 많은 나무 영역은 "16×16을 4×4 단위로 쪼개서 더 세밀하게 그리겠다"고 한다.
이게 H.264의 16×16 매크로블록 + sub-블록 분할의 직관이다. 단조 영역은 큰 단위로(시그널링 절약), 디테일 영역은 작은 단위로(품질 보존).
그리고 인트라 예측은 "옆 칸을 봐서 추측하기". 위쪽 칸이 파란색이면 아래도 파랗겠지(Vertical). 왼쪽이 빨강이면 오른쪽도 비슷하겠지(Horizontal). 9가지 추측 방향. 잘 맞는 방향을 골라 "이 방향으로 추측하고, 실제와의 차이만 적자".
H.264가 모든 디바이스에 들어간 이유: 이 "모눈종이 그림" 방식이 충분히 단순해서 작은 칩으로도 디코딩 가능. 동시에 충분히 정교해서 화질이 인터넷 시대에 맞는 수준. 단순함과 효율의 절묘한 균형.
ffmpeg + libx264로 다양한 H.264 옵션을 비교. Profile·Preset·CABAC·B-frame이 파일 크기와 인코딩 시간에 어떻게 영향을 주는지.
import subprocess, os, time
INPUT = 'sample.mp4'
configs = [
('baseline_fast', ['-profile:v', 'baseline', '-preset', 'ultrafast', '-crf', '23']),
('main_medium', ['-profile:v', 'main', '-preset', 'medium', '-crf', '23']),
('high_slow', ['-profile:v', 'high', '-preset', 'slow', '-crf', '23']),
('high_veryslow', ['-profile:v', 'high', '-preset', 'veryslow', '-crf', '23']),
('no_cabac', ['-profile:v', 'main', '-preset', 'medium', '-crf', '23',
'-x264-params', 'no-cabac=1']),
('no_bframe', ['-profile:v', 'main', '-preset', 'medium', '-crf', '23',
'-bf', '0']),
]
print(f'{"config":<18} {"time":>7} {"size MB":>10} {"vs medium":>12}')
print('-' * 50)
for name, opts in configs:
output = f'h264_{name}.mp4'
t0 = time.time()
subprocess.run([
'ffmpeg', '-y', '-i', INPUT,
'-c:v', 'libx264', *opts,
'-an', output
], check=True, capture_output=True)
dt = time.time() - t0
size = os.path.getsize(output) / 1e6
print(f'{name:<18} {dt:>6.1f}s {size:>9.2f} MB')
# 결과 예시 (1080p 10s 영상):
# baseline_fast 0.4s 3.45 MB ← 호환 최고, 화질 낮음
# main_medium 1.2s 3.12 MB ← 일반적 기본
# high_slow 4.8s 2.95 MB ← +30% 시간, -5% 크기
# high_veryslow 18.3s 2.90 MB ← +15배 시간, -1.7% 크기
# no_cabac 1.1s 3.44 MB ← CABAC 끄면 +10% 커짐
# no_bframe 1.0s 3.51 MB ← B 끄면 +13% 커짐
옵션의 ROI가 명확히 보인다. CABAC을 켜는 것만으로 10% 줄어들고(거의 무료), B-프레임 추가로 13% 줄어든다. Preset slow는 30% 시간 더 들이고 5% 줄임 — sweet spot. veryslow는 15배 시간에 1.7%만 추가 — 비용 대비 거의 무가치. 그래서 표준 권고가 -preset medium 또는 slow. veryslow는 archive용에만.
✅ 시니어가 보는 것
- Profile/Level의 호환성 영향을 안다
- Preset의 "인코딩 시간 vs 압축률" trade-off 직관
- CABAC·B-frame의 비용·효과를 안다
- x264의 옵션을 ffmpeg 명령으로 직접 작성 가능
⚠️ 레드 플래그
- Profile을 "무조건 High가 좋다"고 생각
- Preset veryslow를 일상에 씀 (ROI 0)
- Baseline을 "옛날 거"로 무시 (실제로는 화상회의·옛 모바일에 필수)
- Level 미스매치로 인한 호환성 사고 모름
🎤 예상 인터뷰 질문
- H.264 Baseline·Main·High의 차이와 사용 도메인은?
- CABAC vs CAVLC를 언제 선택하나요?
- Preset medium·slow·veryslow 중 어느 것이 일반 VOD에 적절한가요? 왜?
Key Takeaways
H.264 = AVC
2003년. MPEG-2 대비 같은 화질에 절반 비트레이트.
Macroblock 16×16
처리 단위. 8×4까지 sub-블록 분할.
인트라 9방향
옆 블록 픽셀로 추측. 잘 맞으면 잔차 폭감.
CABAC > CAVLC
10% 더 좋지만 더 무거움.
Profile 호환성
Baseline·Main·High. 디바이스 호환의 미디엄.
Level = 능력
L3.1(SD) ~ L5.2(4K60). 디코더 처리 한계.
Preset = 검색 철저함
Medium~Slow가 sweet spot. Veryslow는 ROI 0.
여전히 표준
2026년에도 가장 많이 쓰이는 코덱. 안전한 선택.