04 · YUV 색공간 · 크로마 서브샘플링
이 문서가 답하는 질문: 왜 비디오는 RGB가 아니라 YUV로 압축되는가? 4:2:0이란 무엇인가? 선행:
02-media-image(sRGB·색공간 기초)
한 줄 답
사람의 눈은 색차(chroma)보다 밝기(luma)에 8배 민감하다. YUV는 RGB를 “밝기 1축 + 색 2축”으로 분리해서, 색만 해상도를 줄여(서브샘플링) 데이터를 절반 이하로 압축하면서도 인지 품질은 거의 유지한다.
Why — 왜 YUV로 분리하는가
RGB는 디스플레이에 쏘는 형식 — 빨강·녹색·파랑 3채널이 모두 같은 해상도. 그런데 사람의 시각 시스템은:
- 간상세포(rod): 1억 2천만 개, 밝기에 매우 민감
- 원추세포(cone): 6백만 개, 색에 민감
→ 비율 약 20:1. 그래서 밝기 정보를 우선 보존하고 색 정보는 뭉개도 우리는 잘 모른다.
YUV(엄밀히는 Y’CbCr)는 이 인지 비대칭을 활용한다:
Y' = 밝기(luma) — 흑백 TV가 그대로 받아 표시 가능
Cb = 파랑 - 밝기 (color difference)
Cr = 빨강 - 밝기 (color difference)Y’ 하나만 봐도 흑백 영상으로 보인다 — 이게 1953년 NTSC 컬러TV가 흑백TV와 호환되도록 한 핵심 트릭.
How — 어떻게 동작하는가
RGB → YUV 변환 매트릭스 (BT.709)
Y' = 0.2126·R + 0.7152·G + 0.0722·B
Cb = (B - Y') / 1.8556 → 정규화 후 [-0.5, 0.5]
Cr = (R - Y') / 1.5748 → 정규화 후 [-0.5, 0.5]→ 녹색 가중치(0.7152)가 가장 큼 — 사람의 눈이 녹색에 가장 민감.
Color Matrix 표준들
| 표준 | 공식 | 용도 |
|---|---|---|
| BT.601 | Y’=0.299R + 0.587G + 0.114B | SD (NTSC/PAL DVD) |
| BT.709 | Y’=0.2126R + 0.7152G + 0.0722B | HD (1080p) |
| BT.2020 | Y’=0.2627R + 0.6780G + 0.0593B | UHD/4K/8K, HDR |
| BT.2100 | BT.2020 + PQ/HLG transfer | HDR (05-bit-depth-and-hdr.md) |
| JPEG (BT.601 full) | BT.601 + full range | 정지 이미지 |
BT.601 매트릭스로 인코딩한 영상을 BT.709로 디코딩하면 색이 어긋난다 — 가장 흔한 아티팩트:
피부톤이 누렇게 보이거나 / 하늘이 청록빛으로 빠짐.
ffmpeg는 메타데이터로 어느 매트릭스인지를 컨테이너에 박는다 (colormatrix, colorspace 태그).
# 매트릭스 확인
ffprobe -select_streams v:0 -show_entries stream=color_space,color_primaries,color_transfer in.mp4
# 강제 명시
ffmpeg -i in.mov -c:v libx264 \
-colorspace bt709 -color_primaries bt709 -color_trc bt709 \
-movflags +faststart out.mp4크로마 서브샘플링 (J:a:b 표기)
J:a:b 는 4픽셀 가로 × 2픽셀 세로 영역 안에서 색 샘플 수를 표기한다.
| 표기 | 의미 | 데이터 비율 (vs 4:4:4) |
|---|---|---|
| 4:4:4 | 모든 픽셀에 Y, Cb, Cr 1개씩 | 100% (full chroma) |
| 4:2:2 | 가로 2픽셀당 색 1쌍 | 67% |
| 4:2:0 | 2×2 영역당 색 1쌍 | 50% |
| 4:1:1 | 가로 4픽셀당 색 1쌍 | 50% |
| 4:0:0 | 색 없음 (Y만) | 33% (흑백) |
4:2:0의 시각화:
Y' Y' Y' Y' ← 4 luma 샘플 (가로)
Y' Y' Y' Y' ← 4 luma 샘플 (다음 줄)
Cb Cb ← 2×2 블록당 Cb 1개
Cr Cr ← 2×2 블록당 Cr 1개→ 2×2 영역의 4픽셀이 같은 색 샘플 1쌍을 공유.
| 서브샘플 | 사용처 |
|---|---|
| 4:4:4 | 그래픽·VFX·아카이브·카메라 raw·ProRes 4444 |
| 4:2:2 | 방송 마스터·ProRes 422·DNxHD·Canon Cinema RAW |
| 4:2:0 | 모든 H.264/HEVC/AV1 소비자 인코딩 — Web/Streaming/Blu-ray |
What — 사양 표와 명령어
Pixel Format 표 (ffmpeg 기준)
| pix_fmt | 비트심도 | 서브샘플 | 비고 |
|---|---|---|---|
yuv420p | 8 | 4:2:0 | H.264 표준 |
yuv422p | 8 | 4:2:2 | 방송용 |
yuv444p | 8 | 4:4:4 | 그래픽용 |
yuv420p10le | 10 | 4:2:0 | HEVC Main 10, AV1 |
yuv422p10le | 10 | 4:2:2 | ProRes 422 HQ |
yuv444p10le | 10 | 4:4:4 | ProRes 4444 |
nv12 | 8 | 4:2:0 (UV interleaved) | GPU 친화 |
p010le | 10 (LSB padded) | 4:2:0 | HW HEVC |
rgb24 | 8 | 4:4:4 (RGB) | 디스플레이용 |
# 입력 pixel format 확인
ffprobe -select_streams v:0 -show_entries stream=pix_fmt in.mp4
# → pix_fmt=yuv420p
# 4:4:4 마스터 → 4:2:0 배포
ffmpeg -i master_444.mov -pix_fmt yuv420p -c:v libx264 deliver.mp4
# 10-bit 4:2:0 (HDR/HEVC Main 10)
ffmpeg -i raw.mov -pix_fmt yuv420p10le -c:v libx265 -tag:v hvc1 hevc10.mp4Range — Limited (TV) vs Full (PC)
| Range | Y 범위 | Cb/Cr 범위 | 사용처 |
|---|---|---|---|
| Limited (TV/Studio) | 16-235 | 16-240 | 비디오 표준 (BT.601/709/2020) |
| Full (PC) | 0-255 | 0-255 | JPEG·웹 캡처·게임 |
Limited 자산을 Full로 디코딩하면: 검은색이 더 검고, 흰색이 빠져나가 콘트라스트가 부풀려진 출력. Full 자산을 Limited로 디코딩하면: 회색빛 washed out — Mac QuickTime이 PC 캡처 영상을 보여줄 때 흔함.
# 명시적 변환 (limited → full)
ffmpeg -i tv.mp4 -vf "scale=in_range=tv:out_range=pc" -c:v libx264 pc.mp4
# h264 인코딩 시 range 박기
ffmpeg -i in.mov -c:v libx264 -color_range tv out.mp4정확한 변환 명령어 (BT.709, full chain)
ffmpeg -i master.mov \
-c:v libx264 -preset slow -crf 18 \
-pix_fmt yuv420p \
-colorspace bt709 -color_primaries bt709 -color_trc bt709 \
-color_range tv \
-movflags +faststart \
out_h264.mp4What-if — 잘못 다루면 어떻게 깨지는가
❌ 함정 1 — 4:2:0으로 텍스트/UI를 캡처하면 가장자리가 번진다
게임 UI·자막·로고는 고대비 색 경계가 많다 — 4:2:0은 2×2 블록당 색 1개라서 빨강 글자가 어두운 배경 위에서 핑크 흐림처럼 번져 보인다.
예시:
- 흰 바탕에 빨간 1픽셀 글씨 → 4:2:0 후 글씨가 분홍 흐림.
- 검은 바탕에 시안 글씨 → 청록 블리딩.
해결책:
- 4:2:2 또는 4:4:4 인코딩 (대역폭 높지만 정확) — Apple ProRes 4444가 마스터링 표준.
- 고해상도 + 4:2:0 — 1080p 4:2:0 글자가 흐리면 1440p/4K 4:2:0으로 올리면 가장자리가 살아난다.
- 별도 그래픽 레이어 — 인코딩 후 클라이언트에서 자막·UI를 따로 그림 (HLS WebVTT 자막).
그래서 Twitch는 1080p 4:2:0이다 — 게이밍 콘솔 H.264 HW 인코더 대부분이 4:2:0만 가속하기 때문. 결과: 채팅·UI 글자가 또렷하지 않다. 1440p/60 partner 등급에서야 텍스트가 살아난다.
❌ 함정 2 — Color Matrix 메타 누락
# 메타 없이 인코딩
ffmpeg -i in.mov -c:v libx264 out.mp4
# → ffprobe에서 color_space=unknown플레이어는 휴리스틱으로 추측 — 1080p 이상이면 BT.709, 그 미만이면 BT.601 가정. 자산이 SD인데 BT.709로 마스터링됐으면 색이 어긋난다.
해결: 인코딩 시 항상 -colorspace -color_primaries -color_trc 3개를 명시.
❌ 함정 3 — Range 라벨링 실수
iPhone QuickTime은 자주 Full Range (PC) 로 캡처하면서 메타에 라벨을 안 박는다. 편집 NLE에서 limited로 가정 → 색이 빠짐. 반대로 PC 캡처 자산을 limited로 인코딩하면 그림자가 까맣게 깔린다.
# 진단
ffprobe -select_streams v:0 -show_entries stream=color_range in.mp4
# range 강제 명시 (limited)
ffmpeg -i in.mov -c:v libx264 -color_range tv -movflags +write_colr out.mp4
# 변환
ffmpeg -i full.mp4 -vf "scale=in_range=pc:out_range=tv" -c:v libx264 limited.mp4❌ 함정 4 — 4:4:4 마스터를 4:2:0 인코딩 후 다시 4:4:4로 복원
크로마 서브샘플링은 비가역. 한 번 잃은 색 디테일은 슈퍼해상도 같은 ML 보강 외에는 못 살린다. 마스터는 언제나 4:4:4 또는 4:2:2 로 보존, 배포만 4:2:0.
❌ 함정 5 — Limited 자산을 sRGB로 가정해 색보정
10bit BT.2020 limited 자산을 sRGB 8bit로 작업하면 첫 단계에서 색·계조가 모두 깎인다. DaVinci Resolve의 Color Space Transform 노드가 표준 — 항상 source → working → display 3-stage.
Insight — 흥미로운 이야기
“4:2:0은 PAL TV의 발명이다”
1980년대 D1 디지털 방송 표준에서 처음 4:2:0이 정의됐다 (정확히는 4:1:1이 NTSC, 4:2:0이 PAL). 그 시대 ASIC가 더 이상 색 데이터를 처리할 여유가 없었다 — 대역폭의 청구서를 색에 떠넘긴 것. 40년 뒤 H.264·HEVC·AV1까지 4:2:0이 소비자 표준의 기본값이고, 모바일 GPU의 비디오 디코더는 4:2:0만 풀가속한다 — 다른 서브샘플링은 SW fallback이 흔하다.
“Twitch가 1440p로 가는 이유는 글자다”
Twitch는 2022년부터 partner에 1440p/60 옵션을 열었다. 이유는 4:2:0이 텍스트에 약한 걸 알기 때문 — 1080p에서 채팅·UI가 흐려지는 걸 해상도 증가로 우회. H.264 4:4:4 인코딩이 정답이지만 GPU 가속이 안 되니 해상도를 1.78배 키워 4:2:0의 색 해상도를 살린 것.
“YouTube의 미스터리 — 같은 영상인데 색이 다르다”
같은 마스터를 YouTube에 올리면 VP9 변환본은 채도가 빠지고 AV1 변환본은 살아있다는 보고가 흔하다. 원인은 YouTube의 BT.601 → BT.709 매트릭스 변환 단계에서 옛 트랜스코더의 휴리스틱 미스 — 코덱이 아니라 매트릭스의 문제.
“ProRes 4444 — 마지막 4가 알파”
Apple ProRes 4444는 4:4:4:4 — Y, Cb, Cr, Alpha 각각 풀 해상도. Hollywood VFX 합성의 표준 마스터링 포맷. 12-bit 4:4:4:4 = 1080p에서 비트레이트 약 330 Mbps. 합성 단계가 끝나면 4:2:0 8bit H.264로 떨어뜨려 배포 — 변환의 끝.
요약 + Mermaid
YUV는 사람 시각의 “밝기 우선” 비대칭을 활용한 압축의 출발점이고, 4:2:0은 그 비대칭을 가장 공격적으로 쓰는 서브샘플링이다. 모든 소비자 H.264/HEVC/AV1 인코딩의 기본값. 텍스트·UI·고대비 그래픽에는 약하다. 마스터는 4:4:4 / 배포는 4:2:0의 일방향 변환. 매트릭스(BT.601/709/2020)와 Range(limited/full)는 메타데이터로 박지 않으면 색이 어긋난다.