LODY/정리

컴퓨터 비전 / YCbCr이 H.264 압축에 맞는 이유

YCbCr이 H.264 압축에 맞는 이유

영상을 디스플레이용 RGB로만 보면 인코딩 파이프라인이 굳이 YCbCr을 쓰는 이유가 잘 안 드러난다. 아래에서는 코덱이 색을 어떻게 다루는지, H.264 비트스트림이 왜 그런 형태인지를 풀어 본다.


비압축 비용

예를 들어 해상도 4032 × 3024, RGB 8bit, 30fps라고 가정한다.

픽셀 수=4,032×3,024=12,192,7681,220RGB 24bit=1,220×3 byte=36 MB/frame초당=36 MB×30fps=1,080 MB/s1 GB/s\begin{aligned} \text{픽셀 수} &= 4{,}032 \times 3{,}024 = 12{,}192{,}768 \approx 1{,}220\text{만} \\ \text{RGB 24bit} &= 1{,}220\text{만} \times 3\text{ byte} = 36\text{ MB/frame} \\ \text{초당} &= 36\text{ MB} \times 30\text{fps} = 1{,}080\text{ MB/s} \approx 1\text{ GB/s} \end{aligned}

초당 1GB에 가깝다. 30초만 저장해도 30GB 급이다. 압축이 필수다.


코덱

코덱(Codec) 은 Coder + Decoder의 합성어다.

비디오 코덱이 압축하는 방식은 두 가지다. 핵심은 중복을 찾아내는 것이다.

공간적 중복 제거 (Intra-frame compression)

같은 프레임 내 인접 픽셀끼리 비슷한 값이 많다. DCT(Discrete Cosine Transform)로 픽셀 블록을 주파수 도메인으로 변환하고, 사람 눈에 덜 민감한 고주파 성분을 버린다. JPEG이 이 원리다.

시간적 중복 제거 (Inter-frame compression)

연속된 프레임끼리 대부분의 영역이 같다. 배경은 그대로고 움직이는 부분만 바뀐다. H.264/HEVC는 이전 프레임과의 차이(motion vector + residual)만 저장한다.


H.264와 YCbCr의 관계

H.264, HEVC, JPEG은 모두 내부적으로 YCbCr을 쓴다. 이유가 있다.

크로마 서브샘플링(YCbCr 4:2:0)으로 이미 색상 정보를 줄인 뒤 DCT를 적용하면 압축 효율이 훨씬 높다. RGB에서 직접 DCT를 돌리면 R, G, B 세 채널이 서로 강하게 상관관계를 가지고 있어서 에너지 집중(energy compaction)이 잘 안 된다. YCbCr로 변환하면 채널 간 상관관계가 줄어들고, Cb/Cr은 이미 절반 해상도라 DCT 계수가 더 잘 모인다.

촬영·전송·저장을 H.264/HEVC·JPEG 계열로 묶는 파이프라인은, 디스플레이용 RGB로 굽기 전에 인코더에 맞춘 YCbCr 4:2:0을 쓰는 설계가 일반적이다. 그래서 센서 이후 경로(예: ISP)에서 애초에 YCbCr로 맞춰 두는 경우가 흔하다.


H.264 비트스트림 구조

H.264 비트스트림은 NALU(Network Abstraction Layer Unit) 단위로 구성된다.

각 NALU 앞에 00 00 00 01 시작 코드가 붙는다. SPS(Sequence Parameter Set) 에 해상도·프레임률·프로파일 정보가 담기고, PPS(Picture Parameter Set) 에 양자화 파라미터와 엔트로피 코딩 모드가 담긴다. 그 뒤로 I-Frame(IDR Slice)과 P/B-Frame(Non-IDR Slice)이 이어진다.

인코더·디코더 구현(소프트웨어·하드웨어)은 압축·복원 시 이 NALU 스트림을 읽고 쓴다.


참고 자료