The Three Redundancies
세 가지 중복 — 공간·시간·시각
비디오 압축이 가능한 이유는 데이터 안에 세 종류의 중복(redundancy)이 있기 때문이다. 모든 코덱은 이 셋을 어떻게 더 잘 발견하고 제거하느냐의 게임이다.
Overview
1장에서 "비디오는 압축 가능한 게 정보이론적 사실"이라고 했다. 이번 장은 그 정보이론적 자산의 정체를 구체화한다 — 세 가지 중복.
공간적·시간적·시각적 중복. 이 셋이 모든 비디오 코덱이 활용하는 자원이고, 코덱의 진화는 사실상 이 셋을 어떻게 더 영리하게 발견하고 제거하느냐의 누적이다. H.264 → H.265 → AV1의 차이도 결국 이 셋을 다루는 정교함의 차이로 설명할 수 있다.
- 세 가지 중복을 각각 정확히 정의할 수 있다
- 왜 인접 픽셀이 비슷한지(공간), 인접 프레임이 비슷한지(시간), 인간 눈이 둔감한지(시각)를 설명할 수 있다
- YUV 4:2:0 color subsampling이 왜 "공짜 50% 압축"인지 안다
- 각 중복이 코덱 파이프라인의 어느 단계에서 활용되는지 매핑할 수 있다
- 왜 모든 비디오 코덱이 RGB가 아닌 YUV를 쓰는지 이해한다
Sections
2.1 공간적 중복 (Spatial Redundancy) — 한 프레임 안에서
한 프레임을 자세히 보면 옆 픽셀이 거의 똑같다. 푸른 하늘은 수십만 픽셀이 거의 같은 파란색이고, 사람 얼굴은 부드러운 살색 그라데이션이다.
이 사실을 코덱은 이렇게 활용한다 — '이 픽셀은 위쪽 또는 왼쪽 픽셀로부터 예측 가능하다'. 예측이 맞으면 그 픽셀의 값을 다시 저장할 필요가 없다. '예측과의 차이(residual)'만 저장한다. 차이가 작을수록 압축이 잘 된다.
이게 인트라 예측(Intra prediction)의 원리다. H.264는 9방향, H.265는 35방향, AV1은 56방향. 방향이 많을수록 더 정확한 예측 → 더 작은 잔차 → 더 좋은 압축.
공간적 중복이 활용되는 곳: I-프레임의 인트라 예측, P/B 프레임 안의 인트라 블록.
2.2 시간적 중복 (Temporal Redundancy) — 프레임 사이에서
30fps 비디오에서 1번 프레임과 2번 프레임의 시간 차이는 1/30초. 그 짧은 시간에 화면 전체가 바뀌는 일은 거의 없다. 사람이 걷는 화면이라도 배경 99%가 그대로고, 다리 위치만 살짝 달라진다.
이걸 활용하는 게 인터 예측(Inter prediction) = 모션 보상(Motion Compensation). 2번 프레임의 어떤 블록을 처음부터 그릴 필요 없이, '1번 프레임의 (x+5, y) 위치에서 블록을 그대로 가져오면 거의 맞는다'고 알려주면 된다. 이때 그 '(+5, 0)'이 모션 벡터(Motion Vector)다.
시간적 중복이 활용되는 곳: P-프레임(이전 프레임 참조), B-프레임(이전+이후 둘 다 참조). 모션 벡터 + 작은 residual만 저장하면 되니까 P/B 프레임은 I 프레임보다 압축률이 압도적으로 높다. 보통 P는 I의 1/5~1/10 크기, B는 1/20~1/50 크기.
코덱 진화의 핵심은 "얼마나 정확한 모션 벡터를 빨리 찾느냐". 이게 챕터 5의 주제다.
2.3 시각적 중복 (Perceptual Redundancy) — 인간 눈의 한계
셋째 중복은 데이터 자체가 아니라 수신자(인간 눈)의 한계에서 온다.
사람 눈은 모든 신호에 동등하게 민감하지 않다. 잘 알려진 비대칭: - 밝기에는 민감, 색상에는 둔감 — 흑백 사진이 컬러보다 디테일이 잘 보이는 이유 - 저주파(부드러운 변화)에는 민감, 고주파(날카로운 디테일)에는 둔감 — 특히 움직이는 영역에서 - 밝은 영역의 노이즈는 잘 보이지 않음, 어두운 영역의 노이즈는 잘 보임 (Weber-Fechner)
이 비대칭이 손실 압축의 황금 영역이다. 사람이 인지 못 하는 정보를 골라 버린다 → 같은 화질에 더 작은 파일.
구체적으로 이게 활용되는 두 곳: 1. Color subsampling: 색상 채널 해상도를 밝기 채널의 절반으로 (YUV 4:2:0). 데이터량 즉시 50% 감소. 2. 양자화의 가중치: 저주파 계수는 정밀하게, 고주파 계수는 거칠게 양자화. 챕터 4에서 다룬다.
2.4 YUV 4:2:0 — 거의 공짜 50% 압축
현대 비디오는 RGB가 아니라 YUV(Y: 밝기, U/V: 색차) 공간에서 작업한다. 변환 공식은 단순한 선형 매트릭스.
Y(밝기)는 풀 해상도로 두고, U/V(색상)는 가로·세로 절반씩 다운샘플 → YUV 4:2:0. 결과: 데이터량이 RGB의 50%. 거의 공짜다. 화질 손실은 사람 눈으로 거의 인지 불가능.
다른 옵션: - 4:4:4: 색차도 풀 해상도 — 영화 제작·HDR 마스터링 등 전문 영역 - 4:2:2: 가로만 절반 — 방송용 (XDCAM 등) - 4:2:0: 가로·세로 모두 절반 — 거의 모든 소비자 비디오의 표준
왜 코덱 강의에서 이 디테일이 중요한가? 모든 H.264/H.265/AV1 인코더가 기본적으로 4:2:0을 가정하기 때문이다. 이 첫 단계가 이미 50% 압축이고, 나머지 단계들이 그 위에서 또 압축한다.
2.5 세 중복이 코덱 어디서 활용되는가
정리: 어떤 중복이 어디서 활용되는지 매핑.
| 중복 | 활용되는 코덱 단계 | 결과 | |---|---|---| | 공간적 | 인트라 예측 + DCT | I-프레임 효율 | | 시간적 | 인터 예측 (모션 보상) | P/B-프레임 효율 | | 시각적 | YUV 4:2:0 + 양자화 가중치 | 손실의 영리한 분배 |
H.264 → H.265 → AV1의 발전을 이 셋의 관점에서 보면: - 공간적: 인트라 예측 방향이 9 → 35 → 56으로 늘어남 - 시간적: 모션 벡터 정밀도가 1/4 픽셀 → 1/4 픽셀 + AMVP → 1/8 픽셀 + warped motion으로 발전 - 시각적: 양자화 매트릭스가 더 정교해지고, AV1은 적응형 양자화 + Loop Restoration까지
이 매핑이 머릿속에 있으면 나머지 챕터의 모든 디테일이 "아, 이건 어느 중복을 더 잘 활용하려는 거구나"로 자연스럽게 연결된다.
국제회의에서 영어 → 한국어 동시통역을 한다고 치자. 통역사는 모든 단어를 그대로 옮기지 않는다. 세 가지 종류의 '중복'을 본능적으로 제거한다.
공간적 중복: "the the the"처럼 한 문장 안의 반복은 한 번만 옮긴다. 시간적 중복: 발언자가 "like", "you know"를 반복하면 무시. 시각적(수신자의) 중복: 청중이 이미 아는 사실("미국 대통령은 워싱턴 D.C.에 산다")은 굳이 옮기지 않는다.
비디오 코덱이 정확히 이렇게 일한다. 한 프레임 안의 반복(공간), 프레임 사이의 반복(시간), 인간 눈이 못 보는 디테일(시각). 셋 다 발견해 제거하면, 100배 압축은 마법이 아니라 통역사가 본능적으로 하는 일이다.
공간·시간·시각 세 가지 중복을 직접 측정해 보자. 인접 픽셀 차이, 인접 프레임 차이, 색차 채널의 분포 — 각각이 얼마나 작은지 보면 압축의 자원이 보인다.
import numpy as np
import cv2
# 비디오 첫 두 프레임 읽기
cap = cv2.VideoCapture('sample.mp4')
_, frame1 = cap.read()
_, frame2 = cap.read()
cap.release()
# 1) 공간적 중복: 인접 픽셀과의 차이 분포
h_diff = np.abs(frame1[:, 1:].astype(int) - frame1[:, :-1].astype(int))
v_diff = np.abs(frame1[1:, :].astype(int) - frame1[:-1, :].astype(int))
print(f'평균 가로 픽셀 차이: {h_diff.mean():.2f} (0~255 중)')
print(f'평균 세로 픽셀 차이: {v_diff.mean():.2f}')
# 2) 시간적 중복: 프레임 간 차이
temporal_diff = np.abs(frame1.astype(int) - frame2.astype(int))
print(f'프레임 간 평균 차이: {temporal_diff.mean():.2f}')
print(f' → 픽셀의 {(temporal_diff < 5).mean()*100:.1f}%는 차이가 5 이하')
# 3) 시각적 중복: YUV 변환 후 색차 채널의 "정보량"
yuv = cv2.cvtColor(frame1, cv2.COLOR_BGR2YUV)
y, u, v = yuv[:,:,0], yuv[:,:,1], yuv[:,:,2]
print(f'Y(밝기) std: {y.std():.1f}')
print(f'U(색차) std: {u.std():.1f} ← 훨씬 작음')
print(f'V(색차) std: {v.std():.1f}')
# → U/V는 변동이 작아서 다운샘플해도 거의 안 보임 = 4:2:0 정당화
이 코드의 결과가 거짓말을 안 한다. 일반 비디오에서 인접 픽셀의 평균 차이는 10 이하(0~255 중)다. 인접 프레임의 60~80% 픽셀은 차이가 5 이하다. 그리고 YUV로 변환하면 U/V 채널의 분산이 Y의 1/3 정도다. 이 세 숫자가 바로 코덱이 활용하는 자원의 양이다. 압축률 100배가 마법이 아니라 이 자원의 정직한 활용 결과라는 사실이 보인다.
✅ 시니어가 보는 것
- 셋을 각각 정확히 정의하고 예시를 댈 수 있는지
- YUV 4:2:0이 왜 거의 공짜인지 (인간 시각의 비대칭) 설명 가능
- 코덱 진화를 '셋의 활용 정교화'로 매핑할 수 있는지
- RGB vs YUV 선택의 의미를 안다
⚠️ 레드 플래그
- 셋을 외운 단어로만 알고 예시를 못 댐
- 왜 YUV를 쓰는지 모름 ('전통이라서' 답변)
- 색상 채널이 밝기 채널보다 덜 중요하다는 사실을 모름
🎤 예상 인터뷰 질문
- 비디오 압축이 가능한 이유를 세 가지로 말해 보세요
- 왜 거의 모든 비디오 코덱이 4:2:0을 쓰나요? 4:4:4이 더 좋지 않나요?
- H.265가 H.264보다 더 잘 압축하는 이유를 '중복 활용'의 관점에서 설명해 주세요
Key Takeaways
세 가지 중복
공간(픽셀 사이) · 시간(프레임 사이) · 시각(인간 눈).
공간적 중복
인접 픽셀이 거의 같다 → 인트라 예측의 자원.
시간적 중복
인접 프레임이 거의 같다 → 모션 보상의 자원.
시각적 중복
인간 눈의 비대칭 → 손실의 영리한 분배.
YUV 4:2:0
거의 공짜 50% 압축. 모든 소비자 코덱의 기본.
Y vs UV
밝기에 민감, 색상에 둔감 → 색차 채널 다운샘플.
코덱 진화의 본질
셋을 더 정교하게 활용하는 누적.
압축은 정직한 게임
마법이 아니라 데이터 안의 진짜 중복을 발견·제거한다.